/*
 * Theme system: three selectable themes, all built on the same set of CSS custom properties, so
 * every component below stays theme-agnostic (they only ever reference var(--...)). main.js sets
 * `data-theme="..."` on <html> (see applyThemeAttribute()) based on state.theme, persisted to
 * localStorage — see renderGlobalControls()'s theme switcher buttons in render.js.
 *
 * Contrast was measured (WCAG relative-luminance formula) for the primary text/background pair
 * and the accent colors in every theme, using the original dark amber theme's measured 14.94:1 as
 * the reference bar Bill confirmed was "accessible" for this app:
 *   terminal-amber (original): text/bg 14.94:1, accent/bg 8.87:1
 *   terminal-slate (new dark): text/bg 15.37:1, accent/bg 9.64:1
 *   daylight (new light):      text/bg 14.51:1, accent/bg 7.53:1
 * All three clear WCAG AAA (7:1) for primary body text. 2026-07-13 readability pass: every
 * theme's --accent-amber-dim and --text-dim were brightened/darkened to clear at least WCAG AA
 * (4.5:1) against --bg-void (daylight's dim accent now clears AAA); per-value before/after
 * ratios are annotated inline in each theme block below.
 *
 * `--pip-text` exists because die-pip badges (Ability/Proficiency dice, see render.js's
 * dicePoolPipsHtml) put small bold text directly on an accent-colored background. In the dark
 * themes the accent colors are bright enough that dark (#111) text reads fine; daylight's accent
 * colors are deliberately darkened (to stay readable as TEXT on a light background), which makes
 * dark-on-dark pip text fail — so daylight flips this to white instead of trying to find one accent
 * shade that works as both light-on-dark-bg text AND a legible pip background simultaneously.
 */
:root, :root[data-theme="terminal-amber"] {
  --bg-void: #0e0c09;
  --bg-panel: #1c1811;
  --bg-panel-raised: #262019;
  --bg-panel-deep: #16130d;
  --border-metal: #453a29;
  --border-metal-light: #6b5c42;
  --accent-amber: #e2a33d;
  /* dim tier brightened 2026-07-13 (was #8f6a2a, 3.96:1): 5.01:1 on --bg-void — clears WCAG AA
     for the small labels/buttons that use it. Same pass raised --text-dim below. */
  --accent-amber-dim: #a37a30;
  --accent-rust: #b8492f;
  --accent-rust-dim: #6e2d1e;
  --accent-navy: #445972;
  --accent-navy-dim: #2b3a4a;
  --accent-green: #6a9955;
  --text-parchment: #ece0c8;
  --text-muted: #a89a80;
  --text-dim: #8a7f6a; /* was #6b6252 (3.25:1); now 4.95:1 (AA) on --bg-void */
  --glow-amber: rgba(226, 163, 61, 0.28);
  --pip-text: #111111;
}

/* Slate Terminal — a second dark theme: same "outer-rim terminal" darkness and contrast profile as
   the original, but a cool blue/cyan accent instead of warm amber/rust, for players who'd prefer
   that to the amber palette without giving up the dark, high-contrast terminal feel entirely. */
:root[data-theme="terminal-slate"] {
  --bg-void: #0a0d10;
  --bg-panel: #131a20;
  --bg-panel-raised: #1b232b;
  --bg-panel-deep: #0c1114;
  --border-metal: #33424f;
  --border-metal-light: #52697a;
  --accent-amber: #4fc3f0;
  --accent-amber-dim: #3f92b3; /* was #2f7691 (3.82:1); now 5.54:1 (AA) on --bg-void */
  --accent-rust: #d9704f;
  --accent-rust-dim: #8a4530;
  --accent-navy: #8fb4d6;
  --accent-navy-dim: #4a6c8c;
  --accent-green: #6fbf73;
  --text-parchment: #dbe6ee;
  --text-muted: #93a5b3;
  --text-dim: #75879a; /* was #5c6c78 (3.59:1); now 5.28:1 (AA) on --bg-void */
  --glow-amber: rgba(79, 195, 240, 0.28);
  --pip-text: #0a0d10;
}

/* Daylight — a light, high-contrast theme for players who find a dark terminal harder to read in
   bright rooms, or simply prefer light mode. Every accent color was individually re-picked (not
   just darkened uniformly) to clear at least WCAG AA against the light background — see the
   contrast notes above the :root block. */
:root[data-theme="daylight"] {
  --bg-void: #f4f1ea;
  --bg-panel: #ffffff;
  --bg-panel-raised: #f7f4ec;
  --bg-panel-deep: #ece7da;
  --border-metal: #c9c0a8;
  --border-metal-light: #a89a80;
  --accent-amber: #6e430f;
  --accent-amber-dim: #6f440c; /* was #8a5410 (5.55:1); now 7.42:1 (AAA) on --bg-void */
  --accent-rust: #7a2812;
  --accent-rust-dim: #a13a22;
  --accent-navy: #25394f;
  --accent-navy-dim: #3d5975;
  --accent-green: #2c5a2c;
  --text-parchment: #241f16;
  --text-muted: #55503f;
  --text-dim: #6d654f; /* was #837a63 (3.78:1); now 5.14:1 (AA) on --bg-void */
  --glow-amber: rgba(110, 67, 15, 0.22);
  --pip-text: #ffffff;
}
* { box-sizing: border-box; }
/* Typography: two-font system.
   - 'Big Shoulders Stencil Text' (loaded via .stencil, and directly on a handful of h2/h3/button
     elements below) is the DISPLAY font — big titles, short section headers, button labels. Its
     stencil/cargo-crate styling is the most visible piece of the "scrappy outer-rim terminal"
     theme, and it's forgivable there because those are short strings at larger sizes.
   - 'IBM Plex Mono' is the BODY/DATA font for everything else — paragraphs, talent/skill
     descriptions, the character sheet, form inputs. It replaced Rajdhani (a geometric sci-fi
     display font, not actually optimized for extended reading) specifically because talent and
     skill descriptions are dense, multi-sentence rules text that people have to actually read
     start to finish. IBM Plex Mono was chosen over other monospace options (JetBrains Mono, Space
     Mono) because it has a notably open, generously-spaced letterform designed for on-screen
     legibility at small sizes, while still reading as "terminal readout" text — arguably a better
     thematic fit for a datapad/terminal UI than Rajdhani ever was, not just a legibility fix. */
body {
  margin: 0;
  background: var(--bg-void);
  background-image:
    repeating-linear-gradient(135deg, rgba(255,255,255,0.015) 0px, rgba(255,255,255,0.015) 1px, transparent 1px, transparent 3px);
  color: var(--text-parchment);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 15px;
  line-height: 1.5;
  min-height: 100vh;
}
.stencil {
  font-family: 'Big Shoulders Stencil Text', sans-serif;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
button { font-family: inherit; }

/* =====================================================================================
   2026-07-13 REDESIGN LAYOUT (from the approved mobile/desktop mockups)
   sticky topbar → step-progress strip → .frame (nav rail | main | dossier)
   Mobile (<900px): rail hides, bottom tab bar shows; dossier becomes a bottom sheet;
   the talent inspector becomes a bottom sheet. Same markup, CSS switches presentation.
   ===================================================================================== */

/* ---- sticky topbar ---- */
.topbar {
  position: sticky; top: 0; z-index: 30;
  background: var(--bg-panel-deep);
  border-bottom: 1px solid var(--border-metal);
}
.topbar-row { display:flex; align-items:center; gap:14px; padding: 10px 18px 8px; }
.topbar .brand { font-size: 10px; letter-spacing: 0.14em; color: var(--text-dim); text-transform: uppercase; white-space: nowrap; line-height:1.35; }
.topbar .who { min-width: 0; }
.topbar .tb-name { font-weight: 700; color: var(--accent-amber); font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar .tb-sub { font-size: 11px; line-height: 1.4; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar-spacer { flex: 1; }
/* Topbar chips use their own tb-chip class — NOT .chip, which is the career-card skill label
   (QA bugfix 2026-07-13: sharing .chip gave career skill labels a 44px min-height and pushed
   long ones like "Knowledge (Outer Rim)" outside their card). */
.tb-chip {
  flex-shrink: 0; border: 1px solid var(--border-metal-light); background: var(--bg-panel-raised);
  padding: 5px 12px; font-size: 12.5px; font-weight: 700; border-radius: 3px; text-align: center;
  line-height: 1.2; font-family: inherit; cursor: pointer; color: var(--text-parchment); min-height: 44px;
}
.tb-chip small { display: block; font-size: 9px; font-weight: 400; color: var(--text-muted); letter-spacing: 0.08em; }
.chip-xp { color: var(--accent-amber); border-color: var(--accent-amber-dim); }
.chip-cr { color: var(--accent-green); }

/* Topbar utility buttons/links (account button, HQ's "◂ Character Builder" door). Works for
   BOTH <button> and <a> — QA 2026-07-13: this class was referenced but never defined, so the
   anchor fell back to a default underlined link that ignored the theme. */
.iconbtn {
  display: inline-flex; align-items: center; gap: 6px; min-height: 38px; padding: 0 14px;
  background: var(--bg-panel-deep); color: var(--text-muted);
  border: 1px solid var(--border-metal-light); border-radius: 3px;
  font: inherit; font-size: 12.5px; letter-spacing: 0.04em; cursor: pointer;
  text-decoration: none; white-space: nowrap;
}
.iconbtn:hover { color: var(--accent-amber); border-color: var(--accent-amber-dim); }

/* Topbar character switcher (QA 2026-07-13): the identity block IS the switcher — a real button
   with a caret so "my other characters live here" is discoverable. */
button.who-switch {
  background: none; border: none; padding: 2px 8px; margin: -2px -8px; font: inherit;
  text-align: left; cursor: pointer; border-radius: 4px; display: block;
}
button.who-switch:hover:not(:disabled) { background: var(--bg-panel-raised); }
button.who-switch:disabled { cursor: default; }
button.who-switch .tb-name, button.who-switch .tb-sub { display: block; }
.switch-caret { color: var(--accent-amber-dim); font-size: 11px; }

/* ---- live wound/strain trackers on the sheet (player-agency package) ---- */
.tracker-btns { display: inline-flex; gap: 4px; margin-top: 2px; }
.tracker-btn {
  font: inherit; font-size: 14px; line-height: 1; width: 26px; height: 26px;
  background: var(--bg-panel-deep); color: var(--text-parchment);
  border: 1px solid var(--border-metal-light); border-radius: 4px; cursor: pointer;
}
.tracker-btn:hover { background: var(--bg-panel-raised); border-color: var(--accent-amber); }

/* ---- attachments panel: the browse control must LOOK clickable (Bill QA 2026-07-13) ---- */
.att-browse {
  cursor: pointer; display: inline-block; margin: 6px 0; padding: 6px 12px;
  font-size: 12.5px; color: var(--accent-amber);
  background: var(--bg-panel-deep); border: 1px solid var(--border-metal-light); border-radius: 4px;
  list-style: none; /* hide the default details marker — the ⚙ and text carry the affordance */
}
.att-browse::-webkit-details-marker { display: none; }
.att-browse:hover { background: var(--bg-panel-raised); border-color: var(--accent-amber); }
details[open] > .att-browse { border-color: var(--accent-amber); }

/* ---- step-progress strip (read-only; tabs are the navigation) ---- */
.progress { display: flex; gap: 4px; padding: 0 18px 8px; }
.progress .seg { flex: 1; height: 3px; background: var(--border-metal); border-radius: 2px; }
.progress .seg.done { background: var(--accent-amber-dim); }
.progress .seg.now { background: var(--accent-amber); box-shadow: 0 0 6px var(--glow-amber); }

/* ---- three-pane frame ---- */
.frame { display: grid; grid-template-columns: 190px minmax(0, 1fr) 280px; max-width: 1400px; margin: 0 auto; }
.main { min-width: 0; padding: 20px 24px 60px; }

/* ---- left nav rail (desktop) ---- */
.rail { border-right: 1px solid var(--border-metal); padding: 14px 0; position: sticky; top: 76px; height: calc(100vh - 76px); }
.rail button {
  display: flex; align-items: center; gap: 12px; width: 100%; min-height: 48px;
  background: none; border: none; border-left: 3px solid transparent; color: var(--text-muted);
  font: inherit; font-size: 13px; line-height: 1.3; letter-spacing: 0.06em; padding: 0 16px; cursor: pointer;
  text-transform: uppercase; position: relative; text-align: left;
}
.rail button .ico { font-size: 17px; width: 22px; text-align: center; }
.rail button:hover:not(:disabled) { color: var(--text-parchment); }
.rail button.active { color: var(--accent-amber); border-left-color: var(--accent-amber); background: linear-gradient(90deg, var(--glow-amber), transparent); }
.rail button:disabled { opacity: 0.4; cursor: not-allowed; }
.rail button .dot { position: absolute; right: 12px; width: 8px; height: 8px; border-radius: 50%; background: var(--accent-rust); }

/* ---- bottom tab bar (mobile) — hidden on desktop ---- */
.tabbar {
  display: none;
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 40;
  background: var(--bg-panel-deep); border-top: 1px solid var(--border-metal);
  padding-bottom: env(safe-area-inset-bottom);
}
.tabbar button {
  flex: 1; min-height: 56px; background: none; border: none; color: var(--text-dim); font: inherit;
  font-size: 10px; line-height: 1.3; letter-spacing: 0.04em; cursor: pointer; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px; text-transform: uppercase; position: relative;
}
.tabbar button .ico { font-size: 18px; line-height: 1; }
.tabbar button.active { color: var(--accent-amber); }
.tabbar button.active::after { content: ''; position: absolute; top: 0; left: 20%; right: 20%; height: 2px; background: var(--accent-amber); }
.tabbar button:disabled { opacity: 0.35; }
.tabbar button .dot { position: absolute; top: 8px; right: calc(50% - 18px); width: 8px; height: 8px; border-radius: 50%; background: var(--accent-rust); }

/* ---- dossier (right column desktop / bottom sheet mobile) ---- */
.dossier {
  border-left: 1px solid var(--border-metal); padding: 16px 16px 40px;
  position: sticky; top: 76px; height: calc(100vh - 76px); overflow-y: auto;
}
.dossier-scrim { display: none; }

/* ---- sub-step segmented control (Build: Species/Career — Story: Bg/Ob/Motivation) ---- */
.seg-control { display: inline-flex; border: 1px solid var(--border-metal-light); border-radius: 3px; overflow: hidden; }
.seg-control button {
  min-height: 44px; min-width: 110px; background: var(--bg-panel-deep); color: var(--text-muted); border: none;
  font: inherit; font-size: 12px; line-height: 1.3; letter-spacing: 0.05em; cursor: pointer; text-transform: uppercase; padding: 0 14px;
}
.seg-control button.active { background: var(--accent-amber); color: var(--bg-void); font-weight: 700; }
.seg-control button:disabled { opacity: 0.4; cursor: not-allowed; }
.substep-nav { margin-bottom: 18px; }

/* ---- talent tree master-detail ---- */
.tree-layout { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 16px; align-items: start; }
/* QA bugfix 2026-07-13: the tree grid is a fixed ~632px (4×140px + gaps) for connector-line
   math, which can exceed its column between ~900-1250px viewports — without these two rules it
   overflowed the panel and painted OVER the inspector (hiding descriptions and the purchase
   button). The panel now clips + scrolls horizontally at ANY width, and the inspector sits
   above in the stacking order regardless. */
.tree-layout > .panel { min-width: 0; } /* tree is fluid now — no horizontal scrolling needed */
.talent-inspector {
  position: sticky; top: 92px; z-index: 5; background: var(--bg-panel); border: 1px solid var(--accent-amber-dim);
  padding: 14px; max-height: calc(100vh - 110px); overflow-y: auto;
}
.talent-inspector .ti-close { display: none; }
.ti-scrim { display: none; }
/* The detail card keeps its historical class; inside the inspector its own chrome is redundant. */
.talent-inspector .talent-inline-expansion { border: none; background: transparent; padding: 0; margin: 0; max-width: none; }

/* Print-only content (e.g. the sheet's text dice pools "2A + 1P") — hidden on screen, shown in
   the print stylesheet below. Counterpart of .screen-only. */
.print-only { display: none; }

h1.screen-title { font-size: 22px; margin: 0 0 4px; color: var(--text-parchment); }
p.screen-sub { color: var(--text-dim); font-size: 13px; margin: 0 0 22px; }

/* ---- panel/card shell ---- */
.panel {
  background: var(--bg-panel);
  border: 1px solid var(--border-metal);
  position: relative;
  padding: 16px;
}
.panel::before, .panel::after {
  content: ""; position:absolute; width:6px; height:6px; border-radius:50%;
  background: var(--bg-panel-deep); border: 1px solid var(--border-metal-light); top:6px;
}
.panel::before { left:6px; } .panel::after { right:6px; }

.error-banner {
  background: var(--bg-panel-deep); border: 1px solid var(--accent-rust); color: var(--accent-rust);
  padding: 8px 12px; font-size: 12.5px; margin-bottom: 16px;
}

/* ================= SPECIES SCREEN ================= */
.species-grid, .career-grid, .spec-grid { display:grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.spec-grid { grid-template-columns: repeat(3, 1fr); }
.species-card, .career-card, .spec-card {
  background: var(--bg-panel-raised); border: 1px solid var(--border-metal); padding: 14px 14px 12px;
  cursor: pointer; position:relative;
}
.species-card.selected, .career-card.selected, .spec-card.selected { border-color: var(--accent-amber); box-shadow: 0 0 0 1px var(--accent-amber), 0 0 14px var(--glow-amber) inset; }
.species-card .name, .career-card .name, .spec-card .name { font-family:'Big Shoulders Stencil Text',sans-serif; font-size:17px; color: var(--text-parchment); letter-spacing:0.03em; }
.species-card.selected .name, .career-card.selected .name, .spec-card.selected .name { color: var(--accent-amber); }
.species-card .xp-badge {
  position:absolute; top:10px; right:10px; font-size:10px; font-weight:700; color: var(--accent-amber-dim);
  border: 1px solid var(--accent-amber-dim); padding: 2px 6px; letter-spacing:0.04em;
}
.charstats { display:grid; grid-template-columns: repeat(6,1fr); gap:4px; margin: 10px 0 8px; }
.charstat { text-align:center; }
.charstat .lbl { font-size:9px; color:var(--text-dim); letter-spacing:0.05em; }
.charstat .bar { height:26px; background: var(--bg-panel-deep); border:1px solid var(--border-metal); position:relative; margin-top:2px; display:flex; align-items:flex-end; }
.charstat .fill { width:100%; background: var(--accent-navy); }
.species-card.selected .charstat .fill { background: var(--accent-amber-dim); }
.charstat .val { position:absolute; top:2px; left:0; right:0; text-align:center; font-size:11px; font-weight:700; color: var(--text-parchment); }
.thresh-line { font-size: 10.5px; color: var(--text-dim); margin: 2px 0; }
.flavor { font-size:12.5px; color: var(--text-muted); margin-top:8px; line-height:1.5; }

.detail-panel { margin-top:16px; padding: 16px 18px; }
.detail-panel h2 { margin:0 0 8px; font-size:16px; color: var(--accent-amber); font-family:'Big Shoulders Stencil Text',sans-serif; letter-spacing:0.03em; }
.detail-panel p { font-size:14px; line-height:1.6; color: var(--text-parchment); margin:0; }

/* ================= CAREER / SPEC SCREEN ================= */
.career-card .skillrow, .spec-card .skillrow { font-size: 11.5px; color: var(--text-muted); margin-top: 8px; line-height: 1.55; }

/* ================= XP TABS ================= */
.nav-toggle { display:flex; gap:10px; margin-bottom:20px; flex-wrap: wrap; }
.nav-toggle button {
  font-family: 'Big Shoulders Stencil Text', sans-serif;
  background: var(--bg-panel-raised); color: var(--text-muted); border: 1px solid var(--border-metal);
  padding: 8px 16px; font-size: 13px; letter-spacing: 0.06em; cursor:pointer; text-transform:uppercase;
}
.nav-toggle button.active { color: var(--accent-amber); border-color: var(--accent-amber-dim); background: var(--bg-panel-deep); }
.nav-toggle button:disabled { opacity: 0.35; cursor: not-allowed; }

/* ---- characteristics tab ---- */
.char-list { display:flex; flex-direction:column; gap:8px; }
.char-row { display:flex; align-items:center; justify-content:space-between; padding:10px 14px; background: var(--bg-panel-raised); border:1px solid var(--border-metal); }
.char-row .cr-name { font-family:'Big Shoulders Stencil Text',sans-serif; font-size:13px; letter-spacing:0.04em; width: 140px; }
.char-row .cr-val { font-size: 18px; font-weight:700; color: var(--accent-amber); width: 40px; text-align:center; }
.char-row .cr-btn { margin-left:auto; }

/* ---- skills tab ---- */
.skill-group-title { font-family:'Big Shoulders Stencil Text',sans-serif; font-size:13px; letter-spacing:0.06em; color: var(--accent-amber-dim); margin: 18px 0 8px; }
.skill-group-title:first-child { margin-top: 0; }
.skill-row { display:flex; align-items:center; padding:7px 12px; background: var(--bg-panel-raised); border:1px solid var(--border-metal); margin-bottom:5px; }
.skill-row.career { border-color: var(--accent-amber-dim); }
.skill-row .sk-name { flex: 1; font-size: 13px; }
.skill-row .sk-name .star { color: var(--accent-amber-dim); margin-right: 4px; }
.skill-row .sk-pips { display:flex; gap:4px; margin-right: 14px; }
.skill-row .pip { width:12px; height:12px; border:1px solid var(--border-metal-light); border-radius:50%; }
.skill-row .pip.filled { background: var(--accent-amber); border-color: var(--accent-amber); }
/* Free (XP-less) ranks render green so it's visible which ranks came from grants vs purchases. */
.skill-row .pip.filled.free { background: var(--accent-green); border-color: var(--accent-green); }
.free-tag {
  display:inline-block; font-size:9.5px; font-weight:700; letter-spacing:0.05em; text-transform:uppercase;
  color: var(--accent-green); border: 1px solid var(--accent-green); border-radius: 2px;
  padding: 0 4px; margin-left: 6px; vertical-align: 1px;
}

/* ---- Free skill ranks panel (Steps 4 & 5 + species grants) ---- */
.free-ranks-panel { margin-bottom: 16px; }
.free-pick-group { margin-bottom: 12px; }
.free-pick-group:last-child { margin-bottom: 0; }
.free-pick-title { font-size: 12px; letter-spacing: 0.05em; color: var(--text-muted); margin-bottom: 6px; }
.free-pick-title .fp-done { color: var(--accent-green); }
.free-pick-title .fp-todo { color: var(--accent-amber); }
.free-pick-chips { display:flex; flex-wrap:wrap; gap:6px; }
.free-pick-chip {
  font-family: inherit; font-size: 11.5px; cursor: pointer;
  background: var(--bg-panel-deep); color: var(--text-parchment);
  border: 1px solid var(--border-metal-light); padding: 4px 10px;
}
.free-pick-chip:hover:not(:disabled) { border-color: var(--accent-amber); }
.free-pick-chip.picked { background: var(--accent-green); color: var(--bg-void); border-color: var(--accent-green); font-weight: 700; }
.free-pick-chip:disabled:not(.picked) { opacity: 0.45; cursor: not-allowed; }
.free-pick-chip.fixed { cursor: default; }

/* ---- Accessibility helpers ---- */
/* Screen-reader-only live region (index.html #live-region). */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* Keyboard focus ring for the div-based interactive elements (talent nodes, collapsed blades)
   and buttons — :focus-visible keeps it off mouse clicks. */
.node:focus-visible, .blade.collapsed:focus-visible, button:focus-visible {
  outline: 2px solid var(--accent-amber);
  outline-offset: 2px;
}

/* ---- buy buttons (shared) ---- */
.buy-btn {
  font-family: 'Big Shoulders Stencil Text', sans-serif;
  background: var(--bg-panel-deep); color: var(--accent-amber-dim); border: 1px solid var(--accent-amber-dim);
  padding: 5px 12px; font-size: 11.5px; letter-spacing:0.05em; cursor:pointer; text-transform:uppercase; white-space:nowrap;
}
.buy-btn:hover { color: var(--accent-amber); border-color: var(--accent-amber); }
/* Selected/committed state (e.g. the Table 2-2 party-size pick) — same treatment as selected cards. */
.buy-btn.active { background: var(--accent-amber); color: var(--bg-void); border-color: var(--accent-amber); font-weight: 700; }
.buy-btn:disabled { opacity: 0.3; cursor: not-allowed; border-color: var(--border-metal); color: var(--text-dim); }

/* ================= TALENT TREE SCREEN ================= */
.tt-header { display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:18px; flex-wrap:wrap; gap:10px; }
.chiprow { display:flex; flex-wrap:wrap; gap:6px; margin-top:6px; }
.chip { font-size:10.5px; padding:3px 8px; border:1px solid var(--border-metal-light); color:var(--text-muted); }
.chip.bonus { border-color: var(--accent-amber-dim); color: var(--accent-amber-dim); }

.spec-tabs { display:flex; gap:8px; margin-bottom: 14px; flex-wrap: wrap; }
.spec-tabs button {
  font-family: 'Big Shoulders Stencil Text', sans-serif; font-size:12px; letter-spacing:0.05em; text-transform:uppercase;
  background: var(--bg-panel-raised); color: var(--text-muted); border:1px solid var(--border-metal); padding:6px 12px; cursor:pointer;
}
.spec-tabs button.active { color: var(--accent-amber); border-color: var(--accent-amber-dim); }
.spec-tabs button.add-spec { color: var(--accent-navy); border-color: var(--accent-navy-dim); }

.tt-grid-wrap { position:relative; padding: 10px 4px 0; }
/* `width: fit-content` + `margin: 0 auto` (not `justify-content:center`) is required here: `.tt-row`
   is a block-level grid container, so by default it stretches to the full width of `.tt-grid-wrap`.
   With `justify-content:center` the 4 columns were centered *within that full width*, shifting the
   real column-0 origin away from x=0 by however much wider the panel was than the 632px the 4
   columns+gaps actually need. The connector lines below are positioned with plain `left:Npx` math
   (`colCenterX()`) that assumes column 0 starts at x=0 — so the two approaches disagreed, and lines
   rendered offset from the nodes they were supposed to connect (reported: stray lines cutting
   through/behind unrelated nodes). Making the row exactly as wide as its columns and centering the
   row itself keeps x=0 pinned to column 0's left edge, matching what colCenterX() assumes. */
/* Fluid tree (QA 2026-07-13): four equal columns + 4% gap — connector lines are positioned in
   the SAME percentage space (render.js colCenterX), so geometry stays exact at any width. */
.tt-row { display:grid; grid-template-columns: repeat(4, 1fr); gap: 4%; width: 100%; position:relative; }
.tt-row + .tt-row { margin-top: 40px; }
/* sticky-left so tier labels stay visible while the (fixed-width) tree scrolls horizontally */
.tt-tier-label { text-align:center; font-size:10px; letter-spacing:0.1em; color: var(--text-dim); margin-bottom:6px; position:sticky; left:0; }

/* Vertical connectors are now rendered as `.tt-row` siblings with an explicit `left:Npx` (see
   render.js), not as a child of `.node` — `.node` has a `clip-path` for its cut-corner shape, which
   clips ALL descendant painting to the node's own box, so a line living at `top:100%` inside a
   clipped node would never actually be visible. Also only rendered per-column when the tree data
   says a link exists there (fixes stray connectors on irregular trees like Gadgeteer/Trader/Bodyguard). */
.vline { position:absolute; top:100%; width:2px; height:40px; background: var(--border-metal-light); transform: translateX(-1px); z-index:0; pointer-events:none; }
.vline.on { background: var(--accent-amber-dim); }
.hline { position:absolute; top:50%; height:2px; background: var(--border-metal-light); transform: translateY(-1px); z-index:0; pointer-events:none; }
.hline.on { background: var(--accent-amber-dim); }

.node { min-width:0; /* fluid grid safety */
  background: var(--bg-panel-raised);
  border: 1px solid var(--border-metal);
  clip-path: polygon(10px 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%, 0 10px);
  position: relative; z-index:1; padding: 0 0 8px;
  opacity: 0.42; filter: grayscale(0.6);
  cursor: default;
}
.node.locked .lock { position:absolute; top:6px; right:8px; font-size:11px; color: var(--text-dim); }
.node.purchasable { opacity:1; filter:none; border-color: var(--accent-amber-dim); animation: pulse 2.2s ease-in-out infinite; cursor:pointer; }
.node.owned { opacity:1; filter:none; border-color: var(--accent-amber); box-shadow: 0 0 12px var(--glow-amber); }
@keyframes pulse { 0%,100% { box-shadow: 0 0 0 var(--glow-amber);} 50% { box-shadow: 0 0 10px var(--glow-amber);} }

.node .bar { height:6px; }
.node.active-t .bar { background: var(--accent-rust); }
.node.passive-t .bar { background: var(--accent-navy); }
.node .body { padding: 8px 10px 4px; text-align:center; }
.node .nname { font-size:12px; font-weight:700; line-height:1.2; color: var(--text-parchment); min-height:29px; display:flex; align-items:center; justify-content:center; }
.node.owned .nname { color: var(--accent-amber); }
.node .cost { font-size:10px; color: var(--text-dim); border-top: 1px solid var(--border-metal); margin-top:6px; padding-top:4px; }
.node .check { position:absolute; top:6px; right:8px; font-size:12px; color: var(--accent-amber); }
.node .fs-star { position:absolute; top:6px; left:8px; font-size:10px; color: var(--accent-navy); }

.legend { display:flex; gap:18px; flex-wrap:wrap; margin-top: 56px; padding-top:14px; border-top:1px solid var(--border-metal); font-size:11px; color: var(--text-muted); position:sticky; left:0; }
.legend span.swatch { display:inline-block; width:10px; height:10px; margin-right:5px; vertical-align:-1px; }

/* ---- sidebar dossier ---- */
.sidebar .panel { margin-bottom: 16px; }
.sidebar h3 { font-family:'Big Shoulders Stencil Text',sans-serif; font-size:13px; letter-spacing:0.08em; color: var(--accent-amber-dim); margin:0 0 10px; border-bottom:1px solid var(--border-metal); padding-bottom:6px; }
.row2 { display:flex; justify-content:space-between; font-size:12px; padding: 3px 0; color: var(--text-muted); }
.row2 b { color: var(--text-parchment); font-weight:700; }
.xp-track { margin-top:8px; }
.xp-bar { height:8px; background: var(--bg-panel-deep); border:1px solid var(--border-metal); }
.xp-bar-fill { height:100%; background: var(--accent-amber-dim); }
.xp-num { font-size:11px; color: var(--text-dim); margin-top:4px; }
.finalize-btn {
  width:100%; margin-top:10px; font-family:'Big Shoulders Stencil Text',sans-serif; letter-spacing:0.05em; text-transform:uppercase;
  background: var(--accent-rust-dim); color: var(--text-parchment); border:1px solid var(--accent-rust); padding:9px; cursor:pointer; font-size:12.5px;
}
.finalize-btn:disabled { opacity:0.35; cursor:not-allowed; }
.finalized-tag { color: var(--accent-amber); font-size: 11px; margin-top: 8px; text-align:center; letter-spacing:0.05em; }

/* ---- summary sheet ---- */
.summary-grid { display:grid; grid-template-columns: 1fr 1fr; gap:16px; }
.summary-grid .panel h3 { font-family:'Big Shoulders Stencil Text',sans-serif; color: var(--accent-amber-dim); font-size:13px; letter-spacing:0.06em; margin:0 0 10px; border-bottom:1px solid var(--border-metal); padding-bottom:6px; }
.talent-list-item { font-size:12.5px; padding:3px 0; color: var(--text-parchment); }

/* ---- global controls (Start Over) ---- */
.start-over-btn {
  font-family:'Big Shoulders Stencil Text',sans-serif; letter-spacing:0.05em; text-transform:uppercase;
  background: var(--bg-panel-raised); color: var(--text-muted); border:1px solid var(--border-metal);
  padding:5px 12px; font-size:11px; cursor:pointer;
}
.start-over-btn:hover { color: var(--accent-rust); border-color: var(--accent-rust-dim); }
.clear-confirm, .notice-banner {
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  background: var(--bg-panel-deep); border:1px solid var(--accent-rust); color: var(--text-parchment);
  padding:8px 12px; font-size:12px;
}
.notice-banner { border-color: var(--accent-amber-dim); margin-bottom:16px; justify-content:space-between; }
.notice-banner .dismiss { background:none; border:none; color: var(--text-dim); cursor:pointer; font-size:13px; }
.clear-confirm button, .confirm-yes, .confirm-no {
  font-family:'Big Shoulders Stencil Text',sans-serif; letter-spacing:0.05em; text-transform:uppercase;
  padding:6px 12px; font-size:11.5px; cursor:pointer; border:1px solid var(--border-metal);
  background: var(--bg-panel-raised); color: var(--text-muted);
}
.confirm-yes { border-color: var(--accent-rust); color: var(--accent-rust); }
.confirm-no { border-color: var(--border-metal-light); }
.confirm-panel {
  background: var(--bg-panel-deep); border:1px solid var(--accent-rust); padding:16px 18px; margin-bottom:20px;
}
.confirm-panel h2 { margin:0 0 8px; font-size:16px; color: var(--accent-rust); font-family:'Big Shoulders Stencil Text',sans-serif; letter-spacing:0.03em; }
.confirm-panel p { font-size:14px; line-height:1.6; color: var(--text-parchment); margin:0 0 14px; }

/* ---- validation / legality panel ---- */
.validation-panel .problem-list { margin:0; padding-left:18px; font-size:12.5px; line-height:1.55; }
.validation-panel .problem-list li.violation { color: var(--accent-rust); }
.validation-panel .problem-list li.reminder { color: var(--accent-amber-dim); }
.validation-panel .ok-tag span { color: var(--accent-green); }

/* ---- name fields (player name / character name) ---- */
.name-fields { display:flex; gap:20px; flex-wrap:wrap; margin-bottom:20px; }
.name-field { flex: 1 1 220px; display:flex; flex-direction:column; gap:5px; }
.name-field label { font-size:10.5px; letter-spacing:0.06em; text-transform:uppercase; color: var(--text-dim); }
.name-field input {
  background: var(--bg-panel-deep); border:1px solid var(--border-metal); color: var(--text-parchment);
  padding:8px 10px; font-family:'IBM Plex Mono',monospace; font-size:14px;
}
.name-field input:focus { outline:none; border-color: var(--accent-amber-dim); }

/* ---- full character sheet ---- */
.sheet-header { display:flex; justify-content:space-between; align-items:flex-start; flex-wrap:wrap; gap:14px; margin-bottom:18px; }
.sheet-header .identity h1 { margin:0; font-size:24px; }
.sheet-header .identity .sub-id { font-size:12.5px; color: var(--text-dim); margin-top:4px; }
.sheet-actions { display:flex; gap:8px; flex-wrap:wrap; }
.sheet-actions button {
  font-family:'Big Shoulders Stencil Text',sans-serif; letter-spacing:0.05em; text-transform:uppercase;
  background: var(--bg-panel-raised); color: var(--text-muted); border:1px solid var(--border-metal);
  padding:7px 14px; font-size:11.5px; cursor:pointer;
}
.sheet-actions button:hover { color: var(--accent-amber); border-color: var(--accent-amber-dim); }

.dice-table { width:100%; border-collapse:collapse; font-size:12px; }
.dice-table th { text-align:left; color: var(--text-dim); font-size:10px; letter-spacing:0.05em; text-transform:uppercase; padding:4px 6px; border-bottom:1px solid var(--border-metal); }
.dice-table td { padding:4px 6px; border-bottom:1px solid var(--bg-panel-raised); }
.dice-table tr.career-row td:first-child { color: var(--accent-amber-dim); }
.dice-table .dice-cell { white-space:nowrap; }
.die-none { color: var(--text-dim); font-size:11px; font-style:italic; }

/* ---- dice pool pips (Ability = green, Proficiency = yellow/amber — real RAW die colors) ---- */
.dice-pips { display:inline-flex; gap:3px; flex-wrap:wrap; vertical-align:middle; }
.die-pip {
  display:inline-flex; align-items:center; justify-content:center;
  width:16px; height:16px; border-radius:3px; font-size:9px; font-weight:800;
  font-family:'IBM Plex Mono',monospace; color: var(--pip-text, #111); line-height:1;
}
.die-pip-ability { background: var(--accent-green); box-shadow: 0 0 0 1px rgba(0,0,0,0.25) inset; }
.die-pip-proficiency { background: var(--accent-amber); box-shadow: 0 0 0 1px rgba(0,0,0,0.25) inset; }
/* Boost dice are light blue on the real dice (talent automation, 2026-07-13). Fixed color across
   themes — the pip text color still follows --pip-text like the other pips. */
.die-pip-boost { background: #5ab4d6; box-shadow: 0 0 0 1px rgba(0,0,0,0.25) inset; }
.setback-removed {
  display:inline-block; margin-left:4px; font-size:10px; font-weight:700; letter-spacing:0.02em;
  color: var(--text-muted); border: 1px solid var(--border-metal-light); border-radius:2px; padding:0 4px;
  vertical-align: 1px;
}

.dice-legend {
  display:flex; flex-direction:column; gap:4px; margin-bottom:12px; padding:8px 12px;
  background: var(--bg-panel-deep); border:1px solid var(--border-metal); font-size:11px; color: var(--text-muted);
}
.dice-legend-item { display:flex; align-items:center; gap:6px; }
.dice-legend-note { color: var(--text-dim); font-size:10.5px; }

/* ---- skills XP tab: inline dice pool + refund button ---- */
.skill-row .sk-dice { margin-right:10px; }
.refund-btn {
  font-family:'Big Shoulders Stencil Text',sans-serif; background: var(--bg-panel-deep); color: var(--accent-rust);
  border:1px solid var(--accent-rust-dim); padding:5px 10px; font-size:13px; font-weight:800; cursor:pointer; margin-right:6px;
}
.refund-btn:hover { border-color: var(--accent-rust); }

/* ---- talent tree detail card (inline expansion — see .talent-inline-expansion below) ---- */
.talent-inspector-empty { color: var(--text-dim); }
.ti-head { display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:8px; }
.ti-head h3 { font-family:'Big Shoulders Stencil Text',sans-serif; font-size:17px; color: var(--accent-amber); letter-spacing:0.03em; border:none; padding:0; }
.ti-status { font-size:10.5px; letter-spacing:0.05em; text-transform:uppercase; padding:3px 8px; border:1px solid var(--border-metal); }
.ti-status-owned { color: var(--accent-amber); border-color: var(--accent-amber-dim); }
.ti-status-purchasable { color: var(--accent-green); border-color: var(--accent-green); }
.ti-status-locked { color: var(--text-dim); }
.ti-meta { font-size:11px; color: var(--text-dim); margin:6px 0; }
.ti-desc { font-size:14px; line-height:1.6; color: var(--text-parchment); margin: 8px 0 12px; }
.ti-action { margin-top:2px; }
.ti-blocked { font-size:12.5px; color: var(--accent-rust); margin-top:4px; }
.node.selected { outline: 2px solid var(--accent-amber); outline-offset:1px; }

.sheet-talent-item { padding:8px 0; border-bottom:1px solid var(--bg-panel-raised); }
.sheet-talent-item .t-name { font-weight:700; color: var(--accent-amber-dim); font-size:13px; }
.sheet-talent-item .t-meta { font-size:10.5px; color: var(--text-dim); margin-left:6px; }
.sheet-talent-item .t-desc { font-size:12.5px; color: var(--text-muted); margin-top:2px; line-height:1.5; }

/* ---- theme switcher + global controls row ---- */
.global-controls-row { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.theme-switcher { display:flex; gap:4px; margin-top:6px; flex-wrap:wrap; }
.theme-btn {
  font-family:'IBM Plex Mono',monospace; font-size:10.5px; letter-spacing:0.03em;
  background: var(--bg-panel-raised); color: var(--text-muted); border:1px solid var(--border-metal);
  padding:4px 9px; cursor:pointer;
}
.theme-btn.active { color: var(--accent-amber); border-color: var(--accent-amber-dim); }
.save-load-btn {
  font-family:'Big Shoulders Stencil Text',sans-serif; letter-spacing:0.05em; text-transform:uppercase;
  background: var(--bg-panel-raised); color: var(--text-muted); border:1px solid var(--border-metal);
  padding:5px 12px; font-size:11px; cursor:pointer;
}
.save-load-btn:hover { color: var(--accent-amber); border-color: var(--accent-amber-dim); }
.save-load-btn:disabled { opacity:0.35; cursor:not-allowed; }

/* ---- background screen (Step 1) ---- */
.bg-grid { display:grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.bg-card {
  background: var(--bg-panel-raised); border:1px solid var(--border-metal); padding: 12px 14px; cursor:pointer;
}
.bg-card.selected { border-color: var(--accent-amber); box-shadow: 0 0 0 1px var(--accent-amber); }
.bg-card .name { font-family:'Big Shoulders Stencil Text',sans-serif; font-size:14px; color: var(--text-parchment); letter-spacing:0.03em; margin-bottom:4px; }
.bg-card.selected .name { color: var(--accent-amber); }
.bg-notes {
  width:100%; background: var(--bg-panel-deep); border:1px solid var(--border-metal); color: var(--text-parchment);
  font-family:'IBM Plex Mono',monospace; font-size:14px; padding:10px; resize:vertical;
}
.bg-notes:focus { outline:none; border-color: var(--accent-amber-dim); }

/* ---- obligation screen (Step 2) ---- */
.ob-grid { display:grid; grid-template-columns: repeat(4, 1fr); gap:8px; }
.ob-card {
  background: var(--bg-panel-raised); border:1px solid var(--border-metal); padding:10px; text-align:center; cursor:pointer;
}
.ob-card.selected { border-color: var(--accent-amber); box-shadow: 0 0 0 1px var(--accent-amber); }
.ob-card .name { font-size:12px; color: var(--text-parchment); }
.ob-card.selected .name { color: var(--accent-amber); }
.ob-bonus-row {
  display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap;
  padding:8px 10px; background: var(--bg-panel-raised); border:1px solid var(--border-metal); margin-bottom:6px; font-size:13px;
}
.ob-bonus-row.taken { border-color: var(--accent-amber-dim); }
.ob-cost { color: var(--text-dim); font-size:11.5px; }

/* ---- gear screen (Step 9) ---- */
.encum-panel .row2 { font-size:13px; }
.gear-table th, .gear-table td { font-size:12.5px; }
.gear-actions { display:flex; align-items:center; gap:6px; flex-wrap:wrap; white-space:nowrap; }
.gear-qty { font-size:11px; color: var(--accent-amber-dim); margin-right:4px; }
.restricted-row td:first-child { color: var(--accent-rust); }

/* ---- talent tree inline expansion (replaces the old fixed-position inspector panel) ---- */
.talent-inline-expansion {
  background: var(--bg-panel); border:1px solid var(--accent-amber-dim); padding:14px 16px; margin: 10px auto 24px;
  max-width: 640px;
}

/* ---- Opening crawl (GM package): the real sequence — blue line, receding title, crawl under
   stars, auto-ends. Every phase uses fill-mode:both so nothing is visible before its cue. ---- */
#crawl-root { display:none; }
body.crawl-open #crawl-root {
  display:block; position:fixed; inset:0; z-index:200; background:#000; overflow:hidden;
}
/* twinkling starfield (pure CSS, two drifting layers) */
.crawl-stars, .crawl-stars::after {
  content:''; position:absolute; inset:-50%;
  background-image:
    radial-gradient(1px 1px at 21% 33%, #9bb0c9 50%, transparent 51%),
    radial-gradient(1px 1px at 43% 71%, #cfd8e3 50%, transparent 51%),
    radial-gradient(1.6px 1.6px at 62% 24%, #ffffff 50%, transparent 51%),
    radial-gradient(1px 1px at 81% 49%, #9bb0c9 50%, transparent 51%),
    radial-gradient(1.4px 1.4px at 91% 82%, #e8eef5 50%, transparent 51%),
    radial-gradient(1px 1px at 12% 86%, #cfd8e3 50%, transparent 51%),
    radial-gradient(1.2px 1.2px at 71% 91%, #ffffff 50%, transparent 51%),
    radial-gradient(1px 1px at 35% 55%, #9bb0c9 50%, transparent 51%),
    radial-gradient(1.4px 1.4px at 52% 12%, #e8eef5 50%, transparent 51%);
  background-size: 420px 420px;
  animation: crawl-twinkle 7s ease-in-out infinite alternate;
}
.crawl-stars::after { background-size: 660px 660px; animation-duration:11s; animation-delay:-4s; opacity:.6; }
@keyframes crawl-twinkle { from { opacity:.4; } to { opacity:.9; } }

/* phase 1: the blue line (0-5s), alone on black */
.crawl-intro {
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  color:#4bd5ee; font-size:clamp(22px, 4vw, 38px); line-height:1.4; padding:0 10vw;
  animation: crawl-intro-fade 5s ease both;
}
@keyframes crawl-intro-fade { 0% { opacity:0; } 8%,60% { opacity:1; } 85%,100% { opacity:0; } }

/* phase 2: the title recedes into the distance (4.5-9s) */
.crawl-title {
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  color:transparent; -webkit-text-stroke: 2px #FFE81F; text-stroke: 2px #FFE81F;
  font-size:clamp(48px, 13vw, 160px); text-align:center; font-weight:800; letter-spacing:.04em;
  animation: crawl-title-recede 4.5s cubic-bezier(.2,.6,.4,1) 4.5s both;
}
/* 0% is INVISIBLE on purpose: fill-mode:both back-fills the first keyframe during the 4.5s
   delay, so a visible 0% frame made the title sit on top of the blue line (QA 2026-07-13). */
@keyframes crawl-title-recede {
  0%   { opacity:0; transform:scale(1); }
  6%   { opacity:1; }
  80%  { opacity:1; }
  100% { opacity:0; transform:scale(.05); }
}

/* phase 3: the crawl itself (starts 8.5s) */
.crawl-stage { position:absolute; inset:0; perspective:380px; overflow:hidden; }
.crawl-text {
  position:absolute; left:50%; bottom:0; width:min(72vw, 820px);
  transform-origin:50% 100%;
  color:#FFE81F; font-size:clamp(22px, 3.4vw, 40px); font-weight:700; text-align:justify; line-height:1.6;
  animation-name: crawl-scroll; animation-timing-function: linear;
  animation-fill-mode: both; /* the fix: text stays at its 0% (offscreen) position during the delay */
}
.crawl-text h2 { text-align:center; text-transform:uppercase; font-size:1.3em; margin:0 0 1em; }
@keyframes crawl-scroll {
  0%   { transform: translateX(-50%) rotateX(58deg) translateY(102%); opacity:1; }
  92%  { opacity:1; }
  100% { transform: translateX(-50%) rotateX(58deg) translateY(-260%); opacity:0; }
}
.crawl-close {
  position:absolute; bottom:16px; right:18px; z-index:210; background:rgba(0,0,0,.55);
  color:#888; border:1px solid #444; font:inherit; font-size:12px; padding:8px 14px; cursor:pointer;
}
.crawl-close:hover { color:#FFE81F; border-color:#FFE81F; }
@media (prefers-reduced-motion: reduce) {
  .crawl-text { animation-duration:1s !important; animation-delay:0s !important; transform:translateX(-50%); position:static; margin:8vh auto; }
  .crawl-stage { overflow-y:auto; }
  .crawl-intro, .crawl-title, .crawl-stars { display:none; }
}

/* ---- Read-only party sheet (Phase E-1): interactive sheet controls act on MY state, not the
   viewed character's — hide them. Printing still works. ---- */
.readonly-sheet .name-fields, .readonly-sheet .sheet-actions, .readonly-sheet .error-banner,
.readonly-sheet button { display: none !important; }
/* The during-play recovery strip is the viewer's control surface — meaningless on someone
   else's sheet (their CURRENT wounds/session log still show; those are data, not controls). */
.readonly-sheet .panel.screen-only { display: none !important; }

/* ---- Campaign HQ mode: the campaign manager gets the full width — no character dossier, no
   creation progress strip. A different mental space than the builder (Bill, 2026-07-13). ---- */
body.campaign-mode .dossier { display: none; }
body.campaign-mode .progress { display: none; }
/* HQ v2 (Bill, 2026-07-13): NO builder chrome at all — the rail/tabbar go too (the topbar's
   "◂ Character Builder" is the way back), and the character save/start-over controls hide. */
body.campaign-mode .rail, body.campaign-mode .tabbar { display: none; }
body.campaign-mode .frame { grid-template-columns: minmax(0, 1fr); max-width: 1100px; }
body.campaign-mode .main { padding-bottom: 60px; }
@media screen and (max-width: 900px) {
  body.campaign-mode .frame { grid-template-columns: 1fr; }
}

/* ---- signed-out save banner on the home (species) screen ---- */
.save-banner {
  margin: 0 0 16px; font-size: 12.5px; line-height: 1.6; color: var(--text-muted);
  border-left: 3px solid var(--accent-green);
}
.save-banner b { color: var(--text-parchment); }

/* ---- XP sub-area cards (QA 2026-07-13: the old small text tabs were getting missed) ---- */
.xp-subnav { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 18px; }
.xp-subcard {
  position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  min-height: 62px; padding: 10px 14px; cursor: pointer; text-align: left; font: inherit;
  background: var(--bg-panel-raised); color: var(--text-parchment); border: 1px solid var(--border-metal-light);
  border-radius: 4px;
}
.xp-subcard:hover { border-color: var(--accent-amber-dim); }
.xp-subcard.active { border-color: var(--accent-amber); box-shadow: 0 0 0 1px var(--accent-amber), inset 0 0 14px var(--glow-amber); }
.xp-subcard .xsc-title { font-family: 'Big Shoulders Stencil Text', sans-serif; font-size: 16px; letter-spacing: 0.05em; text-transform: uppercase; }
.xp-subcard.active .xsc-title { color: var(--accent-amber); }
.xp-subcard .xsc-sub { font-size: 11px; line-height: 1.4; color: var(--text-muted); }
.xp-subcard .dot { position: absolute; top: 10px; right: 10px; width: 9px; height: 9px; border-radius: 50%; background: var(--accent-rust); }
@media screen and (max-width: 560px) { .xp-subnav { grid-template-columns: 1fr; } .xp-subcard { min-height: 52px; } }

/* ---- account panel (Phase A: sign-in / My Characters) — centered modal, all breakpoints ---- */
.account-scrim { display: none; }
.account-sheet {
  position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%) scale(0.98);
  width: min(520px, calc(100vw - 24px)); max-height: 84vh; overflow-y: auto; z-index: 80;
  background: var(--bg-panel); border: 1px solid var(--accent-amber-dim); border-radius: 8px;
  padding: 14px 18px 18px; opacity: 0; pointer-events: none; transition: opacity 0.15s ease;
}
body.account-open .account-sheet { opacity: 1; pointer-events: auto; transform: translate(-50%, -50%); }
body.account-open .account-scrim { display: block; position: fixed; inset: 0; z-index: 70; background: rgba(0,0,0,0.65); }
.account-sheet h2 { color: var(--accent-amber); margin: 4px 0 6px; font-size: 17px; }
.account-sheet .grab { width: 44px; height: 4px; border-radius: 2px; background: var(--border-metal-light); margin: 0 auto 10px; }
.account-btn { white-space: nowrap; max-width: 220px; overflow: hidden; text-overflow: ellipsis; }

/* ================= OFFICIAL-LAYOUT CHARACTER SHEET (os-*) ================= */
/* Mirrors the Core Rulebook sheet's structure (pdf pp.453-454) — see renderSummaryScreen. */
.official-sheet { max-width: 900px; }
.sheet-banner { display:flex; align-items:center; gap:10px; margin:18px 0 8px; }
.sheet-banner::before, .sheet-banner::after { content:''; flex:1; height:1px; background: var(--border-metal-light); }
.sheet-banner span {
  font-size:11px; font-weight:700; letter-spacing:0.18em; color: var(--accent-amber); text-transform:uppercase;
  padding:3px 14px; background: var(--bg-panel); border:1px solid var(--accent-amber-dim);
  clip-path:polygon(8px 0,100% 0,calc(100% - 8px) 100%,0 100%);
}
.os-head { border:1px solid var(--border-metal); background: var(--bg-panel); padding:10px 14px; display:grid; grid-template-columns:2fr 1fr; gap:4px 20px; }
.os-field { border-bottom:1px solid var(--border-metal-light); padding:2px 0 3px; min-width:0; }
.os-field small { display:block; font-size:9px; letter-spacing:0.14em; color: var(--text-dim); text-transform:uppercase; }
.os-field b { font-size:15px; color: var(--accent-amber); font-weight:700; }
.os-derived { display:grid; grid-template-columns:repeat(4,1fr); gap:10px; }
.os-dbox {
  border:2px solid var(--border-metal-light); background: var(--bg-panel-deep); text-align:center;
  clip-path:polygon(10px 0,calc(100% - 10px) 0,100% 10px,100% calc(100% - 10px),calc(100% - 10px) 100%,10px 100%,0 calc(100% - 10px),0 10px);
}
.os-dbox .dl { font-size:9.5px; letter-spacing:0.14em; color: var(--bg-void); background: var(--accent-amber-dim); text-transform:uppercase; padding:3px 0; font-weight:700; }
.os-dbox.combat .dl { background: var(--accent-rust); color: var(--text-parchment); }
.os-dbox .dv { display:flex; }
.os-dbox .dv div { flex:1; padding:8px 0 6px; }
.os-dbox .dv div + div { border-left:1px solid var(--border-metal); }
.os-dbox .dv b { font-size:24px; color: var(--text-parchment); }
.os-dbox .dv small { display:block; font-size:8.5px; color: var(--text-muted); letter-spacing:0.1em; text-transform:uppercase; }
.os-chars { display:grid; grid-template-columns:repeat(6,1fr); gap:10px; background: var(--bg-panel-raised); border:1px solid var(--border-metal); padding:14px 10px 10px; }
.os-medal { text-align:center; }
.os-medal .disc {
  width:64px; height:64px; margin:0 auto; border-radius:50%; background: var(--bg-panel-deep);
  border:3px solid var(--accent-amber-dim); display:flex; align-items:center; justify-content:center;
  box-shadow:0 0 0 2px var(--border-metal), 0 0 12px var(--glow-amber);
}
.os-medal .disc b { font-size:26px; color: var(--accent-amber); }
.os-medal .ml {
  margin-top:6px; font-size:9px; font-weight:700; letter-spacing:0.12em; text-transform:uppercase;
  background: var(--accent-navy); color: var(--text-parchment); padding:2px 0;
  clip-path:polygon(6px 0,100% 0,calc(100% - 6px) 100%,0 100%);
}
.os-skills2col { display:grid; grid-template-columns:1fr 1fr; gap:0 22px; }
.os-sk-title { margin:10px 0 4px; font-size:10px; letter-spacing:0.14em; color: var(--accent-amber-dim); text-transform:uppercase; border-bottom:1px solid var(--border-metal-light); padding-bottom:2px; }
table.os-sk { width:100%; border-collapse:collapse; }
table.os-sk td { padding:2.5px 4px; border-bottom:1px solid var(--border-metal); font-size:12px; line-height:1.45; }
table.os-sk td.nm i { color: var(--text-dim); font-style:normal; font-size:10.5px; }
.sr-only-head { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }
td.career { width:26px; text-align:center; }
.cbox { display:inline-block; width:13px; height:13px; border:1.5px solid var(--border-metal-light); border-radius:2px; position:relative; }
.cbox.on { border-color: var(--accent-amber); }
.cbox.on::after { content:'✓'; position:absolute; inset:-3px 0 0 1px; color: var(--accent-amber); font-size:11px; }
td.ranks { white-space:nowrap; }
.rb { display:inline-block; width:12px; height:12px; border:1px solid var(--border-metal-light); margin-right:2px; border-radius:2px; }
.rb.on { background: var(--accent-amber); border-color: var(--accent-amber); }
.rb.on.free { background: var(--accent-green); border-color: var(--accent-green); }
table.os-wp, table.os-tal { width:100%; border-collapse:collapse; }
table.os-wp th, table.os-tal th { font-size:9.5px; letter-spacing:0.1em; color: var(--text-dim); text-transform:uppercase; text-align:left; border-bottom:1px solid var(--border-metal-light); padding:3px 6px; }
table.os-wp td, table.os-tal td { border-bottom:1px solid var(--border-metal); padding:5px 6px; font-size:12px; line-height:1.5; vertical-align:top; }
table.os-tal td:first-child { white-space:nowrap; font-weight:700; }
.os-xpfoot { display:grid; grid-template-columns:1fr 2fr 1fr; gap:10px; align-items:stretch; margin-top:16px; }
.os-xpbox {
  border:2px solid var(--accent-amber-dim); background: var(--bg-panel-deep); text-align:center; padding:6px 0;
  clip-path:polygon(10px 0,calc(100% - 10px) 0,100% 50%,calc(100% - 10px) 100%,10px 100%,0 50%);
}
.os-xpbox b { font-size:20px; color: var(--accent-amber); display:block; }
.os-xpbox small { font-size:9px; letter-spacing:0.14em; color: var(--text-muted); text-transform:uppercase; }
.os-xptitle {
  background: var(--accent-rust); display:flex; align-items:center; justify-content:center; color: var(--text-parchment);
  font-family:'Big Shoulders Stencil Text',sans-serif; font-weight:800; letter-spacing:0.22em; font-size:15px; text-transform:uppercase;
}
.os-p2grid { display:grid; grid-template-columns:repeat(3,1fr); gap:12px; }
.os-block { border:1px solid var(--border-metal); background: var(--bg-panel); padding:10px 12px; }
.os-block h5 { margin:0 0 6px; font-size:10px; letter-spacing:0.14em; color: var(--accent-amber-dim); text-transform:uppercase; }

/* ================= MOBILE RESPONSIVE ================= */
/* <900px: single-column content, bottom tab bar replaces the rail, dossier + talent inspector
   become bottom sheets (driven by body.dossier-open / body.talent-selected from main.js). */
@media screen and (max-width: 900px) {
  .frame { grid-template-columns: 1fr; }
  .main { padding: 14px 14px calc(80px + env(safe-area-inset-bottom)); } /* room for the tab bar */
  .rail { display: none; }
  .tabbar { display: flex; }
  .topbar .brand { display: none; }
  .topbar-row { flex-wrap: wrap; gap: 8px 10px; padding: 8px 12px 6px; }
  .topbar-controls { width: 100%; }

  /* dossier -> bottom sheet */
  .dossier {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; height: auto; max-height: 78vh;
    z-index: 60; transform: translateY(105%); transition: transform 0.25s ease;
    background: var(--bg-panel); border: none; border-top: 2px solid var(--accent-amber-dim);
    border-radius: 14px 14px 0 0; padding: 14px 16px calc(20px + env(safe-area-inset-bottom));
    overflow-y: auto;
  }
  body.dossier-open .dossier { transform: translateY(0); }
  body.dossier-open .dossier-scrim { display: block; position: fixed; inset: 0; z-index: 50; background: rgba(0,0,0,0.6); }

  /* talent inspector -> bottom sheet */
  .tree-layout { grid-template-columns: 1fr; }
  .talent-inspector {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; z-index: 60; max-height: 72vh;
    transform: translateY(105%); transition: transform 0.25s ease;
    border: none; border-top: 2px solid var(--accent-amber-dim); border-radius: 14px 14px 0 0;
    padding: 14px 16px calc(20px + env(safe-area-inset-bottom));
  }
  .talent-inspector.has-selection { transform: translateY(0); }
  .talent-inspector .ti-close {
    display: block; position: absolute; top: 8px; right: 10px; min-width: 44px; min-height: 44px;
    background: none; border: none; color: var(--text-muted); font-size: 18px; cursor: pointer;
  }
  .ti-scrim { display: block; position: fixed; inset: 0; z-index: 50; background: rgba(0,0,0,0.6); }

  .species-grid, .career-grid { grid-template-columns: repeat(2, 1fr); }
  .spec-grid { grid-template-columns: repeat(2, 1fr); }
  .bg-grid { grid-template-columns: 1fr; }
  .ob-grid { grid-template-columns: repeat(2, 1fr); }
  .summary-grid { grid-template-columns: 1fr; }
  .charstats { grid-template-columns: repeat(3, 1fr); row-gap:8px; }
  .tt-grid-wrap { overflow-x: auto; }
  .dice-table { display:block; overflow-x:auto; white-space:nowrap; }
  .seg-control { display: flex; width: 100%; }
  .seg-control button { flex: 1; min-width: 0; }

  /* official sheet stacks */
  .os-skills2col { grid-template-columns: 1fr; }
  .os-derived { grid-template-columns: repeat(2, 1fr); }
  .os-chars { grid-template-columns: repeat(3, 1fr); row-gap: 14px; }
  .os-p2grid { grid-template-columns: 1fr; }
  .os-head { grid-template-columns: 1fr; }

  /* comfortable touch targets (Material 48dp / Apple 44pt) */
  .nav-toggle button, .buy-btn, .refund-btn, .save-load-btn, .start-over-btn, .theme-btn,
  .confirm-yes, .confirm-no, .finalize-btn { min-height: 44px; }
}
@media screen and (max-width: 560px) {
  .species-grid, .career-grid, .spec-grid, .ob-grid { grid-template-columns: repeat(2, 1fr); }
  .charstats { grid-template-columns: repeat(3, 1fr); }
  h1.screen-title { font-size:19px; }
}

/* ================= PRINT (paper-friendly official sheet) ================= */
@media print {
  /* ---- optimized for paper & PDF, color AND black-and-white (QA 2026-07-13) ----
     Root cause of the earlier bad output: the responsive breakpoints used to apply to the
     ~816px print page (now scoped to `screen`). Below: tight margins, compact header, dice
     pools as guaranteed-visible text, and a grayscale-safe palette (the two accent tones
     print as distinct grays on B&W printers). */
  @page { margin: 11mm; }
  .topbar, #nav-root, .dossier, .dossier-scrim, .sheet-actions, .nav-toggle, .substep-nav,
  .screen-only, .name-fields, .error-banner, .talent-inspector, .ti-scrim,
  .account-sheet, .account-scrim, .save-banner { display:none !important; }
  .frame { display:block; max-width:none; }
  .main { padding: 0 !important; }
  body { background: #fff; background-image: none; color: #111; font-size: 9.5px; line-height: 1.35; }
  .official-sheet { max-width: none; }

  /* compact header strip: one tight three-column grid instead of the roomy screen layout */
  .os-head { grid-template-columns: repeat(3, 1fr); gap: 2px 14px; padding: 6px 10px; }
  .os-field { padding: 1px 0 2px; }
  .os-field small { font-size: 7px; }
  .os-field b { font-size: 11px; color:#111; }

  /* tighter section banners; never orphan a banner at a page bottom */
  .sheet-banner { margin: 8px 0 4px; break-after: avoid; }
  .sheet-banner span { background:#eee; color:#333; border-color:#999; font-size: 9px; padding: 2px 10px; }
  .sheet-banner::before, .sheet-banner::after { background:#999; }

  .panel, .os-block, .os-head, .os-chars { background:#fff; border-color:#888; break-inside: avoid; }
  .panel::before, .panel::after { display:none; }

  /* derived boxes + characteristic medallions, scaled down */
  .os-derived { gap: 6px; }
  .os-dbox { background:#fff; border-color:#555; }
  .os-dbox .dl { background:#444; color:#fff; font-size: 8px; padding: 2px 0; }
  .os-dbox.combat .dl { background:#7a2c1c; color:#fff; }
  .os-dbox .dv div { padding: 4px 0 3px; }
  .os-dbox .dv b { font-size: 16px; color:#111; }
  .os-chars { padding: 8px 6px 6px; gap: 6px; }
  .os-medal .disc { width: 40px; height: 40px; background:#fff; border-color:#555; border-width: 2px; box-shadow:none; }
  .os-medal .disc b { font-size: 17px; color:#111; }
  .os-medal .ml { background:#333; color:#fff; font-size: 7px; }

  /* skills: two columns preserved, dense rows, DICE POOL AS TEXT guaranteed visible */
  .os-skills2col { gap: 0 14px; }
  .os-sk-title { font-size: 8px; margin: 6px 0 2px; }
  table.os-sk td { padding: 1px 3px; font-size: 8.5px; line-height: 1.3; border-color:#ccc; }
  table.os-sk td.nm i { font-size: 7.5px; }
  .rb { width: 8px; height: 8px; margin-right: 1px; }
  .rb.on { background:#333; border-color:#333; }
  .rb.on.free { background:#999; border-color:#999; } /* free ranks = visibly lighter in B&W */
  .cbox { width: 9px; height: 9px; }
  .cbox.on { border-color:#111; } .cbox.on::after { color:#111; font-size: 8px; inset: -2px 0 0 1px; }
  td.dice-cell.print-only { display: table-cell !important; font-weight: 700; white-space: nowrap; }
  .print-only { display: table-cell !important; }

  table.os-wp td, table.os-tal td { border-color:#bbb; padding: 2px 4px; font-size: 8.5px; line-height: 1.35; }
  table.os-wp th, table.os-tal th { font-size: 7.5px; }

  .os-xpfoot { margin-top: 8px; gap: 6px; }
  .os-xpbox { background:#fff; border-color:#555; padding: 3px 0; }
  .os-xpbox b { font-size: 14px; color:#111; }
  .os-xptitle { background:#7a2c1c; color:#fff; font-size: 11px; }

  .os-field b, .os-medal .disc b, .os-xpbox b, .row2 b { color:#111; }
  .os-block h5 { font-size: 8px; margin-bottom: 3px; }
  .os-p2grid { gap: 6px; }
  .row2 { padding: 2px 0; font-size: 9px; border-color:#ddd; }
  .os-page2 { break-before: page; }
  a[href]::after { content: ''; }
}
