/* ====== NOSTROMO CRT AESTHETIC ====== */

:root {
  /* ===== 1. SURFACE (flat colors, opaque) ===== */
  --bg:             #050805;    /* app bg — also used as "on-accent" text color */
  --surface:        #0a1208;    /* default panel background */
  --surface-raised: #0e1a0c;    /* elevated panel (cards inside panels) */

  /* ===== 2. BRAND SOLIDS (opaque, AA-safe on surface) ===== */
  --green:       #33ff33;       /* primary text, active state */
  --green-dim:   #22aa22;       /* secondary / default button */
  --green-faint: #2e9c2e;       /* tertiary / labels (5.36:1 on surface) */
  --amber:       #ffb000;       /* emphasis / primary action */
  --amber-dim:   #aa7600;       /* secondary amber */
  --red:         #ff3030;       /* danger / fumble */
  --red-dim:     #cc3333;       /* danger border (3.71:1 on surface) */

  /* ===== 3. TINT SCALE (semi-transparent — use for hover bgs, glows, tints) ===== */
  /* All three brand hues share the same alpha tiers for consistency. */
  --green-08: rgba(51, 255, 51, 0.08);   /* subtle tint (rest bg) */
  --green-16: rgba(51, 255, 51, 0.16);   /* hover tint */
  --green-24: rgba(51, 255, 51, 0.24);   /* pressed / active tint */
  --green-40: rgba(51, 255, 51, 0.40);   /* glow core */

  --amber-08: rgba(255, 176, 0, 0.08);
  --amber-16: rgba(255, 176, 0, 0.16);
  --amber-24: rgba(255, 176, 0, 0.24);
  --amber-40: rgba(255, 176, 0, 0.40);

  --red-08:   rgba(255, 48, 48, 0.08);
  --red-16:   rgba(255, 48, 48, 0.16);
  --red-24:   rgba(255, 48, 48, 0.24);
  --red-40:   rgba(255, 48, 48, 0.40);

  /* ===== 4. BORDERS (semantic aliases of tint scale) ===== */
  --border:        rgba(51, 255, 51, 0.53);   /* default — AA UI 4.60:1 on surface */
  --border-strong: rgba(51, 255, 51, 0.67);   /* emphasized */

  /* ===== 4b. OVERLAY / SPECIAL (semi-transparent black layers) ===== */
  --overlay-strong: rgba(0, 0, 0, 0.72);      /* modal backdrop */
  --overlay-soft:   rgba(0, 0, 0, 0.30);      /* recessed surface (sub-panel inset) */
  --scanline:       rgba(0, 0, 0, 0.25);      /* CRT scanline overlay stripe */

  /* ===== 4c. BRAND HIGHLIGHTS (blink alternates — lighter solids) ===== */
  --amber-hi: #ffe180;   /* blink peak from --amber */
  --red-hi:   #ff9999;   /* blink peak from --red */

  /* ===== 5. ELEVATION (shadows, depth) ===== */
  --elev-1:    0 1px 3px  rgba(0, 0, 0, 0.4);     /* knob / small button */
  --elev-2:    0 4px 12px rgba(0, 0, 0, 0.5);     /* sticky header / floating bar */
  --elev-3:    0 8px 24px rgba(0, 0, 0, 0.6);     /* modal, popup, flyout */
  --elev-up:   0 -4px 12px rgba(0, 0, 0, 0.5);    /* bar docked to viewport bottom */
  --elev-left: -4px 0 12px rgba(0, 0, 0, 0.5);    /* panel docked to viewport right */

  /* ===== 6. GLOWS (colored halos for emphasis) ===== */
  --glow-sm-amber: 0 0 12px var(--amber-24);
  --glow-md-amber: 0 0 18px var(--amber-40);
  --glow-lg-amber: 0 0 28px var(--amber-40);
  --glow-sm-green: 0 0 12px var(--green-24);
  --glow-md-green: 0 0 18px var(--green-40);
  --glow-lg-green: 0 0 28px var(--green-40);
  --glow-sm-red:   0 0 12px var(--red-24);
  --glow-md-red:   0 0 18px var(--red-40);
  --glow-lg-red:   0 0 28px var(--red-40);

  /* ===== 7. SPACING (4px scale) ===== */
  --sp-1:  4px;
  --sp-2:  8px;
  --sp-3:  12px;
  --sp-4:  16px;
  --sp-5:  24px;
  --sp-6:  32px;
  --sp-7:  48px;
  --sp-8:  64px;
  --sp-9:  96px;

  /* ===== 8. TYPOGRAPHY ===== */
  --font: ui-monospace, Menlo, Consolas, "Cascadia Mono", "Roboto Mono", "Courier New", monospace;

  /* Sizes — golden-ratio modular scale from 10px baseline.
     Every other tier is exactly φ (1.618) apart; adjacent tiers are √φ (1.272) apart. */
  --fs-xs:      10px;   /* baseline (φ⁰) — micro labels, badges */
  --fs-sm:      13px;   /* √φ — small / muted text */
  --fs-base:    16px;   /* φ — body */
  --fs-md:      21px;   /* φ·√φ — subheads, emphasis */
  --fs-lg:      26px;   /* φ² — section titles */
  --fs-xl:      33px;   /* φ²·√φ — stat values */
  --fs-2xl:     42px;   /* φ³ — ability mods, big numbers */
  --fs-display: 68px;   /* φ⁴ — popup total */

  /* Tracking — 3 intentional steps */
  --track-1: 1px;   /* labels, body caps */
  --track-2: 2px;   /* buttons, panel titles */
  --track-3: 3px;   /* display headings */

  /* ===== 9. MOTION ===== */
  --dur-fast: 100ms;              /* hover color swaps, tiny transforms */
  --dur-med:  150ms;              /* bg/border transitions, modal fade */
  --dur-slow: 250ms;              /* panel slides, tab switches */
  --ease:     cubic-bezier(0.2, 0.8, 0.2, 1);  /* ease-out-ish — default */

  /* ===== 10. BORDERS (stroke weights) ===== */
  /* Default weight used on most panels and buttons. "Strong" is reserved for
     elements that should read as primary/heavier (mode cards, modal frames). */
  --border-w:        1px;
  --border-w-strong: 2px;

  /* ---- legacy aliases (kept temporarily for unmigrated callsites) ---- */
  --bg-panel:    var(--surface);
  --bg-panel-hi: var(--surface-raised);
  --border-hi:   var(--border-strong);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--green);
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.4;
  min-height: 100vh;
  /* Tell browsers our UI is dark — affects form controls, scrollbars, autofill */
  color-scheme: dark;
}
/* Extend the background into iOS rubber-band overscroll + under the notch / home-indicator
   so the browser chrome never peeks at a default white surface. */
html {
  background-color: var(--bg);
  min-height: 100%;
}

/* subtle CRT scanlines */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  background: repeating-linear-gradient(
    to bottom,
    transparent 0px,
    transparent 2px,
    var(--scanline) 3px,
    var(--scanline) 3px
  );
  pointer-events: none;
  z-index: 1000;
  mix-blend-mode: multiply;
}

/* faint phosphor glow on text */
body { text-shadow: 0 0 2px var(--green-40); }

/* Disable text selection and the long-press callout globally on both iOS and
   Android — this is a tool, not a document. Inputs / textareas / contenteditable
   re-enable selection so the user can still edit names etc. */
body {
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-drag: none;
}
body ::selection { background: transparent; }
input, textarea, [contenteditable="true"] {
  -webkit-user-select: text;
  -moz-user-select: text;
  -ms-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}
input::selection, textarea::selection, [contenteditable="true"]::selection,
[contenteditable="true"] *::selection {
  background: rgba(255, 176, 0, 0.55);
  color: var(--bg);
}

/* subtle screen flicker */
@keyframes flicker {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.97; }
}
body { animation: flicker 6s infinite; }
@media (prefers-reduced-motion: reduce) {
  body { animation: none; }
}

/* ====== LAYOUT ====== */

.page {
  max-width: 1400px;
  margin: 0 auto;
  /* Content stays out of notch / home-indicator regions; background still extends there
     thanks to html { background: var(--bg) } + meta theme-color. */
  padding:
    max(var(--sp-4), env(safe-area-inset-top))
    max(var(--sp-4), env(safe-area-inset-right))
    max(var(--sp-9), env(safe-area-inset-bottom)) /* bottom clears sticky wizard-nav */
    max(var(--sp-4), env(safe-area-inset-left));
}

/* Roll log / dice tray are character-sheet-only tools — hide during setup flows. */
body:not([data-phase="play"]) #roll-log,
body:not([data-phase="play"]) #roll-dice,
body:not([data-phase="play"]) .corner-btns {
  display: none;
}

.crt-header {
  border: 1px solid var(--border);
  padding: var(--sp-2) var(--sp-3);
  margin-bottom: var(--sp-4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--bg-panel);
}

.crt-header h1 {
  font-size: var(--fs-base);
  letter-spacing: var(--track-3);
  margin: 0;
  color: var(--green);
}

main#app {
  min-width: 0;
}

/* ====== MODE SELECT CARDS ====== */

.mode-grid {
  display: grid;
  /* min(320px, 100%) prevents overflow when container is narrower than 320px */
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: var(--sp-4);
  margin-top: var(--sp-3);
}

.mode-card {
  border: 2px solid var(--border);
  background: var(--bg-panel-hi);
  padding: var(--sp-4);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  transition: border-color var(--dur-med), background var(--dur-med), box-shadow var(--dur-med), transform var(--dur-fast);
  position: relative;
}

/* Interactive state: same visual on desktop hover AND touch press.
   :hover is gated so it doesn't stick on iOS after a tap.
   Treatment matches .preset-card and .class-card for consistency. */
@media (hover: hover) {
  .mode-card:hover {
    border-color: var(--amber);
    background: var(--amber-08);
    box-shadow: 0 0 24px var(--amber-16);
    transform: translateY(-2px);
  }
}
.mode-card:active {
  border-color: var(--amber);
  background: var(--amber-08);
  box-shadow: 0 0 24px var(--amber-16);
  transform: translateY(-2px);
}

.mode-card .mode-kicker {
  font-size: var(--fs-sm);
  letter-spacing: var(--track-2);
  color: var(--green-dim);
  text-transform: uppercase;
}

.mode-card h3 {
  color: var(--amber);
  margin: 0;
  font-size: var(--fs-xl);
  letter-spacing: var(--track-3);
  font-weight: bold;
}

.mode-card .mode-desc {
  color: var(--green);
  font-size: var(--fs-base);
  line-height: 1.5;
  margin: 0;
}

.mode-card .mode-bullets {
  color: var(--green-dim);
  font-size: var(--fs-sm);
  line-height: 1.6;
  margin: 0;
  padding-left: var(--sp-4);
}

/* Shared CTA inside cards — amber-bordered label/icon that inverts when the
   parent card is hovered or pressed. See mode-card, preset-card, class-card. */
.card-action {
  color: var(--amber);
  border: 1px solid var(--amber);
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-base);
  font-weight: bold;
  letter-spacing: var(--track-2);
  transition: background var(--dur-fast), color var(--dur-fast);
}

/* Text-label variant: push to bottom-right of the card flex column. */
.mode-card .card-action,
.preset-card .card-action {
  margin-top: auto;
  align-self: flex-end;
}

@media (hover: hover) {
  .mode-card:hover .card-action,
  .preset-card:hover .card-action,
  .class-card:hover .card-action {
    background: var(--amber);
    color: var(--bg);
  }
}
.mode-card:active .card-action,
.preset-card:active .card-action,
.class-card:active .card-action {
  background: var(--amber);
  color: var(--bg);
}

/* ====== PRESET CARDS (quick-deploy) ====== */

.preset-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: var(--sp-3);
  margin-top: var(--sp-2);
}

.preset-card {
  border: 1px solid var(--border);
  background: var(--bg-panel-hi);
  padding: var(--sp-3);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  transition: transform var(--dur-fast), border-color var(--dur-med), box-shadow var(--dur-med), background var(--dur-med);
}

@media (hover: hover) {
  .preset-card:hover {
    border-color: var(--amber);
    background: var(--amber-08);
    box-shadow: 0 0 24px var(--amber-16);
    transform: translateY(-2px);
  }
}
.preset-card:active {
  border-color: var(--amber);
  background: var(--amber-08);
  box-shadow: 0 0 24px var(--amber-16);
  transform: translateY(-2px);
}

.preset-card h3 {
  color: var(--amber);
  margin: 0;
  font-size: var(--fs-md);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
}

.preset-card .preset-desc {
  color: var(--green);
  font-size: var(--fs-base);
  line-height: 1.5;
  margin: 0;
}

.preset-card .preset-stats {
  color: var(--green-dim);
  font-size: var(--fs-sm);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-2) var(--sp-3);
  letter-spacing: var(--track-1);
}

@media (min-width: 700px) {
  .preset-card .preset-stats {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1100px) {
  .preset-card .preset-stats {
    grid-template-columns: repeat(3, 1fr);
  }
}
.preset-card .preset-stats b {
  color: var(--amber);
  margin-right: 2px;
}

.preset-card .preset-kit {
  color: var(--green-dim);
  font-size: var(--fs-sm);
  line-height: 1.45;
  font-style: italic;
  flex: 1;
}
.preset-card .preset-kit b {
  color: var(--amber);
  font-style: normal;
  letter-spacing: var(--track-1);
}

/* ====== TABS (play phase) ====== */

.tabs {
  margin-top: var(--sp-2);
}

.tab-nav {
  display: flex;
  flex-wrap: nowrap;
  gap: var(--sp-1);
  margin-bottom: var(--sp-3);
  border-bottom: 1px dashed var(--border);
  padding: var(--sp-2) 0 var(--sp-1);
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch; /* momentum scroll on iOS */
  scrollbar-width: thin;             /* Firefox */
  scrollbar-color: var(--green-dim) transparent;

  /* Stick to the top of the viewport when scrolled past */
  position: sticky;
  top: 0;
  z-index: 300;
  background: var(--bg);
  box-shadow: var(--elev-2);
}

/* WebKit scrollbar styling — subtle, matches theme */
.tab-nav::-webkit-scrollbar {
  height: 4px;
}
.tab-nav::-webkit-scrollbar-track {
  background: transparent;
}
.tab-nav::-webkit-scrollbar-thumb {
  background: var(--green-dim);
  border-radius: 2px;
}

.tab-btn {
  background: var(--green-dim);
  border: 1px solid var(--green-dim);
  color: var(--bg);
  padding: var(--sp-2) var(--sp-4);
  font-family: var(--font);
  font-size: var(--fs-sm);
  letter-spacing: var(--track-2);
  font-weight: bold;
  cursor: pointer;
  text-transform: uppercase;
  white-space: nowrap;   /* never break label text */
  flex-shrink: 0;        /* never squeeze tabs; let nav scroll instead */
  transition: background var(--dur-med), color var(--dur-fast), border-color var(--dur-med), box-shadow var(--dur-med), transform var(--dur-fast);
}

/* HOVER (only when not active) — amber accent to stand apart from the green states */
@media (hover: hover) {
  .tab-btn:not(.active):hover {
    background: var(--amber);
    border-color: var(--amber);
    color: var(--bg);
    box-shadow: 0 0 12px var(--amber-40);
    transform: translateY(-1px);
  }
}
.tab-btn:not(.active):active {
  background: var(--amber);
  border-color: var(--amber);
  color: var(--bg);
  box-shadow: 0 0 12px var(--amber-40);
  transform: translateY(-1px);
}

/* ACTIVE — bright pure green */
.tab-btn.active {
  background: var(--green);
  border-color: var(--green);
  color: var(--bg);
  box-shadow: 0 0 18px var(--green-40);
}

.tab-content[hidden] {
  display: none;
}

/* ====== MODAL DIALOG ====== */

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: var(--overlay-strong);
  z-index: 1100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-4);
  animation: modal-fade-in var(--dur-fast) ease-out;
}

.modal {
  background: var(--bg-panel);
  border: 2px solid var(--amber);
  padding: var(--sp-5) var(--sp-5);
  min-width: 320px;
  max-width: 92vw;
  box-shadow: 0 0 40px var(--amber-40), var(--elev-3);
  font-family: var(--font);
  animation: modal-slide-in var(--dur-med) ease-out;
}

.modal-title {
  color: var(--amber);
  margin: 0 0 var(--sp-2) 0;
  font-size: var(--fs-md);
  letter-spacing: var(--track-3);
  text-transform: uppercase;
}

.modal-desc {
  color: var(--green-dim);
  font-size: var(--fs-sm);
  margin: 0 0 var(--sp-3) 0;
  letter-spacing: var(--track-1);
}

.modal-label {
  display: block;
  color: var(--green);
  font-size: var(--fs-sm);
  letter-spacing: var(--track-1);
  margin-bottom: var(--sp-1);
  text-transform: uppercase;
}

.modal-input {
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  font-family: var(--font);
  font-size: var(--fs-xl);
  font-weight: bold;
  margin-bottom: var(--sp-4);
  text-align: center;
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-2);
  flex-wrap: wrap;
}

.modal-actions button {
  min-width: 80px;
}

@keyframes modal-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes modal-slide-in {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ====== ROLL CONTEXT MENU (right-click / long-press flyout) ====== */

.roll-menu {
  position: fixed;
  z-index: 1100;
  min-width: 160px;
  background: var(--bg-panel);
  border: 1px solid var(--amber);
  box-shadow: var(--elev-3), 0 0 16px var(--amber-24);
  display: flex;
  flex-direction: column;
  font-family: var(--font);
}

.roll-menu-item {
  background: transparent;
  color: var(--amber);
  border: none;
  border-bottom: 1px dashed var(--border);
  padding: var(--sp-2) var(--sp-3);
  font-family: var(--font);
  font-size: var(--fs-sm);
  font-weight: bold;
  letter-spacing: var(--track-2);
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-fast), color var(--dur-fast);
}
.roll-menu-item:last-child { border-bottom: none; }
@media (hover: hover) {
  .roll-menu-item:hover {
    background: var(--amber);
    color: var(--bg);
  }
}
.roll-menu-item:active {
  background: var(--amber);
  color: var(--bg);
}

/* ====== ROLL POPUP ====== */

.roll-popup {
  position: fixed;
  bottom: 24px;
  right: 24px;
  transform: scale(0.85);
  transform-origin: bottom right;
  z-index: 1000;
  padding: var(--sp-4) var(--sp-6);
  min-width: 240px;
  max-width: 90vw;
  text-align: center;
  font-family: var(--font);
  background: var(--green);
  color: var(--bg);
  border: 3px solid var(--bg);
  box-shadow: 0 0 40px var(--green-40), var(--elev-3);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-med) ease-out, transform var(--dur-med) ease-out;
}

.roll-popup.visible {
  opacity: 1;
  pointer-events: auto;
  transform: scale(1);
  cursor: pointer;
}

.roll-popup .popup-banner {
  font-size: var(--fs-lg);
  font-weight: bold;
  letter-spacing: var(--track-3);
  margin-bottom: var(--sp-2);
  text-transform: uppercase;
}

.roll-popup .popup-label {
  font-size: var(--fs-base);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  font-weight: bold;
  opacity: 0.85;
  margin-bottom: var(--sp-1);
}

.roll-popup .popup-total {
  font-size: var(--fs-display);
  font-weight: bold;
  line-height: 1;
  margin: var(--sp-1) 0 var(--sp-1);
}

.roll-popup .popup-formula {
  font-size: var(--fs-base);
  opacity: 0.8;
  letter-spacing: var(--track-1);
}

/* CRIT (natural 20 / crit-success) → gold blink */
.roll-popup.crit {
  background: var(--amber);
  box-shadow: 0 0 60px var(--amber-40), var(--elev-3);
  animation: popup-blink-gold 0.4s steps(1) infinite;
}

/* FUMBLE (natural 1 / crit-fail) → red blink */
.roll-popup.fumble {
  background: var(--red);
  color: var(--bg);
  box-shadow: 0 0 60px var(--red-40), var(--elev-3);
  animation: popup-blink-red 0.4s steps(1) infinite;
}

@keyframes popup-blink-gold {
  0%, 50% { background: var(--amber); }
  50.01%, 100% { background: var(--amber-hi); }
}
@keyframes popup-blink-red {
  0%, 50% { background: var(--red); }
  50.01%, 100% { background: var(--red-hi); }
}

/* respect reduced-motion preference — still show color, skip blink */
@media (prefers-reduced-motion: reduce) {
  .roll-popup.crit,
  .roll-popup.fumble {
    animation: none;
  }
}

/* ====== ROLL LOG (off-screen by default, summoned via corner button) ====== */

aside#roll-log {
  position: fixed;
  top: max(var(--sp-4), env(safe-area-inset-top));
  /* stop short of the floating roll-log button (which sits at bottom:24px + safe-area inset
     and is ~40px tall) so the button is never covered by the tray */
  bottom: calc(80px + env(safe-area-inset-bottom, 0px));
  right: 0;
  width: 380px;
  max-width: 92vw;
  z-index: 900;
  transform: translateX(0);
  transition: transform var(--dur-slow) ease-out;
  display: flex;
}

aside#roll-log.collapsed {
  transform: translateX(100%); /* fully off-screen — no visible handle */
  pointer-events: none;
}

/* Mobile: slide up from bottom as a tray, matching the dice roller */
@media (max-width: 699px) {
  aside#roll-log {
    top: auto;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    max-width: 100%;
    max-height: 75vh;
    transform: translateY(100%);
    transition: transform var(--dur-med) ease-out;
  }
  aside#roll-log.collapsed {
    transform: translateY(100%);
  }
  aside#roll-log:not(.collapsed) {
    transform: translateY(0);
  }
  /* Hide corner buttons when log is open so the tray isn't occluded */
  body.log-open .corner-btns {
    display: none;
  }
  .roll-log-body {
    border-left: none;
    border-right: none;
    border-bottom: none;
    padding-bottom: calc(var(--sp-3) + env(safe-area-inset-bottom, 0px));
    max-height: 75vh;
  }
}

.roll-log-body {
  flex: 1;
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-right: none;
  padding: 0 var(--sp-3) var(--sp-3);
  overflow-y: auto;
  box-shadow: var(--elev-left);
  min-width: 0;
}

.roll-log-head {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--bg-panel);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  border-bottom: 1px dashed var(--border);
  padding: var(--sp-3) 0 var(--sp-2);
  margin-bottom: var(--sp-2);
}

.roll-log-head h2 {
  font-size: var(--fs-base);
  letter-spacing: var(--track-2);
  margin: 0;
  color: var(--amber);
  border: none;
  padding: 0;
}

.roll-log-actions {
  display: flex;
  gap: var(--sp-1);
}

.roll-log-close {
  /* override .small's min-width to keep the × compact-square */
  min-width: 36px;
  min-height: 36px;
  font-size: var(--fs-lg);
  line-height: 1;
  padding: var(--sp-1) var(--sp-2);
  font-weight: bold;
}

/* ====== FLOATING CORNER BUTTONS (dice + log) ====== */

.corner-btns {
  position: fixed;
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  right: calc(24px + env(safe-area-inset-right, 0px));
  z-index: 950;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

.corner-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  background: var(--bg-panel);
  color: var(--amber);
  border: 1px solid var(--amber);
  font-family: var(--font);
  font-size: var(--fs-sm);
  font-weight: bold;
  letter-spacing: var(--track-2);
  cursor: pointer;
  box-shadow: var(--elev-2), 0 0 16px var(--amber-24);
  transition: background var(--dur-med), color var(--dur-med), transform var(--dur-fast), box-shadow var(--dur-med);
}

@media (hover: hover) {
  .corner-btn:hover {
    background: var(--amber);
    color: var(--bg);
    transform: translateY(-2px);
    box-shadow: var(--elev-3), 0 0 22px var(--amber-40);
  }
}
.corner-btn:active {
  background: var(--amber);
  color: var(--bg);
  transform: translateY(-2px);
  box-shadow: var(--elev-3), 0 0 22px var(--amber-40);
}

.corner-btn .corner-icon {
  font-size: var(--fs-md);
  line-height: 1;
}

/* ====== FLOATING ROLL-LOG OPEN BUTTON (legacy selector kept for scoped overrides) ====== */

.roll-log-open-btn {
  position: relative; /* inside flex wrapper */
}

@media (hover: hover) {
  .roll-log-open-btn:hover {
    background: var(--amber);
    color: var(--bg);
    transform: translateY(-2px);
    box-shadow: var(--elev-3), 0 0 22px var(--amber-40);
  }
}
.roll-log-open-btn:active {
  background: var(--amber);
  color: var(--bg);
  transform: translateY(-2px);
  box-shadow: var(--elev-3), 0 0 22px var(--amber-40);
}

.roll-log-open-btn .corner-icon,
.roll-log-open-btn .log-icon {
  font-size: var(--fs-md);
  line-height: 1;
}

.roll-log-open-btn .log-badge {
  display: none;
  background: var(--amber);
  color: var(--bg);
  font-size: var(--fs-xs);
  font-weight: bold;
  padding: 1px var(--sp-1);
  border-radius: 10px;
  min-width: 18px;
  text-align: center;
}
@media (hover: hover) {
  .roll-log-open-btn:hover .log-badge {
    background: var(--bg);
    color: var(--amber);
  }
}
.roll-log-open-btn:active .log-badge {
  background: var(--bg);
  color: var(--amber);
}
.roll-log-open-btn .log-badge.has-count {
  display: inline-block;
}

/* Hide the open buttons on setup phases (they're play-phase tools) */
body:not([data-phase="play"]) .corner-btns {
  display: none;
}

/* ====== ROLL DICE TRAY (popover on desktop, bottom sheet on mobile) ====== */

aside#roll-dice {
  position: fixed;
  bottom: calc(80px + env(safe-area-inset-bottom, 0px));
  right: calc(24px + env(safe-area-inset-right, 0px));
  width: 380px;
  max-width: 92vw;
  z-index: 900;
  transform: translateY(0);
  transition: transform var(--dur-med) ease-out, opacity var(--dur-med) ease-out;
  opacity: 1;
}

aside#roll-dice.collapsed {
  transform: translateY(16px);
  opacity: 0;
  pointer-events: none;
}

.roll-dice-body {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  padding: var(--sp-3);
  box-shadow: var(--elev-left);
  max-height: calc(100vh - 140px);
  overflow-y: auto;
}

.roll-dice-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  border-bottom: 1px dashed var(--border);
  padding-bottom: var(--sp-2);
  margin-bottom: var(--sp-3);
}

.roll-dice-head h2 {
  font-size: var(--fs-base);
  letter-spacing: var(--track-2);
  margin: 0;
  color: var(--amber);
  border: none;
  padding: 0;
}

.roll-dice-close {
  min-width: 36px;
  min-height: 36px;
  font-size: var(--fs-lg);
  line-height: 1;
  padding: var(--sp-1) var(--sp-2);
  font-weight: bold;
}

.roll-modifiers.roll-modifiers-stacked {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
  padding: 0;
  background: transparent;
  position: static;
  box-shadow: none;
}

.roll-modifiers.roll-modifiers-stacked .mod-group {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-1);
  padding-bottom: var(--sp-3);
  border-bottom: 1px dashed var(--border);
}

.dice-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
}

.dice-btn {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-3) var(--sp-1);
  background: transparent;
  border: 1px solid var(--border-hi);
  color: var(--green);
  font-family: var(--font);
  cursor: pointer;
  transition: background var(--dur-fast), border-color var(--dur-fast), color var(--dur-fast), box-shadow var(--dur-fast);
  min-height: 72px;
}

.dice-btn .dice-label {
  font-size: var(--fs-md);
  letter-spacing: var(--track-1);
  font-weight: bold;
  color: var(--green);
  text-transform: lowercase;
}

.dice-btn .dice-count {
  position: absolute;
  top: -8px;
  right: -8px;
  background: var(--amber);
  color: var(--bg);
  font-size: var(--fs-xs);
  font-weight: bold;
  min-width: 20px;
  height: 20px;
  padding: 0 var(--sp-1);
  border-radius: 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.dice-btn.active {
  border-color: var(--amber);
  background: var(--amber-08);
}
.dice-btn.active .dice-label { color: var(--amber); }

@media (hover: hover) {
  .dice-btn:hover {
    border-color: var(--amber);
    box-shadow: 0 0 12px var(--amber-24);
  }
  .dice-btn:hover .dice-label { color: var(--amber); }
}
.dice-btn:active {
  background: var(--amber);
}
.dice-btn:active .dice-label { color: var(--bg); }

.dice-actions {
  display: flex;
  gap: var(--sp-2);
}

.dice-reset,
.dice-roll {
  flex: 1;
  font-family: var(--font);
  font-size: var(--fs-base);
  font-weight: bold;
  letter-spacing: var(--track-2);
  padding: var(--sp-2) var(--sp-3);
  cursor: pointer;
  transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast);
}

.dice-reset {
  background: transparent;
  color: var(--green);
  border: 1px solid var(--border-hi);
}
@media (hover: hover) {
  .dice-reset:not(:disabled):hover {
    border-color: var(--green);
    background: var(--green-08);
  }
}
.dice-reset:disabled { opacity: 0.4; cursor: not-allowed; }

.dice-roll {
  background: var(--amber);
  color: var(--bg);
  border: 1px solid var(--amber);
}
@media (hover: hover) {
  .dice-roll:not(:disabled):hover {
    background: var(--amber-hi);
    border-color: var(--amber-hi);
    box-shadow: 0 0 16px var(--amber-40);
  }
}
.dice-roll:disabled { opacity: 0.4; cursor: not-allowed; }

/* Mobile: bottom sheet */
@media (max-width: 699px) {
  aside#roll-dice {
    right: 0;
    left: 0;
    bottom: 0;
    width: 100%;
    max-width: 100%;
    transform: translateY(100%);
  }
  aside#roll-dice:not(.collapsed) {
    transform: translateY(0);
  }
  .roll-dice-body {
    border-left: none;
    border-right: none;
    border-bottom: none;
    max-height: 75vh;
    padding-bottom: calc(var(--sp-3) + env(safe-area-inset-bottom, 0px));
  }
  /* When the bottom sheet is open, hide the corner buttons so the tray's
     ROLL / RESET actions aren't occluded. Close via the X inside the sheet. */
  body.dice-open .corner-btns {
    display: none;
  }
}

.roll-entry {
  border-left: var(--border-w-strong) solid var(--green-faint);
  padding: var(--sp-1) var(--sp-2);
  margin-bottom: var(--sp-1);
  font-size: var(--fs-sm);
  background: var(--green-08);
}

.roll-entry .roll-label { color: var(--amber); }
.roll-entry .roll-formula { color: var(--green-dim); }
.roll-entry .roll-total { color: var(--green); font-weight: bold; font-size: var(--fs-base); }
.roll-entry.crit { border-left-color: var(--amber); background: var(--amber-08); }
.roll-entry.crit .roll-total { color: var(--amber); }
.roll-entry.fumble { border-left-color: var(--red); background: var(--red-08); }
.roll-entry.fumble .roll-total { color: var(--red); }
.roll-entry.system { border-left-color: var(--amber-dim); color: var(--green-dim); font-style: italic; }

.roll-entry .roll-time {
  color: var(--green-faint);
  font-size: var(--fs-xs);
  margin-right: var(--sp-1);
}

/* ====== PANELS ====== */

.panel {
  border: 1px solid var(--border);
  background: var(--bg-panel);
  padding: var(--sp-3);
  margin-bottom: var(--sp-4);
}

/* Selection screens: interactive cards are the primary containers,
   so the outer panel is a bare wrapper — no redundant frame. */
.panel.bare {
  border: none;
  background: transparent;
  padding: 0;
}

.panel h2 {
  font-size: var(--fs-base);
  letter-spacing: var(--track-3);
  margin: 0 0 var(--sp-3) 0;
  color: var(--amber);
  border-bottom: 1px dashed var(--border);
  padding-bottom: var(--sp-1);
}

.panel h3 {
  font-size: var(--fs-base);
  letter-spacing: var(--track-2);
  margin: var(--sp-3) 0 var(--sp-1) 0;
  color: var(--green);
}

.prompt {
  color: var(--amber);
  margin-right: var(--sp-1);
}

/* ====== BUTTONS ====== */

button, .btn {
  background: transparent;
  color: var(--green);
  border: 1px solid var(--green-dim);
  font-family: var(--font);
  font-size: var(--fs-base);
  padding: var(--sp-2) var(--sp-3);
  cursor: pointer;
  letter-spacing: var(--track-1);
  text-transform: uppercase;
  transition: all var(--dur-fast);
  /* WCAG 2.5.5 touch target — 44px preferred, 24px AA minimum.
     Every button defaults to 44px so it's tappable on touch. */
  min-width: 44px;
  min-height: 44px;
}

@media (hover: hover) {
  button:hover:not(:disabled), .btn:hover:not(:disabled) {
    background: var(--green);
    color: var(--bg);
    border-color: var(--green);
    text-shadow: none;
  }
}
button:active:not(:disabled), .btn:active:not(:disabled) {
  background: var(--green);
  color: var(--bg);
  border-color: var(--green);
  text-shadow: none;
}

button:disabled, .btn:disabled {
  color: var(--green-faint);
  border-color: var(--green-faint);
  cursor: not-allowed;
  opacity: 0.5;
}

/* Global keyboard focus — amber outline offset outside the element so it remains
   visible regardless of the button's fill color (green/amber/red variants).
   Components with custom focus treatments (.picker-trigger, .picker-option,
   .item-remove-btn, toggle-switch, .char-row*) opt out explicitly. */
button:focus-visible,
.btn:focus-visible,
.tab-btn:focus-visible,
.corner-btn:focus-visible,
.dice-roll:focus-visible,
.dice-reset:focus-visible,
.roll-modifiers .seg-btn:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 2px;
}

button.primary {
  border-color: var(--amber);
  color: var(--amber);
}
@media (hover: hover) {
  button.primary:hover:not(:disabled) {
    background: var(--amber);
    color: var(--bg);
    border-color: var(--amber);
  }
}
button.primary:active:not(:disabled) {
  background: var(--amber);
  color: var(--bg);
  border-color: var(--amber);
}

button.danger {
  border-color: var(--red-dim);
  color: var(--red);
}
@media (hover: hover) {
  button.danger:hover:not(:disabled) {
    background: var(--red);
    color: var(--bg);
    border-color: var(--red);
  }
}
button.danger:active:not(:disabled) {
  background: var(--red);
  color: var(--bg);
  border-color: var(--red);
}

button.health {
  border-color: var(--green);
  color: var(--green);
}
@media (hover: hover) {
  button.health:hover:not(:disabled) {
    background: var(--green);
    color: var(--bg);
    border-color: var(--green);
  }
}
button.health:active:not(:disabled) {
  background: var(--green);
  color: var(--bg);
  border-color: var(--green);
}

button.small {
  font-size: var(--fs-sm);
  padding: var(--sp-1) var(--sp-2);
  /* Inline / compact controls (-, +, CLEAR, ×, RELOAD, etc.) —
     still comfortably above WCAG 2.5.8 AA (24px) */
  min-width: 36px;
  min-height: 36px;
}

.btn-row {
  display: flex;
  gap: var(--sp-2);
  flex-wrap: wrap;
  margin-top: var(--sp-2);
}

/* ====== FORM BITS ====== */

input[type="text"],
input[type="email"],
input[type="password"],
input[type="search"],
input[type="tel"],
input[type="url"],
input[type="number"],
select {
  background: var(--bg);
  color: var(--green);
  border: 1px solid var(--green-dim);
  font-family: var(--font);
  font-size: var(--fs-base);
  padding: var(--sp-2) var(--sp-3);
  /* WCAG 2.5.5 — match button tap target so forms feel consistent with actions */
  min-height: 44px;
}

input[type="text"]:focus,
input[type="email"]:focus,
input[type="password"]:focus,
input[type="search"]:focus,
input[type="tel"]:focus,
input[type="url"]:focus,
input[type="number"]:focus,
select:focus {
  outline: none;
  border-color: var(--amber);
}

.notes-toolbar {
  display: flex;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
}

.notes-toolbar button.active {
  background: var(--green);
  border-color: var(--green);
  color: var(--bg);
  box-shadow: 0 0 12px var(--green-40);
}

.notes-editor {
  margin-top: var(--sp-2);
  padding: var(--sp-3);
  border: 1px solid var(--green-dim);
  background: var(--bg);
  color: var(--green);
  font-family: var(--font);
  font-size: var(--fs-base);
  line-height: 1.5;
  min-height: 240px;
  overflow-y: auto;
}

.notes-editor:focus {
  outline: none;
  border-color: var(--amber);
}

.notes-editor:empty::before {
  content: attr(data-placeholder);
  color: var(--green-dim);
  font-style: italic;
  pointer-events: none;
}

.notes-editor h1,
.notes-editor h2 {
  color: var(--amber);
  letter-spacing: 0.02em;
  margin: var(--sp-3) 0 var(--sp-2);
  border-bottom: none;
  padding-bottom: 0;
}

.notes-editor h1 { font-size: 22px; }
.notes-editor h2 { font-size: 17px; }

.notes-editor h1:first-child,
.notes-editor h2:first-child,
.notes-editor p:first-child {
  margin-top: 0;
}

.notes-editor p {
  margin: 0 0 var(--sp-2);
}

.notes-editor p:last-child,
.notes-editor h1:last-child,
.notes-editor h2:last-child {
  margin-bottom: 0;
}

.add-panel .text-input,
.add-panel input[type="text"] {
  width: 100%;
  box-sizing: border-box;
}

.custom-form .form-row {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  margin-top: var(--sp-2);
}

.custom-form .form-row label {
  color: var(--green-dim);
  font-size: var(--fs-sm, 12px);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.custom-form .form-row label .muted {
  text-transform: none;
  letter-spacing: 0;
}

.custom-form input[type="text"],
.custom-form input[type="number"],
.custom-form select,
.custom-form textarea {
  width: 100%;
  box-sizing: border-box;
  background: var(--bg);
  color: var(--green);
  border: 1px solid var(--green-dim);
  font-family: var(--font);
  font-size: var(--fs-base);
  padding: var(--sp-2) var(--sp-3);
}

.custom-form textarea {
  resize: vertical;
  min-height: 72px;
  line-height: 1.4;
}

.custom-form input:focus,
.custom-form select:focus,
.custom-form textarea:focus {
  outline: none;
  border-color: var(--amber);
}

.custom-form .form-detail {
  margin-top: var(--sp-3);
  border: 1px dashed var(--green-dim);
  padding: var(--sp-2) var(--sp-3);
}

.custom-form .form-detail summary {
  cursor: pointer;
  color: var(--amber);
  font-size: var(--fs-sm, 12px);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  user-select: none;
}

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-3);
  padding-bottom: var(--sp-3);
  border-bottom: 1px dashed var(--border);
}

.panel-head h2 {
  margin: 0;
  padding-bottom: 0;
  border-bottom: none;
}

.panel-head .head-action {
  flex-shrink: 0;
}

.picker-sheet-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: var(--sp-3) var(--sp-4);
}

.picker-sheet-footer {
  display: flex;
  gap: var(--sp-2);
  justify-content: flex-end;
  padding: var(--sp-3) var(--sp-4);
  border-top: 1px solid var(--green-dim);
  background: var(--bg-panel);
  flex-shrink: 0;
}

.confirm-dialog .confirm-message {
  margin: 0;
  color: var(--green);
  line-height: 1.5;
}

/* ====== CUSTOM PICKER (replaces native <select>)
   The native <select> popup menu is OS-rendered and can't be themed, so we build
   our own. The trigger looks like an input; the menu looks like a small panel. */

.picker {
  position: relative;
  display: block;
  width: 100%;
}

.picker-trigger {
  /* Reset inherited button styling */
  text-transform: none;
  letter-spacing: var(--track-1);
  /* Match input/select visual */
  width: 100%;
  background: var(--bg);
  color: var(--green);
  border: 1px solid var(--green-dim);
  font-family: var(--font);
  font-size: var(--fs-base);
  padding: var(--sp-2) var(--sp-3);
  min-height: 44px;
  min-width: 44px;
  text-align: left;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  transition: border-color var(--dur-fast), background var(--dur-fast);
}

@media (hover: hover) {
  .picker-trigger:hover:not(:disabled) {
    /* Don't invert like a real button — this reads as a form field */
    border-color: var(--amber);
    background: var(--bg);
    color: var(--green);
  }
}
.picker-trigger:active:not(:disabled) {
  border-color: var(--amber);
  background: var(--bg);
  color: var(--green);
}

.picker.open > .picker-trigger,
.picker-trigger:focus-visible {
  outline: none;
  border-color: var(--amber);
}

.picker-trigger-label {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.picker-trigger-label.placeholder {
  color: var(--green-faint);
}

.picker-chevron {
  color: var(--amber);
  font-size: var(--fs-lg);
  line-height: 1;
  flex-shrink: 0;
  font-weight: bold;
}

/* no rotation — the trigger opens a modal, not an inline dropdown, so the
   chevron stays as a single indicator rather than flipping to signal state */

.picker-menu {
  position: absolute;
  top: calc(100% + var(--sp-1));
  left: 0;
  right: 0;
  z-index: 200;
  background: var(--bg-panel);
  border: 1px solid var(--amber);
  box-shadow: var(--glow-sm-amber), 0 4px 16px rgba(0, 0, 0, 0.8);
  max-height: 320px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  scrollbar-width: thin;
  scrollbar-color: var(--green-dim) transparent;
}

.picker-menu.picker-menu--portal {
  position: fixed;
  right: auto;
  z-index: 1200;
}

.picker-menu[hidden] { display: none; }

.picker-menu.picker-menu--flip-up {
  top: auto;
  bottom: calc(100% + var(--sp-1));
}

.picker-menu::-webkit-scrollbar { width: 4px; }
.picker-menu::-webkit-scrollbar-track { background: transparent; }
.picker-menu::-webkit-scrollbar-thumb { background: var(--green-dim); }

/* Each option is a column of up to three rows: main label, tag row, description.
   The checkmark lives inside the main line so tags/note stay indented under the name. */
.picker-option {
  text-transform: none;
  letter-spacing: var(--track-1);
  background: transparent;
  color: var(--green);
  border: none;
  border-bottom: 1px dashed var(--border);
  font-family: var(--font);
  font-size: var(--fs-base);
  padding: var(--sp-2) var(--sp-3);
  min-height: 44px;
  min-width: 0;
  text-align: left;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--sp-1);
  transition: background var(--dur-fast), color var(--dur-fast);
  /* The menu parent is flex-column with max-height + scroll. Without
     flex-shrink:0, options get compressed to fit and their content
     overflows into the next row. */
  flex-shrink: 0;
}
.picker-option.has-detail {
  padding: var(--sp-3);
  gap: 6px;
}
.picker-option:last-child { border-bottom: none; }

/* MAIN label line — flex row so the checkmark sits left of the name */
.picker-option-main {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  letter-spacing: var(--track-1);
}
.picker-option.has-detail .picker-option-main {
  font-weight: bold;
  color: var(--amber);
}

/* Selected / unselected checkmark — via ::before on the main line */
.picker-option.selected .picker-option-main::before {
  content: "✓";
  color: var(--amber);
  font-weight: bold;
  flex-shrink: 0;
}
.picker-option:not(.selected) .picker-option-main::before {
  content: " ";
  flex-shrink: 0;
  width: 1ch;
}

/* TAG row — compact chips, one-line key stats at a glance */
.picker-option-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1);
  padding-left: calc(1ch + var(--sp-2)); /* align under the label, not the ✓ */
}
.picker-option-tag {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-1);
  color: var(--green);
  background: var(--bg);
  border: 1px solid var(--border);
  padding: 1px var(--sp-2);
  white-space: nowrap;
}

/* NOTE / description line */
.picker-option-note {
  font-size: var(--fs-sm);
  line-height: 1.45;
  color: var(--green-faint);
  padding-left: calc(1ch + var(--sp-2));
}

/* Selected state: amber tint across all child elements */
.picker-option.selected {
  background: var(--amber-16);
}
.picker-option.selected .picker-option-main { color: var(--amber); }
.picker-option.selected .picker-option-tag {
  color: var(--amber);
  border-color: var(--amber-dim);
}
.picker-option.selected .picker-option-note { color: var(--amber-dim); }

/* Interactive state — desktop hover AND touch press get a clear amber tint
   with a left-edge accent so the highlighted row reads as the current target. */
@media (hover: hover) {
  .picker-option:hover:not(:disabled) {
    background: var(--amber-16);
    box-shadow: inset 3px 0 0 var(--amber);
  }
  .picker-option:hover:not(:disabled) .picker-option-main {
    color: var(--amber);
  }
}
.picker-option:active:not(:disabled) {
  background: var(--amber-16);
  box-shadow: inset 3px 0 0 var(--amber);
}
.picker-option:active:not(:disabled) .picker-option-main {
  color: var(--amber);
}
.picker-option:focus-visible:not(:disabled) {
  background: var(--amber-16);
  box-shadow: inset 3px 0 0 var(--amber);
  outline: none;
}

.picker-option:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  color: var(--green-faint);
}
.picker-option:disabled .picker-option-main { color: var(--green-faint); }

/* When a picker is inside a stat-slot (stats phase), stretch full width
   and keep the trigger's text centered since the slot itself is centered. */
.stat-slot .picker-trigger {
  justify-content: center;
  gap: var(--sp-2);
  color: var(--amber);
  font-size: var(--fs-md);
}

label {
  color: var(--green-dim);
  font-size: var(--fs-sm);
  letter-spacing: var(--track-1);
  display: block;
  margin-bottom: var(--sp-1);
  text-transform: uppercase;
}

/* ====== CLASS SELECTION ====== */

.class-grid {
  display: grid;
  grid-template-columns: 1fr; /* single column — horizontal cards stack vertically */
  gap: var(--sp-3);
}

.class-card {
  border: 1px solid var(--border);
  background: var(--bg-panel);
  padding: var(--sp-3);
  cursor: pointer;
  transition: transform var(--dur-fast), border-color var(--dur-med), box-shadow var(--dur-med), background var(--dur-med);
  display: grid;
  grid-template-columns: minmax(180px, 220px) minmax(220px, 1fr) 1.6fr auto;
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "avatar header  header  action"
    "avatar tagline details action";
  column-gap: var(--sp-4);
  row-gap: var(--sp-3);
  align-items: stretch;
}

.class-card-identity { grid-area: avatar; }
.class-card-header { grid-area: header; }
.class-card-tagline-col { grid-area: tagline; }
.class-card-details { grid-area: details; }
.class-card-action-col { grid-area: action; }

.class-card-header {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  align-self: start;
}

.class-card-header h3 {
  margin: 0;
}

.class-card-col {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  min-width: 0;
}

.class-card-details {
  justify-content: space-between;
}

@media (max-width: 699px) {
  .class-card {
    grid-template-columns: 1fr; /* stack cols on small screens */
    grid-template-areas:
      "avatar"
      "header"
      "tagline"
      "details"
      "action";
    gap: var(--sp-3);
  }
}

.class-card .class-avatar-wrap {
  width: 100%;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
}

.class-card .class-avatar {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

@media (hover: hover) {
  .class-card:hover {
    background: var(--amber-08);
    border-color: var(--amber);
    box-shadow: 0 0 24px var(--amber-16);
    transform: translateY(-2px);
  }
}
.class-card:active {
  background: var(--amber-08);
  border-color: var(--amber);
  box-shadow: 0 0 24px var(--amber-16);
  transform: translateY(-2px);
}

.class-card.selected {
  border-color: var(--amber);
  background: var(--amber-08);
}

.class-card-action-col {
  display: flex;
  align-items: center;
  justify-content: center;
}

@media (max-width: 699px) {
  .class-card-action-col {
    align-items: flex-end;
  }
}

/* Icon variant — square footprint, centered SVG glyph. */
.class-card .card-action {
  padding: var(--sp-2);
  display: flex;
  align-items: center;
  justify-content: center;
}

.class-card .card-action svg {
  display: block;
  stroke: currentColor;
  fill: none;
}

.class-card h3 {
  margin: 0;
  color: var(--amber);
  font-size: var(--fs-md);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
}

.class-card .sub {
  color: var(--green-dim);
  font-size: var(--fs-sm);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
}

.class-card .stats-line {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1);
  padding: 0;
  border: none;
}

.class-card .stats-line span {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-1);
  color: var(--green);
  background: var(--bg);
  border: 1px solid var(--border);
  padding: 1px var(--sp-2);
  white-space: nowrap;
}

.class-card .stats-line span b { color: var(--amber); }

.class-card ul {
  margin: 0;
  padding-left: var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--green-dim);
}

.class-card ul li { margin-bottom: 2px; }

/* Thematic tagline — the hook that sells the class. Green with a soft amber
   left edge so it reads as flavor, not stats. */
.class-card .class-tagline {
  margin: 0;
  font-size: var(--fs-base);
  line-height: 1.5;
  color: var(--green);
  border-left: var(--border-w-strong) solid var(--amber-dim);
  padding-left: var(--sp-2);
  font-style: italic;
}

/* Section groups (Proficiencies / Skills / Features) share a compact label + list layout. */
.class-card .class-section {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}
.class-card .class-section-label {
  color: var(--amber-dim);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
}

/* ====== STAT ASSIGNMENT ====== */

.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr));
  gap: var(--sp-2);
  margin-bottom: var(--sp-4);
}

.stat-slot {
  background: var(--bg-panel-hi);
  padding: var(--sp-2);
  text-align: center;
}

.stat-slot .label {
  color: var(--green-dim);
  font-size: var(--fs-sm);
  letter-spacing: var(--track-2);
}

.stat-slot select {
  width: 100%;
  margin: var(--sp-1) 0;
  text-align: center;
  font-size: var(--fs-md);
  color: var(--amber);
}

.stat-slot .mod {
  color: var(--amber);
  font-size: var(--fs-lg);
  font-weight: bold;
}

.skill-picker {
  display: flex;
  gap: var(--sp-2);
  flex-wrap: wrap;
  margin: var(--sp-2) 0 var(--sp-4) 0;
}

.skill-checkbox {
  border: 1px solid var(--green-dim);
  padding: var(--sp-2) var(--sp-3);
  cursor: pointer;
  letter-spacing: var(--track-1);
  font-size: var(--fs-sm);
  user-select: none;
  /* WCAG 2.5.5 — match button/input tap target */
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

@media (hover: hover) {
  .skill-checkbox:hover { background: var(--bg-panel-hi); }
}
.skill-checkbox:active { background: var(--bg-panel-hi); }
.skill-checkbox.checked {
  border-color: var(--amber);
  color: var(--amber);
  background: var(--amber-08);
}
.skill-checkbox.disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ====== ITEM SELECTION ====== */

.loadout-slot {
  background: var(--bg-panel-hi);
  padding: var(--sp-2);
  margin-bottom: var(--sp-2);
}

.loadout-slot .slot-label {
  color: var(--amber);
  font-size: var(--fs-sm);
  letter-spacing: var(--track-2);
  margin-bottom: var(--sp-1);
}

.loadout-slot select {
  width: 100%;
  margin-bottom: var(--sp-1);
}

.item-preview {
  font-size: var(--fs-sm);
  color: var(--green-dim);
  padding: var(--sp-1) var(--sp-2);
  border-left: var(--border-w-strong) solid var(--green-faint);
  background: var(--overlay-soft);
  margin-top: var(--sp-1);
  min-height: 18px;
}

.item-preview .tag {
  display: inline-block;
  border: 1px solid var(--green-faint);
  padding: 0 var(--sp-1);
  margin-right: var(--sp-1);
  margin-bottom: 2px;
  color: var(--green);
  font-size: var(--fs-xs);
}

.fixed-items-list {
  list-style: none;
  padding: 0;
  margin: var(--sp-1) 0 0 0;
  font-size: var(--fs-sm);
}
.fixed-items-list li {
  padding: var(--sp-1) var(--sp-2);
  border-left: var(--border-w-strong) solid var(--amber-dim);
  margin-bottom: var(--sp-1);
  color: var(--green-dim);
}
.fixed-items-list b { color: var(--amber); }

/* ====== PLAY VIEW ====== */

/* Back-to-roster row above the play sheet — not sticky, scrolls with page.
   Holds the roster link on the left and the character-actions hamburger on
   the right. Roster button matches the hamburger's tap target (48px tall). */
.roster-back-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
}

.roster-back-row .back-btn {
  min-height: 48px;
  padding: var(--sp-2) var(--sp-3);
}

/* By default the full label reads "DAMAGED" / "HEALED". Mobile swaps in the
   shorthand so both buttons fit side by side inside the compact HP cell. */
.hp-btn-short { display: none; }
.hp-btn-full { display: inline; }

.sheet-header {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

/* Identity block — name input with class/level meta stacked directly below. */
.identity {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  min-width: 0;
}

/* Row containing the hamburger menu button + name input. */
.identity-row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-width: 0;
}

.identity-meta {
  font-size: var(--fs-sm);
  color: var(--green-dim);
  letter-spacing: var(--track-1);
  text-transform: uppercase;
}

.sheet-header .name-input {
  margin: 0;
  width: 100%;
  min-width: 0;
  flex: 1;
  font-size: var(--fs-lg);
  color: var(--amber);
}

/* Character actions menu (hamburger trigger + anchored flyout) */
.char-menu {
  position: relative;
  flex-shrink: 0;
}
/* Square 1:1 button sized to match the name-input's rendered height
   (font-size 26 + line-height normal + padding 8 + border 1 ≈ 48px). */
.char-menu-btn {
  font-size: var(--fs-lg);
  padding: 0;
  line-height: 1;
  min-width: 0;
  min-height: 0;
  width: var(--sp-7);
  height: var(--sp-7);
  display: flex;
  align-items: center;
  justify-content: center;
}

.char-menu-icon {
  fill: currentColor;
  display: block;
}
.char-menu-flyout {
  position: absolute;
  top: calc(100% + var(--sp-1));
  right: 0;
  z-index: 200;
  min-width: 220px;
  background: var(--bg-panel);
  border: 1px solid var(--amber);
  box-shadow: var(--glow-sm-amber), 0 4px 16px rgba(0, 0, 0, 0.8);
  display: flex;
  flex-direction: column;
}
.char-menu-flyout[hidden] {
  display: none;
}
.char-menu-item {
  background: transparent;
  color: var(--green);
  border: none;
  border-bottom: 1px dashed var(--border);
  font-family: var(--font);
  font-size: var(--fs-sm);
  letter-spacing: var(--track-1);
  text-transform: uppercase;
  padding: var(--sp-2) var(--sp-3);
  text-align: left;
  cursor: pointer;
  min-height: 44px;
  transition: background var(--dur-fast), color var(--dur-fast);
}
.char-menu-item:last-child {
  border-bottom: none;
}
.char-menu-item.danger {
  color: var(--red);
}
@media (hover: hover) {
  .char-menu-item:hover {
    background: var(--amber-16);
    color: var(--amber);
  }
  .char-menu-item.danger:hover {
    background: var(--red-16);
    color: var(--red);
  }
}
.char-menu-item:active {
  background: var(--amber-16);
  color: var(--amber);
}
.char-menu-item.danger:active {
  background: var(--red-16);
  color: var(--red);
}

/* --- CORE STATS RESPONSIVE LAYOUT ---
   wide (≥1100px):  6 columns, all stats in one row
   medium (≥700px): 3 columns
   small (<700px):  HP spans full width; the rest scroll horizontally
*/

/* Sheet header: avatar (full height, left) + main column (identity + stats) */
.sheet-top {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: var(--sp-3);
  align-items: stretch;
}

.sheet-main {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  min-width: 0;
}

.avatar-cell {
  background: var(--bg-panel-hi);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1 / 1;
  width: 220px;
}

.sheet-avatar {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Stats row: HP (wide) | INIT (square) | INSP (square) | minor cluster */
.stats-row {
  display: flex;
  gap: var(--sp-2);
  align-items: stretch;
  flex: 1;
  min-width: 0;
}

.stats-row .hp-stat {
  flex: 0 0 auto;
  min-width: 0;
}

.stats-row .square-stat {
  flex: 0 0 auto;
  width: 130px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.stats-row .insp-cell.square-stat {
  width: 130px;
}

.stats-row .insp-cell > .core-stat {
  flex: 1 1 auto;
}

.minor-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-2);
  flex: 1.6 1 0;
  align-items: center;
  min-width: 0;
}

.core-stat.minor-stat {
  padding: var(--sp-2);
  background: transparent;
  border: none;
}

.core-stat.minor-stat .label {
  font-size: 10px;
}

.core-stat.minor-stat .value {
  font-size: var(--fs-lg);
  white-space: nowrap;
}

@media (max-width: 1099px) {
  .sheet-top {
    grid-template-columns: 160px 1fr;
  }
  .avatar-cell {
    width: 160px;
  }
  .stats-row .square-stat {
    width: 110px;
  }
  .stats-row .insp-cell.square-stat {
    width: 110px;
  }
}

@media (max-width: 699px) {
  /* Layout on mobile:
       Row 1: avatar (small) + name
       Row 2: class / level meta (full width)
       Row 3: HP + INIT + INSP (primary stats)
       Row 4: AC / SPEED / PROF / HD (minor stats, smaller) */
  .sheet-top {
    display: grid;
    grid-template-columns: 80px 1fr;
    grid-template-areas:
      "avatar name"
      "meta   meta"
      "stats  stats";
    gap: var(--sp-2);
    align-items: start;
  }
  .sheet-top {
    grid-template-columns: 48px 1fr;
  }
  .sheet-top .avatar-cell {
    grid-area: avatar;
    width: 48px;
    align-self: start;
  }
  /* Flatten nested wrappers so identity-row and identity-meta become direct
     grid items of sheet-top — that lets the meta span its own full-width row. */
  .sheet-main,
  .sheet-header,
  .identity {
    display: contents;
  }
  .identity-row {
    grid-area: name;
    align-self: center;
  }
  .identity-meta {
    grid-area: meta;
  }
  .stats-row {
    grid-area: stats;
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "hp    init  insp"
      "minor minor minor";
    gap: var(--sp-2);
    overflow: visible;
  }
  .stats-row .hp-stat { grid-area: hp; width: auto; min-width: 0; }
  .stats-row .square-stat { grid-area: init; width: auto; min-width: 0; }
  .stats-row .insp-cell.square-stat { grid-area: insp; width: auto; min-width: 0; }
  /* Minor stats wrap to their own line below primary stats. */
  .minor-stats {
    grid-area: minor;
    display: flex;
    gap: var(--sp-2);
    justify-content: space-between;
    padding: 0;
  }
  .core-stat.minor-stat {
    flex: 1 1 0;
    padding: var(--sp-1);
  }
  .core-stat.minor-stat .label {
    font-size: 10px;
  }
  .core-stat.minor-stat .value {
    font-size: var(--fs-base);
  }
  /* Shorter HP action labels fit side by side inside the narrow HP cell. */
  .hp-btn-short { display: inline; }
  .hp-btn-full { display: none; }
  .stats-row .hp-stat .hp-controls button {
    max-width: none;
    padding: var(--sp-2) var(--sp-1);
  }
  /* Let the INSP -/+ buttons shrink so their cell doesn't force its grid
     column wider than the equal INIT column. */
  .stats-row .insp-cell .insp-controls .small {
    min-width: 0;
    padding: var(--sp-1);
  }
}

.core-stat {
  background: var(--bg-panel-hi);
  padding: var(--sp-2);
  text-align: center;
}

.core-stat .label {
  color: var(--green-dim);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-2);
}

.core-stat .value {
  color: var(--amber);
  font-size: var(--fs-xl);
  font-weight: bold;
}

.core-stat .value.big { font-size: var(--fs-xl); }

.core-stat-btn {
  font-family: var(--font);
  border: 1px solid var(--border-hi);
  cursor: pointer;
  transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast), box-shadow var(--dur-fast);
}

@media (hover: hover) {
  .core-stat-btn:hover {
    background: var(--amber);
    border-color: var(--amber);
    box-shadow: 0 0 12px var(--amber-40);
  }
  .core-stat-btn:hover .label,
  .core-stat-btn:hover .value { color: var(--bg); }
}
.core-stat-btn:active {
  background: var(--amber);
  border-color: var(--amber);
  box-shadow: 0 0 12px var(--amber-40);
}
.core-stat-btn:active .label,
.core-stat-btn:active .value { color: var(--bg); }

.hp-controls {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}

.hp-controls button {
  flex: 1;
  max-width: 110px;
  font-weight: bold;
  letter-spacing: var(--track-1);
}

.ability-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr); /* small viewports: 2 columns */
  gap: var(--sp-2);
}

@media (min-width: 700px) {
  .ability-grid {
    grid-template-columns: repeat(3, 1fr); /* mid viewports: 3 columns */
  }
}

@media (min-width: 1100px) {
  .ability-grid {
    grid-template-columns: repeat(6, 1fr); /* wide viewports: 6 columns — all in one row */
  }
}

.ability {
  background: var(--bg-panel-hi);
  padding: var(--sp-2);
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}

.ability.proficient {
  border: 1px solid var(--amber);
  background: var(--amber-08);
}

.ability .ab-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  text-align: center;
  padding-bottom: var(--sp-1);
  border-bottom: 1px dashed var(--border);
}

.ability .ab-name {
  color: var(--amber);
  font-size: var(--fs-md);
  font-weight: bold;
  letter-spacing: var(--track-3);
}

.ability .ab-score {
  color: var(--green-dim);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-1);
}

.ability .prof-tag {
  font-size: var(--fs-xs);
  color: var(--amber);
  letter-spacing: var(--track-2);
  font-weight: bold;
}

/* keep the label's space reserved even when not proficient so card heights align */
.ability:not(.proficient) .prof-tag {
  visibility: hidden;
}

.ability .ab-buttons {
  display: flex;
  gap: var(--sp-1);
}

.ability .ab-btn {
  flex: 1;
  font-family: var(--font);
  border: 1px solid var(--border-hi);
  background: transparent;
  color: var(--amber);
  cursor: pointer;
  padding: var(--sp-2) var(--sp-1);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast), box-shadow var(--dur-fast);
  min-width: 0;
}

@media (hover: hover) {
  .ability .ab-btn:hover {
    background: var(--amber);
    color: var(--bg);
    border-color: var(--amber);
    box-shadow: 0 0 12px var(--amber-40);
  }
}
.ability .ab-btn:active {
  background: var(--amber);
  color: var(--bg);
  border-color: var(--amber);
  box-shadow: 0 0 12px var(--amber-40);
}

/* .ab-btn :active visual is unified with :hover above; no press-down sink. */

.ability .ab-btn .btn-label {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-2);
  font-weight: bold;
  color: var(--green-dim);
}

@media (hover: hover) {
  .ability .ab-btn:hover .btn-label { color: var(--bg); }
}
.ability .ab-btn:active .btn-label { color: var(--bg); }

.ability .ab-btn .btn-mod {
  font-size: var(--fs-xl);
  font-weight: bold;
  line-height: 1;
}

/* items / weapons cards */
.item-card {
  background: var(--bg-panel-hi);
  padding: var(--sp-3);
  margin-bottom: var(--sp-3);
}

.item-card .item-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  margin-bottom: var(--sp-1);
}

.item-card .item-name {
  color: var(--amber);
  font-size: var(--fs-base);
  letter-spacing: var(--track-2);
  font-weight: bold;
}

.item-card .item-remove-btn {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  padding: 0;
  margin: 0;
  color: var(--green-dim);
  cursor: pointer;
  line-height: 0;
  border-radius: 2px;
  transition: color var(--dur-fast, 120ms) ease-out, background var(--dur-fast, 120ms) ease-out;
}

.item-card .item-remove-btn:hover,
.item-card .item-remove-btn:focus-visible {
  color: var(--red, #ff5566);
  background: rgba(255, 80, 96, 0.12);
  outline: none;
}

.item-card .item-remove-btn svg {
  display: block;
  stroke: currentColor;
  fill: none;
}

/* ====== META PATTERN (non-numeric supplementary info) ======
   Mirrors the picker-option layout: chip-style tags row + note paragraph.
   Numeric / roll data is already surfaced in the stat blocks above. */
.item-card .item-meta {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin: var(--sp-2) 0;
}

.item-card .item-meta-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1);
}
.item-card .item-meta-tag {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-1);
  color: var(--green);
  background: var(--bg);
  border: 1px solid var(--border);
  padding: 1px var(--sp-2);
  white-space: nowrap;
}
.item-card .item-meta-note {
  font-size: var(--fs-sm);
  line-height: 1.45;
  color: var(--green-faint);
}

/* ====== ROLL MODIFIER STRIP (weapons tab) ====== */

.roll-modifiers {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3) var(--sp-4);
  padding: var(--sp-2) var(--sp-3);
  margin: var(--sp-2) 0 var(--sp-3);
  background: var(--bg-panel-hi);
  /* Sticks directly under the tabs (which stick at top: 0) so attack/damage
     mode controls stay reachable while scrolling the weapons list. */
  position: sticky;
  top: 57px;
  z-index: 250;
  /* Subtle drop so the row separates from the weapons scrolling behind it. */
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.6);
}

.roll-modifiers .mod-group {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  flex-wrap: wrap;
}

.roll-modifiers .mod-label {
  font-size: var(--fs-xs);
  color: var(--green-dim);
  letter-spacing: var(--track-2);
  font-weight: bold;
  margin-right: var(--sp-1);
}

.roll-modifiers .mod-hint {
  font-size: var(--fs-xs);
  color: var(--green-dim);
  font-style: italic;
  letter-spacing: var(--track-1);
  margin-left: auto;
}

/* Segmented control — connected buttons for ATTACK MODE */
.roll-modifiers .segmented-control {
  display: inline-flex;
  border: 1px solid var(--border-hi);
  overflow: hidden;
  background: var(--bg);
}

.roll-modifiers .seg-btn {
  background: transparent;
  border: none;
  border-right: 1px solid var(--border-hi);
  padding: var(--sp-2) var(--sp-3);
  color: var(--green);
  font-family: var(--font);
  font-size: var(--fs-sm);
  font-weight: bold;
  letter-spacing: var(--track-1);
  cursor: pointer;
  transition: background var(--dur-fast), color var(--dur-fast);
}

.roll-modifiers .seg-btn:last-child { border-right: none; }

@media (hover: hover) {
  .roll-modifiers .seg-btn:hover:not(.active) {
    background: var(--amber-08);
    color: var(--amber);
  }
}
.roll-modifiers .seg-btn:active:not(.active) {
  background: var(--amber-08);
  color: var(--amber);
}

.roll-modifiers .seg-btn.active {
  background: var(--amber);
  color: var(--bg);
  box-shadow: inset 0 0 12px var(--amber-40);
}
.roll-modifiers .seg-btn.adv.active {
  background: var(--green);
}
.roll-modifiers .seg-btn.dis.active {
  background: var(--red);
  color: var(--bg);
}

/* Toggle switch (iOS-style knob) — DAMAGE MODE */
.roll-modifiers .toggle-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  cursor: pointer;
  user-select: none;
  min-height: 44px; /* tap target — even though the slider is smaller, the whole label is clickable */
  padding: var(--sp-1) 0;
}

.roll-modifiers .toggle-switch input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.roll-modifiers .toggle-slider {
  width: 48px;
  height: 24px;
  background: var(--bg-panel-hi);
  border: 1px solid var(--border-hi);
  position: relative;
  transition: background var(--dur-med), border-color var(--dur-med);
}

.roll-modifiers .toggle-slider::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  background: var(--green-dim);
  transition: transform var(--dur-med), background var(--dur-med), box-shadow var(--dur-med);
  box-shadow: var(--elev-1);
}

.roll-modifiers .toggle-switch input:checked + .toggle-slider {
  background: var(--red-24);
  border-color: var(--red);
}

.roll-modifiers .toggle-switch input:checked + .toggle-slider::before {
  transform: translateX(22px);
  background: var(--red);
  box-shadow: var(--elev-1), 0 0 12px var(--red-40);
}

.roll-modifiers .toggle-text {
  font-size: var(--fs-sm);
  color: var(--green-dim);
  font-weight: bold;
  letter-spacing: var(--track-1);
  transition: color var(--dur-med);
}

.roll-modifiers .toggle-switch input:checked ~ .toggle-text {
  color: var(--red);
}

/* Keyboard focus ring for accessibility */
.roll-modifiers .toggle-switch input:focus-visible + .toggle-slider {
  outline: 2px solid var(--amber);
  outline-offset: 2px;
}

/* ====== LARGER ACTION BUTTONS (ATTACK / DAMAGE / HEAL) ====== */

.item-card .action-btn {
  flex: 1 1 140px;
  min-width: 120px;
  padding: var(--sp-2) var(--sp-4);
  font-size: var(--fs-base);
  font-weight: bold;
  letter-spacing: var(--track-2);
  font-family: var(--font);
  cursor: pointer;
  border: 1px solid var(--border-hi);
  background: transparent;
  color: var(--green);
  transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast), box-shadow var(--dur-fast);
}

@media (hover: hover) {
  .item-card .action-btn:hover:not(:disabled) {
    background: var(--green);
    color: var(--bg);
    border-color: var(--green);
  }
}
.item-card .action-btn:active:not(:disabled) {
  background: var(--green);
  color: var(--bg);
  border-color: var(--green);
}

.item-card .action-btn.primary {
  color: var(--amber);
  border-color: var(--amber);
}

@media (hover: hover) {
  .item-card .action-btn.primary:hover:not(:disabled) {
    background: var(--amber);
    color: var(--bg);
    border-color: var(--amber);
    box-shadow: 0 0 12px var(--amber-40);
  }
}
.item-card .action-btn.primary:active:not(:disabled) {
  background: var(--amber);
  color: var(--bg);
  border-color: var(--amber);
  box-shadow: 0 0 12px var(--amber-40);
}

.item-card .action-btn.health {
  color: var(--green);
  border-color: var(--green);
}

@media (hover: hover) {
  .item-card .action-btn.health:hover:not(:disabled) {
    background: var(--green);
    color: var(--bg);
    border-color: var(--green);
    box-shadow: 0 0 12px var(--green-40);
  }
}
.item-card .action-btn.health:active:not(:disabled) {
  background: var(--green);
  color: var(--bg);
  border-color: var(--green);
  box-shadow: 0 0 12px var(--green-40);
}

.item-card .action-btn.danger {
  color: var(--red);
  border-color: var(--red);
  box-shadow: 0 0 10px var(--red-40);
}

@media (hover: hover) {
  .item-card .action-btn.danger:hover:not(:disabled) {
    background: var(--red);
    color: var(--bg);
    border-color: var(--red);
  }
}
.item-card .action-btn.danger:active:not(:disabled) {
  background: var(--red);
  color: var(--bg);
  border-color: var(--red);
}

.item-card .action-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ====== PROMINENT STAT BLOCKS (Attack / Damage / Heal / DC / Range) ====== */

.item-card .item-stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  margin: var(--sp-2) 0 var(--sp-2);
  background: var(--amber-08);
  border-left: 3px solid var(--amber);
}

.item-card .item-stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  align-items: flex-start;
  min-width: 88px;
  padding: var(--sp-1) var(--sp-3);
  margin: 0; /* button reset */
  background: transparent;
  border: 1px solid transparent;
  font-family: inherit;
  text-align: left;
  color: inherit;
}

/* Rollable stat blocks (attack / damage / heal) — entire block is clickable */
.item-card .item-stat.rollable {
  cursor: pointer;
  border-color: var(--amber);
  background: var(--amber-08);
  transition: background var(--dur-fast), border-color var(--dur-fast), box-shadow var(--dur-fast), transform var(--dur-fast);
}
.item-card .item-stat.rollable .stat-value {
  text-shadow: 0 0 6px var(--amber-40);
}
@media (hover: hover) {
  .item-card .item-stat.rollable:hover:not(:disabled) {
    background: var(--amber-24);
    box-shadow: 0 0 16px var(--amber-40);
    transform: translateY(-1px);
  }
}
.item-card .item-stat.rollable:active:not(:disabled) {
  background: var(--amber-24);
  box-shadow: 0 0 16px var(--amber-40);
  transform: translateY(-1px);
}
.item-card .item-stat.rollable:disabled {
  opacity: 0.35;
  cursor: not-allowed;
  border-style: dashed;
}

/* Healing has its own color */
.item-card .item-stat.heal.rollable {
  border-color: var(--green);
  background: var(--green-08);
}
.item-card .item-stat.heal.rollable .stat-value {
  text-shadow: 0 0 6px var(--green-40);
}
@media (hover: hover) {
  .item-card .item-stat.heal.rollable:hover:not(:disabled) {
    background: var(--green-16);
    box-shadow: 0 0 16px var(--green-40);
  }
}
.item-card .item-stat.heal.rollable:active:not(:disabled) {
  background: var(--green-16);
  box-shadow: 0 0 16px var(--green-40);
}

/* Crit-armed damage block gets a red glow so the player sees it's primed */
.item-card .item-stat.dmg.rollable.crit-armed {
  border-color: var(--red);
  background: var(--red-08);
}
.item-card .item-stat.dmg.rollable.crit-armed .stat-value {
  color: var(--red);
  text-shadow: 0 0 8px var(--red-40);
}
@media (hover: hover) {
  .item-card .item-stat.dmg.rollable.crit-armed:hover:not(:disabled) {
    background: var(--red-24);
    box-shadow: 0 0 18px var(--red-40);
  }
}
.item-card .item-stat.dmg.rollable.crit-armed:active:not(:disabled) {
  background: var(--red-24);
  box-shadow: 0 0 18px var(--red-40);
}

/* Modifier badges (ADV / DIS / CRIT) — inline with the stat label */
.item-card .item-stat .stat-badge {
  font-size: var(--fs-xs);
  font-weight: bold;
  letter-spacing: var(--track-1);
  padding: 1px var(--sp-1);
  margin-left: var(--sp-1);
  background: var(--amber);
  color: var(--bg);
  border-radius: 2px;
  vertical-align: middle;
}
.item-card .item-stat .stat-badge.adv { background: var(--green); }
.item-card .item-stat .stat-badge.dis { background: var(--red); }
.item-card .item-stat .stat-badge.crit { background: var(--red); }

.item-card .item-stat .stat-label {
  font-size: var(--fs-xs);
  color: var(--green-dim);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  font-weight: bold;
}

.item-card .item-stat .stat-value {
  font-size: var(--fs-xl);
  color: var(--amber);
  font-weight: bold;
  line-height: 1;
  letter-spacing: var(--track-1);
}

.item-card .item-stat .stat-value-sm {
  font-size: var(--fs-base);
  color: var(--amber);
  font-weight: bold;
  line-height: 1.2;
  letter-spacing: var(--track-1);
}

.item-card .item-stat .stat-sub {
  font-size: var(--fs-xs);
  color: var(--amber);
  letter-spacing: var(--track-1);
  font-weight: bold;
  opacity: 0.85;
}

/* Color variants so different stat types are scannable at a glance */
.item-card .item-stat.heal .stat-value,
.item-card .item-stat.heal .stat-sub { color: var(--green); }

.item-card .item-stat.dc .stat-value,
.item-card .item-stat.dc .stat-sub { color: var(--red); }

.item-card .item-stat.range .stat-value-sm {
  color: var(--green);
  font-weight: normal;
}
.item-card .item-stat.range .stat-label {
  color: var(--green-dim);
}

/* Save effect line — high-signal "what happens on a failed save" */
.item-card .item-save-effect {
  font-size: var(--fs-sm);
  color: var(--red);
  margin: var(--sp-1) 0 var(--sp-1);
  padding: var(--sp-1) var(--sp-2);
  background: var(--red-08);
  border-left: var(--border-w-strong) solid var(--red-dim);
  line-height: 1.4;
}
.item-card .item-save-effect b {
  color: var(--red);
  letter-spacing: var(--track-1);
}

.item-card .uses-line {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--green-dim);
}

.item-card .uses-counter {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.item-card .uses-adjust {
  margin-left: auto;
  display: flex;
  gap: var(--sp-1);
}

.item-card .uses-line .count {
  color: var(--amber);
  font-weight: bold;
  font-size: var(--fs-md);
  min-width: 20px;
  text-align: center;
}

.item-card .item-action {
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  letter-spacing: var(--track-1);
  font-weight: bold;
}

.item-card.depleted .item-header,
.item-card.depleted .item-stats,
.item-card.depleted .item-save-effect,
.item-card.depleted .item-meta,
.item-card.depleted .btn-row {
  opacity: 0.4;
  pointer-events: none;
}
.item-card.depleted .item-name { color: var(--red); }
.item-card.depleted .uses-line .count { color: var(--red); }

/* features */
.feature-card {
  border-left: var(--border-w-strong) solid var(--amber);
  padding: var(--sp-3);
  margin-bottom: var(--sp-3);
  background: var(--amber-08);
}

.feature-card .fname {
  color: var(--amber);
  font-weight: bold;
  font-size: var(--fs-base);
  letter-spacing: var(--track-1);
}

.feature-card .fdesc {
  font-size: var(--fs-sm);
  color: var(--green-dim);
  margin-top: var(--sp-2);
  line-height: 1.5;
}

.feature-card .fuses {
  margin-top: var(--sp-3);
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
}

.feature-card .fuses-counter {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.feature-card .fuses-adjust {
  margin-left: auto;
  display: flex;
  gap: var(--sp-1);
}

.feature-card .fuses .count {
  color: var(--amber);
  font-weight: bold;
  font-size: var(--fs-md);
  min-width: 20px;
  text-align: center;
}

.feature-card .feature-action {
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  letter-spacing: var(--track-1);
  font-weight: bold;
}

/* Inspiration cell: mirrors the INIT button cell, with a manual -/+ row below.
   The outer wrapper is the grid item; the inner button keeps the same
   .core-stat styling as the other top-row cells. */
.insp-cell {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.insp-cell > .core-stat {
  width: 100%;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.insp-cell .insp-controls {
  display: flex;
  gap: var(--sp-1);
  justify-content: center;
  flex-shrink: 0;
}

.insp-cell .insp-controls .small {
  flex: 1;
  min-height: 36px;
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-base);
}

/* misc */
.muted { color: var(--green-dim); font-size: var(--fs-sm); }
.row { display: flex; gap: var(--sp-2); align-items: center; flex-wrap: wrap; }
.right { margin-left: auto; }
.spacer { flex: 1; }
.mt-8 { margin-top: var(--sp-2); }
.mt-16 { margin-top: var(--sp-4); }
.hidden { display: none; }

.wizard-nav {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  justify-content: space-between;
  gap: var(--sp-2);
  /* Setup phases don't show the flyout, so the 64px right reserve is unneeded here. */
  padding: var(--sp-3) var(--sp-4);
  background: var(--bg-panel);
  border-top: 1px solid var(--border);
  box-shadow: var(--elev-up);
  z-index: 400; /* below roll-log flyout (500) */
}

/* constrain button area to match .page max-width on wide viewports */
@media (min-width: 1400px) {
  .wizard-nav {
    padding-left: calc((100vw - 1400px) / 2 + 16px);
    padding-right: calc((100vw - 1400px) / 2 + 16px);
  }
}

.status-bar {
  color: var(--green-dim);
  font-size: var(--fs-sm);
  letter-spacing: var(--track-1);
  margin-bottom: var(--sp-2);
  padding: var(--sp-1) var(--sp-2);
  border-left: var(--border-w-strong) solid var(--amber);
}

/* mobile — log covers the full viewport width */
@media (max-width: 600px) {
  aside#roll-log { width: 100vw; }
  aside#roll-log.collapsed { transform: translateX(100%); }
}

/* =======================================================================
   AUTH / LIST / LOADING PHASES
   Shown before the character sheet flow — login + roster browsing.
   Same tokens as the rest of the system.
   ======================================================================= */

/* --- AUTH + LOADING PHASES — CENTERED ON VIEWPORT --- */
/* Override .page layout when on auth or loading phases so the content sits
   dead-center vertically and horizontally. 100dvh accounts for mobile
   browser chrome changing size dynamically. */
body[data-phase="auth"] .page,
body[data-phase="loading"] .page {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
body[data-phase="auth"] main#app,
body[data-phase="loading"] main#app {
  display: flex;
  justify-content: center;
  width: 100%;
}

/* --- LOADING PHASE --- */
.loading-panel {
  min-height: 40vh;
  display: grid;
  place-items: center;
  gap: var(--sp-4);
}
.loading-text {
  font-size: var(--fs-md);
  letter-spacing: var(--track-2);
  color: var(--green-dim);
  animation: loading-blink 1.2s ease-in-out infinite;
}
/* Escape-hatch button — fades in after a brief delay so it doesn't flash during
   a quick normal boot. Uses a self-contained CSS animation (not JS timer) so that
   every freshly-rendered loading phase starts its own countdown cleanly. */
.loading-escape {
  opacity: 0;
  pointer-events: none;
  animation: loading-escape-show 0.25s ease-out 2s forwards;
}
@keyframes loading-escape-show {
  from { opacity: 0;   pointer-events: none; }
  to   { opacity: 0.9; pointer-events: auto; }
}
@keyframes loading-blink {
  0%, 100% { opacity: 0.35; }
  50%      { opacity: 1; }
}

/* --- AUTH PHASE --- */
.auth-panel {
  max-width: 480px;
  margin: 0 auto;
}
.auth-form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  margin: var(--sp-4) 0 var(--sp-3);
}
.auth-label {
  color: var(--green-faint);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  font-weight: bold;
}
.auth-input {
  /* Matches the character .name-input styling: amber text at a display size,
     so form entry feels like filling in a dossier rather than a generic form. */
  color: var(--amber);
  font-size: var(--fs-md);
  width: 100%;
  letter-spacing: var(--track-1);
}
.auth-input::placeholder {
  color: var(--green-faint);
  opacity: 0.55;
}
.auth-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: var(--sp-2);
}
.auth-msg {
  min-height: 1.3em;
  font-size: var(--fs-sm);
  letter-spacing: var(--track-1);
}
.auth-msg[data-tone="ok"]  { color: var(--amber); }
.auth-msg[data-tone="err"] { color: var(--red); }
.auth-help {
  font-size: var(--fs-sm);
  margin-top: var(--sp-3);
  line-height: 1.5;
}

/* --- AUTH TABS (Magic Link / Password) --- */
.auth-tabs {
  display: flex;
  gap: 0;
  margin-top: var(--sp-3);
  margin-bottom: var(--sp-2);
  border: 1px solid var(--border);
}
.auth-tab {
  flex: 1;
  background: transparent;
  border: none;
  border-right: 1px solid var(--border);
  color: var(--green-dim);
  padding: var(--sp-2) var(--sp-3);
  font-family: var(--font);
  font-size: var(--fs-sm);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  font-weight: bold;
  cursor: pointer;
  min-height: 44px;
  transition: background var(--dur-fast), color var(--dur-fast);
}
.auth-tab:last-child { border-right: none; }
.auth-tab.active {
  background: var(--amber);
  color: var(--bg);
}
@media (hover: hover) {
  .auth-tab:not(.active):hover {
    color: var(--amber);
    background: var(--amber-08);
  }
}
.auth-tab:not(.active):active {
  color: var(--amber);
  background: var(--amber-08);
}

/* Field wrapper used for both email + password. Keeping both fields in the
   DOM (visually hidden when not active) lets iOS Keychain correctly
   identify the login-form shape at page load. */
.auth-field { display: contents; }
.auth-field.is-hidden {
  /* visibility:hidden + size 0 keeps the field in form/accessibility trees
     (so Keychain still sees it) but removes it from layout + tab order. */
  display: block;
  height: 0;
  overflow: hidden;
  margin: 0;
  padding: 0;
  visibility: hidden;
  pointer-events: none;
}
.auth-field.is-hidden .auth-label,
.auth-field.is-hidden .auth-input,
.auth-field.is-hidden .auth-password-toggle {
  /* Zero out so the hidden field doesn't affect layout at all. */
  height: 0;
  min-height: 0;
  padding: 0;
  border: 0;
  margin: 0;
}

/* --- PASSWORD FIELD with inline SHOW/HIDE toggle --- */
.auth-password-field {
  position: relative;
  display: flex;
}
.auth-password-field .auth-input {
  width: 100%;
  padding-right: 72px; /* reserve space for the toggle button */
}
.auth-password-toggle {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  background: transparent;
  border: 1px solid transparent;
  color: var(--green-dim);
  font-family: var(--font);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-2);
  font-weight: bold;
  padding: var(--sp-1) var(--sp-2);
  min-height: 32px;
  min-width: 56px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color var(--dur-fast), border-color var(--dur-fast);
}
@media (hover: hover) {
  .auth-password-toggle:hover {
    color: var(--amber);
    border-color: var(--amber-dim);
  }
}
.auth-password-toggle:active {
  color: var(--amber);
  border-color: var(--amber-dim);
}

/* --- SIGNIN <-> SIGNUP + FORGOT-PASSWORD TOGGLE LINKS --- */
.auth-toggle {
  margin-top: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--green-dim);
  text-align: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1);
  align-items: center;
  justify-content: center;
}
.auth-toggle-sep {
  color: var(--green-faint);
  opacity: 0.6;
}
.auth-link {
  background: transparent;
  border: none;
  color: var(--amber);
  text-decoration: underline;
  font-family: var(--font);
  font-size: var(--fs-sm);
  letter-spacing: var(--track-1);
  cursor: pointer;
  padding: var(--sp-1) var(--sp-2);
  min-height: 36px;
  -webkit-tap-highlight-color: transparent;
}
@media (hover: hover) {
  .auth-link:hover { color: var(--amber-hi); }
}
.auth-link:active { color: var(--amber-hi); }

/* --- LIST PHASE --- */
.list-panel { max-width: 760px; margin: 0 auto; }

.list-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-2);
}

.char-list {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
}
.char-list-empty {
  padding: var(--sp-5) var(--sp-4);
  text-align: center;
  border: 1px dashed var(--border);
  background: var(--bg-panel-hi);
  font-size: var(--fs-sm);
}

/* Row: two columns — content body | actions. No avatar anymore.
   position: relative so the subtle corner × delete button can anchor to it. */
/* The entire row is now the primary tap target (LOAD button removed).
   Padding leaves room on the right for the absolute × delete button. */
.char-row {
  position: relative;
  display: block;
  padding: var(--sp-3) calc(44px + var(--sp-3)) var(--sp-3) var(--sp-4);
  background: var(--bg-panel-hi);
  border: 1px solid var(--border);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  transition:
    background var(--dur-fast),
    border-color var(--dur-fast),
    box-shadow var(--dur-fast);
}

/* Consistent focus ring for keyboard users — same colour as hover emphasis */
.char-row:focus { outline: none; }
.char-row:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 2px;
}

/* Interactive state — identical on desktop hover AND touch press */
@media (hover: hover) {
  .char-row:hover {
    background: var(--green-08);
    border-color: var(--border-strong);
    box-shadow: 0 0 0 1px var(--border-strong) inset;
  }
}
.char-row:active {
  background: var(--green-08);
  border-color: var(--border-strong);
  box-shadow: 0 0 0 1px var(--border-strong) inset;
}

.char-row-body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.char-row-name {
  color: var(--amber);
  font-size: var(--fs-md);
  font-weight: bold;
  letter-spacing: var(--track-1);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Meta rows — labeled key/value pairs, one per line. */
.char-row-meta {
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  color: var(--green);
  font-size: var(--fs-sm);
}
.char-row-meta .meta-pair {
  display: flex;
  gap: var(--sp-2);
  align-items: baseline;
}
.char-row-meta dt {
  color: var(--green-faint);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  font-weight: bold;
  width: 52px;
  flex-shrink: 0;
}
.char-row-meta dd {
  margin: 0;
  color: var(--green);
}

.char-row-time {
  margin-top: var(--sp-1);
  font-size: var(--fs-xs);
  letter-spacing: var(--track-1);
  text-transform: uppercase;
}

.list-actions {
  margin-top: var(--sp-4);
  display: flex;
  justify-content: flex-end;
}

.list-pill {
  margin: var(--sp-2) 0;
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--fs-sm);
  border: 1px dashed var(--border);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
}
.list-pill-error {
  color: var(--red);
  border-color: var(--red);
}
.list-pill .link-btn {
  background: none;
  border: none;
  padding: 0;
  color: inherit;
  font-family: inherit;
  font-size: inherit;
  letter-spacing: var(--track-1);
  text-transform: uppercase;
  text-decoration: underline;
  cursor: pointer;
  min-width: 0;
  min-height: 0;
}

/* =======================================================================
   SUBTLE DELETE BUTTON on .char-row
   An × glyph in the top-right of each row — dim by default so it doesn't
   compete with the primary LOAD action. Becomes red on hover / press.
   ======================================================================= */
.char-row-delete {
  position: absolute;
  top: var(--sp-2);
  right: var(--sp-2);
  width: 44px;
  height: 44px;
  padding: 0;
  display: grid;
  place-items: center;
  background: transparent;
  border: 1px solid transparent;
  color: var(--green-faint);
  font-size: 30px;
  line-height: 1;
  font-weight: normal;
  cursor: pointer;
  opacity: 0.7;
  transition:
    color var(--dur-fast),
    border-color var(--dur-fast),
    background var(--dur-fast),
    opacity var(--dur-fast);
}

/* Interactive state — identical on desktop hover AND touch press.
   Opacity also jumps to full so the ×/target feels directly tappable. */
@media (hover: hover) {
  .char-row:hover .char-row-delete { opacity: 1; }
  .char-row-delete:hover {
    color: var(--red);
    border-color: var(--red-dim);
    background: var(--red-16);
    opacity: 1;
  }
}
.char-row-delete:active {
  color: var(--red);
  border-color: var(--red-dim);
  background: var(--red-16);
  opacity: 1;
}

/* When the × is being pressed, reset the ancestor row to its resting state
   so only ONE interactive element visually activates at a time. */
.char-row:has(.char-row-delete:active) {
  background: var(--bg-panel-hi);
  border-color: var(--border);
  box-shadow: none;
}

/* Clear any lingering focus outline after click — keyboard focus uses focus-visible. */
.char-row-delete:focus { outline: none; }
.char-row-delete:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 2px;
}

/* =======================================================================
   TAP-THROUGH GUARD
   After a phase change or picker selection, briefly disable interaction on
   the app content so a lingering touch can't "ghost-click" whatever just
   rendered at the same coordinate. ~300ms is imperceptible to users but
   covers the window in which iOS/Android fire synthesized click events.
   ======================================================================= */
#app.nav-locked {
  pointer-events: none;
}

/* =======================================================================
   TOUCH / TAP INTERACTION
   Remove default OS blue flash, ensure every interactive control has a clear
   pressed-state. iOS/Android both need the :active rules to fire on touch.
   ======================================================================= */
button,
a,
.char-row,
.class-card,
.mode-card,
.preset-card,
.picker-trigger,
.picker-option,
.skill-checkbox {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

/* Per-button :active styles live next to their :hover rules so the two
   states are visually identical (touch down = hover in). No generic filter. */

/* Card :active visuals are defined per-card next to their :hover rules so
   both states produce the exact same look. Nothing extra needed here. */

/* Picker options — clear tap feedback inside both the anchored menu and the sheet */
/* Picker option :active is defined next to its :hover rule — both states
   show the same subtle amber-08 hint (touch down = hover in). */

/* =======================================================================
   SAVE STATUS PILL (play phase identity-meta)
   ======================================================================= */
.sheet-header .identity-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  color: var(--green-faint);
  font-size: var(--fs-sm);
  letter-spacing: var(--track-1);
}
.save-pill {
  font-size: var(--fs-xs);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  font-weight: bold;
  padding: 2px var(--sp-2);
  border: 1px solid transparent;
  min-height: 0;
  transition: opacity var(--dur-fast);
}
.save-pill:empty { display: none; }
.save-pill[data-status="saving"] {
  color: var(--amber);
  border-color: var(--amber-dim);
  background: var(--amber-16);
}
.save-pill[data-status="saved"] {
  color: var(--green);
  border-color: var(--green-dim);
  background: var(--green-08);
}
.save-pill[data-status="error"] {
  color: var(--red);
  border-color: var(--red-dim);
  background: var(--red-16);
}

/* =======================================================================
   PICKER — BOTTOM SHEET (mobile)
   Below 640px the anchored dropdown swaps to a bottom sheet mounted to
   document.body so long lists never clip off-screen or overflow the card.
   ======================================================================= */

/* Scroll lock while a sheet is open */
body.picker-sheet-lock {
  overflow: hidden;
  /* Prevent iOS "rubber band" of the page behind the sheet */
  touch-action: none;
}

/* Dimmed backdrop */
.picker-sheet-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.7);
  z-index: 1000;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  opacity: 0;
  pointer-events: auto;
  transition: opacity var(--dur-med) ease-out;
}
.picker-sheet-backdrop.open {
  opacity: 1;
}

/* The sheet itself — full width, slides up from bottom (mobile) */
.picker-sheet {
  width: 100%;
  max-height: 80vh;
  background: var(--bg-panel);
  border-top: 1px solid var(--border-strong);
  box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.75);
  transform: translateY(100%);
  transition: transform var(--dur-slow) cubic-bezier(0.2, 0.8, 0.2, 1);
  display: flex;
  flex-direction: column;
  /* Respect notches / home indicator */
  padding-bottom: env(safe-area-inset-bottom, 0);
}
.picker-sheet-backdrop.open .picker-sheet {
  transform: translateY(0);
}

/* Desktop: center the dialog as a modal instead of a bottom sheet */
@media (min-width: 641px) {
  .picker-sheet-backdrop {
    align-items: center;
  }
  .picker-sheet {
    width: min(560px, 92vw);
    max-height: min(640px, 85vh);
    border: 1px solid var(--amber);
    border-top: 1px solid var(--amber);
    box-shadow: var(--elev-3), 0 0 32px var(--amber-24);
    transform: scale(0.94);
    opacity: 0;
    transition: transform var(--dur-med) ease-out, opacity var(--dur-med) ease-out;
    padding-bottom: 0;
  }
  .picker-sheet-backdrop.open .picker-sheet {
    transform: scale(1);
    opacity: 1;
  }
  /* Drag-handle only makes sense on the bottom-sheet — hide on desktop modal */
  .picker-sheet .picker-sheet-handle {
    display: none;
  }
}

/* Drag-indicator bar at top — visual affordance only */
.picker-sheet-handle {
  width: 48px;
  height: 4px;
  background: var(--green-faint);
  margin: var(--sp-2) auto var(--sp-1);
  opacity: 0.6;
  flex-shrink: 0;
}

.picker-sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-4) var(--sp-3);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.picker-sheet-title {
  margin: 0;
  color: var(--amber);
  font-size: var(--fs-md);
  letter-spacing: var(--track-2);
  text-transform: uppercase;
  font-weight: normal;
}
.picker-sheet-close {
  font-size: var(--fs-lg);
  line-height: 1;
  padding: 0 var(--sp-3);
  min-height: 44px;
  min-width: 44px;
  /* Inherits existing .small button styling for borders/hover */
}

.picker-sheet-options {
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: var(--sp-2) var(--sp-2) var(--sp-3);
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  flex: 1;
  min-height: 0;
}

/* Options inside the sheet — bigger tap targets than the anchored menu.
   flex-shrink:0 is critical — the sheet parent is flex-column, which would
   otherwise compress rich options below their natural content height. */
.picker-sheet-options .picker-option {
  width: 100%;
  flex-shrink: 0;
  min-height: 52px;
  padding: var(--sp-3) var(--sp-4);
  text-align: left;
  font-size: var(--fs-base);
}
.picker-sheet-options .picker-option.has-detail {
  padding: var(--sp-4);
  gap: var(--sp-2);
}

/* On tall phones with many options, ensure the list stays usable */
@media (max-height: 560px) {
  .picker-sheet { max-height: 90vh; }
}

/* Picker uses the sheet dialog on both mobile (bottom sheet) and desktop
   (centered modal) — no display: none override. */
