/* poc/css/ui.css — shell tokens + base components shared by every screen.
   Palette copied from ui-prototype: navy #05060f, teal #66e0d0, green #34d399,
   amber #ffc844. Loaded after style.css so these rules win during the bridge. */

:root {
  --bg: #05060f;   --bg2: #0b0e1e;  --bg3: #121633;  --line: #1e2450;
  --teal: #66e0d0; --teal-dim: #3a8f86;
  --green: #34d399; --amber: #ffc844; --red: #ff5c6c;
  --purple: #b06cff; --blue: #4aa8ff; --gray: #9aa3b2;
  --txt: #d8e2ff;  --muted: #6b73a0;
  --top-h: 64px;   --tab-h: 72px;
  --coin: 16px;    /* one size for every inline currency icon */
}

/* ---- base components ---- */
.card { border: 1px solid var(--line); background: var(--bg2); padding: 10px; }

.btn { display: inline-block; border: 2px solid var(--teal); color: var(--teal); padding: 8px 10px; font-size: calc(8px * var(--fs, 1)); letter-spacing: 1px; text-align: center; }
.btn:active, .btn.pressed { background: var(--teal); color: var(--bg); }
.btn.green { border-color: var(--green); color: var(--green); }
.btn.amber { border-color: var(--amber); color: var(--amber); }
.btn.dim { border-color: var(--line); color: var(--muted); pointer-events: none; }
/* not yet playable — reads as a real control, just switched off */
.btn.off { border-color: var(--line); color: #4b5266; pointer-events: none;
  background: repeating-linear-gradient(45deg, transparent 0 5px, rgba(255,255,255,.03) 5px 10px); }
.btn.wide { display: block; width: 100%; }

.chip { display: flex; align-items: center; gap: 3px; padding: 3px 5px; border: 1px solid var(--line); background: var(--bg2); }
.chip img { width: 14px; height: 14px; }
.chip.plus::after { content: '+'; color: var(--green); margin-left: 2px; }

.price { font-size: calc(7px * var(--fs, 1)); color: var(--muted); display: flex; gap: 4px; align-items: center; justify-content: center; }
.price img { width: var(--coin); height: var(--coin); }

.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.grid4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }

/* blueprint strip row above the tree */
.budget { display: flex; gap: 6px; font-size: calc(7px * var(--fs, 1)); margin-bottom: 8px; flex-wrap: wrap; }
.budget .chip { padding: 3px 5px; }
/* small muted line under a heading or control */
.hint { font-size: calc(6px * var(--fs, 1)); color: var(--muted); margin: -2px 0 8px; letter-spacing: 0; }
/* coming-soon note on a parked feature */
.soon { font-size: calc(6px * var(--fs, 1)); color: var(--muted); margin-top: 5px; letter-spacing: 0; }

/* ---- shell frame (U003) ---- */
/* The five-tab shell, full-bleed inside #start-screen. Ported from
   ui-prototype/css/style.css minus the .phone frame. z-index 3 sits above the
   in-run chrome (2) and below the rank-up panel (4) — the legacy pages that
   used to sit at 4 are gone (U015). Topbar rules are U004's. */
/* no background of its own: #stars (z 0) and the idle #player (z 1) show
   through on PLAY (001 #layout) — the other four screens paint their own */
#shell { position: absolute; inset: 0; z-index: 3; overflow: hidden; color: var(--txt); font-size: calc(8px * var(--fs, 1)); }
/* :where() keeps these resets at zero specificity, so .btn and a screen's own
   button classes still win */
:where(#shell) img { image-rendering: pixelated; image-rendering: crisp-edges; }
:where(#shell) button { font-family: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

/* screens host — one section visible at a time, the tabbar band stays clear */
#screens { position: absolute; top: 0; left: 0; right: 0; bottom: var(--tab-h); }
#shell .screen { position: absolute; inset: 0; display: none; overflow-y: auto; overflow-x: hidden; padding: calc(var(--top-h) + 6px) 12px 16px; scrollbar-width: none; }
#shell .screen::-webkit-scrollbar { display: none; }
#shell .screen.active { display: block; }
/* every screen but PLAY is opaque, like the prototype and the legacy pages */
#shell .screen:not([data-screen="play"]) { background: var(--bg); }

/* bottom nav — 5 equal tabs, PLAY styled like the rest */
#tabbar { position: absolute; left: 0; right: 0; bottom: 0; height: var(--tab-h); z-index: 6; display: grid; grid-template-columns: repeat(5, 1fr); background: var(--bg2); border-top: 1px solid var(--line); }
#tabbar button { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px; font-size: calc(7px * var(--fs, 1)); letter-spacing: 1px; color: var(--muted); }
#tabbar button img { width: 42px; height: 42px; opacity: .2; }
#tabbar button.active { color: var(--teal); }
#tabbar button.active img { opacity: 1; }
/* the glow the play screen's .bigplay pulses with */
@keyframes tab-pulse { 0%, 100% { box-shadow: 0 0 10px rgba(102, 224, 208, .25); } 50% { box-shadow: 0 0 22px rgba(102, 224, 208, .6); } }

/* bottom sheet + toast — shell.mjs toggles .open / .show and nothing else, so
   the slide and the fade actually run */
#sheet-backdrop { position: absolute; inset: 0; z-index: 8; display: none; background: rgba(0, 0, 0, .6); }
#sheet-backdrop.open { display: block; }
#sheet { position: absolute; left: 0; right: 0; bottom: 0; z-index: 9; transform: translateY(110%); transition: transform .22s ease-out; background: var(--bg2); border-top: 2px solid var(--teal); padding: 14px 14px 20px; font-size: calc(7px * var(--fs, 1)); }
#sheet.open { transform: translateY(0); }
#sheet h3 { font-size: calc(10px * var(--fs, 1)); color: var(--teal); margin-bottom: 8px; }
#sheet p { color: var(--muted); line-height: 1.7; margin-bottom: 8px; }
#toast { position: absolute; left: 50%; bottom: calc(var(--tab-h) + 14px); z-index: 10; transform: translate(-50%, 10px); opacity: 0; transition: .2s; padding: 8px 12px; font-size: calc(7px * var(--fs, 1)); color: var(--bg); background: var(--teal); pointer-events: none; }
#toast.show { opacity: 1; transform: translate(-50%, 0); }

/* the run gate: setShellVisible(false) sets hidden, and no rule above beats it */
#shell[hidden] { display: none; }

/* ---- topbar (U004) ---- */
/* the fixed strip above the screens: LV + xp bar left, wallet chips and the
   gear right. Ported from ui-prototype's .topbar onto the #topbar host. */
#topbar { position: absolute; top: 0; left: 0; right: 0; height: var(--top-h); z-index: 5; display: flex; align-items: center; gap: 8px; padding: 0 10px; background: linear-gradient(var(--bg) 70%, transparent); font-size: calc(10px * var(--fs, 1)); }
#topbar .lvl { display: flex; align-items: center; gap: 6px; }
#topbar .lvl-badge { color: var(--amber); border: 1px solid var(--amber); padding: 5px 6px; }
#topbar .xp-ic { width: 20px; height: 20px; }
#topbar .xpbar { width: 56px; height: 8px; border: 1px solid var(--line); background: var(--bg2); display: block; }
#topbar .xpbar i { display: block; height: 100%; background: var(--amber); }
#topbar .wallet { display: flex; gap: 6px; margin-left: auto; }
#topbar .gear { display: flex; align-items: center; justify-content: center; height: 40px; font-size: 34px; line-height: 1; color: var(--muted); transform: translateY(-6px); }
#topbar .chip { gap: 4px; padding: 4px 6px; }
#topbar .chip img { width: 20px; height: 20px; }

/* ---- play screen (U006 → M006) ---- */
/* The PLAY body is drawn OVER the pre-play scene: the section paints nothing
   and takes no clicks, so #stars (z 0) and the idle #player (z 1) stay visible
   and live — only the stage head, strip and big button are hit targets (the
   head is pointer-transparent too). Ported from ui-prototype/css/style.css
   lines 200-214, plus the .stagehead itself (201-203) now that PLAY reads a
   real chapter/stage from levels.mjs. The glow is ui.css's own tab-pulse —
   the legacy `pulse` keyframe went with U015. */
#shell .screen[data-screen="play"] { flex-direction: column; justify-content: flex-end; pointer-events: none; overflow: hidden; }
#shell .screen[data-screen="play"].active { display: flex; }

.stagehead { text-align: center; margin: calc(var(--top-h) + 16px) 0 auto; pointer-events: none; }
.stagehead .ch { font-size: calc(7px * var(--fs, 1)); color: var(--teal-dim); letter-spacing: 2px; }
.stagehead .st { font-size: calc(16px * var(--fs, 1)); color: var(--teal); margin-top: 6px; text-shadow: 0 3px 0 #0a2a28; }

.loadout { display: flex; gap: 6px; justify-content: center; margin-bottom: 12px; pointer-events: auto; }
.loadout .lo { font-size: calc(6px * var(--fs, 1)); padding: 6px 8px; border: 1px solid var(--line); background: rgba(11, 14, 30, .85); }
.loadout .lo b { color: var(--teal); }
.loadout .lo.pas b { color: var(--purple); }
.loadout .lo.edit { color: var(--teal); border-color: var(--teal-dim); cursor: pointer; }

.bigplay { display: block; width: 100%; padding: 16px 0; font-size: calc(16px * var(--fs, 1)); letter-spacing: 4px; border: 3px solid var(--teal); color: var(--teal); background: rgba(5, 6, 15, .7); pointer-events: auto; animation: tab-pulse 1.6s ease-in-out infinite; }
.bigplay:active { background: var(--teal); color: var(--bg); }

/* the idle float — the prototype's .hero bob (its style.css line 147) as a
   class on #player, added on show() and dropped on hide(). Safe because
   js/core/entity.mjs positions the ship with left/top, never transform. */
#player.idle-float { animation: hover 3s ease-in-out infinite; }
@keyframes hover { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }

/* ---- map screen (U013 → M006) ---- */
/* Ported from ui-prototype/css/style.css lines 218-235 (.chapter, .path,
   .stage) plus the progress paint at 201-204, 225, 231-238, 265: .locked
   chapters/nodes, the .current ring (tab-pulse, this file line 74 — the
   prototype's own `pulse` keyframe is gone, deleted in U015), .stars and
   .lockmsg. The blocks stack highest chapter first, so chapter 1 is the last
   one and the screen opens scrolled to it (map.screen.mjs show()). */
#shell .screen[data-screen="map"] { padding: 0; }
.chapter { position: relative; min-height: 640px; background-size: cover; background-position: center; }
.chapter::before { content: ''; position: absolute; inset: 0; background: rgba(5, 6, 15, .45); }
/* the head sits UNDER its path — it labels the chapter you climb into from below */
.chapter .head { position: relative; padding: 8px 14px 16px; }
.mapback + .chapter { padding-top: calc(var(--top-h) + 8px); } /* the top block clears the topbar */
.chapter .head .n { font-size: calc(7px * var(--fs, 1)); color: var(--teal-dim); letter-spacing: 2px; }
.chapter .head .nm { font-size: calc(12px * var(--fs, 1)); color: var(--txt); margin-top: 6px; text-shadow: 0 2px 0 #000; }
.chapter .head .prog { font-size: calc(6px * var(--fs, 1)); color: var(--muted); margin-top: 6px; }

.path { position: relative; height: 560px; }
.path svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.stage { position: absolute; width: 52px; height: 52px; margin: -26px 0 0 -26px; display: grid; place-items: center; cursor: pointer; }
.stage img { width: 40px; height: 40px; }
.stage .num { position: absolute; bottom: -10px; font-size: calc(6px * var(--fs, 1)); color: var(--txt); background: var(--bg); padding: 2px 3px; border: 1px solid var(--line); }
.stage.boss img { width: 52px; height: 52px; }
.stage.boss .num { color: var(--red); }
.stage .stars { position: absolute; top: -17px; display: flex; gap: 2px; }
.stage .stars .star { position: static; background: none; font-size: calc(13px * var(--fs, 1)); color: var(--muted); text-shadow: 0 1px 0 #000, 0 0 3px #000; }
.stage .stars .star.on { color: var(--amber); }
.stage.locked img { filter: grayscale(1) brightness(.5); }
.stage.current::before { content: ''; position: absolute; inset: 3px; border-radius: 50%; border: 2px solid var(--teal); animation: tab-pulse 1.6s ease-in-out infinite; }
.stage.boss.current::before { inset: -3px; }

.chapter.locked .path { filter: grayscale(.7) brightness(.55); }
.chapter .lockmsg { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 2; text-align: center; font-size: calc(7px * var(--fs, 1)); line-height: 1.8; color: var(--txt); }
.chapter .lockmsg img { width: 32px; height: 32px; display: block; margin: 0 auto 6px; }

/* the sheet's button row — the prototype's .actions (its style.css 156) */
#sheet .actions { display: flex; gap: 8px; margin-top: 10px; }
#sheet .actions .btn { flex: 1; }
#sheet .best { display: flex; gap: 3px; margin-top: 6px; }
#sheet .best .star { position: static; background: none; font-size: calc(14px * var(--fs, 1)); color: var(--muted); text-shadow: 0 1px 0 #000, 0 0 3px #000; }
#sheet .best .star.on { color: var(--amber); }
#sheet .rules { list-style: none; padding: 0; margin: 6px 0; color: var(--muted); line-height: 1.8; }
#sheet .rewards { display: flex; gap: 6px; margin: 8px 0 12px; }

/* ---- extras screen (U014) ---- */
/* The three render-only cards. Ported from ui-prototype/css/style.css .ex
   (241-255); .card, .btn, .btn.off and .soon are U002 base components and are
   NOT redefined here. Only the PVP card carries a meter, so the prototype's
   per-card meter colours collapse to one rule. The section heading is scoped to
   this screen so it cannot fight another screen's own h2. */
#shell .screen[data-screen="extras"] h2 { font-size: calc(9px * var(--fs, 1)); color: var(--teal-dim); letter-spacing: 2px; margin: 14px 0 8px; }

.ex { display: grid; grid-template-columns: 48px 1fr; gap: 10px; align-items: center; margin-bottom: 8px; }
.ex img { width: 48px; height: 48px; }
.ex .ttl { font-size: calc(9px * var(--fs, 1)); color: var(--txt); }
.ex .sub { font-size: calc(6px * var(--fs, 1)); color: var(--muted); margin-top: 5px; line-height: 1.6; }
.ex .cta { grid-column: 1 / -1; display: flex; gap: 6px; align-items: center; }
.ex .cta .btn { flex: 1; }
.ex .cta .timer { font-size: calc(6px * var(--fs, 1)); margin-left: auto; }
.ex .meter { grid-column: 1 / -1; height: 6px; border: 1px solid var(--line); background: var(--bg3); }
.ex .meter i { display: block; height: 100%; background: var(--red); }
/* the YOU / ENEMIES modifier pair on a challenge card */
.ex .eff { display: flex; gap: 6px; margin-bottom: 4px; }
.ex .eff span { flex: 0 0 38px; letter-spacing: 0; }
.ex .eff .you { color: var(--teal); }
.ex .eff .foe { color: var(--red); }

/* ---- shop screen (U008) ---- */
/* Ported from ui-prototype/css/style.css lines 110-135 (.boxslot, .timerbar,
   .timer, .keys, .keycard, .gemcard, .btn.buybig). The prototype's .freebox
   (DAILY FREE BOX) and its SKIP price line have no poc source and are dropped.
   .card, .btn, .btn.dim, .btn.off, .chip, .grid2 and --coin are U002 base
   components and are not redefined here; .btn.buybig is a NEW modifier, used
   only by the key shop. The h2 is scoped to this screen so it cannot fight
   another screen's own h2. */
#shell .screen[data-screen="shop"] h2 { font-size: calc(9px * var(--fs, 1)); color: var(--teal-dim); letter-spacing: 2px; margin: 14px 0 8px; }
#shell .screen[data-screen="shop"] h2 small { color: var(--muted); float: right; letter-spacing: 0; }

/* one cell = one queue entry; four of them, always, inside a .grid2 */
.boxslot { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; padding: 10px 6px; min-height: 130px; }
.boxslot > img { width: 48px; height: 48px; } /* box art only — cost icons keep --coin */
.boxslot .tier { font-size: calc(7px * var(--fs, 1)); }
.boxslot.empty { border-style: dashed; color: var(--muted); font-size: calc(7px * var(--fs, 1)); cursor: pointer; }
/* no usable key: the cell still takes the tap, and answers with the NO KEY toast */
.boxslot.empty.nokey { color: #4b5266; border-color: var(--line); }
.timerbar { width: 100%; height: 5px; background: var(--bg3); border: 1px solid var(--line); }
.timerbar i { display: block; height: 100%; background: var(--teal); }
.timer { font-size: calc(7px * var(--fs, 1)); color: var(--teal); }

/* the box.data.mjs tier colours, as classes — no screen writes a hex */
.tier-gray { color: var(--gray); }
.tier-blue { color: var(--blue); }
.tier-purple { color: var(--purple); }
.tier-gold { color: var(--amber); }

/* key inventory — its own row, so the keys read big (topbar chips stay 14px) */
.keys { display: flex; gap: 6px; margin-top: 8px; }
.keys .chip { flex: 1; justify-content: center; gap: 6px; padding: 8px 6px; font-size: calc(8px * var(--fs, 1)); }
.keys .chip img { width: 28px; height: 28px; }

.keycard, .gemcard { text-align: center; display: flex; flex-direction: column; gap: 6px; align-items: center; }
.keycard img { width: 32px; height: 32px; }
.keycard b { font-size: calc(9px * var(--fs, 1)); line-height: 1.5; }
/* BUY carries its own price tag: big verb, small gem */
.btn.buybig { display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; padding: 10px 6px; font-size: calc(12px * var(--fs, 1)); }
.btn.buybig .cost { display: flex; align-items: center; gap: 4px; font-size: calc(9px * var(--fs, 1)); font-style: normal; color: var(--muted); }
.btn.buybig .cost img { width: var(--coin); height: var(--coin); }
.btn.buybig:active .cost, .btn.buybig.pressed .cost { color: var(--bg); }
.gemcard img { width: 28px; height: 28px; }
.gemcard b { font-size: calc(10px * var(--fs, 1)); color: var(--teal); }
.gemcard .bonus { font-size: calc(6px * var(--fs, 1)); color: var(--green); }

/* ---- ships screen (U009) ---- */
/* HANGAR | TREE | WORKSHOP: the sub-tab row, the blueprint strip host under it
   and the three bodies — one visible, the hidden ones keeping their DOM. The
   BULLETS | PASSIVES segment lives inside the WORKSHOP body. Ported from
   ui-prototype/css/style.css lines 103-108 (.subtabs, .segment); the strip
   itself is the base .budget row + .chip (U002), blueprints only. The bodies
   host the panels, which bring their own rules from poc/css/style.css; the
   TREE body's own box is U011's block below. */
.subtabs { display: grid; grid-template-columns: repeat(3, 1fr); border: 1px solid var(--line); margin-bottom: 10px; }
.subtabs button { padding: 9px 0; font-size: calc(7px * var(--fs, 1)); color: var(--muted); letter-spacing: 1px; }
.subtabs button.active { background: var(--bg3); color: var(--teal); }

/* one body visible; display:none is the whole switch, so the hidden ones keep
   their DOM and their scroll */
.ships-sub { display: none; }
.ships-sub.active { display: block; }

.segment { display: inline-flex; border: 1px solid var(--line); margin-bottom: 8px; }
.segment button { padding: 6px 10px; font-size: calc(7px * var(--fs, 1)); color: var(--muted); }
.segment button.active { background: var(--bg3); color: var(--teal); }
.ws-body { display: none; }
.ws-body.active { display: block; }

/* ---- hangar (U010) ---- */
/* The HANGAR body: the picked hull previewed big, its stat bars and allowed
   shape / passive pills on a .card, and the three-column roster under it.
   Ported from ui-prototype/css/style.css lines 137-157 (.shipgrid, .shipcard,
   .preview, .stats, .bar, .pills, .pill, .actions). .card and .btn are U002
   base components and are NOT redefined here, and the float reuses U006's
   `hover` keyframes rather than declaring a second copy. The prototype's
   HULL bar is dropped — poc hulls carry no hp stat, only multipliers — and so
   is its .shipcard price line: no poc hull has a price (006). The button row
   is scoped to this body so it cannot fight `#sheet .actions` (U013). */
.preview { position: relative; height: 170px; margin: 0 0 8px; border: 1px solid var(--line); background: radial-gradient(ellipse at 50% 60%, #0f1a3a, var(--bg) 70%); display: flex; align-items: center; justify-content: center; }
.preview img { width: 128px; height: 128px; object-fit: contain; animation: hover 3s ease-in-out infinite; }
.preview .nm { position: absolute; top: 8px; left: 10px; font-size: calc(10px * var(--fs, 1)); color: var(--teal); }
.preview .cap { position: absolute; top: 8px; right: 10px; font-size: calc(7px * var(--fs, 1)); color: var(--purple); }

/* label · bar · value, one row per multiplier the def carries */
.stats { display: grid; grid-template-columns: 60px 1fr 30px; gap: 6px 8px; font-size: calc(7px * var(--fs, 1)); align-items: center; }
.stats .v { color: var(--muted); text-align: right; }
.bar { height: 6px; background: var(--bg3); border: 1px solid var(--line); }
.bar i { display: block; height: 100%; background: var(--teal); }

/* a pill states what the hull MAY buy — passives read purple, like the topbar */
.pills { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.pill { font-size: calc(6px * var(--fs, 1)); padding: 3px 5px; border: 1px solid var(--line); color: var(--muted); }
.pill.on { color: var(--teal); border-color: var(--teal); }
.pill.on.pas { color: var(--purple); border-color: var(--purple); }

.ships-sub[data-sub="hangar"] .actions { display: flex; gap: 8px; margin-top: 10px; }
.ships-sub[data-sub="hangar"] .actions .btn { flex: 1; }
/* the hold owns the gesture — no scroll/pan steal, no text selection mid-press
   (carried over from the legacy page's hold-to-reset, deleted in U015) */
.ships-sub[data-sub="hangar"] .actions [data-wipe] { touch-action: none; user-select: none; -webkit-user-select: none; }
/* arming FILLS over the hold, like the legacy hold-to-reset did: 1.2s linear
   forwards = HOLD_WIPE_MS in hangar.panel.mjs. Its own keyframe name — the
   legacy `wipe-arm` went with U015 and is never redefined here. */
.ships-sub[data-sub="hangar"] .actions .btn.arming { color: var(--red); border-color: var(--red); animation: hangar-wipe-arm 1.2s linear forwards; }
@keyframes hangar-wipe-arm { from { background: transparent; } to { background: rgba(255, 92, 108, .25); } }

.shipgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 10px; }
.shipcard { text-align: center; padding: 8px 4px 10px; font-size: calc(6px * var(--fs, 1)); line-height: 1.6; border: 1px solid var(--line); background: var(--bg2); }
.shipcard img { display: block; width: 60px; height: 60px; margin: 0 auto; object-fit: contain; }
.shipcard.selected { border-color: var(--teal); box-shadow: inset 0 0 0 1px var(--teal); }
.shipcard.locked img { opacity: .45; }
.shipcard .nm { display: block; margin-top: 6px; color: var(--txt); }
.shipcard .st { display: block; margin-top: 3px; color: var(--muted); }

/* ---- tree tab (U011) ---- */
/* The TREE sub-tab hosts poc/js/ui/tree.panel.mjs UNCHANGED, so the only css
   this task owns is the BOX the panel's viewport fills — the node, edge and
   tooltip rules ride with the panel in poc/css/style.css and are not touched
   here (U002). The legacy `.panel-tree .up-viewport` rule there was keyed on
   the old page's class and died with U015; this pair replaces it under the new
   host. Both lines are load-bearing, not decoration: the panel clamps its pan
   against viewport.clientWidth/clientHeight, so the body must be a positioned
   box with a real height BEFORE showTreePanel() runs — a zero-size viewport
   centres the canvas wrongly. Sizing only, no repaint. */
.ships-sub[data-sub="tree"].active { position: relative; height: 62vh; border: 1px solid var(--line); }
.ships-sub[data-sub="tree"] .up-viewport { position: absolute; inset: 0; }

/* ---- workshop (U012) ---- */
/* The BULLETS and PASSIVES bodies inside the WORKSHOP sub-tab: the shape
   ladder, the cap-long slot strip and the passive rows. Ported from
   ui-prototype/css/style.css lines 176-192 (.ladder, .shape, .slots, .slot,
   .passive) onto the panels' OWN class names — weapons.panel.mjs and
   passives.panel.mjs keep the .weapon-row / .passive-row vocabulary that
   poc/css/style.css and their tests read, so every rule here is scoped to
   .ws-body and simply wins on specificity during the bridge. .price, .hint,
   .btn and --coin are U002 base components and are not redefined. The
   prototype's NOT ON HULL card has no rows to sit on (the panels list the hull
   SUBSET, commit 2316c7f) and is dropped with its .notallowed rule.

   LEGACY RESET: poc/css/style.css's .weapon-row, .weapon-state, .passive-cap
   and .passive-row.equipped still reach these elements — a passive row wears
   the weapon-row classes, so both land on it. U015 kept those rules because
   the two panels still build that DOM; the first rules below neutralise every
   property they carry that the prototype does not want (margin-bottom,
   border-radius, letter-spacing, the spread justify-content, the 2px tracking,
   the hardcoded greys and the teal affordable border). */
.ws-body .weapon-row, .ws-body .passive-row { margin-bottom: 0; border-radius: 0; letter-spacing: 0; color: var(--txt); }
.ws-body .weapon-row.affordable { border-color: var(--line); } /* legacy paints this teal */
.ws-body .passive-cap { font-size: calc(7px * var(--fs, 1)); letter-spacing: 0; color: var(--muted); }

.ws-body .ladder { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.ws-body .ladder .weapon-row { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px; text-align: center; padding: 8px 4px; font-size: calc(7px * var(--fs, 1)); border: 1px solid var(--line); background: var(--bg2); }
.ws-body .weapon-glyph { width: 28px; height: 28px; display: grid; place-items: center; font-size: calc(12px * var(--fs, 1)); color: var(--teal); }
.ws-body .ladder .weapon-row.owned { border-color: var(--teal); }
.ws-body .ladder .weapon-row.locked { opacity: .4; }
.ws-body .ladder .weapon-row.affordable { cursor: pointer; }
.ws-body .weapon-state { font-size: calc(5px * var(--fs, 1)); color: var(--muted); }
.ws-body .weapon-row.owned .weapon-state { color: var(--teal); }
.ws-body .weapon-row.affordable .weapon-state { color: var(--green); }

/* the slot strip: one cell per passiveCap slot, the cap line as its caption */
.ws-body .passive-cap { margin: 8px 0; }
.ws-body .cap-label { font-size: calc(6px * var(--fs, 1)); color: var(--muted); letter-spacing: 0; }
.ws-body .slots { display: flex; gap: 6px; margin-top: 6px; }
.ws-body .slot { flex: 1; height: 44px; border: 1px dashed var(--purple); display: grid; place-items: center; font-size: calc(7px * var(--fs, 1)); color: var(--purple); }
.ws-body .slot.filled { border-style: solid; background: var(--bg3); }

/* the passive rows: the prototype's .passive card, on the panel's own row */
.ws-body .passive-row { display: flex; align-items: center; justify-content: flex-start; gap: 8px; padding: 8px; font-size: calc(7px * var(--fs, 1)); border: 1px solid var(--line); background: var(--bg2); }
.ws-body .passive-row + .passive-row { margin-top: 6px; }
.ws-body .passive-glyph { width: 36px; height: 36px; flex: none; border: 1px solid var(--line); display: grid; place-items: center; font-size: calc(14px * var(--fs, 1)); color: var(--purple); }
.ws-body .passive-name { flex: 1; font-size: calc(8px * var(--fs, 1)); }
.ws-body .passive-cost { justify-content: flex-start; }
.ws-body .passive-row.affordable { cursor: pointer; }
.ws-body .passive-row.equipped { border-color: var(--purple); }
.ws-body .passive-equip { padding: 6px 8px; font-size: calc(6px * var(--fs, 1)); cursor: pointer; }

/* ---- clear screen (M007) ---- */
/* #win-screen content (003 #clearscreen). Box + z-index 3 stay in style.css.
   Every revealed element carries --d (ms); .play starts, .skip jumps to the end. */
#win-screen .clear { width: 86%; max-width: 360px; padding: 16px; background: var(--bg2); border: 2px solid var(--line); text-align: center; font-size: calc(8px * var(--fs, 1)); color: var(--txt); animation: clear-in .2s ease-out; }
@keyframes clear-in { from { opacity: 0; } to { opacity: 1; } }
#win-screen .rv, #win-screen .star { opacity: 0; transition: opacity .2s var(--d, 0ms), color .2s var(--d, 0ms); }
#win-screen.play .rv, #win-screen.play .star { opacity: 1; }
#win-screen.skip .rv, #win-screen.skip .star { transition: none; }
#win-screen .cl-ch { color: var(--muted); letter-spacing: 2px; }
#win-screen .cl-title { margin-top: 8px; font-size: calc(14px * var(--fs, 1)); color: var(--amber); text-shadow: 0 0 12px rgba(255, 200, 68, .5); }
#win-screen .cl-stars { margin: 12px 0 4px; font-size: calc(22px * var(--fs, 1)); letter-spacing: 8px; }
#win-screen .star { position: static; background: none; color: var(--line); }
#win-screen.play .star.on { color: var(--amber); }
#win-screen .cl-best { color: var(--green); }
#win-screen .cl-rules { list-style: none; margin: 10px 0; padding: 8px 0; border-block: 1px solid var(--line); text-align: left; line-height: 2; }
#win-screen .cl-rules li { display: flex; justify-content: space-between; }
#win-screen .cl-rules li.ok span:first-child { color: var(--green); }
#win-screen .cl-rules li.no span:first-child { color: var(--red); }
#win-screen .cl-chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; max-height: 30vh; overflow-y: auto; } /* many drops wrap, then scroll — never past the panel */
#win-screen .cl-stat { margin-top: 8px; color: var(--muted); }
#win-screen .cl-unlock { margin-top: 8px; color: var(--teal); }
#win-screen .actions { display: flex; gap: 8px; margin-top: 12px; }
#win-screen .actions .btn { flex: 1; pointer-events: none; opacity: .4; }
#win-screen.ready .actions .btn { pointer-events: auto; opacity: 1; }

/* mail (R012) */
/* the mail button beside the gear (#topbar) and its sheet body — the sheet
   itself is #sheet, .card/.btn/.chip base components (U002). */
#topbar .mail { position: relative; display: flex; align-items: center; justify-content: center; height: 40px; font-size: calc(34px * var(--fs, 1)); line-height: 1; color: var(--muted); transform: translateY(-6px); }
#topbar .mail .badge { position: absolute; top: 10px; right: -8px; min-width: 14px; padding: 2px 4px; font-size: calc(8px * var(--fs, 1)); line-height: 1.4; text-align: center; color: var(--bg); background: var(--red); border-radius: 8px; }
.mail-list { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.mail-row { display: flex; align-items: center; justify-content: space-between; padding: 8px; font-size: calc(8px * var(--fs, 1)); border: 1px solid var(--line); background: var(--bg2); cursor: pointer; }
.mail-row.claimed { opacity: .6; }
.mail-flag { font-size: calc(6px * var(--fs, 1)); color: var(--amber); }
.mail-row.claimed .mail-flag { color: var(--muted); }

/* rewards tab (R013) */
/* the MAP button beside the big PLAY (play.screen.mjs), the chapter head's
   new BACK button (map.screen.mjs), and the REWARDS tab body
   (rewards.screen.mjs): LOGIN cells, DAILY/WEEKLY/ACHIEVEMENTS goal rows.
   .card, .btn, .chip and .timerbar are U002 base components and are not
   redefined here. */
.playrow { display: flex; gap: 8px; align-items: stretch; }
.playrow .bigplay { flex: 3; width: auto; }
.mapbtn { flex: 1; display: flex; align-items: center; justify-content: center; padding: 0; border: 3px solid var(--teal); background: rgba(5, 6, 15, .7); opacity: 1; pointer-events: auto; }
.mapbtn img { width: 32px; height: 32px; image-rendering: pixelated; opacity: 1; }
.mapbtn:active { background: var(--teal); }

.chapter .head { position: relative; }
/* ONE BACK for the whole map: a zero-height sticky strip pinned under the
   topbar, so the button rides the top right while the chapters scroll */
.mapback { position: sticky; top: calc(var(--top-h) + 8px); height: 0; z-index: 4; }
.mapback .back { position: absolute; top: 0; right: 14px; padding: 4px 6px; font-size: calc(6px * var(--fs, 1)); }

#shell .screen[data-screen="rewards"] { padding: 8px 14px calc(var(--top-h)); overflow-y: auto; }
.rewards-section { margin-top: 14px; }
.rewards-section:first-child { margin-top: calc(var(--top-h) + 8px); }
.rewards-section h3 { font-size: calc(11px * var(--fs, 1)); color: var(--teal-dim); letter-spacing: 2px; margin-bottom: 8px; }

.logincells { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.logincell { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 8px 4px; font-size: calc(8px * var(--fs, 1)); border: 1px solid var(--line); background: var(--bg2); text-align: center; }
.logincell.today { border-color: var(--teal); }
.logincell.claimed { opacity: .6; }
.logincell .daynum { color: var(--muted); letter-spacing: 1px; }
.logincell .cellrewards { display: flex; flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 4px; }
.logincell:nth-child(7) { grid-column: span 2; }
.logincell .cellrewards .chip { padding: 2px 4px; }
[data-screen="rewards"] .chip { font-size: calc(9px * var(--fs, 1)); gap: 4px; }
[data-screen="rewards"] .chip img { width: 24px; height: 24px; }
.logincell .check { color: var(--green); font-size: calc(12px * var(--fs, 1)); }

.goalrow { display: grid; grid-template-columns: 32px 1fr auto; column-gap: 10px; align-items: center; padding: 8px; margin-bottom: 8px; border: 1px solid var(--line); background: var(--bg2); }
.goalrow .goalicon { grid-column: 1; grid-row: 1 / span 3; width: 32px; height: 32px; image-rendering: pixelated; }
.goalrow .goalhead { display: flex; justify-content: space-between; font-size: calc(9px * var(--fs, 1)); margin-bottom: 2px; }
.goalrow .goalhead .title { font-weight: bold; color: var(--teal); letter-spacing: 1px; }
.goalrow .goalhead .have { color: var(--muted); }
.goalrow .subline { font-size: calc(7px * var(--fs, 1)); color: var(--muted); margin-bottom: 4px; }
.goalrow .goalhead, .goalrow .subline, .goalrow .timerbar { grid-column: 2; }
.goalrow .timerbar { margin-bottom: 0; }
.goalrow .goalfoot { grid-column: 3; grid-row: 1 / span 3; display: flex; align-items: center; justify-content: flex-end; gap: 6px; }
.goalrow .goalfoot .check { color: var(--green); font-size: calc(10px * var(--fs, 1)); }
.goalrow .goalfoot .btn { padding: 4px 8px; }

/* DAILY | WEEKLY | ACHIEVEMENTS | EVENTS sub-tab strip: same .subtabs look as
   the ships screen (U009 above), four columns instead of three. */
.rewards-tabs { grid-template-columns: repeat(4, 1fr); }

/* EVENTS sub-tab body until events get real UI again (ui.data.mjs REWARDS_EVENTS_SOON) */
.comingsoon { text-align: center; color: var(--muted); padding: 24px 0; }

/* stage drops (R010) */
#sheet .drops { display: flex; gap: 6px; margin: 0 0 12px; }

/* events section (R014) */
/* the EVENTS cards on the REWARDS tab (rewards.screen.mjs) — reuses .card,
   .btn, .btn.green, .btn.off, .chip (U002 base components); only new
   selectors below. */
.card.event { padding: 8px; margin-bottom: 8px; border: 1px solid var(--line); background: var(--bg2); text-align: left; }
.card.event .eventhead { display: flex; justify-content: space-between; font-size: calc(8px * var(--fs, 1)); color: var(--teal); margin-bottom: 4px; }
.card.event .eventhead .ends { color: var(--muted); }
.card.event .eventplays { font-size: calc(6px * var(--fs, 1)); color: var(--muted); margin-bottom: 6px; }
.card.event .eventmods { display: flex; flex-direction: column; gap: 2px; font-size: calc(6px * var(--fs, 1)); margin-bottom: 6px; }
.card.event .eventmods .side { color: var(--teal-dim); margin-right: 4px; }
.card.event .eventrewards { display: flex; flex-direction: column; gap: 4px; margin-bottom: 8px; }
.card.event .eventreward { display: flex; align-items: center; gap: 6px; font-size: calc(6px * var(--fs, 1)); }
.card.event .eventreward .onlabel { color: var(--muted); min-width: 40px; }
.card.event .btn { display: block; width: 100%; text-align: center; }

/* ---- settings overlay (js/ui/settings.panel.mjs) — gear in the menu, pause
   in a run. Above the shell sheet and the run HUD; cursor back for the run. ---- */
#settings { position: absolute; inset: 0; z-index: 20; display: flex; align-items: center; justify-content: center; padding: 16px; background: rgba(0, 0, 0, .7); cursor: auto; color: var(--txt); }
#settings[hidden] { display: none; }
.settings-box { width: 100%; max-width: 340px; background: var(--bg2); border: 2px solid var(--teal); padding: 16px 14px; display: flex; flex-direction: column; gap: 14px; }
.settings-box h3 { font-size: calc(12px * var(--fs, 1)); color: var(--teal); text-align: center; }
.settings-row { display: grid; grid-template-columns: 5em minmax(0, 1fr) 3em; align-items: center; gap: 8px; font-size: calc(8px * var(--fs, 1)); }
.settings-row b { text-align: right; color: var(--muted); font-weight: normal; }
.settings-row input[type=range] { width: 100%; accent-color: var(--teal); }
.settings-seg { grid-column: 2 / 4; display: flex; gap: 6px; }
#settings button { font-family: inherit; background: none; cursor: pointer; }
#settings .btn.pressed, #settings .btn:active { background: var(--teal); color: var(--bg); }
.settings-seg .btn { flex: 1; }
#pause-btn { position: absolute; top: 10px; right: 10px; z-index: 6; width: 36px; height: 36px; border: 2px solid var(--teal); background: rgba(5, 6, 15, .6); color: var(--teal); font-family: inherit; font-size: 10px; cursor: pointer; }
#pause-btn[hidden] { display: none; }
.settings-row input[type=checkbox] { justify-self: start; width: 18px; height: 18px; accent-color: var(--teal); cursor: pointer; }
