/* Underworld Character Builder — visual layer
 *
 * Direction: verified style `dark-mode-oled` (dark only; requires 4.5:1 text,
 * keyboard operation, visible focus, reduced-motion support) with the verified
 * pairing "Classic Elegant" (Playfair Display display face + Inter body).
 * Palette is taken from the rulebook cover — near-black ground, blood red,
 * gold, and the pale celestial blue of the angel half — rather than a generic
 * slate. Density dial 8/10: this is a data-dense tool, so an 8-32px scale.
 */

/* ---- Tokens ---------------------------------------------------------- */
:root {
  /* Ground */
  --ink:        #0A0A0C;
  --ink-2:      #121116;
  --ink-3:      #1A181F;
  --ink-4:      #24212B;
  --line:       rgba(237, 230, 218, 0.12);
  --line-soft:  rgba(237, 230, 218, 0.06);

  /* Text — 16:1 and 8:1 on the ground */
  --parchment:       #EDE6DA;
  --parchment-dim:   #A89F93;
  --parchment-faint: #776F66;

  /* Brand */
  --blood:      #A8142A;
  --blood-hi:   #C81D33;
  --blood-text: #FF8A95;   /* red that stays readable as text on dark */
  --gold:       #C9A227;
  --gold-hi:    #E0B733;
  --celestial:  #9FC4E8;

  /* Semantic */
  --success: #5BB07D;
  --warn:    #E0A93B;
  --danger:  #F0727D;

  /* Type */
  --font-display: 'Playfair Display', 'Iowan Old Style', Georgia, 'Times New Roman', serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
               'Helvetica Neue', Arial, sans-serif;

  /* Space — dense scale */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 20px; --s6: 24px; --s7: 32px; --s8: 48px;

  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.5);
  --shadow-2: 0 8px 28px rgba(0, 0, 0, 0.55);

  --tap: 36px;
}


/* ---- Reset & base ---------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--ink); color: var(--parchment);
  font-family: var(--font-body); font-size: 16px; line-height: 1.6;
  font-feature-settings: 'kern' 1;
}
h1,h2,h3,h4 { font-family: var(--font-display); font-weight: 600; line-height: 1.25; margin: 0; }
a { color: var(--celestial); text-decoration-color: rgba(159,196,232,.4); text-underline-offset: 2px; }
a:hover { text-decoration-color: var(--celestial); }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-radius: 3px; }
[hidden] { display: none !important; }
.visually-hidden {
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
.skip { position:absolute; left:-9999px; top:var(--s2); z-index:100;
  background:var(--ink-3); color:var(--parchment); padding:var(--s3) var(--s4);
  border:1px solid var(--gold); border-radius:var(--radius-sm); }
.skip:focus { left: var(--s2); }

/* ---- Shell ----------------------------------------------------------- */
.shell { min-height:100vh; display:flex; flex-direction:column; }
.topbar {
  position:sticky; top:0; z-index:40; background:rgba(10,10,12,.92);
  backdrop-filter: blur(10px); border-bottom:1px solid var(--line);
  display:flex; align-items:center; gap:var(--s4); padding:var(--s3) var(--s4);
}
.brand { display:flex; align-items:center; gap:var(--s3); text-decoration:none; color:inherit; flex:0 0 auto; }
.brand svg { color: var(--blood-hi); flex:0 0 auto; }
.brand { min-height: var(--tap); }
.brand b { font-family:var(--font-display); font-size:19px; letter-spacing:.2px; display:block; }
.brand .sub { font-size:10px; letter-spacing:.16em; text-transform:uppercase; color:var(--parchment-faint); display:block; }

/* ---- Search ---------------------------------------------------------- */
.searchwrap { position:relative; flex:1 1 auto; max-width:620px; }
.searchbox { display:flex; align-items:center; gap:var(--s2);
  background:var(--ink-2); border:1px solid var(--line); border-radius:var(--radius-md);
  padding:0 var(--s3); transition:border-color .15s var(--ease), box-shadow .15s var(--ease); }
.searchbox:focus-within { border-color:var(--gold); box-shadow:0 0 0 3px rgba(201,162,39,.14); }
.searchbox svg { color:var(--parchment-faint); flex:0 0 auto; }
.searchbox input {
  flex:1; background:none; border:0; color:var(--parchment);
  font:inherit; padding:10px 0; min-width:0; outline:none;
}
.searchbox input::placeholder { color:var(--parchment-faint); }
.kbd { font:600 11px var(--font-body); color:var(--parchment-faint);
  border:1px solid var(--line); border-radius:4px; padding:2px 6px; white-space:nowrap; }

.results { position:absolute; top:calc(100% + 6px); left:0; right:0; z-index:50;
  background:var(--ink-2); border:1px solid var(--line); border-radius:var(--radius-md);
  box-shadow:var(--shadow-2); max-height:min(70vh,560px); overflow:auto; padding:var(--s2); }
.res { display:block; width:100%; text-align:left; background:none; border:0; color:inherit;
  padding:var(--s3); border-radius:var(--radius-sm); cursor:pointer; font:inherit; }
.res:hover, .res[aria-selected="true"] { background:var(--ink-3); }
.res-top { display:flex; align-items:baseline; gap:var(--s2); flex-wrap:wrap; }
.res-title { font-weight:600; color:var(--parchment); }
.res-cite { font-size:11px; color:var(--gold); white-space:nowrap; }
.res-snip { font-size:13px; color:var(--parchment-dim); margin-top:3px;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.res mark { background:rgba(201,162,39,.26); color:var(--gold-hi); border-radius:2px; padding:0 1px; }
.res-empty { padding:var(--s5); text-align:center; color:var(--parchment-dim); }
.res-empty b { color:var(--parchment); display:block; margin-bottom:var(--s2); font-family:var(--font-display); }
.res-chip { display:inline-block; margin:3px; padding:4px 10px; border:1px solid var(--line);
  border-radius:999px; background:var(--ink-3); color:var(--parchment-dim); font-size:12px; cursor:pointer; }
.res-chip:hover { border-color:var(--gold); color:var(--gold); }
.res-head { font-size:10px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--parchment-faint); padding:var(--s3) var(--s3) var(--s1); }

/* ---- Layout ---------------------------------------------------------- */
.main { display:grid; grid-template-columns:300px minmax(0,1fr); flex:1; align-items:start; }
.side { position:sticky; top:61px; max-height:calc(100vh - 61px); overflow:auto;
  border-right:1px solid var(--line); padding:var(--s4); }
.side h2 { font-size:10px; letter-spacing:.16em; text-transform:uppercase;
  color:var(--parchment-faint); margin:var(--s5) 0 var(--s2); font-family:var(--font-body); font-weight:700; }
.side h2:first-child { margin-top:0; }
.navbtn { display:flex; align-items:center; gap:var(--s2); width:100%; text-align:left;
  background:none; border:0; color:var(--parchment-dim); font:inherit; font-size:14px;
  padding:7px var(--s3); border-radius:var(--radius-sm); cursor:pointer; min-height:var(--tap); }
.navbtn:hover { background:var(--ink-2); color:var(--parchment); }
.navbtn[aria-current="true"] {
  background:linear-gradient(90deg, rgba(168,20,42,.22), transparent);
  color:var(--parchment); box-shadow:inset 2px 0 0 var(--blood-hi); font-weight:600;
}
.navbtn .count { margin-left:auto; font-size:11px; color:var(--parchment-faint); }
.content { padding:var(--s6) var(--s7); max-width:860px; min-width:0; }

/* ---- Reader ---------------------------------------------------------- */
.crumbs { font-size:12px; color:var(--parchment-faint); margin-bottom:var(--s3); }
.crumbs span + span::before { content:'›'; margin:0 var(--s2); color:var(--line); }
.doc h1 { font-size:clamp(26px,4vw,34px); margin-bottom:var(--s2); }
.cite { display:inline-flex; align-items:center; gap:var(--s2); font-size:12px;
  color:var(--gold); border:1px solid rgba(201,162,39,.3); background:rgba(201,162,39,.07);
  padding:3px 10px; border-radius:999px; }
.doc section { margin-top:var(--s7); scroll-margin-top:80px; }
.doc h2 { font-size:22px; color:var(--parchment); margin-bottom:var(--s3);
  padding-bottom:var(--s2); border-bottom:1px solid var(--line); }
.doc h3 { font-size:17px; color:var(--gold-hi); margin:var(--s5) 0 var(--s2); }
.doc p { margin:0 0 var(--s4); color:var(--parchment); max-width:72ch; }
.doc .lead { color:var(--parchment-dim); }
.doc ul { margin:0 0 var(--s4) var(--s5); padding:0; }
.doc li { margin-bottom:var(--s2); max-width:70ch; }

/* charts */
.chart { margin:0 0 var(--s5); border:1px solid var(--line); border-radius:var(--radius-md);
  overflow:auto; background:var(--ink-2); }
.chart table { border-collapse:collapse; width:100%; font-size:14px; }
.chart th, .chart td { padding:8px var(--s3); text-align:left; border-bottom:1px solid var(--line-soft);
  white-space:nowrap; }
.chart thead th { background:var(--ink-3); color:var(--gold); font-weight:600;
  font-size:11px; letter-spacing:.08em; text-transform:uppercase; position:sticky; top:0; }
.chart tbody tr:hover { background:rgba(237,230,218,.03); }
.chart td:first-child { color:var(--parchment); font-weight:500; }

/* cross references */
.xrefs { margin-top:var(--s7); padding-top:var(--s5); border-top:1px solid var(--line); }
.xrefs h3 { font-size:11px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--parchment-faint); font-family:var(--font-body); margin-bottom:var(--s3); }
.xref { display:inline-block; margin:0 var(--s2) var(--s2) 0; padding:6px 12px;
  background:var(--ink-2); border:1px solid var(--line); border-radius:999px;
  font-size:13px; color:var(--parchment-dim); cursor:pointer; }
.xref:hover { border-color:var(--celestial); color:var(--celestial); }

/* flags */
.flag { border:1px solid rgba(224,169,59,.35); background:rgba(224,169,59,.08);
  border-radius:var(--radius-md); padding:var(--s4); margin:0 0 var(--s5); }
.flag > b { color:var(--warn); display:block; margin-bottom:var(--s2); }
.flag p b { color:var(--parchment); }
.flag p { font-size:14px; color:var(--parchment-dim); margin:0; }

/* cards / index */
.grid { display:grid; gap:var(--s3); grid-template-columns:repeat(auto-fill,minmax(230px,1fr)); }
.card { background:var(--ink-2); border:1px solid var(--line); border-radius:var(--radius-md);
  padding:var(--s4); text-align:left; cursor:pointer; color:inherit; font:inherit;
  transition:border-color .15s var(--ease), transform .15s var(--ease); }
.card:hover { border-color:var(--gold); transform:translateY(-1px); }
.card b { display:block; margin-bottom:4px; }
.card small { color:var(--parchment-faint); font-size:12px; }
.az { position:sticky; top:61px; background:var(--ink); padding:var(--s3) 0;
  border-bottom:1px solid var(--line); z-index:5; display:flex; flex-wrap:wrap; gap:4px; }
.az button { min-width:28px; min-height:28px; background:var(--ink-2); border:1px solid var(--line);
  color:var(--parchment-dim); border-radius:var(--radius-sm); cursor:pointer; font:600 12px var(--font-body); }
.az button:hover { border-color:var(--gold); color:var(--gold); }
.entry { display:flex; align-items:baseline; gap:var(--s3); padding:var(--s3);
  border-bottom:1px solid var(--line-soft); cursor:pointer; background:none; border-left:0;
  border-right:0; border-top:0; width:100%; text-align:left; color:inherit; font:inherit; }
.entry:hover { background:var(--ink-2); }
.entry b { font-weight:600; }
.entry .meta { margin-left:auto; font-size:11px; color:var(--parchment-faint); white-space:nowrap; }

.booktag { font-size:10px; letter-spacing:.1em; text-transform:uppercase; padding:2px 7px;
  border-radius:999px; border:1px solid var(--line); color:var(--parchment-faint); }
.booktag.core { color:var(--blood-text); border-color:rgba(255,138,149,.3); }
.booktag.soulfrag { color:var(--celestial); border-color:rgba(159,196,232,.3); }
.booktag.synergy { color:var(--gold); border-color:rgba(201,162,39,.3); }
.booktag.monsters { color:var(--success); border-color:rgba(91,176,125,.32); }
.booktag.weapons { color:var(--warn); border-color:rgba(224,169,59,.32); }

.drawer-btn { display:none; }

/* ---- Responsive ------------------------------------------------------ */
@media (max-width: 900px) {
  .main { grid-template-columns:1fr; }
  .side { position:fixed; inset:61px auto 0 0; width:min(82vw,320px); z-index:45;
    background:var(--ink); transform:translateX(-102%); transition:transform .22s var(--ease-out);
    max-height:none; height:calc(100vh - 61px); box-shadow:var(--shadow-2); }
  .side.open { transform:none; }
  .drawer-btn { display:inline-flex; align-items:center; justify-content:center;
    width:var(--tap); height:var(--tap); background:var(--ink-2); border:1px solid var(--line);
    border-radius:var(--radius-sm); color:var(--parchment); cursor:pointer; flex:0 0 auto; }
  .content { padding:var(--s5) var(--s4); }
  .topbar { gap:var(--s2); padding:var(--s2) var(--s3); flex-wrap:wrap; }
  .brand b { font-size:16px; } .brand .sub { display:none; }
  .scrim { position:fixed; inset:61px 0 0; background:rgba(0,0,0,.6); z-index:44; }
}
@media (max-width: 560px) { .searchwrap { order:3; flex-basis:100%; max-width:none; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration:.01ms !important; transition-duration:.01ms !important; }
}

/* ---- Print ----------------------------------------------------------- */
@media print {
  .topbar, .side, .xrefs, .az, .drawer-btn { display:none !important; }
  body { background:#fff; color:#000; }
  .content { max-width:none; padding:0; }
  .doc h1,.doc h2,.doc h3 { color:#000; }
  .doc p, .doc li { color:#000; }
  .chart th { background:#eee; color:#000; }
  .cite { color:#555; border-color:#999; }
  a { color:#000; }
}
.charthint { font-size:11px; color:var(--parchment-faint); margin:-12px 0 var(--s5); font-style:italic; }

/* ---- Glossary -------------------------------------------------------- */
.gterm { padding:var(--s4) 0; border-bottom:1px solid var(--line-soft); }
.gterm-head { display:flex; align-items:baseline; gap:var(--s2); flex-wrap:wrap; margin-bottom:var(--s2); }
.gterm-head b { font-family:var(--font-display); font-size:17px; color:var(--parchment); }
.gterm p { margin:0 0 var(--s2); color:var(--parchment-dim); max-width:72ch; }
.prov { font-size:10px; letter-spacing:.1em; text-transform:uppercase; padding:2px 7px;
  border-radius:999px; border:1px solid var(--line); }
.prov-printed  { color:var(--gold); border-color:rgba(201,162,39,.35); background:rgba(201,162,39,.08); }
.prov-compiled { color:var(--celestial); border-color:rgba(159,196,232,.3); background:rgba(159,196,232,.07); }

/* ---- Spell sphere cheat sheet ---------------------------------------- *
 * A lookup surface, so it is denser than the rules pages: the existing 8-32px
 * scale at its tight end. No new tokens, no new type faces.
 * Deliberately a GRID and not a table: a table at this width needs horizontal
 * scroll on a phone, and a sheet you scroll sideways is useless mid-game.
 * The spell tracks must be allowed to WRAP -- a 1fr track cannot shrink below
 * its content, so nowrap+ellipsis here would overflow the row instead.      */
.sheet-filters { position:sticky; top:61px; z-index:6; background:var(--ink);
  padding:var(--s2) 0 var(--s3); margin-bottom:var(--s2);
  border-bottom:1px solid var(--line-soft); }
.chiprow { display:flex; flex-wrap:wrap; gap:var(--s1) var(--s2); align-items:center;
  margin-bottom:var(--s2); }
.chiplab { font-size:10px; letter-spacing:.12em; text-transform:uppercase;
  color:var(--parchment-faint); min-width:48px; }
.chip { min-height:var(--tap); padding:5px 11px; background:var(--ink-2);
  border:1px solid var(--line); border-radius:999px; color:var(--parchment-dim);
  font:inherit; font-size:13px; cursor:pointer;
  transition:border-color .15s var(--ease), color .15s var(--ease); }
.chip:hover { border-color:var(--gold); color:var(--gold); }
.chip.on { border-color:var(--gold); color:var(--ink); background:var(--gold); font-weight:600; }

.sheet-legend { font-size:12px; color:var(--parchment-faint); margin:0 0 var(--s5); }
.sheet-legend b { color:var(--gold); }

.sphere { margin:0 0 var(--s6); border:1px solid var(--line);
  border-radius:var(--radius-md); background:var(--ink-2); overflow:hidden; }
.sphere-head { display:flex; align-items:center; gap:var(--s2); flex-wrap:wrap;
  padding:var(--s3) var(--s4); background:var(--ink-3);
  border-bottom:1px solid var(--line); }
.sphere-head h2 { font-family:var(--font-display); font-size:19px; margin:0;
  color:var(--gold); }
.sphere-more { margin-left:auto; }
.sphere-meta { display:flex; flex-wrap:wrap; gap:var(--s2) var(--s6); margin:0;
  padding:var(--s3) var(--s4); border-bottom:1px solid var(--line-soft); }
.sphere-meta dt { font-size:10px; letter-spacing:.12em; text-transform:uppercase;
  color:var(--parchment-faint); }
.sphere-meta dd { margin:2px 0 0; font-size:14px; color:var(--parchment); }

.sph-rows { padding:var(--s2) var(--s3) var(--s3); }
.sph-row { display:grid; grid-template-columns:30px minmax(0,1fr) minmax(0,1fr);
  gap:var(--s1) var(--s2); align-items:stretch;
  border-bottom:1px solid var(--line-soft); padding:3px 0; }
.sph-row:last-child { border-bottom:0; }
.sph-lvl { display:flex; align-items:center; justify-content:center;
  font-family:var(--font-display); font-size:15px; font-weight:600;
  color:var(--blood-text); }
.spell { display:flex; align-items:center; gap:6px; flex-wrap:wrap;
  min-height:var(--tap); min-width:0; padding:5px var(--s2); text-align:left;
  background:transparent; border:1px solid transparent; border-radius:var(--radius-sm);
  color:var(--parchment); font:inherit; font-size:14px; cursor:pointer;
  transition:background .14s var(--ease), border-color .14s var(--ease); }
.spell:hover { background:var(--ink-3); border-color:var(--line); color:var(--gold); }
.spell-nm { min-width:0; }
.pre { color:var(--gold); font-weight:700; }
.spell-alt { font-size:10.5px; color:var(--parchment-faint); white-space:nowrap; }

@media (max-width: 620px) {
  /* Stack the two spells in one column and let the level number span both,
     so the row never scrolls sideways. */
  .sph-row { grid-template-columns:30px minmax(0,1fr); }
  .sph-lvl { grid-row:1 / span 2; align-items:flex-start; padding-top:9px; }
  /* 12 sphere chips + 10 level chips wrap to ~250px on a phone. Pinned, that
     is a third of the screen held back from the spells you opened this for,
     so below 620px the filters scroll away with the page. */
  .sheet-filters { position:static; }
  .chiplab { min-width:100%; }
}
@media print {
  .sheet-filters, .sphere-more { display:none !important; }
  .sphere { break-inside:avoid; border-color:#999; background:#fff; }
  .sphere-head, .sphere-meta { background:#fff; }
  .sphere-head h2, .sph-lvl, .pre { color:#000; }
}


/* ---- UW-BACKBTN: back button + cross-tool switcher ----------------- */
/* Deliberately in .content, NOT the sticky topbar: the bar is already 61px and
   prior mobile work showed sticky height is the scarce resource on a phone. */
.backbar { margin: 0 0 var(--s4); }
.backbtn {
  display: inline-flex; align-items: center; gap: var(--s2);
  min-height: var(--tap); padding: var(--s2) var(--s4) var(--s2) var(--s3);
  background: var(--ink-2); color: var(--parchment-dim);
  border: 1px solid var(--line); border-radius: 999px;
  font: inherit; font-size: 13.5px; cursor: pointer;
  transition: color 180ms var(--ease), border-color 180ms var(--ease),
              background 180ms var(--ease);
}
.backbtn:hover { color: var(--parchment); border-color: rgba(201,162,39,.45); background: var(--ink-3); }
.backbtn b { color: var(--parchment); font-weight: 600; }
.backbtn svg { flex: 0 0 auto; transition: transform 180ms var(--ease-out); }
.backbtn:hover svg { transform: translateX(-2px); }
.backbtn:focus-visible { outline: 2px solid var(--gold-hi); outline-offset: 3px; }
/* The label can be a long rule title; let it ellipsis rather than widen the row. */
.backbtn span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 46ch; }

.xtool { display: flex; gap: var(--s1); flex: 0 0 auto; }
.xtool-link {
  display: inline-flex; align-items: center; min-height: var(--tap);
  padding: var(--s2) var(--s3); border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 500; color: var(--parchment-dim);
  text-decoration: none; white-space: nowrap;
  transition: background 180ms var(--ease), color 180ms var(--ease);
}
.xtool-link:hover { background: var(--ink-2); color: var(--parchment); }
.xtool-link:focus-visible { outline: 2px solid var(--gold-hi); outline-offset: 2px; }
/* On a phone the search field needs the whole row, so the switcher drops out of the
   topbar and the drawer carries the links instead. Growing the topbar is NOT an
   option here: .side, .az, .scrim and .sheet-filters all pin to a hardcoded 61px. */
/* Deliberately NOT class .navbtn: that selector means "a rulebook nav button" and
   the app's own browser suite waits on the FIRST .navbtn being visible. Borrowing
   it put a desktop-hidden element first in DOM order and broke that wait. */
.xtool-drawer { display: none; }
.xtool-dnav {
  display: flex; align-items: center; gap: var(--s2); width: 100%;
  padding: 7px var(--s3); min-height: var(--tap);
  border-radius: var(--radius-sm); color: var(--parchment-dim);
  font-size: 14px; text-decoration: none;
}
.xtool-dnav:hover { background: var(--ink-2); color: var(--parchment); }
.xtool-dnav:focus-visible { outline: 2px solid var(--gold-hi); outline-offset: 2px; }
@media (max-width: 860px) {
  .xtool { display: none; }
  .xtool-drawer { display: block; margin-bottom: var(--s5);
    padding-bottom: var(--s4); border-bottom: 1px solid var(--line); }
}
@media (prefers-reduced-motion: reduce) {
  .backbtn, .backbtn svg, .xtool-link { transition: none; }
}
