/* ============================================================
   DC20 Codex — design system
   "Violet & Ember" (2026-07-11): deep-violet base, gold accent, dragonfire
   ember highlight. Supersedes "Obsidian & Ember" — see
   docs/superpowers/specs/2026-07-11-violet-ember-visual-identity-design.md.
   Token NAMES are unchanged from the brass/ember era on purpose (avoids a
   global rename across styles.css/landing.css/dc20-events.js) — only the
   hex values below changed. Semantic resource color unchanged:
   HP=ember-red, MP=arcane-blue, SP=vital-green.
   ============================================================ */
:root{
  /* surfaces */
  --ink-900:#0a050d;   /* page */
  --ink-850:#120a17;
  --ink-800:#1a0f21;   /* panels */
  --ink-750:#22142b;
  --ink-700:#2c1a37;   /* raised */
  --ink-600:#3a2447;
  --line:#33203f;
  --line-strong:#452c54;
  /* ink text */
  --paper:#f3e6da;     /* primary text on dark */
  --paper-dim:#cdb8c9;
  --paper-faint:#8f7a8c;
  /* gold / ember identity */
  --brass:#f0d9a0;
  --brass-bright:#ffe9b8;
  --brass-deep:#b8873f;
  --ember:#e06e32;
  --ember-deep:#a84f1f;
  /* violet base — atmosphere gradients, hero/frame backgrounds (new) */
  --violet:#3c145a;
  --violet-bright:#6b2fa0;
  --violet-deep:#160a1a;
  /* semantic resources */
  --hp:#d4504a;  --hp-bg:#2a1614;
  --mp:#5b8bd0;  --mp-bg:#13202f;
  --sp:#5fae72;  --sp-bg:#13241a;
  --grit:#f0d9a0;
  /* feedback */
  --ok:#5fae72; --warn:#d8a23a; --bad:#d4504a;
  --focus:#ffe9b8;

  /* [B1 Chunk 2 2026-07-09] class-accent defaults — per-character override is
     set inline by applyAccent() on .play / .pc-card nodes */
  --accent:#f0d9a0;
  --accent-bright:#ffe9b8;
  /* type */
  --display:"Cinzel",Georgia,"Iowan Old Style","Palatino Linotype",serif;
  --body:"Inter",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,"SF Mono",Menlo,monospace;
  --r:10px; --r-sm:7px;
  --shadow:0 8px 30px rgba(0,0,0,.45);
  --shadow-sm:0 2px 10px rgba(0,0,0,.35);
}
*{box-sizing:border-box}
html, body{margin:0;height:100%}
body{
  background:
    radial-gradient(130% 100% at 50% 38%,transparent 62%,var(--vignette) 100%),
    radial-gradient(1200px 700px at 80% -10%, color-mix(in srgb,var(--ink-700) 55%,transparent) 0%, transparent 60%),
    radial-gradient(900px 600px at -10% 110%, color-mix(in srgb,var(--ink-700) 55%,transparent) 0%, transparent 55%),
    var(--ink-900);
  color:var(--paper);
  font-family:var(--body);
  font-size:15px; line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
h1, h2, h3, h4{font-family:var(--display);font-weight:600;letter-spacing:.02em;margin:0}
a{color:var(--brass-bright);text-decoration:none}
button{font-family:inherit}
::selection{background:var(--brass);color:#1a1505}
:focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:4px}

/* scrollbars */
*{scrollbar-width:thin;scrollbar-color:var(--line-strong) transparent}
*::-webkit-scrollbar{width:10px;height:10px}
*::-webkit-scrollbar-thumb{background:var(--line-strong);border-radius:8px;border:2px solid transparent;background-clip:content-box}

/* ---------- dead-rule removal (Risk 5 audit, reapplied 2026-07-09) ----------
   Removed selectors with zero references anywhere in the live app (scanned all
   dc20-*.js modules, dc20-items.js, dc20-monsters.js, auth-client.js, the
   bundle, and every HTML page incl. app/ and the auth pages, accounting for
   dynamic class construction — theme-* classes are built as 'theme-'+id and
   were kept): the retired in-app login view (.login-* — real auth pages
   replaced it), pre-3D CSS cube dice (.dice-3d-*, .dice-anim), the retired
   roll-log FAB (.log-fab*), the legacy inline theme picker (.theme-picker —
   live picker is .theme-dd), the never-wired portrait panel (.portrait-*,
   .play-portrait-wrap), stale roster sign-in chrome (.roster-avatar/-who/
   -signedin) and orphaned play/builder classes (.apc-*, .pickbtn, .roll-bar,
   .play-section, .step-rail, .next-prev, .undo-btn, .attr-play-*,
   .skill-play-grid, .trades-section, .inv-title-row). Restore from git
   history if a future pass rewires any of them. */

/* ---------- layout shell ---------- */
.app{display:flex;flex-direction:column;min-height:100vh}
.topbar{
  display:flex;align-items:center;gap:18px;
  padding:12px 22px;border-bottom:1px solid var(--line);
  background:linear-gradient(180deg,var(--ink-850),var(--ink-900));
  position:sticky;top:0;z-index:40;backdrop-filter:blur(6px)
}
.brand{display:flex;align-items:center;gap:12px;cursor:pointer}
.brand .mark{
  width:42px;height:42px;border-radius:9px;display:grid;place-items:center;
  overflow:hidden;padding:3px;background:#f1ead9;border:1px solid var(--brass-deep);
  box-shadow:inset 0 1px 1px rgba(255,255,255,.5),var(--shadow-sm)
}
.brand .mark img, .brand .mark svg{width:100%;height:100%;object-fit:contain;display:block}
.brand .name{font-family:var(--display);font-size:19px;letter-spacing:.06em}
.brand .name b{color:var(--brass-bright)}
.brand .tag{color:var(--paper-faint);font-size:11px;letter-spacing:.18em;text-transform:uppercase}
.topbar .spacer{flex:1}
.topbar .ctx{color:var(--paper-dim);font-size:13px;display:flex;align-items:center;gap:8px}
.topbar .ctx b{color:var(--paper)}
/* Phone topbar: keep brand + controls reachable, drop secondary text */
@media(max-width:600px){
  .topbar{gap:10px;padding:10px 12px;flex-wrap:wrap}
  .topbar .spacer{flex:1 1 auto}
  .brand .tag{display:none}
  .brand .name{font-size:16px}
  .brand .mark{width:34px;height:34px}
  .topbar .ctx{display:none}
  /* Icon-only on phones — the label just steals space a 44px tap target needs. */
  #rulesQuickBtn .rqb-label{display:none}
  #rulesQuickBtn{padding:9px 11px;min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center}
}

.main{flex:1;display:flex;min-height:0}

/* ---------- buttons ---------- */
.btn{
  appearance:none;border:1px solid var(--line-strong);background:var(--ink-700);
  color:var(--paper);padding:9px 15px;border-radius:var(--r-sm);cursor:pointer;
  font-size:14px;font-weight:500;display:inline-flex;align-items:center;gap:8px;
  transition:background .15s,border-color .15s,transform .05s
}
.btn:hover{background:var(--ink-600);border-color:var(--brass-deep)}
.btn:active{transform:translateY(1px)}
.btn.primary{
  background:linear-gradient(180deg,var(--brass),var(--brass-deep));
  border-color:var(--brass-deep);color:#1a1404;font-weight:600
}
.btn.primary:hover{background:linear-gradient(180deg,var(--brass-bright),var(--brass))}
.btn.ghost{background:transparent;border-color:var(--line)}
.btn.ghost:hover{background:var(--ink-800)}
.btn.danger{border-color:var(--ember-deep);color:#f0b6a3}
.btn.danger:hover{background:var(--hp-bg)}
.btn.sm{padding:6px 11px;font-size:13px}
.btn:disabled{opacity:.4;cursor:not-allowed}
.btn .ico{font-size:15px;line-height:1}

/* ---------- roster ---------- */
.roster{max-width:1080px;margin:0 auto;padding:44px 28px;width:100%}
.roster-hd{display:flex;align-items:flex-end;justify-content:space-between;margin-bottom:26px;gap:20px;flex-wrap:wrap}
.roster-hd h1{font-size:32px}
.roster-hd p{color:var(--paper-dim);margin:6px 0 0;max-width:46ch}
.card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px}
.pc-card{
  background:linear-gradient(180deg,var(--ink-800),var(--ink-850));
  border:1px solid var(--line);border-radius:var(--r);padding:18px;cursor:pointer;
  transition:border-color .15s,transform .1s;position:relative;overflow:hidden
}
.pc-card:hover{border-color:var(--brass-deep);transform:translateY(-2px)}
.pc-card::before{content:"";position:absolute;inset:0 0 auto 0;height:3px;
  background:linear-gradient(90deg,var(--brass),transparent)}
.pc-card .pc-name{font-family:var(--display);font-size:20px;margin-bottom:2px}
.pc-card .pc-sub{color:var(--paper-dim);font-size:13px}
.pc-card .pc-stats{display:flex;flex-wrap:wrap;gap:10px 14px;margin-top:14px;font-size:13px}
.pc-card .pc-stats .s{display:flex;flex-direction:column}
.pc-card .pc-stats .s b{font-family:var(--mono);font-size:16px}
.pc-card .pc-stats .s span{color:var(--paper-faint);font-size:10px;letter-spacing:.1em;text-transform:uppercase}
.pc-card .pc-actions{position:absolute;top:14px;right:12px;display:flex;gap:4px;opacity:0;transition:opacity .15s}
.pc-card:hover .pc-actions{opacity:1}
.pc-card .icobtn{background:var(--ink-700);border:1px solid var(--line);border-radius:6px;width:28px;height:28px;display:grid;place-items:center;cursor:pointer;color:var(--paper-dim)}
.pc-card .icobtn:hover{color:var(--paper);border-color:var(--brass-deep)}
.empty{text-align:center;padding:70px 20px;color:var(--paper-faint)}
.empty .big{font-size:46px;margin-bottom:10px;opacity:.6}
.empty-roster-art{display:flex;justify-content:center;margin:24px 0 0;opacity:.9}
.empty-roster-art img{max-width:280px;height:auto;border-radius:var(--r)}
.empty-inventory-art{display:flex;justify-content:center;margin:16px 0 0;opacity:.9}
.empty-inventory-art img{max-width:240px;height:auto;border-radius:var(--r)}

.new-card{
  border:1.5px dashed var(--line-strong);background:transparent;display:grid;
  place-items:center;min-height:128px;color:var(--paper-dim);gap:6px;text-align:center
}
.new-card:hover{border-color:var(--brass);color:var(--brass-bright);transform:translateY(-2px)}
.new-card .plus{font-size:30px;line-height:1}
.new-card.muted{cursor:default;opacity:.55}
.new-card.muted:hover{border-color:var(--line-strong);color:var(--paper-dim);transform:none}

/* ---------- builder layout (mobile-first) ---------- */
/* Base = phone/tablet: single column that scrolls as one. Step nav is a
   sticky horizontal rail; the live-stat ledger flows at the bottom.
   The 3-column desktop grid is restored at >=1024px (see media query below). */
.builder{display:flex;flex-direction:column;flex:1;min-height:0;overflow-y:auto}
.stepnav{
  display:flex;gap:6px;overflow-x:auto;padding:10px 12px;
  background:var(--ink-850);border-bottom:1px solid var(--line);
  position:sticky;top:0;z-index:15;scrollbar-width:none
}
.stepnav::-webkit-scrollbar{display:none}
.stepnav .step{
  display:flex;align-items:center;gap:11px;padding:9px 10px;border-radius:var(--r-sm);
  cursor:pointer;color:var(--paper-dim);font-size:13.5px;
  flex:0 0 auto;white-space:nowrap;
  border:1px solid transparent;transition:background .12s
}
.stepnav .step:hover{background:var(--ink-800)}
.stepnav .step.active{background:var(--ink-750);color:var(--paper);border-color:var(--line-strong)}
.stepnav .step .n{
  font-family:var(--mono);font-size:12px;width:23px;height:23px;flex:0 0 23px;border-radius:6px;
  display:grid;place-items:center;background:var(--ink-700);color:var(--paper-faint);border:1px solid var(--line)
}
.stepnav .step.active .n{background:var(--brass);color:#1a1404;border-color:var(--brass)}
.stepnav .step.done .n{background:var(--sp-bg);color:var(--sp);border-color:var(--sp)}
.stepnav .step .lbl{flex:1}
.stepnav .step .warn{color:var(--warn);font-size:13px}

.stage{padding:18px 16px;min-width:0}
.stage-toolbar{display:flex;justify-content:flex-start;margin-bottom:14px}
.stage-hd{margin-bottom:20px}
.stage-hd .kicker{color:var(--brass);font-size:11px;letter-spacing:.22em;text-transform:uppercase;font-weight:600}
.stage-hd h2{font-size:26px;margin-top:4px}
.stage-hd p{color:var(--paper-dim);margin:6px 0 0;max-width:62ch}
.stage-foot{display:flex;justify-content:space-between;margin-top:30px;padding-top:18px;border-top:1px solid var(--line)}

/* ---------- ledger (signature element) ---------- */
.ledger{border-top:1px solid var(--line);background:linear-gradient(180deg,var(--ink-850),var(--ink-900));padding:18px 16px}
.ledger h3{font-size:13px;letter-spacing:.16em;text-transform:uppercase;color:var(--paper-faint);margin-bottom:12px;font-family:var(--body);font-weight:600}
.led-name{font-family:var(--display);font-size:20px;line-height:1.15}
.led-name .ph{color:var(--paper-faint);font-style:italic}
.led-sub{color:var(--paper-dim);font-size:12.5px;margin:2px 0 16px}
.res-row{display:flex;gap:8px;margin-bottom:16px}
.res{flex:1;border-radius:var(--r-sm);padding:9px 8px;text-align:center;border:1px solid var(--line)}
.res.hp{background:var(--hp-bg);border-color:#43221f}
.res.mp{background:var(--mp-bg);border-color:#1c3148}
.res.sp{background:var(--sp-bg);border-color:#1f3a28}
.res .v{font-family:var(--mono);font-size:22px;font-weight:600;line-height:1}
.res.hp .v{color:var(--hp)} .res.mp .v{color:var(--mp)} .res.sp .v{color:var(--sp)}
.res .k{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--paper-faint);margin-top:3px}
.led-grid{display:grid;grid-template-columns:1fr 1fr;gap:7px;margin-bottom:8px}
.stat{
  background:var(--ink-800);border:1px solid var(--line);border-radius:var(--r-sm);
  padding:8px 10px;cursor:help;position:relative;transition:border-color .12s
}
.stat:hover{border-color:var(--brass-deep)}
.stat .k{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--paper-faint)}
.stat .v{font-family:var(--mono);font-size:18px;font-weight:600;color:var(--paper)}
.stat .v.changed{animation:pop .4s ease}
@keyframes pop{0%{color:var(--brass-bright);transform:scale(1.18)}100%{transform:scale(1)}}
.stat .formula{
  display:none;position:absolute;z-index:30;bottom:calc(100% + 6px);left:0;right:auto;
  min-width:190px;background:var(--ink-700);border:1px solid var(--brass-deep);
  border-radius:var(--r-sm);padding:8px 10px;font-size:11.5px;color:var(--paper-dim);
  box-shadow:var(--shadow);font-family:var(--mono);line-height:1.5
}
.stat:hover .formula{display:block}
.stat .formula b{color:var(--brass-bright)}
.attr-strip{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin:14px 0}
@media(max-width:480px){.attr-strip{grid-template-columns:1fr 1fr}}
.attr-chip{background:var(--ink-800);border:1px solid var(--line);border-radius:var(--r-sm);padding:7px 4px;text-align:center}
.attr-chip.prime{border-color:var(--brass);background:linear-gradient(180deg,var(--ink-750),var(--ink-800))}
.attr-chip .a{font-size:10px;letter-spacing:.08em;color:var(--paper-faint)}
.attr-chip .m{font-family:var(--mono);font-size:18px;font-weight:600}
.attr-chip .m.pos{color:var(--sp)} .attr-chip .m.neg{color:var(--hp)}
.attr-chip .prime-tag{font-size:8px;color:var(--brass-bright);letter-spacing:.1em}

/* ---------- option cards / forms ---------- */
.opt-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(176px,1fr));gap:10px}
.opt{
  background:var(--ink-800);border:1px solid var(--line);border-radius:var(--r-sm);
  padding:13px 14px;cursor:pointer;transition:border-color .12s,background .12s;position:relative
}
.opt:hover{border-color:var(--brass-deep);background:var(--ink-750)}
.opt.sel{border-color:var(--brass);background:linear-gradient(180deg,var(--ink-750),var(--ink-800));box-shadow:inset 0 0 0 1px var(--brass-deep)}
.opt.sel::after{content:"✓";position:absolute;top:9px;right:11px;color:var(--brass-bright);font-weight:700}
.opt .t{font-family:var(--display);font-size:16px}
.opt .d{color:var(--paper-dim);font-size:12px;margin-top:3px}
.opt .badge{display:inline-block;font-size:10px;padding:2px 7px;border-radius:20px;margin-top:7px;letter-spacing:.06em;text-transform:uppercase}
.badge.martial{background:var(--sp-bg);color:var(--sp);border:1px solid #1f3a28}
.badge.caster{background:var(--mp-bg);color:var(--mp);border:1px solid #1c3148}
.badge.hybrid{background:#2a2417;color:var(--brass-bright);border:1px solid var(--brass-deep)}
.badge.supp{background:var(--ink-700);color:var(--paper-dim);border:1px solid var(--line-strong)}
.badge.exp{background:#23202b;color:#b79de0;border:1px solid #4a3d63}

.field{margin-bottom:16px}
.field label{display:block;font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--paper-faint);margin-bottom:6px}
.field input[type=text], .field input[type=number], .field select, .field textarea{
  width:100%;background:var(--ink-850);border:1px solid var(--line-strong);color:var(--paper);
  padding:10px 12px;border-radius:var(--r-sm);font-family:inherit;font-size:14px
}
.field input:focus, .field select:focus, .field textarea:focus{border-color:var(--brass);outline:none}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:14px}

/* [Code-health 2026-09-18] Homebrew Editor form inputs — was the
   HB_INPUT_STYLE JS string constant threaded through 17 inline style="..."
   attributes. One real CSS class instead of a JS string re-typed into the
   DOM at every call site. */
.hb-input{background:var(--ink-700);color:var(--paper);border:1px solid var(--line);border-radius:5px;padding:6px}

/* pools / counters */
.pool{display:flex;align-items:center;gap:10px;background:var(--ink-800);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:8px 14px;font-size:13px}
.pool b{font-family:var(--mono);font-size:16px}
.pool.over{border-color:var(--bad);color:#f0b6a3}
.pool-bar{display:flex;gap:10px;flex-wrap:wrap;margin:0 -16px 18px;padding:10px 16px;
  position:sticky;top:var(--rail-h,60px);z-index:14;background:linear-gradient(180deg,var(--ink-900) 80%,transparent);
  backdrop-filter:blur(6px);border-bottom:1px solid var(--line);
  box-shadow:0 2px 8px rgba(0,0,0,.45)}

/* attribute editor */
.attr-edit{display:grid;grid-template-columns:repeat(2,1fr);gap:12px;margin:18px 0}
.attr-box{background:var(--ink-800);border:1px solid var(--line);border-radius:var(--r);padding:16px 12px;text-align:center}
.attr-box .nm{font-family:var(--display);font-size:15px;margin-bottom:10px}
.attr-box .val{font-family:var(--mono);font-size:34px;font-weight:600;line-height:1}
.attr-box .val.pos{color:var(--sp)} .attr-box .val.neg{color:var(--hp)}
.attr-box .ctrls{display:flex;justify-content:center;gap:8px;margin-top:12px}
.attr-box .ctrls button{width:32px;height:32px;border-radius:7px;border:1px solid var(--line-strong);
  background:var(--ink-700);color:var(--paper);font-size:18px;cursor:pointer}
.attr-box .ctrls button:hover:not(:disabled){border-color:var(--brass);color:var(--brass-bright)}
.attr-box .ctrls button:disabled{opacity:.3;cursor:not-allowed}
.attr-box .save{font-size:11px;color:var(--paper-faint);margin-top:8px;font-family:var(--mono)}
.method-tabs{display:flex;gap:8px;margin-bottom:6px}
.method-tabs .mt{padding:8px 14px;border-radius:var(--r-sm);border:1px solid var(--line);
  background:var(--ink-800);cursor:pointer;font-size:13px;color:var(--paper-dim)}
.method-tabs .mt.on{border-color:var(--brass);background:var(--ink-750);color:var(--paper)}

/* skill/trade rows */
.mast-list{display:flex;flex-direction:column;gap:6px}
.mast-row{display:flex;align-items:center;gap:12px;background:var(--ink-800);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:8px 14px}
.mast-row .nm{flex:1;font-size:14px}
.mast-row .nm small{color:var(--paper-faint);margin-left:7px;font-size:11px;text-transform:uppercase;letter-spacing:.06em}
.pips{display:flex;gap:5px}
/* .pip was a 15x15px hit area -- well under the WCAG 2.5.8 / HIG 24px floor, and with
   up to 104 of these on one character sheet (Skills+Trades mastery rows) it was the
   single largest concentration of undersized touch targets the mobile audit found.
   Unlike .rule-link-btn/.coin-btn (icon-in-a-box, so the hit area could grow invisibly
   around a fixed-size glyph), a pip's entire box IS the visible dot -- there's no
   separate icon layer to decouple from the hit target. So this grows the dot itself to
   24x24 (border-radius scaled up to match) rather than faking an invisible hit area;
   at a glance a mastery row still reads as a compact strip of filled/unfilled squares,
   just slightly larger ones. Row gap widened 4px->5px to keep adjacent pips visually
   distinct at the bigger size. */
.pip{width:24px;height:24px;border-radius:6px;border:1px solid var(--line-strong);background:var(--ink-700);cursor:pointer}
.pip.full{background:var(--brass);border-color:var(--brass)}
.pip.cap{border-color:var(--ember);opacity:.6}
.mast-row .bonus{font-family:var(--mono);font-size:13px;color:var(--paper-dim);width:34px;text-align:right}
.cap-stepper{display:flex;align-items:center;gap:4px;flex:0 0 auto}
/* .cap-btn was 20x20px (same WCAG 2.5.8 miss as .coin-btn, same +/- stepper shape) --
   grown to 24x24 the same way .coin-btn was: the visible box grows, glyph (11px −/▲)
   left untouched since place-items:center recenters it automatically. */
.cap-btn{width:24px;height:24px;border-radius:5px;border:1px solid var(--line-strong);background:var(--ink-700);
  color:var(--paper-dim);cursor:pointer;font-size:11px;line-height:1;display:grid;place-items:center;padding:0}
.cap-btn:hover:not(:disabled){border-color:var(--brass-deep);color:var(--paper)}
.cap-btn:disabled{opacity:.35;cursor:default}
.cap-n{font-family:var(--mono);font-size:10.5px;color:var(--brass-bright);min-width:38px;text-align:center}
/* At 390px a Skill/Trade row with a raised Mastery Limit (5 pips, reachable via the
   ▲ capSpendAdj control -- e.g. an Expertise-boosted skill) plus the 24px pips above
   no longer fits on one line: .nm + 5 pips + cap-stepper + .tier adds up to more than
   the row's content width, and .builder scrolls overflow-x rather than hiding it, so
   the .tier mastery-name label (e.g. "Expert") was getting pushed off-screen into that
   horizontal scroll instead of being visible. Rather than shrink the pips back down,
   let the row wrap: the name gets its own line and the pips/stepper/tier group flows
   onto the next, which comfortably fits a 5-pip row at 390px. Below 600px only --
   desktop rows have ample width and stay single-line/pixel-identical. */
@media(max-width:600px){
  .mast-row{flex-wrap:wrap;row-gap:6px}
  .mast-row .nm{flex:1 1 100%}
}

/* spell/maneuver browser */
.browser-toolbar{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:14px}
.search{flex:1;min-width:180px;background:var(--ink-850);border:1px solid var(--line-strong);
  border-radius:var(--r-sm);padding:9px 12px;color:var(--paper);font-size:14px}
.chip{padding:5px 12px;border-radius:20px;border:1px solid var(--line);background:var(--ink-800);
  cursor:pointer;font-size:12.5px;color:var(--paper-dim)}
.chip.on{border-color:var(--brass);background:var(--ink-750);color:var(--brass-bright)}
.chip.sm{padding:3px 9px;font-size:11px}
.chip.ghost{background:transparent;border-style:dashed;color:var(--paper-faint)}
.chip.ghost:hover{color:var(--paper)}
.tag-filter-wrap{margin-bottom:10px}
.spell-list{display:flex;flex-direction:column;gap:8px}
.spell-row{display:flex;align-items:center;gap:12px;background:var(--ink-800);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:11px 14px;cursor:pointer;transition:border-color .12s}
.spell-row:hover{border-color:var(--brass-deep)}
.spell-row.picked{border-color:var(--brass);background:linear-gradient(180deg,var(--ink-750),var(--ink-800))}
.spell-row .main{flex:1;min-width:0}
.spell-row .nm{font-weight:600;font-size:14.5px}
.spell-row .meta{color:var(--paper-faint);font-size:11.5px;margin-top:2px;display:flex;gap:10px;flex-wrap:wrap}
.spell-row .cost{font-family:var(--mono);font-size:12px;color:var(--brass-bright);white-space:nowrap}
.tagpill{font-size:10px;padding:1px 7px;border-radius:12px;background:var(--ink-700);color:var(--paper-dim);border:1px solid var(--line)}

/* modal */
.modal-bg{position:fixed;inset:0;background:rgba(6,6,10,.7);backdrop-filter:blur(3px);z-index:100;
  display:grid;place-items:center;padding:24px;animation:fade .15s}
@keyframes fade{from{opacity:0}to{opacity:1}}
.modal{background:linear-gradient(180deg,var(--ink-800),var(--ink-850));border:1px solid var(--line-strong);
  border-radius:var(--r);max-width:560px;width:100%;max-height:85vh;overflow-y:auto;box-shadow:var(--shadow)}
.modal-hd{padding:18px 22px;border-bottom:1px solid var(--line);display:flex;justify-content:space-between;align-items:flex-start;gap:14px;position:sticky;top:0;background:var(--ink-800);z-index:1}
.modal-hd h3{font-size:21px}
.modal-hd .sub{color:var(--brass);font-size:12px;letter-spacing:.1em;text-transform:uppercase;margin-top:3px}
.modal-bd{padding:18px 22px;font-size:14px;line-height:1.6;color:var(--paper-dim)}
.modal-bd .desc{color:var(--paper);white-space:pre-wrap}
.modal .x{background:none;border:none;color:var(--paper-faint);font-size:22px;cursor:pointer;line-height:1}
.modal .x:hover{color:var(--paper)}
.enh{background:var(--ink-750);border:1px solid var(--line);border-radius:var(--r-sm);padding:10px 12px;margin-top:8px}
.enh .eh{display:flex;justify-content:space-between;gap:10px;align-items:baseline}
.enh .en{font-weight:600;color:var(--paper)}
.enh .ec{font-family:var(--mono);font-size:12px;color:var(--brass-bright)}
.enh .ed{font-size:13px;margin-top:4px}
.statline{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:14px}
.statline .b{background:var(--ink-700);border:1px solid var(--line);border-radius:6px;padding:5px 10px;font-size:12px}
.statline .b b{color:var(--brass-bright);font-family:var(--mono)}
@media(max-width:600px){
  .modal-bg{padding:12px}
  .modal-hd{padding:14px 16px}
  .modal-bd{padding:14px 16px}
}

/* ---------- play mode ---------- */
/* Mobile-first responsive play layout */
.play{flex:1;display:flex;flex-direction:column;min-height:0;overflow-y:auto;position:relative}
.play-left, .play-main{padding:14px 16px;min-width:0}
.play-left{border-bottom:1px solid var(--line)}
/* Tablet ≥780px: left panel as a top bar, main fills below */
@media(min-width:780px){
  .play{display:grid;grid-template-columns:340px 1fr;grid-template-rows:1fr;overflow:hidden}
  .play-left{grid-column:1;grid-row:1;border-right:1px solid var(--line);border-bottom:none;overflow-y:auto;padding:16px 18px}
  .play-main{grid-column:2;grid-row:1;overflow-y:auto;padding:20px 24px}
}
/* Desktop ≥1180px: give left a bit more breathing room */
@media(min-width:1180px){
  .play{grid-template-columns:380px 1fr}
  .play-left{padding:18px 20px}
  .play-main{padding:22px 28px}
}
.hp-track{background:linear-gradient(180deg,var(--hp-bg),var(--ink-850));border:1px solid #43221f;border-radius:var(--r);padding:20px;margin-bottom:18px}
.hp-track .hp-top{display:flex;align-items:baseline;gap:10px;justify-content:center}
.hp-track .hp-cur{font-family:var(--mono);font-size:52px;font-weight:700;color:var(--hp);line-height:1}
.hp-track .hp-max{font-family:var(--mono);font-size:24px;color:var(--paper-dim)}
.hp-bar{height:14px;background:var(--ink-900);border-radius:8px;overflow:hidden;margin:14px 0;border:1px solid #43221f;position:relative}
.hp-bar .fill{height:100%;background:linear-gradient(90deg,var(--hp),#e8847e);transition:width .3s}
.hp-bar .temp{height:100%;background:repeating-linear-gradient(45deg,var(--mp),var(--mp) 6px,#3d6aa3 6px,#3d6aa3 12px)}
.hp-ctrls{display:flex;gap:8px;align-items:center;justify-content:center;flex-wrap:wrap}
.hp-ctrls input{width:72px;text-align:center;background:var(--ink-850);border:1px solid var(--line-strong);
  border-radius:var(--r-sm);color:var(--paper);padding:9px;font-family:var(--mono);font-size:16px}
/* ---------- shared play-panel scaffold ----------
   [Code-health 2026-07-09, Risk 3] The 16 class-action renderers (plus
   ancestry/talent panels) used to hardcode identical inline styles on every
   feature box and chip row — 108 call sites. They now share these classes,
   so a global play-panel restyle is one edit here instead of 16 files' worth
   of string surgery. Modifier classes mirror the inline variants that existed. */
.feature-box{border:1px solid var(--line);border-radius:var(--r-sm);padding:11px;background:var(--ink-800)}
.feature-box.mt8{margin-top:8px}
.feature-box.frow{display:flex;align-items:center;gap:10px}
.chip-row{display:flex;gap:8px;flex-wrap:wrap}
.chip-row.mt6{margin-top:6px}
.chip-row.mt8{margin-top:8px}
.chip-row.mid{align-items:center}
/* [Code-health 2026-09-18] Hint/caption text — font-size:11px + paper-faint
   color was hand-typed inline at 60+ call sites across 3 modules. One class
   here, plus margin-top modifiers matching the .feature-box/.chip-row pattern
   above, instead of that. */
.field-hint{font-size:11px;color:var(--paper-faint)}
.field-hint.mt8{margin-top:8px}
.field-hint.mt6{margin-top:6px}

/* ---------- identity kit (B3/B5, Chunk 9 2026-07-10) ---------- */
/* High Contrast: the only surviving theme variant besides the default —
   a real accessibility affordance, not a cosmetic skin, so it's kept
   independent of the Violet & Ember palette (2026-07-11). */
:root.theme-contrast{
  --ink-900:#000000; --ink-850:#050505; --ink-800:#0d0d0d; --ink-750:#141414;
  --ink-700:#1f1f1f; --ink-600:#2e2e2e; --line:#4a4a4a; --line-strong:#6a6a6a;
  --paper:#ffffff; --paper-dim:#d8d8d8; --paper-faint:#a8a8a8;
  --brass:#ffd75e; --brass-bright:#ffe89a; --brass-deep:#c9a53a;
  --hp:#ff6a60; --sp:#7ce392; --mp:#7ab4ff; --focus:#ffe89a;
}
/* B3: portrait frames upgrade with level tier */
.pc-ava.tier2,.portrait-img.tier2,.pi-portrait.tier2{border:2px solid var(--brass);box-shadow:0 0 10px color-mix(in srgb,var(--brass) 35%,transparent)}
.pc-ava.tier3,.portrait-img.tier3,.pi-portrait.tier3{border:2px solid var(--brass-bright);
  box-shadow:0 0 0 2px var(--brass-deep),0 0 16px color-mix(in srgb,var(--brass-bright) 45%,transparent)}

/* B5: print pass — the play sheet prints clean */
@media print{
  .mvitals,.cmd-bar,.tour-veil,.gloss-pop,.dr-recents,.dice-roller,
  .play-tabbar,.mfab-wrap,.play-actions-menu,.dd-spotlight,.empty-cta,.hh-actions{display:none!important}
  .play{padding-bottom:0!important}
  .feature-box,.rw-opt,.weapon-card{break-inside:avoid;border-color:#999!important}
  .play-identity{border-bottom:2px solid #333;margin-bottom:10px}
  .section-title{color:#333!important}
  body::before{display:none!important}
}

/* ---------- deep delight (A4/A6/D3/D4, Chunk 8 2026-07-10) ---------- */
.dr-recents{display:flex;gap:5px;flex-wrap:wrap;margin:6px 0 2px}
.dr-recent{font-size:11px;padding:4px 9px;border-radius:10px;border:1px solid var(--line-strong);
  background:var(--ink-750);color:var(--paper-dim);cursor:pointer;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dr-recent:hover{border-color:var(--brass);color:var(--paper)}
.dr-skin.locked{opacity:.45;filter:grayscale(.6)}
.dr-skin em{position:absolute;font-size:10px;right:-4px;top:-6px;font-style:normal}
.ach-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px;margin:4px 0 12px}
.ach{border:1px solid var(--line);border-radius:var(--r-sm);padding:8px 10px;background:var(--ink-800);opacity:.45}
.ach.got{opacity:1;border-color:var(--brass-deep);box-shadow:inset 0 1px 0 rgba(255,255,255,.05)}
.ach span{font-size:17px;display:block}
.ach b{font-size:12px;display:block;color:var(--paper)}
.ach.got b{color:var(--brass-bright)}
.ach i{font-size:10.5px;color:var(--paper-faint);font-style:normal}
.tl{max-height:180px;overflow:auto;margin-bottom:12px}
.tl-row{font-size:12px;color:var(--paper-dim);padding:3px 0;border-bottom:1px solid var(--line)}
.tl-row span{color:var(--paper-faint);font-size:10.5px;margin-right:8px;font-family:var(--mono)}

/* ---------- glossary, tour & empty states (E1/E3/E4, Chunk 6 2026-07-10) ---------- */
.gloss{border-bottom:1px dotted var(--brass);cursor:help}
.gloss:hover,.gloss:focus-visible{color:var(--brass-bright);border-bottom-style:solid}
.gloss-pop{position:fixed;z-index:9600;max-width:300px;font-size:12.5px;line-height:1.55;
  background:var(--ink-750);border:1px solid var(--brass-deep);border-radius:var(--r-sm);
  padding:9px 12px;box-shadow:var(--shadow);color:var(--paper-dim)}
.gloss-pop b{color:var(--brass-bright)}
.gloss-pop i{color:var(--paper-faint);font-size:11px}
.gp-ref{float:right;font-size:10px;color:var(--paper-faint);letter-spacing:.06em}
.modal.modal-glossary{max-width:520px}
.gls-list{max-height:52vh;overflow:auto}
/* [E4 follow-up 2026-09-06] Rules Compendium deep-link button — see ruleLinkBtn()
   [Touch-target fix 2026-09-17] Box grown to a real 28px tap target (WCAG
   2.5.8 floor) — the 13px icon stays exactly as small since it's centered by
   the same flex rule that centered it before, so nothing visually changes
   except the invisible hit area around it. margin-left dropped since the
   bigger box now supplies its own breathing room from the preceding text. */
.rule-link-btn{display:inline-flex;align-items:center;justify-content:center;
  width:28px;height:28px;padding:0;vertical-align:middle;
  background:none;border:none;cursor:pointer;opacity:.55}
.rule-link-btn:hover,.rule-link-btn:focus-visible{opacity:1}
.rule-link-btn .vx-icon{width:13px;height:13px;display:inline-block}
.gls-row{padding:8px 2px;border-bottom:1px solid var(--line);font-size:12.5px;color:var(--paper-dim);line-height:1.5}
.gls-row b{color:var(--paper)}
.gls-row i{color:var(--paper-faint);font-size:11px}

.tour-veil{position:fixed;inset:0;z-index:9700;background:rgba(5,5,9,.62)}
.tour-ring{position:fixed;border:2px solid var(--brass-bright);border-radius:10px;
  box-shadow:0 0 0 6px rgba(226,196,120,.18),0 0 30px rgba(226,196,120,.35);
  pointer-events:none;transition:all .3s var(--ease,ease)}
.tour-card{position:fixed;left:50%;transform:translateX(-50%);width:min(92vw,360px);
  background:var(--ink-800);border:1px solid var(--brass-deep);border-radius:var(--r);
  padding:14px 16px;box-shadow:var(--shadow);z-index:9701}
.tour-card b{font-family:var(--display);font-size:16px;color:var(--brass-bright)}
.tour-card p{font-size:12.5px;color:var(--paper-dim);line-height:1.6;margin:6px 0 10px}
.tc-step{font-size:10px;letter-spacing:.14em;color:var(--paper-faint);margin-bottom:2px}
.tc-btns{display:flex;justify-content:space-between}

.empty-cta{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:6px 0 14px;
  padding:12px 14px;border:1px dashed var(--line-strong);border-radius:var(--r-sm);
  background:var(--ink-800);font-size:13px;color:var(--paper-dim)}
.empty-cta div{flex:1;min-width:200px}

/* ---------- journal & stats (D1/D2, Chunk 5 2026-07-10) ---------- */
.modal.modal-journal{max-width:560px}
.jr-nums{display:flex;gap:14px;flex-wrap:wrap;font-size:12.5px;color:var(--paper-dim);margin:4px 0 8px}
.jr-nums b{color:var(--paper);font-size:15px}
.jr-nums i{color:var(--paper-faint);font-style:normal;font-size:11px}
.lk-curve{display:flex;align-items:flex-end;gap:2px;height:56px;margin:2px 0 14px;
  padding:4px 6px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--ink-800)}
.lk-col{flex:1;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;height:100%}
.lk-col i{display:block;width:100%;min-height:2px;border-radius:2px 2px 0 0;background:var(--brass-deep)}
.lk-col i.hi{background:var(--brass-bright)}
.lk-col i.lo{background:var(--ember-deep)}
.lk-col span{font-size:8px;color:var(--paper-faint);height:10px}
.jr-sess{display:flex;align-items:center;gap:10px;padding:7px 4px;border-bottom:1px solid var(--line);font-size:13px}
.jr-sess span{flex:1;color:var(--paper-dim);font-size:12px}
.jr-md{white-space:pre-wrap;font-family:var(--mono);font-size:11.5px;line-height:1.55;
  background:var(--ink-800);border:1px solid var(--line);border-radius:var(--r-sm);
  padding:10px 12px;max-height:300px;overflow:auto;color:var(--paper-dim)}

/* ---------- session recap screen (reuses .cer-splash/.modal-ceremony +
   .lk-curve/.lk-col above for visual consistency with achievementCeremony()
   and the Journal modal's luck chart) 2026-09-19 ---------- */
.recap-hero .cer-level{font-size:34px}
.recap-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(92px,1fr));gap:8px;margin:4px 0 14px}
.recap-tile{border:1px solid var(--line);border-radius:var(--r-sm);background:var(--ink-800);padding:10px 8px;text-align:center}
.recap-tile-ic{display:block;font-size:16px;margin-bottom:4px}
.recap-tile b{display:block;font-family:var(--display);font-size:18px;color:var(--brass-bright)}
.recap-tile span{display:block;font-size:10px;color:var(--paper-faint);text-transform:uppercase;letter-spacing:.03em;margin-top:2px}
.recap-highlights{margin:2px 0 4px;display:flex;flex-direction:column;gap:5px}
.recap-hl{font-size:12.5px;color:var(--paper-dim);background:var(--ink-800);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:6px 10px}
.recap-hl b{color:var(--paper)}
.recap-raw{margin-top:10px}
.recap-raw>summary{cursor:pointer;font-size:12px;color:var(--paper-faint);letter-spacing:.04em;
  text-transform:uppercase;padding:4px 0}
.recap-raw>summary:hover{color:var(--paper-dim)}
.recap-raw .jr-md{margin-top:6px}

/* ---------- death screen (2026-07-10) ----------
   Past the Death Threshold: the sheet mutes its combat controls and the only
   interactive path is the Revivify panel (terms quoted from the spell DB). */
.death-screen{border:2px solid var(--ink-600);border-radius:var(--r);padding:16px 18px;margin-bottom:14px;
  background:linear-gradient(180deg,#101014,var(--ink-850));box-shadow:0 0 30px rgba(0,0,0,.6)}
.ds-hd{display:flex;gap:12px;align-items:center;margin-bottom:10px}
.ds-skull{font-size:34px;filter:grayscale(1) drop-shadow(0 0 8px rgba(0,0,0,.8))}
.ds-title{font-family:var(--display);font-size:22px;letter-spacing:.06em;color:var(--paper-dim)}
.ds-sub{font-size:12px;color:var(--paper-faint)}
.ds-quote{font-size:12px;color:var(--paper-dim);line-height:1.6;border-left:3px solid var(--ink-600);padding-left:10px;margin:6px 0 8px}
.ds-terms{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px}
.ds-apply{display:flex;gap:10px;align-items:center;flex-wrap:wrap;font-size:13px}
.ds-apply input{background:var(--ink-800);color:var(--paper);border:1px solid var(--line-strong);border-radius:5px;padding:5px 7px}
.ds-note{font-size:11px;color:var(--paper-faint);margin-top:8px;line-height:1.5}
.play.char-dead .hp-ctrls,.play.char-dead .ap-track,.play.char-dead [data-a="openRestWizard"]{opacity:.3;pointer-events:none}
.play.char-dead .hp-track{filter:grayscale(.7)}

/* ---------- big moments (C4/C6/C7, Chunk 4 2026-07-09) ----------
   Death's Door spotlight, the Rest wizard cards, and the level-up ceremony. */
.dd-spotlight{border:2px solid var(--ember-deep);border-radius:var(--r);padding:14px 16px;margin-bottom:14px;
  background:linear-gradient(180deg,var(--hp-bg),var(--ink-850));box-shadow:0 0 24px rgba(180,50,30,.25);
  animation:dds-breathe 2.6s ease-in-out infinite}
@keyframes dds-breathe{0%,100%{box-shadow:0 0 18px rgba(180,50,30,.18)}50%{box-shadow:0 0 30px rgba(220,70,40,.35)}}
.dds-hd{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.dds-skull{font-size:30px;filter:drop-shadow(0 0 6px rgba(220,70,40,.6))}
.dds-t{flex:1;min-width:140px}
.dds-t b{font-family:var(--display);font-size:19px;letter-spacing:.08em;color:#f0b6a3}
.dds-sub{display:block;color:var(--paper-dim);font-size:12px}
.dds-bar{position:relative;height:8px;border-radius:5px;background:#3a120e;margin:10px 0 8px;overflow:visible}
.dds-bar i{display:block;height:100%;border-radius:5px;background:linear-gradient(90deg,var(--ember-deep),var(--ember))}
.dds-tick{position:absolute;right:0;top:-3px;bottom:-3px;border-right:2px dashed var(--paper-faint);
  font-size:9px;color:var(--paper-faint);padding-right:4px;line-height:22px}
.dds-chips{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:8px}
.dds-chip{font-size:11px;padding:3px 9px;border-radius:10px;border:1px solid var(--ember-deep);color:#f0b6a3;background:rgba(0,0,0,.25)}
.dds-chip.bleed{border-color:var(--hp);color:#ffd4d0}
.dds-ladder{font-size:11.5px;color:var(--paper-dim);line-height:1.6}
.dds-ladder b{color:var(--paper)}
.dds-help{font-size:11.5px;color:var(--paper-faint);margin-top:5px;border-top:1px solid rgba(255,255,255,.06);padding-top:6px}
@media(prefers-reduced-motion:reduce){.dd-spotlight{animation:none}}

.modal.modal-rest{max-width:560px}
.rw-opt{border:1px solid var(--line);border-radius:var(--r-sm);background:var(--ink-800);padding:10px 12px;margin-bottom:10px}
.rw-hd{display:flex;align-items:center;gap:10px}
.rw-ico{font-size:20px}
.rw-t{flex:1;min-width:0}
.rw-t b{display:block}
.rw-time{font-size:11px;color:var(--paper-faint)}
.rw-list{margin:8px 0 0 20px;padding:0;font-size:12.5px;color:var(--paper-dim);line-height:1.6}
.rw-note{font-size:11px;color:var(--paper-faint);margin-top:6px}

.modal.modal-ceremony{max-width:600px;padding:0;overflow:hidden;animation:cer-in .45s cubic-bezier(.16,.84,.44,1)}
@keyframes cer-in{0%{transform:scale(.92);opacity:0}100%{transform:scale(1);opacity:1}}
.cer-splash{position:relative;text-align:center;padding:30px 20px 22px;
  background:radial-gradient(ellipse at 50% 0%,color-mix(in srgb,var(--accent) 30%,transparent),transparent 70%),linear-gradient(180deg,var(--ink-750),var(--ink-800));
  border-bottom:2px solid var(--accent)}
.cer-kicker{font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--paper-dim)}
.cer-level{font-family:var(--display);font-weight:700;font-size:46px;letter-spacing:.06em;
  color:var(--accent-bright);text-shadow:0 0 28px color-mix(in srgb,var(--accent) 40%,transparent)}
/* [Illuminated Tome 2026-07-10] wrapped in @supports w/ solid fallback above —
   the bare rule this replaced left text invisible (color:transparent) on any
   engine without background-clip:text support. */
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .cer-level{background:linear-gradient(180deg,var(--accent-bright),var(--accent));-webkit-background-clip:text;background-clip:text;color:transparent}
}
.cer-cls{color:var(--paper-dim);font-size:13px;margin-top:2px}
.cer-x{position:absolute;top:10px;right:12px}
.cer-jumps{display:flex;gap:8px;flex-wrap:wrap;margin-top:6px}
.modal-ceremony .modal-bd{padding:16px 20px 18px}
@media(prefers-reduced-motion:reduce){.modal.modal-ceremony{animation:none}}

/* Achievement ceremony (reuses .cer-splash/.modal-ceremony above; achievements
   have no "class" to accent from, so --accent is fixed to the brass/gold that
   already reads as "achievement" via the 🏅 toast icon and locked-skin UI). */
.ach-skin-row{display:flex;align-items:center;gap:12px;margin:8px 0 2px;padding:10px 12px;
  background:var(--ink-800);border:1px solid var(--line);border-radius:var(--r)}
.ach-skin-preview{width:40px;height:40px;border-radius:9px;border:2px solid var(--brass-bright);
  flex:none;position:relative;box-shadow:0 0 0 2px rgba(226,196,120,.2)}
.ach-skin-preview i{position:absolute;width:13px;height:13px;border-radius:50%;left:50%;top:50%;transform:translate(-50%,-50%)}

/* ---------- home dashboard & roster shelf (C1/B4, Chunk 3 2026-07-09) ----------
   The roster is the app's front door: a Continue hero card (accented in the
   character's class color), a recent-highlights strip fed by ⭐/💀 log
   markers, and shelf cards with avatar monograms, level badges and
   last-played lines. */
.home-hero{display:flex;align-items:center;gap:16px;margin:16px 0 6px;padding:16px 18px;
  background:linear-gradient(135deg,var(--ink-800),var(--ink-850));border:1px solid var(--line-strong);
  border-left:4px solid var(--accent);border-radius:var(--r);box-shadow:var(--shadow-sm);flex-wrap:wrap}
.home-hero .hh-main{flex:1;min-width:180px}
.hh-kicker{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--paper-faint)}
.hh-name{font-family:var(--display);font-size:24px;color:var(--accent-bright)}
.hh-sub{color:var(--paper-dim);font-size:13px;margin-top:2px}
.hh-hp{height:6px;border-radius:4px;background:var(--hp-bg);margin-top:8px;max-width:280px;overflow:hidden}
.hh-hp i{display:block;height:100%;background:var(--hp);border-radius:4px}
.hh-actions{display:flex;gap:8px;flex-wrap:wrap}
.hl-strip{margin:10px 0 4px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--ink-800);padding:8px 12px}
.hl-title{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--paper-faint);margin-bottom:4px}
.hl-row{display:flex;gap:8px;align-items:baseline;padding:4px 0;font-size:13px;cursor:pointer;border-radius:5px}
.hl-row:hover{background:var(--ink-750)}
.hl-row .hl-msg{color:var(--paper-dim);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}
.hl-row .hl-when{color:var(--paper-faint);font-size:11px;flex-shrink:0}
.party-strip{margin:10px 0 4px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--ink-800);padding:8px 12px;display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.party-strip .hl-title{width:100%;margin-bottom:2px}
.ps-chip{display:flex;align-items:center;gap:7px;padding:4px 10px;border:1px solid var(--line-strong);border-left:3px solid var(--accent);border-radius:8px;cursor:pointer;font-size:12px;background:var(--ink-750)}
.ps-chip:hover{background:var(--ink-700)}
.ps-hp{width:52px;height:5px;border-radius:3px;background:var(--hp-bg);overflow:hidden}
.ps-hp i{display:block;height:100%;background:var(--hp)}
.ps-num{color:var(--paper-faint);font-size:10.5px}
.pc-head{display:flex;gap:10px;align-items:center;min-width:0}
.pc-head>div{min-width:0}
.pc-ava{width:44px;height:44px;border-radius:10px;flex-shrink:0;overflow:hidden;
  border:1px solid var(--line-strong);background:var(--ink-700)}
.pc-ava img{width:100%;height:100%;object-fit:cover;display:block}
.pc-ava.mono{display:flex;align-items:center;justify-content:center;font-family:var(--display);
  font-size:20px;font-weight:700;color:var(--accent-bright);
  background:linear-gradient(135deg,var(--ink-700),var(--ink-800));border-color:var(--accent)}
.pc-ava.lg{width:64px;height:64px;border-radius:14px;font-size:30px}
.pc-lvl{display:inline-block;font-size:10.5px;font-weight:700;font-family:var(--body);
  color:var(--accent-bright);border:1px solid var(--accent);border-radius:10px;
  padding:1px 7px;vertical-align:2px;margin-left:4px}
.pc-meta{color:var(--paper-faint);font-size:11px;margin-top:3px}
@media(max-width:600px){.home-hero{gap:10px;padding:12px}.hh-name{font-size:20px}.hh-actions{width:100%}}

/* ---------- class accents (B1, Chunk 2 2026-07-09) ----------
   applyAccent() sets --accent/--accent-bright inline per character; these
   rules decide where the tint shows. Deliberately restrained: card edge,
   section titles, AP pips, active feature-box edges. */
.pc-card.accented{border-left:3px solid var(--accent)}
.play.accented .section-title{color:var(--accent-bright)}
.play.accented .feature-box{border-left:3px solid var(--accent)}
.play.accented .ap-pip.active{border-color:var(--accent);color:var(--accent-bright)}
.play.accented .play-identity b{color:var(--accent-bright)}

/* ---------- dice-skin swatches (A3, Chunk 2 2026-07-09) ---------- */
.dr-skins{display:flex;flex-wrap:wrap;gap:5px;align-items:center}
.dr-skin{width:24px;height:24px;border-radius:6px;border:2px solid var(--line);cursor:pointer;position:relative;padding:0}
.dr-skin:hover{border-color:var(--brass)}
.dr-skin.on{border-color:var(--brass-bright);box-shadow:0 0 0 2px rgba(226,196,120,.25)}
.dr-skin i{position:absolute;width:8px;height:8px;border-radius:50%;left:50%;top:50%;transform:translate(-50%,-50%);pointer-events:none}

/* ---------- event stingers (A5, Chunk 2 2026-07-09) ----------
   Body-class pulses reusing the fx-pulse keyframes; distinct tint per event.
   Same gates as the crit ceremony (fxLevel + prefers-reduced-motion). */
body.fx-sting-level::after{content:'';position:fixed;inset:0;pointer-events:none;z-index:9997;
  background:radial-gradient(ellipse at center,rgba(226,196,120,.20),transparent 60%);animation:fx-pulse 900ms ease-out forwards}
body.fx-sting-death::after{content:'';position:fixed;inset:0;pointer-events:none;z-index:9997;
  background:radial-gradient(ellipse at center,transparent 40%,rgba(140,20,20,.28) 100%);animation:fx-pulse 950ms ease-out forwards}
body.fx-sting-reprieve::after{content:'';position:fixed;inset:0;pointer-events:none;z-index:9997;
  background:radial-gradient(ellipse at center,rgba(95,174,114,.18),transparent 60%);animation:fx-pulse 850ms ease-out forwards}
body.fx-sting-rest::after{content:'';position:fixed;inset:0;pointer-events:none;z-index:9997;
  background:radial-gradient(ellipse at center,rgba(91,139,208,.16),transparent 60%);animation:fx-pulse 900ms ease-out forwards}
body.fx-sting-foe::after{content:'';position:fixed;inset:0;pointer-events:none;z-index:9997;
  background:rgba(10,10,14,.20);animation:fx-pulse 600ms ease-out forwards}

/* ---------- crit ceremony (A2, 2026-07-09) ----------
   Pure presentation for nat 20 / nat 1. Everything here is behind the ✨
   Full-effects setting (fxLevel() in dc20-play.js) AND prefers-reduced-motion,
   and auto-removes itself — no persistent DOM. Colors ride the theme vars so
   every page theme celebrates in its own palette. */
.fx-burst{position:fixed;inset:0;pointer-events:none;z-index:9998;overflow:hidden}
.fx-burst i{position:absolute;left:50%;top:55%;width:7px;height:7px;border-radius:2px;
  background:var(--brass-bright);box-shadow:0 0 6px var(--brass-bright);
  animation:fx-ember var(--dur,900ms) cubic-bezier(.16,.84,.44,1) forwards}
.fx-burst i.em2{background:var(--ember);box-shadow:0 0 6px var(--ember);width:5px;height:5px}
@keyframes fx-ember{
  0%{opacity:1;transform:translate(-50%,-50%) rotate(0)}
  70%{opacity:.9}
  100%{opacity:0;transform:translate(calc(-50% + var(--dx)),calc(-50% + var(--dy))) rotate(var(--rot))}}
body.fx-crit-pulse::after{content:'';position:fixed;inset:0;pointer-events:none;z-index:9997;
  background:radial-gradient(ellipse at center,color-mix(in srgb,var(--brass-bright) 24%,transparent),transparent 62%);
  animation:fx-pulse 900ms ease-out forwards}
body.fx-fumble-flash::after{content:'';position:fixed;inset:0;pointer-events:none;z-index:9997;
  background:rgba(8,8,12,.42);backdrop-filter:saturate(.35);-webkit-backdrop-filter:saturate(.35);
  animation:fx-pulse 750ms ease-out forwards}
@keyframes fx-pulse{0%{opacity:0}16%{opacity:1}100%{opacity:0}}
.rl-star, .rl-skull{font-size:11px}
@media(prefers-reduced-motion:reduce){
  .fx-burst, body.fx-crit-pulse::after, body.fx-fumble-flash::after,
  body.fx-sting-level::after, body.fx-sting-death::after, body.fx-sting-reprieve::after,
  body.fx-sting-rest::after, body.fx-sting-foe::after{display:none!important;animation:none!important}
}

.resbank{display:grid;grid-template-columns:repeat(auto-fit,minmax(90px,1fr));gap:10px;margin-bottom:18px}
.resbank .rb{border:1px solid var(--line);border-radius:var(--r-sm);padding:11px;text-align:center;background:var(--ink-800)}
.resbank .rb .rv{font-family:var(--mono);font-size:24px;font-weight:600}
.resbank .rb.mp .rv{color:var(--mp)} .resbank .rb.sp .rv{color:var(--sp)} .resbank .rb.grit .rv{color:var(--grit)}
.resbank .rb .rk{font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--paper-faint);margin-top:2px}
.resbank .rb .step{display:flex;justify-content:center;gap:6px;margin-top:8px}
.resbank .rb .step button{width:26px;height:26px;border-radius:6px;border:1px solid var(--line-strong);background:var(--ink-700);color:var(--paper);cursor:pointer}
.cond-grid{display:flex;flex-wrap:wrap;gap:6px}
.cond{padding:5px 11px;border-radius:20px;border:1px solid var(--line);background:var(--ink-800);font-size:12.5px;cursor:pointer;color:var(--paper-dim)}
.cond.on{background:var(--ember-deep);border-color:var(--ember);color:#fff}
/* A2 — conditions bar near HP + collapsible panel */
.cond-bar{display:flex;flex-wrap:wrap;align-items:center;gap:7px;margin:8px 0}
.cond-toggle{display:inline-flex;align-items:center;gap:7px;padding:6px 12px;border-radius:20px;
  border:1px solid var(--line);background:var(--ink-800);color:var(--paper-dim);font-size:13px;cursor:pointer;
  font-family:inherit;transition:background .12s,border-color .12s}
.cond-toggle:hover{background:var(--ink-750);border-color:var(--line-strong)}
.cond-toggle.open{border-color:var(--ember);color:var(--paper)}
.cond-toggle .ct-ico{color:var(--ember)}
.cond-toggle .ct-caret{font-size:9px;color:var(--paper-faint)}
.cond-count{display:inline-grid;place-items:center;min-width:18px;height:18px;padding:0 5px;border-radius:9px;
  background:var(--ember);color:#fff;font-family:var(--mono);font-size:11px;font-weight:700}
.cond-chip{display:inline-flex;align-items:center;gap:5px;padding:4px 9px;border-radius:20px;
  background:var(--ember-deep);border:1px solid var(--ember);color:#fff;font-size:12px;cursor:pointer}
.cond-chip b{font-family:var(--mono);font-size:11px}
.cond-chip .cc-x{color:rgba(255,255,255,.55);font-size:10px}
.cond-chip:hover .cc-x{color:#fff}
.cond-none{color:var(--paper-faint);font-size:12px;font-style:italic}
.cond-panel{border:1px solid var(--line);border-radius:var(--r);background:var(--ink-850);padding:12px;margin:4px 0 10px}
.cond-detail{margin-top:10px;border-top:1px solid var(--line);padding-top:10px;display:flex;flex-direction:column;gap:8px}
.cond-detail-row .cdr-name{font-weight:600;color:var(--ember);font-size:13px}
.cond-detail-row .cdr-desc{color:var(--paper-dim);font-size:12.5px;margin-top:2px}
.dice{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:12px}
.dice button{padding:8px 12px;border-radius:var(--r-sm);border:1px solid var(--line-strong);background:var(--ink-700);color:var(--paper);cursor:pointer;font-family:var(--mono);font-size:13px}
.dice button:hover{border-color:var(--brass);color:var(--brass-bright)}
.roll-log{background:var(--ink-900);border:1px solid var(--line);border-radius:var(--r-sm);padding:10px;height:160px;overflow-y:auto;font-family:var(--mono);font-size:12.5px}
.roll-log .r{padding:4px 2px;border-bottom:1px solid var(--line);display:flex;justify-content:space-between;gap:8px}
.roll-log .r .tot{color:var(--brass-bright);font-weight:600}
.roll-log .r.crit .tot{color:var(--sp)} .roll-log .r.fail .tot{color:var(--hp)}
.section-title{font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--paper-faint);
  margin:18px 0 10px;font-weight:600;display:flex;align-items:center;gap:10px}
.section-title::after{content:"";flex:1;height:1px;background:var(--line)}
.mast-subhead{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--brass);
  font-weight:600;margin:14px 0 8px;display:flex;align-items:center;gap:8px}
.mast-subhead::after{content:"";flex:1;height:1px;background:var(--line)}

/* sheet (review) */
.sheet-grid{display:grid;grid-template-columns:1fr;gap:16px}
.sheet-card{background:var(--ink-800);border:1px solid var(--line);border-radius:var(--r);padding:16px 18px}
.sheet-card h4{font-size:13px;letter-spacing:.12em;text-transform:uppercase;color:var(--brass);margin-bottom:12px;font-family:var(--body);font-weight:600}
.sheet-card .kv{display:flex;justify-content:space-between;padding:5px 0;border-bottom:1px solid var(--line);font-size:13.5px}
.sheet-card .kv:last-child{border:none}
.sheet-card .kv b{font-family:var(--mono)}
.feat-item{padding:10px 0;border-bottom:1px solid var(--line)}
.feat-item:last-child{border:none}
.feat-item .fn{font-weight:600;color:var(--paper);font-family:var(--display);font-size:15px}
.feat-item .fd{font-size:13px;color:var(--paper-dim);margin-top:4px;white-space:pre-wrap}

.toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);background:var(--ink-700);
  border:1px solid var(--brass-deep);border-radius:var(--r-sm);padding:11px 20px;color:var(--paper);
  box-shadow:var(--shadow);z-index:200;font-size:14px;animation:toastin .25s}
@keyframes toastin{from{opacity:0;transform:translate(-50%,12px)}to{opacity:1;transform:translate(-50%,0)}}

/* [A11y 2026-09-18] Screen-reader-only announcer nodes (HP/AP/resource/roll/
   condition narration) -- visible-content clipped but still in the a11y tree,
   the standard "sr-only" pattern. Not display:none (that would hide it from
   assistive tech too). */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}

.note{background:var(--ink-800);border-left:3px solid var(--brass);border-radius:var(--r-sm);padding:11px 14px;font-size:13px;color:var(--paper-dim);margin:14px 0}
.note b{color:var(--brass-bright)}
/* [Export nudge 2026-09-06] LAN/local-mode backup reminder on the roster screen */
.export-nudge{display:flex;align-items:flex-start;gap:12px;
  background:var(--ink-800);border-left:3px solid var(--hp);border-radius:var(--r-sm);
  padding:12px 14px;margin:14px 0}
.export-nudge .en-icon{flex:0 0 auto;padding-top:1px}
.export-nudge .en-icon .vx-icon{width:18px;height:18px;display:inline-block}
.export-nudge .en-body{flex:1;min-width:0}
.export-nudge .en-body b{color:var(--paper);font-size:13.5px}
.export-nudge .en-body p{margin:3px 0 0;font-size:12.5px;color:var(--paper-dim)}
.export-nudge .en-actions{flex:0 0 auto;display:flex;gap:6px;flex-wrap:wrap;align-items:center}
@media(max-width:600px){.export-nudge{flex-wrap:wrap}.export-nudge .en-actions{width:100%}}
.warn-note{border-left-color:var(--warn)}

/* ---------- responsive restores (mobile-first) ---------- */
/* Layouts above are authored mobile-first. These min-width queries progressively
   restore the roomier multi-column desktop arrangements. Play mode has its own
   mobile-first system earlier in this file and is intentionally untouched here. */
@media(min-width:600px){
  .attr-edit{grid-template-columns:repeat(4,1fr)}
}
@media(min-width:760px){
  .sheet-grid{grid-template-columns:1fr 1fr}
}
@media(min-width:1024px){
  /* Builder returns to the 3-column workspace: step nav | stage | live ledger. */
  .builder{display:grid;grid-template-columns:236px 1fr 320px;overflow:hidden}
  .stepnav{
    flex-direction:column;gap:0;overflow-x:visible;overflow-y:auto;
    padding:16px 12px;border-right:1px solid var(--line);border-bottom:none;
    position:static;scrollbar-width:thin
  }
  .stepnav::-webkit-scrollbar{display:block}
  .stepnav .step{white-space:normal;margin-bottom:2px}
  .stage{padding:26px 32px;overflow-y:auto}
  .pool-bar{margin-left:-32px;margin-right:-32px;padding-left:32px;padding-right:32px;top:0}
  .ledger{border-left:1px solid var(--line);border-top:none;overflow-y:auto}
}
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ============================================================
   v23 additions — mastery, subclass, paths, AP tracker, feature panels
   ============================================================ */
/* mastery row pips (5-level) */
.pip.m1{background:var(--sp);border-color:var(--sp)}
.pip.m2{background:#5ba8d0;border-color:#5ba8d0}
.pip.m3{background:#9d5bd0;border-color:#9d5bd0}
.pip.m4{background:var(--brass);border-color:var(--brass)}
.pip.m5{background:var(--ember);border-color:var(--ember)}
.mast-row .tier{font-size:11px;color:var(--paper-faint);width:80px;text-align:right;font-family:var(--mono)}
.mast-row .tier.cap{color:var(--brass-bright)}
.knowledge-tag{font-size:10px;padding:1px 6px;border-radius:10px;background:var(--mp-bg);color:var(--mp);border:1px solid var(--mp-bg)}

/* sub-choice panel (inline trait/feature pick) */
.subchoice{background:var(--ink-750);border:1px solid var(--brass-deep);border-radius:var(--r-sm);padding:12px 14px;margin:8px 0 4px}
.subchoice .sc-prompt{font-size:12px;color:var(--brass-bright);font-weight:600;margin-bottom:8px;letter-spacing:.06em}
.sc-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:6px}
.sc-opt{background:var(--ink-800);border:1px solid var(--line);border-radius:var(--r-sm);padding:7px 9px;cursor:pointer;font-size:12.5px;transition:border-color .12s}
.sc-opt:hover{border-color:var(--brass-deep)}
.sc-opt.sel{border-color:var(--brass);background:var(--ink-700)}
.sc-opt .sv{font-weight:600;color:var(--paper)}
.sc-opt .sd{font-size:11px;color:var(--paper-faint);margin-top:3px}
.sc-group{margin-bottom:10px}
.sc-group:last-child{margin-bottom:0}
.sc-group-label{font-size:10.5px;color:var(--paper-faint);text-transform:uppercase;letter-spacing:.12em;font-weight:600;margin-bottom:5px}
.sc-grid-compact{grid-template-columns:repeat(auto-fill,minmax(120px,1fr))}

/* subclass cards */
.sub-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:10px}
.sub-card{background:var(--ink-800);border:1px solid var(--line);border-radius:var(--r-sm);padding:14px;cursor:pointer;transition:border-color .12s}
.sub-card:hover{border-color:var(--brass-deep)}
.sub-card.sel{border-color:var(--brass);background:linear-gradient(180deg,var(--ink-750),var(--ink-800))}
.sub-card.sel::after{content:"✓";float:right;color:var(--brass-bright);font-weight:700}
.sub-card .sn{font-family:var(--display);font-size:15px}
.sub-card .sd{font-size:12px;color:var(--paper-dim);margin-top:4px}

/* path chips */
.path-chip{display:flex;align-items:center;gap:10px;background:var(--ink-800);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:10px 14px;cursor:pointer;transition:border-color .12s}
.path-chip:hover{border-color:var(--brass-deep)}
.path-chip.sel.martial{border-color:var(--sp);background:var(--sp-bg)}
.path-chip.sel.caster{border-color:var(--mp);background:var(--mp-bg)}
.path-chip .pn{font-weight:600;flex:1}
.path-chip .pd{font-size:12px;color:var(--paper-faint)}
.path-slot{width:18px;height:18px;border-radius:4px;border:1px solid var(--line-strong);background:var(--ink-700)}
.path-slot.filled.martial{background:var(--sp);border-color:var(--sp)}
.path-slot.filled.caster{background:var(--mp);border-color:var(--mp)}

/* AP tracker (play mode) */
.ap-track{display:flex;gap:6px;margin-bottom:12px;justify-content:center}
.ap-pip{width:38px;height:38px;border-radius:9px;border:1px solid var(--line-strong);background:var(--ink-800);
  display:grid;place-items:center;font-family:var(--mono);font-size:11px;cursor:pointer;transition:background .12s}
.ap-pip.used{background:var(--ink-600);border-color:var(--line);opacity:.45}
.ap-pip.active{background:linear-gradient(180deg,var(--brass),var(--brass-deep));border-color:var(--brass);color:#1a1404}
.ap-pip.max-cap{border-color:var(--ember);opacity:.3}

/* roll-vs-defense input */
.hit-badge{font-size:11px;padding:2px 8px;border-radius:12px;font-weight:600}
.hit-badge.hit{background:var(--sp-bg);color:var(--sp);border:1px solid var(--sp)}
.hit-badge.heavy{background:#2a1f0a;color:var(--warn);border:1px solid var(--warn)}
.hit-badge.brutal{background:var(--hp-bg);color:var(--hp);border:1px solid var(--hp)}
.hit-badge.crit{background:#1a1228;color:#b79de0;border:1px solid #7b6fd4}
.hit-badge.miss{background:var(--ink-800);color:var(--paper-faint);border:1px solid var(--line)}

/* undo button */

/* stacking condition value */
.cond-x{font-family:var(--mono);font-size:11px;margin-left:3px;color:var(--ember)}

/* ── Party Dashboard ── */
.party-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:14px;margin-top:4px}
.party-card{background:linear-gradient(180deg,var(--ink-800),var(--ink-850));border:1px solid var(--line);border-radius:var(--r);padding:16px;position:relative;overflow:hidden}
.party-card::before{content:"";position:absolute;inset:0 0 auto 0;height:3px;background:linear-gradient(90deg,var(--brass),transparent)}
.party-name{font-family:var(--display);font-size:18px;margin-bottom:2px}
.party-sub{color:var(--paper-faint);font-size:12px;margin-bottom:10px}
.party-hp{margin-bottom:10px}
.party-hp-nums{display:flex;align-items:baseline;gap:5px;margin-bottom:4px}
.party-hp-nums span{font-family:var(--mono);font-size:22px;font-weight:600;color:var(--hp)}
.party-hp-nums .of{font-size:14px;color:var(--paper-faint)}
.party-hp-nums .thp{font-size:13px;color:var(--mp)}
.party-hp-nums .dead{color:var(--ember);animation:pulse 1.5s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}
.party-bar{height:8px;background:var(--ink-900);border-radius:4px;overflow:hidden;border:1px solid #43221f}
.party-bar .fill{height:100%;transition:width .3s}
.party-resources{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}
.pr{font-size:12px;color:var(--paper-faint);background:var(--ink-700);border:1px solid var(--line);border-radius:5px;padding:3px 8px}
.pr b{color:var(--paper);font-family:var(--mono)}
.pr.sp b{color:var(--sp)} .pr.mp b{color:var(--mp)}
.party-stats{display:flex;gap:8px;font-size:11px;color:var(--paper-faint);font-family:var(--mono);margin-bottom:8px;flex-wrap:wrap}
.party-conds{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:8px}
.party-actions{display:flex;justify-content:flex-end}

/* ── Level-up attention badges ── */
.step.needs-review .lbl{color:var(--brass-bright)}
.step.needs-review .n{border-color:var(--brass);background:rgba(184,142,68,.15);color:var(--brass-bright)}
.rev-badge{display:inline-block;margin-left:4px;font-size:10px;background:var(--brass);color:var(--ink-900);border-radius:3px;padding:0 4px;font-weight:700;vertical-align:middle;line-height:16px}

/* ── 3D Dice System ─────────────────────────────────────────────────────── */
/* @keyframes cubeRoll removed with the dead .dice-3d cube rules (Risk 5) */

/* ── Interactive Character Sheet ────────────────────────────────────────── */
.play-identity{display:flex;align-items:flex-start;gap:12px;padding:0 0 12px;border-bottom:1px solid var(--line);margin-bottom:12px}
.pi-portrait-slot{position:relative;flex-shrink:0}
.pi-portrait{width:72px;height:96px;object-fit:cover;border-radius:6px;border:2px solid var(--line);display:block}
.pi-portrait-placeholder{width:72px;height:96px;border-radius:6px;border:2px dashed var(--line);
  background:var(--ink-800);display:flex;flex-direction:column;align-items:center;
  justify-content:center;font-size:22px;color:var(--paper-faint);gap:3px;cursor:pointer;text-align:center}
.pi-portrait-placeholder span{font-size:10px;letter-spacing:.02em}
.pi-portrait-badge{position:absolute;bottom:2px;right:2px;background:rgba(0,0,0,.7);border-radius:4px;
  font-size:14px;cursor:pointer;padding:2px 4px;opacity:.7;transition:opacity .15s}
.pi-portrait-badge:hover{opacity:1}
.pi-info{flex:1;min-width:0}
.pi-name{font-family:var(--display);font-size:20px;font-weight:700;color:var(--paper);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pi-sub{font-size:12px;color:var(--paper-dim);margin-top:2px}
.pi-stats{display:flex;flex-wrap:wrap;gap:8px;margin-top:6px}
.pi-stats span{font-size:12px;color:var(--paper-faint);white-space:nowrap}

/* Attribute cards */

/* Skill list */
.skill-play-row{display:flex;align-items:center;gap:8px;padding:5px 8px;border-radius:6px;cursor:pointer;
  border:1px solid transparent;transition:background .12s,border-color .12s;font-size:13px}
.skill-play-row:hover{background:var(--ink-800);border-color:var(--line)}
.skill-play-row:active{background:var(--ink-750)}
.spr-name{flex:1;font-weight:500}
.spr-mod{width:36px;text-align:right;font-variant-numeric:tabular-nums}
.spr-roll{width:16px;opacity:0;transition:opacity .12s}
.skill-play-row:hover .spr-roll{opacity:1}
.spr-pips{width:52px;font-size:9px}

/* ── AI Portrait / Appearance ───────────────────────────────────────────── */
.appearance-wrap{display:grid;grid-template-columns:160px 1fr;gap:16px;margin:12px 0}
.portrait-col{display:flex;flex-direction:column;gap:6px;align-items:center}
.portrait-img{width:160px;height:210px;object-fit:cover;border-radius:8px;
  border:2px solid var(--line);display:block;box-shadow:var(--shadow)}
.portrait-placeholder{width:160px;height:210px;border-radius:8px;
  border:2px dashed var(--line);background:var(--ink-800);
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  font-size:32px;gap:8px;color:var(--paper-faint);text-align:center}
.portrait-placeholder.play{width:100%;height:160px;font-size:28px}
.portrait-placeholder span{font-size:12px}
.portrait-spinner{width:36px;height:36px;border:3px solid var(--line);
  border-top-color:var(--brass-bright);border-radius:50%;
  animation:spin .7s linear infinite;margin-bottom:6px}
@keyframes spin{to{transform:rotate(360deg)}}
.portrait-regen{width:100%}
.portrait-desc-col{display:flex;flex-direction:column;gap:4px}
.portrait-desc{width:100%;background:var(--ink-800);color:var(--paper);
  border:1px solid var(--line);border-radius:6px;padding:8px 10px;
  font-size:13px;line-height:1.5;resize:vertical;font-family:inherit}
.portrait-desc:focus{outline:none;border-color:var(--brass)}
/* Mobile appearance layout */
@media(max-width:580px){
  .appearance-wrap{grid-template-columns:1fr}
  .portrait-col{flex-direction:row;flex-wrap:wrap}
  .portrait-img, .portrait-placeholder{width:120px;height:160px}
}

/* portrait management bar in play side panel */

/* ── Weapon damage table (play mode) ────────────────────────────────────── */
.weapon-list{display:flex;flex-direction:column;gap:10px;margin:4px 0}
.weapon-card{background:var(--ink-800);border:1px solid var(--line);border-radius:8px;padding:10px 12px;display:flex;flex-direction:column;gap:6px}
.weapon-atk-row{display:flex;align-items:center;flex-wrap:wrap;gap:6px}
.weapon-nm{font-weight:700;font-size:14px}
.weapon-sub{font-size:11px;color:var(--paper-faint)}
.weapon-dmg-table{display:grid;grid-template-columns:repeat(5,1fr);gap:4px;margin-top:4px}
@media(max-width:600px){
  .weapon-dmg-table{grid-template-columns:repeat(3,1fr)}
  .dt-label{white-space:normal;overflow:visible}
}
.dt-col{background:var(--ink-850);border-radius:5px;padding:5px 4px;text-align:center;border:1px solid var(--line)}
.dt-label{font-size:10px;color:var(--paper-faint);margin-bottom:3px;white-space:nowrap;overflow:hidden}
.dt-val{font-size:16px;font-weight:800;font-variant-numeric:tabular-nums}
.dmg-miss .dt-val{color:var(--paper-faint);font-size:13px}
.dmg-hit .dt-val{color:var(--paper)}
.dmg-heavy{border-color:var(--brass)}
.dmg-heavy .dt-val{color:var(--brass-bright)}
.dmg-brutal{border-color:var(--sp)}
.dmg-brutal .dt-val{color:var(--sp)}
.dmg-crit{border-color:var(--hp);background:rgba(192,57,43,.08)}
.dmg-crit .dt-val{color:var(--hp);font-size:13px}
.weapon-dr-note{font-size:10px;color:var(--paper-faint);margin-top:2px;text-align:center;font-style:italic}

/* ── Attack enhancement modal rows ─────────────────────────────────────── */
.atk-enh-row{display:flex;align-items:flex-start;gap:10px;padding:8px 6px;margin:4px 0;background:var(--ink-850);border-radius:7px}
.enh-count-ctrl{display:flex;align-items:center;gap:4px;flex-shrink:0}
.enh-count{display:inline-block;min-width:28px;text-align:center;font-size:16px;font-weight:800}
.enh-rs-toggle{display:flex;gap:3px;flex-shrink:0;margin-top:2px}
.enh-rs-toggle .btn{padding:3px 8px;font-size:11px}

/* ── Adventuring Supplies list ─────────────────────────────────────────── */
.supplies-list{display:flex;flex-direction:column;gap:8px;margin:4px 0}
.supply-row{background:var(--ink-800);border:1px solid var(--line);border-radius:6px;padding:8px 10px}
.supply-hd{display:flex;align-items:center;gap:8px;margin-bottom:4px;flex-wrap:wrap}
.supply-nm{font-weight:700;font-size:13px}
.supply-price{color:var(--brass-bright);font-family:var(--mono);font-size:12px;margin-left:auto}
.supply-desc{font-size:12px;color:var(--paper-dim);line-height:1.45}

/* ── Responsive: mobile-first play layout above is authoritative ── */

/* ── Inventory list ──────────────────────────────────────────────────────── */
.inv-list{display:flex;flex-direction:column;gap:4px;margin:4px 0 12px}
.inv-row{display:flex;align-items:center;gap:8px;padding:7px 10px;background:var(--ink-800);border:1px solid var(--line);border-radius:6px;font-size:13px}
.inv-name{font-weight:600}
.inv-qty{color:var(--brass-bright);font-family:var(--mono);font-weight:700}
.inv-uses{color:var(--paper-faint);font-size:11px}

/* ── Mobile-friendly tap targets ─────────────────────────────────────────── */
@media(max-width:780px){
  .btn{min-height:38px;padding:8px 12px;font-size:14px}
  .btn.sm{min-height:32px;padding:6px 10px;font-size:13px}
  .chip{min-height:28px;font-size:13px}
  .skill-play-row{padding:8px}
  /* In a single-column layout on mobile, attributes stay 2x2 instead of stretching wide */
  /* Skills become 2-column on mobile too for better space use */
}

/* ── Trades section (mirrors skill list) ────────────────────────────────── */

/* ── Roster controls (search + sort) ────────────────────────────────────── */
.roster-ctrls{display:flex;gap:10px;align-items:center;margin:12px 0 8px;flex-wrap:wrap}
.roster-ctrls input.search{background:var(--ink-800);color:var(--paper);border:1px solid var(--line);border-radius:6px;padding:8px 12px;font-size:14px}
.roster-ctrls input.search:focus{outline:none;border-color:var(--brass)}


/* Theme picker chip group */
/* [UX 2026-07-03] Theme dropdown — current icon toggles a menu (scales to any theme count) */
.theme-dd{position:relative;display:inline-flex}
.theme-dd-btn{background:var(--ink-800);border:1px solid var(--line);border-radius:6px;
  padding:5px 10px;font-size:14px;cursor:pointer;color:var(--paper-dim);line-height:1}
.theme-dd-btn:hover{border-color:var(--brass);color:var(--paper)}
.theme-dd-menu{position:absolute;top:calc(100% + 6px);right:0;z-index:9500;min-width:150px;
  background:var(--ink-850);border:1px solid var(--line-strong);border-radius:8px;padding:6px;
  box-shadow:0 8px 24px rgba(0,0,0,.5);display:flex;flex-direction:column;gap:2px}
.theme-dd-menu button{display:flex;align-items:center;gap:8px;background:transparent;border:none;
  color:var(--paper-dim);padding:7px 10px;font-size:12.5px;border-radius:5px;cursor:pointer;
  font-family:inherit;text-align:left;width:100%}
.theme-dd-menu button:hover{background:var(--ink-700);color:var(--paper)}
.theme-dd-menu button.on{background:var(--brass);color:var(--ink-900);font-weight:700}

/* [Dice polish 2026-07-03] roller style/sound selectors */
.dr-style-row{display:flex;gap:6px;margin:4px 0}
.dr-style-row select{flex:1;background:var(--ink-800);color:var(--paper-dim);border:1px solid var(--line);
  border-radius:5px;font-size:11px;padding:4px 6px;font-family:inherit;min-width:0}

/* [Onboarding 2026-07-03] Guided-mode explainer note — sticky so it follows
   the user down long steps [UX 2026-07-03] */
.guide-note{border-left:3px solid var(--brass);background:var(--ink-850);
  font-size:13px;line-height:1.6;padding:10px 12px;margin-bottom:10px;
  position:sticky;top:8px;z-index:80;box-shadow:0 4px 14px rgba(0,0,0,.35)}

/* [UX 2026-07-03] Floating remaining-points HUD — always in view while scrolling */
.points-hud{position:fixed;left:14px;bottom:16px;z-index:8100;display:flex;flex-direction:column;gap:4px;
  background:var(--ink-850);border:1px solid var(--line-strong);border-radius:10px;padding:8px 10px;
  box-shadow:0 6px 20px rgba(0,0,0,.45);min-width:120px}
.points-hud .ph-row{display:flex;align-items:center;gap:8px}
.points-hud .ph-n{font-family:var(--mono);font-size:16px;font-weight:700;min-width:24px;text-align:center;
  color:var(--brass-bright)}
.points-hud .ph-row.done .ph-n{color:var(--ok)}
.points-hud .ph-row.over .ph-n{color:var(--bad)}
.points-hud .ph-l{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--paper-faint)}
.points-hud .ph-row.over .ph-l{color:var(--bad)}
@media(max-width:780px){.points-hud{left:8px;bottom:calc(72px + env(safe-area-inset-bottom,0))}}

/* [Review overhaul 2026-07-03] clickable review items */
.review-click{cursor:pointer;transition:border-color .12s,background .12s}
.review-click:hover{border-color:var(--brass);background:var(--ink-750)}
.rd-hint{color:var(--brass);font-size:11px}
.review-pick-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:6px}

/* ── Death's Door dramatic display ─────────────────────────────────────── */
.hp-track.deaths-door{animation:dd-pulse 1.8s ease-in-out infinite}
@keyframes dd-pulse{
  0%,100%{box-shadow:0 0 0 0 rgba(212,80,74,0)}
  50%{box-shadow:0 0 24px 4px rgba(212,80,74,.35)}
}
/* ── Log filter chips ───────────────────────────────────────────────────── */
.log-filters{display:flex;gap:3px;flex-wrap:wrap;margin:6px 0 4px;align-items:center}
.chip.xs{padding:3px 8px;font-size:10px;border-radius:4px;cursor:pointer;
  background:var(--ink-800);border:1px solid var(--line);color:var(--paper-dim)}
.chip.xs.on{background:var(--brass-deep);color:var(--brass-bright);border-color:var(--brass)}
.chip.xs:hover:not(.on){background:var(--ink-700);color:var(--paper)}

/* ── Print Stylesheet ────────────────────────────────────────────────────── */
@media print{
  @page{margin:0.5in;size:letter portrait}
  body{background:white!important;color:black!important;font-size:11pt}
  /* Hide app chrome */
  .topbar, .brand, .partytoggle, #playtoggle, .roster-hd, .pc-actions, .dice, .roll-log, .log-filters, #customroll, .browser-toolbar, .play-actions-menu, .cond-grid, button, .btn, .chip{display:none!important}
  /* Layout for printing */
  .play{display:block!important;background:white!important}
  .play-left, .play-main{display:block!important;width:100%!important;
    background:white!important;color:black!important;border:none!important;
    padding:8pt!important;overflow:visible!important}
  /* Text colors */
  *{color:black!important;background:transparent!important;
    box-shadow:none!important;text-shadow:none!important}
  .section-title{font-weight:700;font-size:14pt;border-bottom:1px solid black;
    margin:8pt 0 4pt;padding-bottom:2pt;display:block!important}
  /* Show key stat boxes plainly */
  .rb, .pool, .skill-play-row, .weapon-card{
    border:1px solid black!important;background:white!important;
    padding:4pt!important;margin:2pt 0!important}
  /* Compact attribute grid */
  /* Skills list as 2-col */
  /* Print-only character header */
  .play-identity{display:flex!important;align-items:flex-start;gap:12pt;
    border-bottom:2px solid black!important;padding-bottom:8pt!important;margin-bottom:8pt!important}
  .pi-portrait{width:1.2in!important;height:1.5in!important;
    border:1px solid black!important;display:block!important}
  .pi-portrait-placeholder, .pi-portrait-badge{display:none!important}
  .pi-name{font-size:18pt!important;font-weight:700!important}
  /* Page break hints */
  .play-left{page-break-after:always}
}

/* ── Print Cards overlay (item #15, sub-feature 3) ──────────────────────────
   Browser-printable spell/maneuver reference cards — a dedicated view, not a
   form-fill PDF (variable-length rules text doesn't fit the pdf-lib fixed-field
   sheet). Screen mode: full-viewport scrollable overlay. Print mode: only this
   overlay is shown (everything else, including the Play print stylesheet
   above, is suppressed via the body.printing-cards toggle); one card per
   ~1/3 page in a 3-column grid, page-break-inside:avoid so a card never splits
   across pages. */
.print-cards-overlay{position:fixed;inset:0;z-index:9999;background:var(--ink-900);
  overflow:auto;padding:24px}
.print-cards-toolbar{display:flex;align-items:center;gap:10px;margin-bottom:14px}
.print-cards-note{margin-bottom:14px}
.print-card-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:18px}
.print-card{border:1px solid var(--line);border-radius:6px;padding:10px;background:var(--ink-800)}
.pc-hd{display:flex;justify-content:space-between;align-items:baseline;gap:8px;font-size:13.5px;margin-bottom:4px}
.pc-cost{font-family:var(--mono);color:var(--brass-bright);white-space:nowrap}
.pc-meta{display:flex;gap:6px;flex-wrap:wrap;font-size:10.5px;color:var(--paper-faint);margin-bottom:6px}
.pc-tag{background:var(--ink-700);border-radius:3px;padding:1px 5px}
.pc-desc{font-size:11px;line-height:1.4}
.pc-enh{font-size:10.5px;color:var(--paper-faint);margin-top:6px;border-top:1px solid var(--line);padding-top:5px}
.pc-enh-item{margin-top:5px}
.pc-enh-item:first-of-type{margin-top:4px}
.pc-enh-hd{color:var(--paper-dim);font-weight:600}
.pc-enh-cost{font-family:var(--mono);color:var(--brass-bright);font-weight:400}
.pc-enh-desc{line-height:1.4;margin-top:1px}
@media print{
  body.printing-cards *{visibility:hidden}
  body.printing-cards .print-cards-overlay, body.printing-cards .print-cards-overlay *{visibility:visible}
  body.printing-cards .print-cards-overlay{position:absolute;top:0;left:0;width:100%;
    background:white!important;color:black!important;padding:0;overflow:visible}
  body.printing-cards .print-cards-toolbar, body.printing-cards .print-cards-note{display:none!important}
  body.printing-cards .print-card-grid{grid-template-columns:repeat(3,1fr)!important;gap:8pt!important}
  body.printing-cards .print-card{border:1px solid black!important;background:white!important;
    color:black!important;page-break-inside:avoid;break-inside:avoid;padding:6pt!important}
  body.printing-cards .pc-tag{background:white!important;border:1px solid black!important}
  body.printing-cards .print-cards-overlay *{color:black!important}
  @page{margin:0.4in;size:letter portrait}
}

/* ── Sustained Spells display ───────────────────────────────────────────── */
.sustained-list{display:flex;flex-direction:column;gap:4px;margin:4px 0 12px}
.sustained-row{display:flex;align-items:center;gap:8px;padding:6px 10px;background:linear-gradient(90deg,rgba(91,139,208,.12),rgba(91,139,208,.04));border:1px solid var(--mp);border-radius:6px;font-size:13px}
.sus-icon{font-size:16px}
.sus-name{font-weight:600}
.sus-dur{color:var(--paper-faint);font-size:11px}

/* ── Prepared spell star button ─────────────────────────────────────────── */
.star-btn{background:transparent;border:none;color:var(--paper-faint);font-size:18px;cursor:pointer;padding:2px 4px;line-height:1;transition:color .15s}
.star-btn:hover{color:var(--brass)}
.star-btn.on{color:var(--brass-bright)}
.spell-row .star-btn{margin-right:2px;align-self:flex-start;margin-top:2px}

/* ── Mobile FAB (Floating Action Button) ────────────────────────────────── */
.mfab-wrap{position:fixed;bottom:16px;right:16px;z-index:8000;display:none}
@media(max-width:780px){.mfab-wrap{display:block}}
.mfab-main{width:56px;height:56px;border-radius:50%;background:var(--brass);
  color:var(--ink-900);border:none;font-size:24px;font-weight:900;cursor:pointer;
  box-shadow:0 4px 16px rgba(0,0,0,.4);transition:transform .2s}
.mfab-main:hover{transform:scale(1.05)}
.mfab-main.open{transform:rotate(45deg)}
.mfab-actions{position:absolute;bottom:68px;right:0;display:flex;flex-direction:column;gap:8px;
  opacity:0;pointer-events:none;transition:opacity .2s,transform .2s;transform:translateY(8px)}
.mfab-actions.open{opacity:1;pointer-events:auto;transform:translateY(0)}
.mfab-action{display:flex;align-items:center;gap:8px;background:var(--ink-800);
  color:var(--paper);border:1px solid var(--line);border-radius:24px;padding:8px 14px;
  font-size:13px;cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,.3);white-space:nowrap}
.mfab-action:hover{background:var(--ink-700);border-color:var(--brass)}
.mfab-action-icon{font-size:18px}

/* ── Accessibility: focus states ────────────────────────────────────────── */
*:focus-visible{outline:2px solid var(--brass-bright);outline-offset:2px}
button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible, .chip:focus-visible, .skill-play-row:focus-visible{
  outline:2px solid var(--brass-bright);outline-offset:2px;
  box-shadow:0 0 0 4px rgba(184,142,68,.25)}
/* Skip-to-main link */
.skip-link{position:absolute;top:-100px;left:8px;background:var(--brass);color:var(--ink-900);
  padding:8px 16px;border-radius:5px;font-weight:700;z-index:10000;text-decoration:none}
.skip-link:focus{top:8px}
/* High contrast for color-conveyed info (also use text/icons) */
.tagpill[aria-label]{cursor:help}
/* Reduced motion respect */
@media(prefers-reduced-motion:reduce){
  .hp-track.deaths-door{animation:none!important}
  *{transition-duration:0.01ms!important}
}

/* ── Initiative Tracker ─────────────────────────────────────────────────── */
.init-list{display:flex;flex-direction:column;gap:6px;margin:12px 0}
.init-row{display:flex;align-items:center;gap:12px;padding:10px 14px;background:var(--ink-800);border:1px solid var(--line);border-radius:8px;cursor:pointer;transition:all .15s}
.init-row:hover{border-color:var(--brass);background:var(--ink-750)}
.init-row.current{border-color:var(--brass-bright);background:linear-gradient(90deg,rgba(184,142,68,.18),rgba(184,142,68,.04));box-shadow:0 0 0 1px var(--brass)}
.init-row.dead{opacity:0.45}
.init-roll{font-size:24px;font-weight:900;font-family:var(--display);color:var(--brass-bright);width:48px;text-align:center;flex-shrink:0}
.init-info{flex:1;min-width:0}
.init-name{font-weight:700;font-size:15px}
.init-badge{display:inline-block;background:var(--brass-deep);color:var(--brass-bright);font-size:9px;padding:1px 5px;border-radius:3px;margin-left:6px;letter-spacing:0.05em;vertical-align:middle}
.init-hp{font-size:13px;color:var(--paper-dim);margin-top:2px}
.init-hp .dead{color:var(--hp)}
.init-hp-max{color:var(--paper-faint);font-size:11px;margin-left:2px}

/* ── A3: Floating dice roller + collapsible log drawer ─────────────────────── */
.dice-fab-wrap{position:fixed;left:20px;bottom:20px;z-index:8500;width:54px}
.dice-fab-btn{width:54px;height:54px;border-radius:50%;border:2px solid var(--brass);
  background:radial-gradient(circle at 35% 30%,var(--ink-700),var(--ink-900));
  color:var(--paper);font-size:26px;line-height:1;cursor:grab;touch-action:none;
  box-shadow:0 6px 18px rgba(0,0,0,.5);transition:transform .12s,box-shadow .12s;
  display:flex;align-items:center;justify-content:center;padding:0}
.dice-fab-btn:hover{transform:scale(1.06)}
.dice-fab-wrap.dragging .dice-fab-btn{cursor:grabbing;transform:scale(1.1);box-shadow:0 10px 26px rgba(0,0,0,.6)}
.dice-fab-wrap.open .dice-fab-btn{border-color:var(--brass-bright);box-shadow:0 0 0 4px rgba(184,142,68,.18),0 6px 18px rgba(0,0,0,.5)}

/* Panel — hidden until .open; flips around the button via .open-up / .open-left */
.dice-roller{position:absolute;left:0;top:64px;width:300px;max-width:84vw;max-height:70vh;overflow-y:auto;
  background:var(--ink-850);border:1px solid var(--line-strong);border-radius:var(--r);
  box-shadow:0 14px 40px rgba(0,0,0,.55);padding:12px;
  opacity:0;pointer-events:none;transform:translateY(-6px) scale(.98);transform-origin:top left;
  transition:opacity .14s,transform .14s}
.dice-fab-wrap.open .dice-roller{opacity:1;pointer-events:auto;transform:translateY(0) scale(1)}
.dice-fab-wrap.open-up .dice-roller{top:auto;bottom:64px;transform-origin:bottom left;transform:translateY(6px) scale(.98)}
.dice-fab-wrap.open-up.open .dice-roller{transform:translateY(0) scale(1)}
.dice-fab-wrap.open-left .dice-roller{left:auto;right:0;transform-origin:top right}
.dice-fab-wrap.open-up.open-left .dice-roller{transform-origin:bottom right}

.dr-hd{display:flex;align-items:center;justify-content:space-between;font-weight:700;font-size:14px;
  color:var(--paper);margin-bottom:10px}
.dr-x{background:none;border:none;color:var(--paper-faint);font-size:20px;line-height:1;cursor:pointer;padding:0 2px}
.dr-x:hover{color:var(--paper)}
.dr-hd-tools{display:flex;align-items:center;gap:8px}
/* play-dice-tray is now just an event-dispatch anchor — the canvas is position:fixed
   on document.body at viewport size so dice always roll in the visible area. */
.play-dice-tray{position:absolute;inset:0;z-index:0;pointer-events:none}
.dice3d-canvas{pointer-events:none}
/* Damage tier row in roll log and attack popup */
.dmg-tier-row{font-size:11px;margin-top:4px;display:flex;flex-wrap:wrap;gap:4px;align-items:center}
.dmg-tier-cell b{font-weight:700}
.dr-3d{font-size:11px;font-weight:700;letter-spacing:.04em;padding:3px 9px;border-radius:7px;cursor:pointer;
  border:1px solid var(--line-strong);background:var(--ink-700);color:var(--paper-faint)}
.dr-3d:hover{border-color:var(--brass);color:var(--brass-bright)}
.dr-3d.on{background:var(--ink-750);border-color:var(--brass);color:var(--brass-bright)}
.dr-dice{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin-bottom:10px}
.rdie{padding:8px 0;border-radius:var(--r-sm);border:1px solid var(--line-strong);background:var(--ink-700);
  color:var(--paper);font-family:var(--mono);font-size:13px;cursor:pointer;transition:background .1s,border-color .1s}
.rdie:hover{border-color:var(--brass)}
.rdie.on{background:var(--brass-deep);border-color:var(--brass-bright);color:#fff;font-weight:700}
.dr-controls{display:flex;align-items:center;gap:8px;margin-bottom:10px;flex-wrap:wrap}
.dr-stepper{display:flex;align-items:center;border:1px solid var(--line-strong);border-radius:var(--r-sm);overflow:hidden}
.dr-stepper button{width:30px;height:32px;border:none;background:var(--ink-700);color:var(--paper);font-size:17px;cursor:pointer}
.dr-stepper button:hover{background:var(--ink-600,var(--ink-700));color:var(--brass-bright)}
.dr-stepper input{width:42px;height:32px;text-align:center;border:none;border-left:1px solid var(--line);
  border-right:1px solid var(--line);background:var(--ink-850);color:var(--paper);font-family:var(--mono);font-size:14px}
.dr-x-lbl{font-family:var(--mono);color:var(--paper-faint);font-size:13px}
.dr-mod{display:flex;align-items:center;gap:5px;font-size:12px;color:var(--paper-faint);margin-left:auto}
.dr-mod input{width:48px;height:32px;text-align:center;background:var(--ink-850);border:1px solid var(--line-strong);
  border-radius:var(--r-sm);color:var(--paper);font-family:var(--mono);font-size:14px}
.dr-adv{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;margin-bottom:10px}
.radv{padding:7px 0;border-radius:var(--r-sm);border:1px solid var(--line-strong);background:var(--ink-700);
  color:var(--paper-dim);font-size:12px;cursor:pointer}
.radv:hover{border-color:var(--brass)}
.radv.on{background:var(--brass-deep);border-color:var(--brass-bright);color:#fff;font-weight:700}
.radv.on.dis{background:var(--ember-deep,#5a2020);border-color:var(--ember)}
.dr-appump{display:flex;align-items:center;gap:7px;margin:-2px 0 10px;padding:6px 8px;border-radius:var(--r-sm);
  background:var(--ink-850);border:1px solid var(--line-strong);font-size:12px}
.dr-appump-lbl{color:var(--paper-dim);font-weight:600;white-space:nowrap}
.dr-ap-btn{width:24px;height:24px;border-radius:var(--r-sm);border:1px solid var(--line-strong);
  background:var(--ink-700);color:var(--paper);cursor:pointer;font-size:14px;line-height:1}
.dr-ap-btn:hover{border-color:var(--brass)}
.dr-ap-val{min-width:16px;text-align:center;font-family:var(--mono);font-weight:700;
  color:var(--good,#3a9d6e)}
.dr-ap-cost{margin-left:auto;color:var(--paper-faint);font-size:11px;white-space:nowrap}
.dr-roll{width:100%;padding:11px;border-radius:var(--r-sm);border:1px solid var(--brass-bright);
  background:var(--brass);color:var(--ink-900);font-weight:800;font-size:15px;cursor:pointer;letter-spacing:.02em}
.dr-roll:hover{filter:brightness(1.08)}
.dr-roll-fml{font-family:var(--mono);font-weight:600;opacity:.85;font-size:13px}
.dr-vs{display:flex;gap:10px;margin:10px 0 4px}
.dr-vs label{flex:1;display:flex;align-items:center;gap:6px;font-size:12px;color:var(--paper-faint)}
.dr-vs input{width:100%;height:30px;text-align:center;background:var(--ink-850);border:1px solid var(--line-strong);
  border-radius:var(--r-sm);color:var(--paper);font-family:var(--mono)}
.dr-quick-hd{font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--paper-faint);margin:8px 0 6px}
.dr-quick{display:grid;grid-template-columns:1fr 1fr;gap:6px}
.rquick{padding:7px 8px;border-radius:var(--r-sm);border:1px solid var(--line);background:var(--ink-800);
  color:var(--paper-dim);font-size:12px;cursor:pointer;text-align:left}
.rquick:hover{border-color:var(--brass);color:var(--paper)}
.rquick b{color:var(--brass-bright);font-family:var(--mono)}

/* Collapsible left-edge roll log drawer */
/* ── Floating draggable log fab ───────────────────────────────────────────── */
.log-panel{display:none;position:absolute;bottom:calc(100% + 10px);left:0;
  width:300px;max-width:82vw;max-height:55vh;
  background:var(--ink-850);border:1px solid var(--line-strong);border-radius:12px;
  box-shadow:0 8px 28px rgba(0,0,0,.55);overflow:hidden;flex-direction:column}
.log-panel.open{display:flex}
/* [Fix 2026-07-03] Roll log anchored under the ⋮ play-actions menu */
.play-actions-menu .log-panel.menu-anchored{position:static;width:320px;max-width:86vw;max-height:60vh;margin-top:2px}
.log-panel-hd{display:flex;align-items:center;justify-content:space-between;
  padding:10px 12px 8px;font-weight:700;font-size:14px;color:var(--paper);
  border-bottom:1px solid var(--line);flex-shrink:0}
.log-x{background:none;border:none;color:var(--paper-faint);font-size:20px;line-height:1;cursor:pointer;padding:0 2px}
.log-x:hover{color:var(--paper)}
.log-panel .log-filters{display:flex;flex-wrap:wrap;gap:5px;align-items:center;
  padding:8px 12px 6px;border-bottom:1px solid var(--line);flex-shrink:0}
.lp-log{flex:1;overflow-y:auto;padding:4px 0;min-height:0}
.rl-time{color:var(--paper-faint);font-size:11px;flex-shrink:0}
.rl-msg{flex:1}

/* ── A4: Featured hero stats, damage-reduction track, exhaustion ladder ────── */
.hero-stats{margin:4px 0 16px}
.hs-def{display:grid;grid-template-columns:1fr 1fr auto;gap:10px;align-items:stretch;margin-bottom:10px}
.hd-card{background:var(--ink-850);border:1px solid var(--line-strong);border-radius:var(--r);padding:10px 12px;text-align:center}
.hd-lbl{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--paper-faint)}
.hd-val{font-family:var(--display);font-size:34px;line-height:1.05;color:var(--paper);margin:2px 0}
.hd-fml{font-family:var(--mono);font-size:10px;color:var(--paper-faint)}
.hs-dr{display:flex;flex-direction:column;gap:5px;justify-content:center}
.dr-box{display:flex;align-items:center;gap:7px;justify-content:space-between;min-width:96px;
  padding:4px 9px;border:1px solid var(--line);border-radius:var(--r-sm);background:var(--ink-800)}
.dr-box span{font-family:var(--mono);font-size:11px;color:var(--paper-faint);letter-spacing:.06em}
.dr-box b{font-size:12px;color:var(--paper-dim)}
.dr-box.on{border-color:var(--brass);background:rgba(201,162,75,.08)}
.dr-box.on b{color:var(--brass-bright)}
.hs-combat{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-bottom:10px}
@media(max-width:780px){.hs-combat{grid-template-columns:1fr 1fr}}
.cstat{background:var(--ink-800);border:1px solid var(--line);border-radius:var(--r-sm);padding:7px 9px;text-align:center}
.cs-lbl{display:block;font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--paper-faint)}
.cs-val{display:block;font-family:var(--mono);font-size:21px;font-weight:700;color:var(--paper);margin:1px 0}
.cs-val.pen{color:var(--hp)}
.cs-fml{display:block;font-family:var(--mono);font-size:9.5px;color:var(--paper-faint);line-height:1.3}
.hs-move{display:flex;gap:10px;margin-bottom:12px}
.hs-move .mv{flex:1;display:flex;align-items:baseline;gap:8px;background:var(--ink-800);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:7px 11px}
.hs-move .mv-lbl{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--paper-faint)}
.hs-move .mv b{font-family:var(--mono);font-size:18px;color:var(--paper)}
.hs-move .mv b.pen{color:var(--hp)}
.hs-move .mv-sub{font-size:10px;color:var(--paper-faint);margin-left:auto}

.exh-ladder{border:1px solid var(--line);border-radius:var(--r);padding:9px 11px;background:var(--ink-850)}
.exh-ladder.active{border-color:var(--ember-deep)}
.exh-hd{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:7px}
.exh-title{font-weight:700;font-size:13px;color:var(--paper);text-transform:uppercase;letter-spacing:.06em}
.exh-title b{color:var(--hp);font-family:var(--mono)}
.exh-note{font-size:10.5px;color:var(--paper-faint);margin-left:auto}
.exh-pips{display:flex;gap:6px;align-items:center}
.exh-pip{width:46px;height:34px;border-radius:var(--r-sm);border:1px solid var(--line-strong);
  background:var(--ink-700);color:var(--paper-faint);font-family:var(--mono);font-size:14px;font-weight:700;cursor:pointer;
  transition:background .1s,border-color .1s,color .1s}
.exh-pip:hover{border-color:var(--ember)}
.exh-pip.on{background:var(--ember-deep);border-color:var(--ember);color:#fff}
.exh-clear{width:34px;height:34px;border-radius:var(--r-sm);border:1px solid var(--line);background:var(--ink-700);
  color:var(--paper-faint);cursor:pointer;margin-left:4px}
.exh-clear:hover{color:var(--paper);border-color:var(--brass)}
@media(max-width:560px){
  .hs-def{grid-template-columns:1fr 1fr}
  .hs-dr{grid-column:1/-1;flex-direction:row;flex-wrap:wrap}
  .hs-combat{grid-template-columns:1fr 1fr}
  .exh-pip{flex:1}
}

/* ── A4 part 2: Attribute clusters (attribute + Save + its skills) ─────────── */
.attr-cluster{border:1px solid var(--line);border-radius:var(--r);background:var(--ink-850);
  margin:0 0 8px;overflow:hidden}
.ac-head{display:flex;align-items:center;gap:10px;padding:7px 10px;background:var(--ink-800);
  border-bottom:1px solid var(--line)}
.ac-id{display:flex;align-items:baseline;gap:8px;flex:1;min-width:0}
.ac-name{font-family:var(--display);font-size:15px;letter-spacing:.04em;color:var(--paper)}
.ac-mod{font-family:var(--mono);font-size:18px;font-weight:700;color:var(--brass-bright)}
.ac-sub{font-size:10px;color:var(--paper-faint);text-transform:uppercase;letter-spacing:.08em}
.ac-btns{display:flex;gap:6px;flex-shrink:0}
.ac-btns .btn{font-size:11px;padding:4px 9px}
.ac-skills{padding:4px 6px;display:flex;flex-direction:column;gap:2px}
.ac-skills .skill-play-row{padding:5px 8px}

/* ── A4 part 2: Equipped body-slot paperdoll + attunement ─────────────────── */
.paperdoll{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;margin:8px 0}
.pd-slot{display:flex;flex-direction:column;gap:3px;background:var(--ink-850);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:7px 9px}
.pd-lbl{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--brass-bright);font-weight:700}
.pd-slot input{background:var(--ink-900);border:1px solid var(--line);border-radius:5px;padding:5px 7px;
  color:var(--paper);font-size:13px;font-family:inherit}
.pd-slot input:focus{outline:none;border-color:var(--brass)}
@media(max-width:560px){.paperdoll{grid-template-columns:1fr}}

/* ── Roll presets on the floating roller ──────────────────────────────────── */
.dr-preset-hd{display:flex;align-items:center;justify-content:space-between;gap:8px}
.dr-save{background:none;border:1px solid var(--line-strong);border-radius:var(--r-sm);color:var(--brass-bright);
  font-size:10px;padding:3px 7px;cursor:pointer;text-transform:none;letter-spacing:0}
.dr-save:hover{border-color:var(--brass)}
.dr-presets{display:flex;flex-wrap:wrap;gap:6px}
.dr-preset{display:inline-flex;align-items:stretch;border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden}
.dr-preset-roll{background:var(--ink-800);border:none;color:var(--paper);font-size:12px;padding:6px 9px;cursor:pointer}
.dr-preset-roll:hover{background:var(--ink-700);color:var(--brass-bright)}
.dr-preset-x{background:var(--ink-850);border:none;border-left:1px solid var(--line);color:var(--paper-faint);
  font-size:10px;padding:0 7px;cursor:pointer}
.dr-preset-x:hover{color:var(--hp)}
.dr-preset-empty{font-size:11px;color:var(--paper-faint);font-style:italic}

/* ============================================================
   LOGIN / PLAYER PROFILES  (client-side, convenience-grade)
   ============================================================ */
.login{max-width:560px;margin:0 auto;padding:48px 24px 64px;width:100%;
  display:flex;flex-direction:column;align-items:center;text-align:center}
/* roster: signed-in banner */
.btn.sm{padding:4px 10px;font-size:12px}
.chip.ghost{border-style:dashed;color:var(--paper-faint)}
.chip.ghost:hover{color:var(--brass-bright);border-color:var(--brass)}
#profileChip{font-size:13px;padding:5px 11px}

/* Roll result popup — position:fixed so it always appears in the visible viewport
   regardless of scroll position or container height. Auto-dismisses in 3.2s. */
.roll-popup{position:fixed;left:50%;bottom:clamp(16px,4vh,48px);
  transform:translateX(-50%);z-index:9000;text-align:center;
  pointer-events:auto;cursor:pointer;
  background:linear-gradient(165deg,var(--ink-800),var(--ink-850));
  border:1px solid var(--line-strong);border-radius:14px;
  padding:14px 28px 12px;
  box-shadow:0 8px 32px rgba(0,0,0,.55),0 0 0 1px rgba(201,162,75,.12);
  animation:rpIn .22s cubic-bezier(.22,.68,0,1.2) both;
  /* prevent popup from wider than viewport on narrow screens */
  max-width:min(90vw,360px)}
@keyframes rpIn{from{opacity:0;transform:translateX(-50%) translateY(12px) scale(.92)}to{opacity:1;transform:translateX(-50%) translateY(0) scale(1)}}
.rp-label{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--paper-faint);margin-bottom:4px}
.rp-total{font-size:48px;font-weight:800;line-height:1;color:var(--brass-bright);
  text-shadow:0 2px 16px rgba(226,196,120,.35)}
.rp-total.crit{color:#7fe08a;text-shadow:0 2px 20px rgba(127,224,138,.5)}
.rp-total.fail{color:var(--ember);text-shadow:0 2px 20px rgba(232,98,58,.5)}
.rp-breakdown{font-size:13px;color:var(--paper-dim);margin-top:5px}
.rp-discards{font-size:11px;color:var(--paper-faint);margin-top:2px;font-style:italic}

/* ── Coin Purse ──────────────────────────────────────────────────────────── */
.coin-purse{display:flex;flex-wrap:wrap;gap:10px;margin-top:6px}
.coin-cell{display:flex;align-items:center;gap:7px;background:var(--ink-800);
  border:1px solid var(--line);border-radius:10px;padding:7px 10px;flex:1 0 88px;min-width:88px}
.coin-icon{width:32px;height:32px;border-radius:50%;display:grid;place-items:center;
  font-size:10px;font-weight:800;color:var(--ink-900);flex-shrink:0;letter-spacing:-.02em}
.coin-controls{display:flex;flex-direction:column;align-items:center;gap:5px;flex:1}
.coin-val{width:52px;text-align:center;background:var(--ink-750);border:1px solid var(--line);
  border-radius:6px;color:var(--paper);font-size:16px;font-weight:700;font-family:var(--mono);padding:2px 4px}
.coin-val::-webkit-inner-spin-button, .coin-val::-webkit-outer-spin-button{opacity:.5}
/* [Touch-target fix 2026-09-17] 22x18 sat under the 24px WCAG 2.5.8 floor;
   grown to 30x26 (coin-cell/coin-val are already wide enough to hold it) and
   the column gap widened 3px->5px so a miss lands on empty space instead of
   the adjacent +/- button or the number input between them. */
.coin-btn{background:var(--ink-700);border:1px solid var(--line);border-radius:6px;color:var(--paper-dim);
  width:30px;height:26px;font-size:14px;line-height:1;cursor:pointer;padding:0}
.coin-btn:hover{color:var(--brass-bright);border-color:var(--brass)}

/* ── Enhanced Inventory ──────────────────────────────────────────────────── */
.inv-count{font-size:12px;font-weight:400;color:var(--paper-faint)}
.inv-category-hd{font-size:11px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--paper-faint);margin:10px 0 5px;padding:0 2px}
.inv-row{display:flex;align-items:center;gap:7px;padding:6px 8px;background:var(--ink-800);
  border:1px solid var(--line);border-radius:8px;margin-bottom:4px;font-size:13px}
.gear-row{opacity:.88}
.inv-icon{font-size:15px;width:18px;text-align:center;flex-shrink:0}
.inv-name{font-weight:600;color:var(--paper);flex:1}
.inv-note{font-size:11px;color:var(--paper-faint);margin-left:auto}
.inv-qty{font-size:12px;color:var(--paper-dim);background:var(--ink-750);border-radius:5px;padding:1px 5px}
.inv-uses{font-size:11px;color:var(--paper-faint)}
.inv-remove{width:22px;height:22px;padding:0;line-height:1;font-size:12px}
.inv-add-row{display:flex;gap:8px;margin-top:10px}
.inv-add-input{flex:1;background:var(--ink-800);border:1px solid var(--line);border-radius:8px;
  color:var(--paper);font-size:13px;padding:7px 10px}
.inv-add-input:focus{outline:none;border-color:var(--brass)}

/* ── Quick Rest indicator ────────────────────────────────────────────────── */
.rest-bar{gap:8px}
.rest-bar .btn.ghost:disabled{opacity:.45;cursor:not-allowed}

/* ── GP Budget (Step 10) ────────────────────────────────────────────────── */
.gp-budget{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  background:var(--ink-800);border:1px solid var(--line);border-radius:10px;
  padding:8px 12px;margin-bottom:12px;font-size:13px}
.gp-label{font-weight:600;color:var(--brass-bright);flex-shrink:0}
.gp-input{width:68px;text-align:center;background:var(--ink-750);border:1px solid var(--line);
  border-radius:6px;color:var(--paper);font-size:14px;font-weight:700;font-family:var(--mono);padding:3px 6px}
.gp-input:focus{outline:none;border-color:var(--brass)}
.gp-sep{color:var(--paper-faint);font-size:12px}
.gp-remain{color:var(--paper-dim);font-size:12px;margin-left:auto}
.gp-remain.over{color:var(--ember);font-weight:700}

/* ── Coin convert bar ────────────────────────────────────────────────────── */
.coin-convert-bar{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}
.btn.xs{font-size:11px;padding:3px 8px;border-radius:6px}

/* ── Log panel copy button ───────────────────────────────────────────────── */
.log-copy-btn{background:none;border:none;color:var(--paper-faint);font-size:14px;
  cursor:pointer;padding:0 4px;line-height:1}
.log-copy-btn:hover{color:var(--brass-bright)}

/* ── Play page tabs (D&D Beyond–style) ──────────────────────────────────── */
.play-tabbar{
  display:flex;gap:0;overflow-x:auto;scrollbar-width:none;
  border-bottom:2px solid var(--line);margin:0 -22px 16px;
  padding:0 22px;flex-shrink:0
}
.play-tabbar::-webkit-scrollbar{display:none}
.play-tab{
  appearance:none;border:none;background:transparent;
  color:var(--paper-faint);padding:10px 14px;font-size:13px;font-weight:600;
  cursor:pointer;white-space:nowrap;border-bottom:2px solid transparent;
  margin-bottom:-2px;transition:color .12s,border-color .12s;font-family:inherit
}
.play-tab:hover{color:var(--paper)}
.play-tab.on{color:var(--brass-bright);border-bottom-color:var(--brass-bright)}
.play-tab-body{flex:1;min-height:0}

/* ── Attribute cluster: fix Intelligence overflow ───────────────────────── */
/* Use abbreviated button labels (MIG / AGI / etc.) and shrink the button text */
.ac-chk{font-size:11px;padding:3px 7px;min-width:0}
.ac-sav{font-size:11px;padding:3px 7px;min-width:0}
.ac-btns{display:flex;gap:4px;flex-shrink:0}
/* Trade sub-header inside a cluster */
.ac-trade-hd{
  font-size:10px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--brass);font-weight:600;padding:6px 8px 2px;
  border-top:1px solid var(--line);margin-top:4px
}
/* Trade rows inherit skill-play-row; make attr badge more visible */
.spr-attr{color:var(--brass);font-size:10px;font-weight:700;letter-spacing:.05em;flex-shrink:0}

/* ── Play page floating actions menu (⋮ button, replaces the old right panel) ── */
.play-actions-menu{
  position:absolute;top:12px;right:14px;z-index:55;
  display:flex;flex-direction:column;align-items:flex-end;gap:6px
}
.play-actions-btn{
  width:34px;height:34px;border-radius:50%;
  background:var(--ink-800);border:1px solid var(--line-strong);
  color:var(--paper-dim);font-size:20px;font-weight:900;line-height:1;
  cursor:pointer;display:grid;place-items:center;
  box-shadow:0 2px 8px rgba(0,0,0,.35);transition:border-color .12s,color .12s
}
.play-actions-btn:hover{border-color:var(--brass);color:var(--brass-bright)}
.play-actions-dropdown{
  display:flex;flex-direction:column;gap:6px;
  background:var(--ink-850);border:1px solid var(--line-strong);
  border-radius:10px;padding:10px;
  box-shadow:0 8px 24px rgba(0,0,0,.5);
  animation:rpIn .16s cubic-bezier(.22,.68,0,1.2) both
}
.play-actions-dropdown .btn{white-space:nowrap;justify-content:flex-start}

/* ── [A11y 2026-07-03] Keyboard & motion ────────────────────────────────── */
[data-a]:focus-visible, button:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible{
  outline:2px solid var(--focus);outline-offset:2px;border-radius:4px}
@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;scroll-behavior:auto!important}
}

/* ── [Mobile pass 2026-07-03] Phone-first play sheet ───────────────────────
   ≤780px: the tab bar becomes a fixed bottom navigation (thumb-reach), the
   AP/SP/MP resource bank pins to the top of the scroll, and floating widgets
   are lifted clear of the nav. The play sheet is usable as the only screen
   at the table. */
@media(max-width:780px){
  /* Bottom tab navigation */
  .play-tabbar{
    position:fixed;left:0;right:0;bottom:0;z-index:8200;margin:0;padding:0;
    padding-bottom:env(safe-area-inset-bottom,0);
    background:var(--ink-850);border-top:1px solid var(--line-strong);border-bottom:none;
    display:grid;grid-auto-flow:column;grid-auto-columns:1fr;overflow-x:auto;
    box-shadow:0 -4px 16px rgba(0,0,0,.4)
  }
  .play-tab{
    padding:10px 2px 12px;font-size:10.5px;text-align:center;white-space:nowrap;
    display:flex;flex-direction:column;align-items:center;gap:1px;min-height:48px
  }
  .play-tab.on{border-bottom:none;box-shadow:inset 0 3px 0 var(--brass)}
  /* Content clears the fixed nav */
  .play{padding-bottom:calc(64px + env(safe-area-inset-bottom,0))}
  /* Pinned resource bank — always visible while scrolling the sheet */
  .resbank{
    position:sticky;top:0;z-index:60;
    background:var(--ink-900);padding:6px 0;margin:0 0 8px;
    border-bottom:1px solid var(--line);
    display:grid;grid-template-columns:repeat(4,1fr);gap:6px
  }
  .resbank .rb{padding:6px 4px}
  .resbank .rb .rv{font-size:18px}
  .resbank .rb .step button{width:44px;height:40px} /* [ui-ux-pro-max] ≥44px touch targets */
  /* Floating widgets sit above the bottom nav */
  .mfab-wrap{bottom:calc(72px + env(safe-area-inset-bottom,0))}
  .dice-fab-wrap{bottom:calc(140px + env(safe-area-inset-bottom,0))!important;width:44px}
  .dice-fab-btn{width:44px;height:44px;font-size:20px} /* [ui-ux-pro-max] shrunk on phones — was covering nearby content */
  /* Roll-log panel fits phone width */
  .play-actions-menu .log-panel.menu-anchored{width:92vw;max-width:92vw}
}

/* ---------- cinematic polish pass (ui-ux-pro-max, 2026-07-10) ----------
   Informed by the toolkit's "Modern Dark (Cinema)" profile — its Best For
   list literally includes "high-end gaming companion apps". Adapted to
   vanilla CSS on our existing brass/ink system: expo-out easing everywhere,
   slow ambient light drift, accent glow on primary actions, press-scale
   feedback, and a default modal entrance. All motion dies under the global
   prefers-reduced-motion rule (animation:none + transition:none), and the
   ambient layer is display:none in print. */
:root{--ease:cubic-bezier(0.16,1,0.3,1)}

/* Ambient light — two slow-breathing glow blobs behind everything. body::after
   is reserved by the fx pulses (crit/stingers); ::before is free. */
body::before{content:'';position:fixed;inset:-20%;pointer-events:none;z-index:-1;
  background:
    radial-gradient(560px 420px at 22% 18%, color-mix(in srgb,var(--brass) 7%,transparent), transparent 70%),
    radial-gradient(640px 480px at 82% 78%, color-mix(in srgb,var(--accent,var(--brass)) 6%,transparent), transparent 70%);
  animation:ambient-drift 46s ease-in-out infinite alternate}
@keyframes ambient-drift{
  0%{transform:translate(0,0) scale(1)}
  100%{transform:translate(3%,-2%) scale(1.06)}}

/* Motion system: retune existing micro-interactions onto the expo-out curve */
.btn{transition:background .2s var(--ease),border-color .2s var(--ease),transform .16s var(--ease),box-shadow .25s var(--ease)}
.btn:active{transform:translateY(1px) scale(.97)}
.btn.primary{box-shadow:0 0 14px color-mix(in srgb,var(--brass) 22%,transparent)}
.btn.primary:hover{box-shadow:0 0 22px color-mix(in srgb,var(--brass) 38%,transparent)}
.chip{transition:background .18s var(--ease),border-color .18s var(--ease),transform .12s var(--ease)}
.chip:active{transform:scale(.95)}

/* Depth: hairline top-light + hover lift family (cards & rows that invite a tap) */
.pc-card,.home-hero,.rw-opt,.feature-box,.hl-strip,.party-strip,.modal{
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04),var(--shadow-sm)}
.pc-card{transition:border-color .2s var(--ease),transform .22s var(--ease),box-shadow .25s var(--ease)}
.pc-card:hover{box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 10px 26px rgba(0,0,0,.45)}
.hl-row,.ps-chip{transition:background .18s var(--ease),transform .16s var(--ease)}
.hl-row:hover,.ps-chip:hover{transform:translateX(2px)}
.dr-skin{transition:border-color .15s var(--ease),transform .15s var(--ease)}
.dr-skin:hover{transform:scale(1.15)}
.dr-skin.on{transform:scale(1.08)}

/* Default modal entrance (the ceremony keeps its bigger cer-in) */
.modal-bg{animation:mbg-in .16s var(--ease)}
.modal:not(.modal-ceremony){animation:m-in .2s var(--ease)}
@keyframes mbg-in{from{opacity:0}to{opacity:1}}
@keyframes m-in{from{opacity:0;transform:translateY(8px) scale(.985)}to{opacity:1;transform:none}}

@media print{body::before{display:none}}

/* ---------- mobile vitals + combat command bar (C2/C3, 2026-07-10) ----------
   ui-ux-pro-max guidance applied: ≥44px touch targets, 8px gaps,
   touch-action:manipulation, numeric inputmode (markup), fixed-nav clearance
   (already present), icon-over-label bottom nav. */
button,.chip,.play-tab,[data-a]{touch-action:manipulation}
.mvitals{display:none}
.mv-pip{width:15px;height:15px;border-radius:50%;display:inline-block;margin-right:5px;
  border:2px solid var(--brass-deep);background:transparent;cursor:pointer;vertical-align:-2px}
.mv-pip.on{background:var(--brass);border-color:var(--brass-bright)}
.mv-pip.cap{opacity:.25;border-style:dashed}
.mv-ap{white-space:nowrap}
.cmd-bar{position:sticky;top:0;z-index:70;display:flex;align-items:center;gap:12px;
  padding:9px 12px;margin:0 0 12px;border:1px solid var(--line-strong);
  border-left:3px solid var(--accent,var(--brass));border-radius:var(--r-sm);
  background:color-mix(in srgb,var(--ink-850) 88%,transparent);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  box-shadow:var(--shadow-sm)}
.cb-lbl{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--paper-faint)}
.cb-spacer{flex:1}
@media(max-width:780px){
  .cmd-bar{display:none} /* vitals bar + bottom nav own this job on phones */
  .mvitals{
    display:flex;align-items:center;gap:12px;flex-wrap:nowrap;overflow-x:auto;
    position:sticky;top:0;z-index:70;padding:9px 12px;margin:0 0 10px;
    background:color-mix(in srgb,var(--ink-900) 92%,transparent);
    backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
    border-bottom:1px solid var(--line-strong)}
  .mvitals.danger{border-bottom-color:var(--ember-deep);background:color-mix(in srgb,var(--hp-bg) 60%,var(--ink-900))}
  .mv-hp{font-size:17px;font-weight:700;color:var(--hp);white-space:nowrap}
  .mv-hp i{font-style:normal;color:var(--mp);font-size:13px}
  .mv-hp .mv-max{color:var(--paper-faint);font-weight:400;font-size:12px}
  .mv-pool{font-size:12px;color:var(--paper-dim);white-space:nowrap}
  .mv-pool b{color:var(--paper);font-size:14px}
  .mv-pip{width:17px;height:17px;margin-right:8px} /* thumb-friendly */
  .pt-ico{font-size:17px;display:block}
  .pt-lbl{display:block;font-size:9.5px;letter-spacing:.02em}
}
@media(min-width:781px){
  .play-tab .pt-ico{margin-right:6px}
}

/* ---------- DDB-inspired chrome pass (2026-07-10) ----------
   Transferable patterns lifted from the provided D&D Beyond main.css, run
   through the ui-ux-pro-max lens and adapted to our brass identity (their
   red stays theirs): the header's accent underline (their 1px #e40712
   border-bottom), condensed uppercase letterspaced CTAs (.ddb-button), the
   heavier dropdown shadow (0 5px 5px), and uppercase micro-labels. */
.topbar{box-shadow:0 1px 0 var(--brass-deep),0 4px 14px rgba(0,0,0,.35)}
.btn.primary{text-transform:uppercase;letter-spacing:.075em;font-size:12.5px;font-weight:700}
.theme-dd-menu{box-shadow:0 5px 12px rgba(0,0,0,.7)}
.topbar .ctx{text-transform:uppercase;font-size:11px;letter-spacing:.08em}
.play-tab .pt-lbl{letter-spacing:.02em}
.modal-hd h3{letter-spacing:.03em}

/* Dice & Sound settings modal */
.modal.modal-dice{max-width:480px}
.modal-dice .dr-skins{margin-bottom:6px}
.modal-dice select{background:var(--ink-800);color:var(--paper);border:1px solid var(--line-strong);border-radius:6px;padding:6px 10px}

/* ============================================================
   Illuminated Tome — aesthetic elevation (2026-07-10)
   Spec: docs/superpowers/specs/2026-07-10-illuminated-tome-design.md
   Additive grimoire layer on top of Violet & Ember: parchment grain,
   gilded frames, candle-glow, illuminated-manuscript type. Everything here
   derives from existing tokens (--brass/--ember/--accent/--ink-*) so all
   7 themes and 17 class accents keep working without touching them.
   ============================================================ */
:root{
  --gild:linear-gradient(172deg,var(--paper) 0%,var(--brass-bright) 52%,var(--brass) 100%);
  --grain:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  --grain-o:.035;
  --glow-brass:0 0 18px color-mix(in srgb,var(--brass) 30%,transparent);
  --flavor:"Cormorant Garamond",Georgia,"Iowan Old Style",serif;
  --vignette:rgba(22,10,26,.30);
}
:root.theme-contrast{--grain-o:0;--vignette:rgba(0,0,0,.30)}

/* ---------- atmosphere: parchment grain + vignette ---------- */
html::before{content:'';position:fixed;inset:0;z-index:2000;pointer-events:none;
  background:var(--grain);background-size:160px 160px;opacity:var(--grain-o);
  mix-blend-mode:overlay}
@media print{html::before{display:none!important}}

/* ---------- ornamental framing ---------- */
hr,.gild-rule{border:0;height:9px;margin:18px 0;position:relative;
  background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--brass) 55%,transparent) 18%,color-mix(in srgb,var(--brass) 55%,transparent) 82%,transparent) center/100% 1px no-repeat}
hr::after,.gild-rule::after{content:'◆';position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  font-size:8px;line-height:1;color:var(--brass);text-shadow:0 0 8px color-mix(in srgb,var(--brass) 55%,transparent)}
.section-title::after{background:linear-gradient(90deg,color-mix(in srgb,var(--brass-deep) 70%,var(--line)),transparent)}

/* corner-bracket frames: home hero + play identity plate */
.home-hero{position:relative}
.home-hero::after{content:'';position:absolute;inset:5px;pointer-events:none;border-radius:calc(var(--r) - 4px);
  background:
    linear-gradient(var(--brass) 0 0) top left/14px 1px,
    linear-gradient(var(--brass) 0 0) top left/1px 14px,
    linear-gradient(var(--brass) 0 0) bottom right/14px 1px,
    linear-gradient(var(--brass) 0 0) bottom right/1px 14px;
  background-repeat:no-repeat;opacity:.55}
.play-identity{position:relative;border-bottom-color:transparent;
  background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--brass) 60%,transparent) 15%,color-mix(in srgb,var(--brass) 60%,transparent) 85%,transparent) bottom/100% 1px no-repeat}
.play-identity::after{content:'';position:absolute;left:50%;bottom:-2.5px;width:6px;height:6px;
  transform:translateX(-50%) rotate(45deg);background:var(--brass);
  box-shadow:0 0 8px color-mix(in srgb,var(--brass) 60%,transparent)}

/* embossed gilded primary button */
.btn.primary{box-shadow:inset 0 1px 0 rgba(255,255,255,.30),inset 0 -1px 0 rgba(0,0,0,.28),0 0 14px color-mix(in srgb,var(--brass) 22%,transparent)}
.btn.primary:hover{box-shadow:inset 0 1px 0 rgba(255,255,255,.36),inset 0 -1px 0 rgba(0,0,0,.28),0 0 24px color-mix(in srgb,var(--brass) 40%,transparent)}
.btn.primary:active{box-shadow:inset 0 2px 5px rgba(0,0,0,.32)}

/* roster card gild strip (class accent still wins when present) */
.pc-card::before{background:linear-gradient(90deg,var(--brass-bright),var(--brass) 45%,transparent)}
.pc-card.accented::before{background:linear-gradient(90deg,var(--accent-bright,var(--brass-bright)),var(--accent,var(--brass)) 45%,transparent)}

/* ---------- illuminated type: flavor voice, versal initials, gilded headings ---------- */
.guide-note{font-family:var(--flavor);font-size:15.5px;font-style:italic}
.guide-note b{font-family:var(--body);font-style:normal}
.stage-hd p{font-family:var(--flavor);font-size:16.5px;font-style:italic}
.stage-hd p::first-letter{font-family:var(--display);font-style:normal;font-size:1.5em;
  line-height:1;color:var(--brass-bright);letter-spacing:.02em}
.roster-hd p{font-family:var(--flavor);font-size:16px;font-style:italic}
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .roster-hd h1{background:var(--gild);-webkit-background-clip:text;background-clip:text;color:transparent}
}

/* ---------- candle-glow interactions + gem resources ---------- */
.btn:focus-visible{box-shadow:var(--glow-brass)}
.field input:focus,.field select:focus,.field textarea:focus{box-shadow:0 0 0 3px color-mix(in srgb,var(--brass) 16%,transparent)}
.play-identity .pc-ava,.play-identity .pi-portrait{box-shadow:0 0 14px color-mix(in srgb,var(--accent,var(--brass)) 26%,transparent)}
.res{position:relative;overflow:hidden}
.res::after{content:'';position:absolute;inset:0 0 auto 0;height:46%;pointer-events:none;
  background:linear-gradient(180deg,rgba(255,255,255,.07),transparent)}
.res.hp .v{text-shadow:0 0 12px color-mix(in srgb,var(--hp) 40%,transparent)}
.res.mp .v{text-shadow:0 0 12px color-mix(in srgb,var(--mp) 40%,transparent)}
.res.sp .v{text-shadow:0 0 12px color-mix(in srgb,var(--sp) 40%,transparent)}
.hp-bar .fill{box-shadow:0 0 10px color-mix(in srgb,var(--hp) 50%,transparent),inset 0 1px 0 rgba(255,255,255,.22)}
.hh-hp i,.ps-hp i{box-shadow:0 0 6px color-mix(in srgb,var(--hp) 45%,transparent)}

/* stagger reveal for the roster shelf (killed by the global reduced-motion rule above) */
@keyframes tome-rise{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}
.card-grid>*{animation:tome-rise .45s var(--ease) backwards}
.card-grid>*:nth-child(2){animation-delay:.04s}.card-grid>*:nth-child(3){animation-delay:.08s}
.card-grid>*:nth-child(4){animation-delay:.12s}.card-grid>*:nth-child(5){animation-delay:.16s}
.card-grid>*:nth-child(6){animation-delay:.20s}.card-grid>*:nth-child(7){animation-delay:.24s}
.card-grid>*:nth-child(8){animation-delay:.28s}.card-grid>*:nth-child(9){animation-delay:.32s}
.card-grid>*:nth-child(n+10){animation-delay:.36s}

/* ---------- icon manifest (Violet & Ember, 2026-07-11) ---------- */
.vx-icon{display:inline-block;width:1em;height:1em;vertical-align:-0.15em;
  background-color:var(--ink-700);background-size:contain;background-position:center;
  background-repeat:no-repeat;border-radius:2px}


/* ── Rules Compendium — documentation-style knowledge base [2026-07-16] ─── */
/* [Mobile fix 2026-09-17] Every other top-level view wrapper tells #root's
   flex layout to fill/shrink it (.roster{width:100%}, .builder/.play{flex:1})
   -- this one didn't, so as a flex child with no size hint it sized to its
   content's preferred width instead of the viewport, and the @media(max-width:
   780px) column-collapse below never got a narrow enough box to matter. */
.rules{display:flex;align-items:stretch;min-height:calc(100vh - 64px);flex:1;min-width:0}
.rules-side{width:300px;flex:0 0 300px;border-right:1px solid var(--line);padding:12px 10px 18px;overflow-y:auto;max-height:calc(100vh - 64px);position:sticky;top:0}
.rules-side-top{display:flex;flex-direction:column;gap:8px;margin-bottom:10px}
.rules-side-top input{width:100%;background:var(--ink-700);color:var(--paper);border:1px solid var(--line);border-radius:6px;padding:7px 10px}
.rules-tree{font-size:13px}
.rt-type{font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--brass-bright);margin:14px 4px 4px;font-weight:700}
.rt-src{font-size:11.5px;color:var(--paper-faint);margin:8px 4px 2px;font-weight:600}
.rt-chap{padding:4px 6px;border-radius:5px;cursor:pointer;color:var(--paper);font-weight:600}
.rt-chap:hover{background:var(--ink-800)}
.rt-chap.active{background:var(--ink-700)}
.rt-tw{display:inline-block;width:12px;color:var(--paper-faint)}
.rt-sec{padding:3px 6px 3px 24px;border-radius:5px;cursor:pointer;color:var(--paper-faint)}
.rt-sec:hover{background:var(--ink-800);color:var(--paper)}
.rt-sec.active{background:var(--ink-700);color:var(--brass-bright)}
.rules-version{margin-top:16px;font-size:10.5px;color:var(--paper-faint);line-height:1.5;border-top:1px solid var(--line);padding-top:10px}
.rules-main{flex:1;min-width:0;padding:20px 30px 60px;overflow-y:auto;max-height:calc(100vh - 64px)}
.rules-main>*{max-width:820px}
.rules-crumb{font-size:12px;color:var(--paper-faint);margin-bottom:4px}
.rules-pageref{opacity:.8}
.rules-h1{font-size:26px;margin:2px 0 14px}
.rules-body p{margin:0 0 10px;line-height:1.65;font-size:14px}
.rules-body h4{margin:16px 0 6px;font-size:15px;color:var(--brass-bright)}
.rules-body ul{margin:0 0 10px 20px;line-height:1.6;font-size:14px}
.rules-body li{margin-bottom:3px}
.rules-body mark,.rh-snippet mark{background:var(--brass-bright);color:#1a1408;border-radius:2px;padding:0 1px}
.rules-children{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px;margin-top:14px}
.rules-childlink{border:1px solid var(--line);border-radius:6px;padding:9px 12px;cursor:pointer;font-size:13.5px}
.rules-childlink:hover{background:var(--ink-800);border-color:var(--brass)}
.rules-hit{border-bottom:1px solid var(--line);padding:10px 2px;cursor:pointer}
.rules-hit:hover{background:var(--ink-800)}
.rh-crumb{font-size:11.5px;color:var(--paper-faint)}
.rh-title{font-weight:700;font-size:15px;margin:2px 0}
.rh-snippet{font-size:12.5px;color:var(--paper-faint);line-height:1.5}
.rules-empty{color:var(--paper-faint)}
@media(max-width:780px){
  .rules{flex-direction:column}
  .rules-side{width:100%;flex:none;position:static;max-height:38vh;border-right:0;border-bottom:1px solid var(--line)}
  .rules-main{max-height:none;padding:14px}
}
/* Type filter chips — shared by the Compendium's own search pane and the
   quick-search overlay below. [2026-09-16] */
.rules-type-filters{display:flex;gap:6px;flex-wrap:wrap;margin:2px 0 14px}
/* Quick-search overlay [2026-09-16] — a Ctrl/Cmd+K command palette reachable
   from any screen; reuses .rules-hit/.rh-* and .rules-type-filters so a hit
   looks identical here and in the full Compendium. */
.modal.modal-rules-quick{max-width:640px}
.rules-quick input{width:100%;background:var(--ink-700);color:var(--paper);border:1px solid var(--line);
  border-radius:6px;padding:10px 12px;font-size:15px;margin-bottom:10px}
.rules-quick #rulesQuickResults{max-height:50vh;overflow-y:auto}
@media(max-width:600px){
  .modal.modal-rules-quick{max-width:none}
  .rules-quick input{font-size:16px} /* >=16px stops iOS Safari auto-zooming on focus */
}
/* kv stat tables (spell/item blocks) inside rules sections [2026-07-16] */
.rules-kv{border-collapse:collapse;margin:4px 0 12px;font-size:13.5px;min-width:260px}
.rules-kv th{text-align:left;color:var(--brass-bright);font-weight:600;padding:3px 14px 3px 0;vertical-align:top;white-space:nowrap}
.rules-kv td{padding:3px 0;line-height:1.5}
.rules-kv tr{border-bottom:1px solid var(--line)}
.rules-kv tr:last-child{border-bottom:0}
/* entry spacing + level tables in rules sections [2026-07-16 formatting pass] */
.rules-body h4{margin:26px 0 8px;padding-top:16px;border-top:1px solid var(--line);font-size:15.5px}
.rules-body h4:first-child{margin-top:8px;padding-top:0;border-top:0}
.rules-lvl{border-collapse:collapse;margin:8px 0 16px;font-size:13.5px;width:100%;max-width:640px}
.rules-lvl th{text-align:left;color:var(--brass-bright);font-weight:700;border-bottom:2px solid var(--brass);padding:5px 10px 5px 0;font-size:12px;letter-spacing:.06em;text-transform:uppercase}
.rules-lvl td{padding:5px 10px 5px 0;line-height:1.5;border-bottom:1px solid var(--line);vertical-align:top}
.rules-lvl .rl-n{font-weight:700;color:var(--brass-bright);width:52px}
.rules-lvl tr:nth-child(even) td{background:rgba(255,255,255,.02)}
.rules-num{display:inline-block;background:var(--ink-700);border:1px solid var(--line);border-radius:4px;padding:0 5px;margin:0 1px;font-weight:600;font-size:12.5px}
.talent-subpicker{grid-column:1/-1;background:var(--ink-750);border:1px solid var(--brass-deep);border-radius:var(--r-sm);padding:12px 14px;margin:2px 0 4px}
.talent-subpicker .attr-edit{display:grid;grid-template-columns:repeat(auto-fill,minmax(90px,1fr));gap:8px;margin-top:8px}
.talent-subpicker .sc-grid-compact{max-height:220px;overflow-y:auto}

/* ── Homebrew Editor: live preview card [2026-09-19] ──────────────────────
   Mirrors the compendium-entry look (statline/.b, .opt, .sub-card,
   .supply-row) so the preview reads as the real thing, not a mockup. Scoped
   entirely under .hb-preview — reuses existing shared classes unscoped. */
.hb-preview{background:var(--ink-800);border:1px solid var(--line);border-radius:8px;padding:14px;margin-bottom:14px}
.hb-prev-eyebrow{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--paper-faint);margin-bottom:8px}
.hb-prev-hd{margin-bottom:10px}
.hb-prev-name{font-family:var(--display);font-size:18px}
.hb-prev-sub{color:var(--brass);font-size:12px;letter-spacing:.06em;margin-top:2px}
.hb-prev-desc{color:var(--paper);white-space:pre-wrap;font-size:13px;line-height:1.55}
.hb-preview .ph{color:var(--paper-faint);font-style:italic}
.hb-preview .opt,.hb-preview .sub-card{margin-bottom:0}
.hb-prev-pending{border-style:dashed;opacity:.7}
