Liquid-glass UI redesign (2026-09-24)
Liquid-glass UI redesign — design
Section titled “Liquid-glass UI redesign — design”Status: approved in brainstorming by Chris, 2026-09-24. Mockups (browser companion, gitignored):
.superpowers/brainstorm/11906-1790207428/content/{levelup-layout,stats-overlay,stats-overlay-v2}.html.
Chris: “do a full redesign of the interface layouts, overall they feel a bit WIP, decide the best way to present the information particularly the level up interface, perhaps show just the 3 cards and allow one of the controller buttons to bring up an overlay showing ship stats … make everything look a bit more liquid glass with nova glows.”
Decisions taken in brainstorming:
- Level-up = layout C: three wide glass cards in a strip along the bottom third; the frozen arena stays visible above. (Chris picked C over the recommended centred-tall-cards A.)
- Ship stats = side sheet (A) with live card preview: Y opens a glass sheet over the top-left of the arena; the three cards stay visible and selectable underneath; moving focus between cards re-draws the sheet with that card applied (Chris: “keep the cards so the player can move to each one and see the changes to the stats if they need to”).
- One shared glass component; blur only where the game is paused; tinted glass (no blur) on the live HUD.
- Every screen gets a layout pass, not only a restyle.
- Dead (“no effect”) upgrade cards are never offered.
Why the current UI reads as WIP (baseline captures, tools/ui_sweep/baseline/)
Section titled “Why the current UI reads as WIP (baseline captures, tools/ui_sweep/baseline/)”- Level-up: a dense left column (cards + a separate detail box) and a right “BUILD OVERVIEW” column of monospace key/value text. Two places to read, rank labels on every card, a dud “no effect” card on offer, lots of empty panel.
- Pause: a stack of seven outlined buttons with a green debug string (“Remote control: not armed”) in the player-facing header.
- Bestiary: a plain text list with a mostly empty detail pane.
- Ship config: labels floating around the hull with no containing structure.
- Dimension choice: a single small button in a sea of dim arena.
- Styling is per-screen (
nova_box,_card_box,_btn_box, hand-built StyleBoxFlats), so the look drifts screen to screen.
1. Glass language
Section titled “1. Glass language”One visual system, defined once:
- Surface: a subtle vertical gradient (white 13% → 3.5%, faint cool tint), 1px pale border (~22% white), a bright 1px inner top highlight, a soft inner bottom shade, corner radius 16px at 1080p (scaled with the viewport like the rest of the UI).
- Frost (paused screens only): the game frame behind is blurred and slightly saturated,
sampled from the screen texture’s mip chain (
hint_screen_texture, filter_linear_mipmap+textureLod), so it costs one screen copy + mip build per frame, not a multi-pass blur. - Nova glow: focus is shown by an outer glow in the element’s accent colour (cyan stat/mod, violet crystal, gold weapon/evolve, green positive deltas, red danger) plus a brighter border. Unfocused glass has no outer glow. This replaces the current full-outline neon boxes.
- Type: Orbitron for names/titles, the existing mono font for numbers and lines; numbers use tabular figures. At 1080p, card names ≥ 28px and card lines ≥ 20px (the TV-legibility mitigation for layout C).
- Button prompts: real glyphs (A/B/X/Y) in a bottom hint bar, platform-resolved like the
tutorial’s
{move}/{aim}tokens (keyboard shows keys, touch shows nothing — touch taps the card).
Component: GlassPanel
Section titled “Component: GlassPanel”ui/theme/glass_panel.gd(class_name GlassPanel extends PanelContainer) +ui/theme/glass.gdshader.- API:
accent: Color,focus: float(0 = resting, 1 = focused),frosted: bool,dim: bool(unavailable/locked). Setters only; no per-screen StyleBoxFlat construction. frosted=falsedraws the same surface without sampling the screen texture (the HUD variant).NeonTheme.nova_box()stays for the old look; the new look routes throughGlassPanel.- Old look one flag away:
VisualLook.glass_ui(default true once shipped). With it false, every screen renders exactly as today — the existing ui-sweep baselines stay valid for that path.
2. Level-up (layout C)
Section titled “2. Level-up (layout C)”- Sim is paused (unchanged). A gradient dim darkens only the lower ~45% of the screen; the arena above stays readable.
- Title line above the strip:
LEVEL 7 · CHOOSE ONE(co-op:PLAYER 2 · LEVEL 7, P2 colour). - Three
GlassPanelcards across the strip (5% side margins, 2% gaps). Each card carries its own content; the separate detail box and the right-hand build column are removed:- kind label (BLASTER MOD / CRYSTALS / NEW WEAPON / STAT) in the accent colour,
- name,
- up to three change lines from
upgrade_effects()(target: detail, green for gains, gold for EVOLVE), or for a crystal card below a threshold, the nearestprogressline (27/30 → RAILSPIKE).
- Rank: one small
BESTpill on the top-ranked card only; no GOOD/OK/WEAK labels. - Focus: the focused card lifts (scale ~1.03) and glows; the others rest. Left/right moves focus (the current up/down also works so muscle memory survives). A confirms, as now.
- Hint bar:
A CHOOSE · Y SHIP STATS. - Entry animation: cards rise into place, staggered ~60ms (ui-sweep capture waits for the tween, per the known staggered-tween gotcha).
Dead cards never offered
Section titled “Dead cards never offered”Stat and mod duds are already kept out at roll time (mod_eligible() excludes capped fire rate
and the reaction-era CRYSTALS_DEAD_EFFECTS). The dud that still ships is a crystal grant that
crosses no threshold and builds towards none (baseline capture: “+3 Lightning, +2 Fire, +3 Kinetic
· no effect”). roll_upgrade_choices rejects a rolled crystal spec whose upgrade_effects() is
dead with empty progress and re-rolls it from the same upgrade_rng (bounded retries; if still
dead, that slot falls back to the mod/weapon pool). A crystal card that crosses nothing but builds
towards a threshold is kept (it shows progress). Because this can change the upgrade draw
sequence, the survival determinism baseline may need a re-pin, done deliberately in its own commit.
3. Ship stats overlay
Section titled “3. Ship stats overlay”- New
ui/stats_sheet.gd(StatsSheet), aGlassPanel(frosted) anchored top-left, ~40% width, ~56% height at 16:9; slides in from the left (~180ms). - Opens with Y (joypad), Tab (keyboard), a STATS pill (touch) while the level-up panel is
open, and from a new Ship stats entry in the pause menu (read-only there, no preview).
Y/Tab/B closes it. Y is safe to reuse:
main._inputalready suppresses its in-play HUD-toggle meaning while any modal is open. - Contents, two columns:
- Ship: hull name, Hull (bar), Armor, Speed, Fire rate, Pickup, DPS.
- Crystals: one bar per element the pilot holds,
have/next-threshold. - Weapons: one row per slot (hex icon, name, tier pips); empty slots shown. The selected weapon expands to its upgrade path (met rungs ✓, next rung, evolve condition) — this absorbs today’s → weapon inspector. Right stick or shoulder buttons move the weapon selection so the left stick/D-pad stays on the cards.
- Live preview: while the sheet is open over the level-up panel, the focused card’s effect is
drawn onto the sheet:
- stat/mod card: the matching row shows
old → new(fromupgrade_preview’snow/after) with a green glow; - crystal card: the element bar gains a ghost segment up to the new total; any rung it crosses
flags on the affected weapon row (
★ RAILSPIKE); - weapon card: a ghost of the new weapon fills the first empty slot.
- No DPS delta is shown: nothing in the sim computes one, and inventing one would mislead. DPS shows the current value only.
- stat/mod card: the matching row shows
- The sheet reads sim/pilot state only (one-way data flow preserved); preview values come from the
existing
upgrade_effects()/upgrade_preview()calls the panel already makes. - Co-op: the sheet shows the pilot whose panel is open and obeys the same device gate as the panel.
4. Other screens (layout pass + glass)
Section titled “4. Other screens (layout pass + glass)”Order of work, each its own commit and ui-sweep re-bless:
- Pause — title + run time, then a compact glass column: Resume, Ship stats, Ship, Shop, Bestiary, Quit to menu. Remote control and Debug settings move under a single dimmed “Dev” entry at the bottom (still reachable on device builds, where Remote Control is used); the “Remote control: not armed” line leaves the header. Build number stays, small.
- Start menu — keep the carousel (Chris’s choice), cards become
GlassPanels with the existing hologram brackets on the focused card; title gets the Nova glow treatment. - Results — a glass summary card (time, kills, level, gold earned, cause of death) above the existing three-action carousel.
- Dimension choice — the three options as glass cards in the same bottom-strip layout as level-up (one layout family for all “pick 1 of N in-run” choices), each with its element colour, boss name and one line of flavour.
- Shop — carousel cards and the item grid on glass; gold total in a glass pill.
- Ship config — the hull sits in a glass bay with slots arranged on a clear ring; stats in a
StatsSheet(read-only mode) instead of floating labels. - Bestiary — glass list (left) with element dot + threat pips per row; the detail pane gets a large enemy render, stat chips and the counter text in a glass card.
- Dialogue box — glass panel, speaker name as a glowing tab; layout rules from the 2026-08-19 tutorial pass (viewport-relative, clear of touch buttons) are kept.
- HUD docks — weapon and drone hexes on unfrosted glass; wave banner and HP bar keep their current behaviour, restyled.
5. Performance
Section titled “5. Performance”- Frost is only ever drawn while the sim is paused (level-up, stats sheet, pause and its children, results, dimension choice, shop, ship config, bestiary, dialogue freeze). The HUD never samples the screen texture.
- Multiple frosted panels on one screen share one screen copy (a single
BackBufferCopyper screen, not one per panel). - Gate: a real Apple TV frame-time check on the level-up screen with the stats sheet open, via telemetry, before this is called done. The paused frame has no swarm cost, so the budget is loose, but it is measured, not assumed.
6. Testing
Section titled “6. Testing”- GUT:
GlassPanelsetters (focus/accent/frosted);StatsSheetpreview mapping for each card kind (stat row delta, crystal ghost + crossed rung, weapon ghost slot) driven through the realupgrade_effects(); dead-card filtering through the realroll_upgrade_choicespath (never hand-set state); level-up focus/confirm with left/right and up/down; Y/Tab open-close and the co-op device gate. - ui-sweep: new baselines per screen, blessed only after eyeballing; the old-look path
(
VisualLook.glass_ui = false) keeps passing against the old baselines. - Determinism: re-pin the survival baseline once for the dead-card filter, in its own commit.
- Soak: one clean
scripts/soak.shrun after the dead-card filter. - On-device: Apple TV build for Chris’s eye and the frame-time gate.
7. Release process
Section titled “7. Release process”This is a freeze exception under docs/RELEASE-0.1.md §0. It ships behind VisualLook.glass_ui.
The exception slot must be confirmed by Chris against the current candidates list before
implementation starts (see open question below).
Open question for Chris
Section titled “Open question for Chris”RELEASE-0.1.md caps graphics freeze exceptions at 3, and three candidates are already listed
(enemy hit-flash, damage-number merge, the Nova look). This redesign would be a fourth. Either one
of those drops, or the cap goes to 4.
Out of scope
Section titled “Out of scope”- New gameplay, stats or upgrade mechanics (the dead-card filter only removes duds).
- A DPS-delta calculator.
- The debug settings panel’s internal layout (dev-only).
- Touch-control button art beyond the STATS pill.