/* ==========================================================================
   KING rules site - royal grimoire design system
   Single stylesheet. No frameworks, no client libraries.

   CONTENTS
     1  tokens ................ colours, type, spacing, radii (all custom props)
     2  base .................. reset, document, focus, selection
     3  layout ................ topbar, sidebar, main, toc, footer, drawer
     4  prose ................. headings, paragraphs, lists, links, rules
     5  components ............ see the index below
     6  palette ............... command-palette search
     7  utilities ............. stat colours, chip rows, spacing helpers
     8  responsive ............ 360px -> 4K
     9  print ................. statblocks and reference pages on paper
     10 motion ................ prefers-reduced-motion

   COMPONENT INDEX (markup patterns are demonstrated on /styleguide.html)
     .statblock          creature statblock card
     .statband           key/value band inside a statblock
     .stat-table         six-stat table (value / mod / die)
     .tier-badge         T3 + die glyph, --t1 .. --t5
     .role-chip          --minor (steel) --major (gold) --sovereign (maroon)
     .ability            ability card, --passive --maneuver --declaration
                         --reaction --deed
     .spell              spell / prayer / litany card with tier + cost line
     .ladder             tree rank ladder (.ladder__rung + .ladder__tier)
     .data-table         data table, sticky header, zebra, tabular numerals
                         (always wrapped in .table-wrap for overflow)
     .callout            --note --example --gm --danger --rule
     .filterbar          filter pill bar + text box + live count
     .cardgrid / .card   image card grid (bestiary browser)
     .tilegrid / .tile   section tiles (landing page)
     .chiprow .tag .kbd .lede .orn .statline
   ========================================================================== */


/* ==========================================================================
   1  TOKENS
   ========================================================================== */

:root {
  color-scheme: dark;

  --font-display: "Cinzel", "Trajan Pro", "Palatino Linotype", Georgia, serif;
  --font-body: "Source Serif 4", "Iowan Old Style", "Palatino Linotype", Georgia, serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", "Consolas", monospace;

  --step--2: clamp(.72rem, .70rem + .10vw, .78rem);
  --step--1: clamp(.84rem, .81rem + .14vw, .92rem);
  --step-0:  clamp(1rem, .97rem + .17vw, 1.09rem);
  --step-1:  clamp(1.18rem, 1.12rem + .30vw, 1.36rem);
  --step-2:  clamp(1.42rem, 1.31rem + .52vw, 1.78rem);
  --step-3:  clamp(1.70rem, 1.50rem + .95vw, 2.40rem);
  --step-4:  clamp(2.10rem, 1.70rem + 1.90vw, 3.60rem);

  --sp-1: .25rem;  --sp-2: .5rem;   --sp-3: .75rem;  --sp-4: 1rem;
  --sp-5: 1.5rem;  --sp-6: 2rem;    --sp-7: 3rem;    --sp-8: 4.5rem;

  --r-sm: 3px;  --r-md: 5px;  --r-lg: 9px;
  --sidebar-w: 16.5rem;
  --toc-w: 14rem;
  --topbar-h: 3.5rem;
  --measure: 74ch;

  --ease: cubic-bezier(.22, .61, .36, 1);
}

/* --- dark: inky navy ground, claret accent, gold ornament ---------------- */
/* Three roles, and they do not trade places.
     accent (maroon) = anything the reader acts on or follows: links, the
       active nav item, hovers, the current TOC marker, focus, selection.
     navy            = structure. In this theme it is the ground itself, and
       raised to a slate for the few places structure has to be text.
     gold            = ornament only: crown, wordmark, tier badge, the
       decorative rules, corner flourishes, list marks.
   A true maroon and a true navy are both illegible as text on a near-black
   ground, so each has a raised text weight; the deep values stay for fills,
   edges and gradients. Ratios in the comments are against --bg unless said. */
:root,
:root[data-theme="dark"] {
  color-scheme: dark;

  --bg:          #0b0e15;
  --bg-raise:    #11151f;
  --bg-card:     #161b28;
  --bg-sunk:     #070910;
  --bg-inset:    #191e2c;
  --line:        #262d3e;
  --line-strong: #47536c;
  /* a text input is identified by its border alone, so that border owes 3:1
     (WCAG 1.4.11) where a decorative card edge does not. --line is 1.5:1 on
     the sunk fill; this is the same navy raised until it clears on the
     lightest fill it lands on (--bg-inset, the select). 3.9:1 on --bg-sunk,
     3.3:1 on --bg-inset. */
  --line-input:  #606e8c;

  --text:        #e9e0cf;   /* 14.7:1 - warm ivory, deliberately not blue */
  --text-dim:    #b0a898;   /* 8.6:1  */
  --text-faint:  #8f8878;   /* 5.5:1 on --bg, 4.7:1 on --bg-inset */

  --accent:        #d9767f;   /* 6.3:1 on --bg, 5.6:1 on --bg-card */
  --accent-bright: #e88b91;   /* 7.8:1 on --bg, 7.0:1 on --bg-card */
  --accent-soft:   #c06a70;   /* 5.1:1 on --bg - small ornament and edges */
  --accent-deep:   #7e3038;
  --accent-wash:   rgba(217, 118, 127, .13);
  --accent-line:   rgba(217, 118, 127, .34);
  /* the link underline is the non-colour cue that marks a link, so it is the
     one accent edge that has to clear 3:1 on its own. At .34 it read as
     nothing (1.7:1) and links were left leaning on a 1.3:1 colour shift
     against body text. 3.6:1 on --bg, 3.7:1 on --bg-card. */
  --accent-underline: rgba(217, 118, 127, .75);

  --navy-head:  #dfe4ef;   /* 15.1:1 - page titles */
  --navy-text:  #9dbadf;   /* 9.7:1 on --bg, 8.3:1 on --bg-inset */
  --navy-line:  rgba(157, 186, 223, .30);
  --navy-wash:  rgba(157, 186, 223, .08);

  --gold:        #d9b872;
  --gold-bright: #f0d8a0;
  --gold-soft:   #b0904f;
  --gold-deep:   #7d6531;
  --gold-wash:   rgba(217, 184, 114, .10);
  --gold-line:   rgba(217, 184, 114, .26);

  --danger:      #e2664a;
  --danger-soft: #ec8b74;   /* 6.7:1 on the tinted callout card */
  --danger-wash: rgba(226, 102, 74, .12);

  --stat-body:    #e2895f;
  --stat-mind:    #74a6e2;
  --stat-sense:   #63bb97;
  --stat-heart:   #e178ad;
  --stat-cunning: #b58ce4;
  --stat-fate:    #e2c476;

  --hp-vitality: #e2664a;
  --hp-stamina:  #5f9ed6;
  --hp-vigor:    #58b3a2;
  --hp-wound:    #c96b52;      /* 5.3:1 on --bg, 4.7:1 on --bg-card */
  --hp-wound-soft: #dd9078;    /* wound hue at title contrast on a dark card */

  --scrim: rgba(4, 6, 12, .66);

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .5);
  --shadow-md: 0 6px 20px -8px rgba(0, 0, 0, .8);
  --shadow-lg: 0 24px 60px -20px rgba(0, 0, 0, .88);
  --grain-opacity: .035;
  --vignette: radial-gradient(120% 80% at 50% -10%, rgba(217, 184, 114, .05), transparent 60%);
}

/* --- light: aged parchment, iron-gall ink -------------------------------- */
/* The parchment is unchanged. Here the maroon and the navy are true deep
   values: maroon carries the links and state, navy carries the headings and
   the structural card and table furniture, gold is ornament. The three reds
   on this page are told apart by their blue channel - only the accent has
   more blue than green (wine); the health reds are brick and sienna. */
:root[data-theme="light"] {
  color-scheme: light;
  --bg:          #f2e8d4;
  --bg-raise:    #f8f1e1;
  --bg-card:     #fcf7ec;
  --bg-sunk:     #e6d8ba;
  --bg-inset:    #ede0c6;
  --line:        #d5c4a1;
  --line-strong: #b9a377;
  --line-input:  #8a7449;   /* 3.2:1 on --bg-sunk, 3.7:1 on --bg */

  --text:        #2a2217;
  --text-dim:    #574a37;
  --text-faint:  #6a5c43;   /* 5.0:1 on --bg */

  --accent:        #962a36;   /* 6.2:1 on --bg, 5.3:1 on --bg-sunk */
  --accent-bright: #7a1c28;   /* 8.5:1 on --bg, 9.7:1 on --bg-card */
  --accent-soft:   #8c2733;   /* 6.7:1 on --bg */
  --accent-deep:   #5f131d;
  --accent-wash:   rgba(150, 42, 54, .09);
  --accent-line:   rgba(150, 42, 54, .30);
  --accent-underline: rgba(150, 42, 54, .75);   /* 3.8:1 on --bg, 4.3:1 on --bg-card */

  --navy-head:  #1d3357;   /* 10.4:1 on --bg */
  --navy-text:  #24406e;   /* 8.5:1 on --bg, 7.9:1 on --bg-inset */
  --navy-line:  rgba(29, 51, 87, .30);
  --navy-wash:  rgba(29, 51, 87, .07);

  /* gold is ornament here too, but the wordmark and the tier badge are text,
     so it stays at the darkest value that still reads as brass */
  --gold:        #7a5a10;
  --gold-bright: #6d500f;
  --gold-soft:   #785a12;
  --gold-deep:   #5b430c;
  --gold-wash:   rgba(138, 103, 22, .08);
  --gold-line:   rgba(138, 103, 22, .28);

  --danger:      #9e2a18;
  --danger-soft: #7d211a;
  --danger-wash: rgba(158, 42, 24, .09);

  --stat-body:    #96461a;   /* 5.4:1 on --bg, 4.6:1 on its own tier-badge tint */
  --stat-mind:    #2a568f;
  --stat-sense:   #1a6a4e;
  --stat-heart:   #96305a;
  --stat-cunning: #613793;
  /* was #806015: 4.46:1 as a .tag on --bg-inset, and hue 42 - the same angle
     as the gold ornament token, so a Fate tag and a tier badge were the same
     colour. Darkened and pushed to 49 for 4.9:1 on --bg-inset and a bronze
     that reads as its own stat rather than as gilt. */
  --stat-fate:    #6f5e14;

  --hp-vitality: #9e2a18;
  --hp-stamina:  #26537f;
  --hp-vigor:    #1a6559;
  --hp-wound:    #7a2418;
  --hp-wound-soft: #8a3220;

  --scrim: rgba(26, 22, 15, .5);

  --shadow-sm: 0 1px 2px rgba(90, 70, 35, .16);
  --shadow-md: 0 6px 20px -10px rgba(90, 70, 35, .38);
  --shadow-lg: 0 22px 55px -22px rgba(90, 70, 35, .45);
  --grain-opacity: .05;
  --vignette: radial-gradient(120% 80% at 50% -10%, rgba(138, 103, 22, .06), transparent 60%);
}


/* ==========================================================================
   2  BASE
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--topbar-h) + 1.25rem);
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.65;
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* a faint gilt bloom at the top of the page, then film grain over everything */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: var(--vignette);
}
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: var(--grain-opacity);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23g)'/%3E%3C/svg%3E");
}

img, svg, video { max-width: 100%; height: auto; display: block; }
button, input, select, textarea { font: inherit; color: inherit; }

::selection { background: var(--accent-wash); color: var(--text); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

.skiplink {
  position: fixed;
  top: .5rem;
  left: .5rem;
  z-index: 999;
  padding: .6rem 1rem;
  background: var(--bg-card);
  color: var(--accent);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-md);
  transform: translateY(-160%);
  transition: transform .18s var(--ease);
}
.skiplink:focus { transform: translateY(0); }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}


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

/* --- topbar -------------------------------------------------------------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  height: var(--topbar-h);
  padding: 0 var(--sp-4);
  background: color-mix(in srgb, var(--bg-raise) 88%, transparent);
  backdrop-filter: blur(10px) saturate(1.1);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 1px 0 var(--gold-wash);
}

.wordmark {
  display: flex;
  align-items: baseline;
  gap: .55rem;
  text-decoration: none;
  color: var(--text);
  white-space: nowrap;
}
.wordmark__crown { color: var(--gold); align-self: center; }
.wordmark__crown svg { filter: drop-shadow(0 0 6px var(--gold-wash)); }
.wordmark__text {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.22rem;
  letter-spacing: .22em;
  color: var(--gold);
}
.wordmark__tag {
  font-size: var(--step--2);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.iconbtn {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  flex: none;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  color: var(--text-dim);
  cursor: pointer;
  transition: color .16s var(--ease), background .16s var(--ease), border-color .16s var(--ease);
}
.iconbtn:hover { color: var(--accent); background: var(--accent-wash); border-color: var(--accent-line); }

.topbar__menu { display: none; }
.burger, .burger::before, .burger::after {
  display: block;
  width: 17px; height: 1.5px;
  background: currentColor;
  border-radius: 2px;
}
.burger { position: relative; }
.burger::before, .burger::after { content: ""; position: absolute; left: 0; }
.burger::before { top: -5px; }
.burger::after { top: 5px; }

.searchbtn {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex: 1 1 auto;
  max-width: 30rem;
  margin-left: auto;
  padding: .42rem .7rem;
  background: var(--bg-sunk);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  color: var(--text-faint);
  font-size: var(--step--1);
  cursor: pointer;
  text-align: left;
  transition: border-color .16s var(--ease), color .16s var(--ease), background .16s var(--ease);
}
.searchbtn:hover { border-color: var(--accent-line); color: var(--text-dim); background: var(--bg-inset); }
.searchbtn__icon { display: flex; color: var(--accent-soft); }
.searchbtn__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.searchbtn__keys { margin-left: auto; display: flex; gap: 3px; }

kbd, .kbd {
  font-family: var(--font-mono);
  font-size: .72em;
  line-height: 1;
  padding: .28em .42em;
  color: var(--text-dim);
  background: var(--bg-inset);
  border: 1px solid var(--line-strong);
  border-bottom-width: 2px;
  border-radius: var(--r-sm);
  white-space: nowrap;
}

.themebtn__sun { display: none; }
:root[data-theme="light"] .themebtn__sun { display: block; }
:root[data-theme="light"] .themebtn__moon { display: none; }

/* --- shell grid ---------------------------------------------------------- */
.layout {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  align-items: start;
  max-width: 100rem;
  margin: 0 auto;
}
.layout.has-toc { grid-template-columns: var(--sidebar-w) minmax(0, 1fr) var(--toc-w); }
.page--full .layout { display: block; max-width: none; }
.page--full .main { padding: 0; }
.page--full .prose { max-width: none; }
/* layout: "wide" keeps the sidebar but drops the TOC and the reading measure,
   for browsers and directories (bestiary index, spell lists) */
.page--wide .prose { max-width: none; }

/* --- sidebar ------------------------------------------------------------- */
.sidebar {
  position: sticky;
  top: var(--topbar-h);
  align-self: start;
  height: calc(100vh - var(--topbar-h));
  overflow-y: auto;
  overscroll-behavior: contain;
  border-right: 1px solid var(--line);
  background: color-mix(in srgb, var(--bg-raise) 55%, transparent);
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
}
.sidebar__inner { padding: var(--sp-5) var(--sp-3) var(--sp-8); }

.navgroup { margin-bottom: .15rem; }
.navgroup__toggle {
  display: flex;
  align-items: center;
  gap: .5rem;
  width: 100%;
  padding: .45rem .6rem;
  background: none;
  border: 0;
  border-radius: var(--r-md);
  color: var(--text-dim);
  cursor: pointer;
  font-family: var(--font-display);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  transition: color .16s var(--ease), background .16s var(--ease);
}
.navgroup__toggle:hover { color: var(--accent); background: var(--accent-wash); }
.navgroup__name { flex: 1; text-align: left; }
.navgroup__chev {
  width: 7px; height: 7px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg);
  transition: transform .2s var(--ease);
  opacity: .7;
}
.navgroup.is-open > .navgroup__toggle .navgroup__chev { transform: rotate(45deg); }
.navgroup.is-open > .navgroup__toggle { color: var(--text); }

.navgroup__list {
  list-style: none;
  margin: 0 0 .4rem;
  padding: 0 0 0 .35rem;
  display: none;
  border-left: 1px solid var(--line);
  margin-left: .85rem;
}
.navgroup.is-open > .navgroup__list { display: block; }

.navlink, .navgroup__solo {
  display: block;
  padding: .3rem .6rem;
  margin: 1px 0;
  border-radius: var(--r-sm);
  color: var(--text-dim);
  text-decoration: none;
  font-size: var(--step--1);
  line-height: 1.4;
  transition: color .14s var(--ease), background .14s var(--ease);
}
.navlink:hover, .navgroup__solo:hover { color: var(--accent); background: var(--accent-wash); }
.navlink.is-active, .navgroup__solo.is-active {
  color: var(--accent-bright);
  background: var(--accent-wash);
  box-shadow: inset 2px 0 0 var(--accent);
}
.navgroup__solo {
  font-family: var(--font-display);
  font-size: var(--step--1);
  letter-spacing: .1em;
  text-transform: uppercase;
  font-weight: 600;
  padding: .45rem .6rem;
}

.navsub { list-style: none; margin: .5rem 0 .25rem; }
.navsub__label {
  display: block;
  padding: 0 .6rem;
  font-size: var(--step--2);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.navsub ul { list-style: none; margin: .1rem 0 0; padding: 0; }

.scrim {
  position: fixed;
  inset: 0;
  z-index: 55;
  background: var(--scrim);
  backdrop-filter: blur(2px);
  border: 0;
}
.scrim[hidden] { display: none; }

/* --- main ---------------------------------------------------------------- */
.main {
  min-width: 0;
  padding: var(--sp-6) var(--sp-6) var(--sp-8);
}
.main:focus { outline: none; }

.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .45rem;
  margin-bottom: var(--sp-4);
  font-size: var(--step--2);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.crumbs a { color: var(--text-faint); text-decoration: none; }
.crumbs a:hover { color: var(--accent); }
.crumbs__sep { color: var(--text-faint); }
.crumbs [aria-current] { color: var(--text-dim); }

.prose { max-width: var(--measure); }
.prose--wide { max-width: none; }

/* --- toc ----------------------------------------------------------------- */
.toc {
  position: sticky;
  top: var(--topbar-h);
  align-self: start;
  max-height: calc(100vh - var(--topbar-h));
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--sp-6) var(--sp-4) var(--sp-8) 0;
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
}
.toc__title {
  margin: 0 0 .6rem;
  padding-left: .75rem;
  font-family: var(--font-display);
  font-size: var(--step--2);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.toc__list { list-style: none; margin: 0; padding: 0; border-left: 1px solid var(--line); }
.toc__item a {
  display: block;
  padding: .25rem .5rem .25rem .75rem;
  margin-left: -1px;
  border-left: 2px solid transparent;
  color: var(--text-faint);
  font-size: var(--step--2);
  line-height: 1.45;
  text-decoration: none;
  transition: color .14s var(--ease), border-color .14s var(--ease);
}
.toc__item--h3 a { padding-left: 1.5rem; font-size: calc(var(--step--2) * .96); }
.toc__item a:hover { color: var(--accent); }
.toc__item a.is-current { color: var(--accent-bright); border-left-color: var(--accent); }

/* --- footer -------------------------------------------------------------- */
.footer {
  position: relative;
  z-index: 1;
  margin-top: var(--sp-8);
  border-top: 1px solid var(--line);
  background: var(--bg-sunk);
}
.footer::before {
  content: "";
  display: block;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--gold-line), transparent);
}
.footer__inner {
  max-width: 62rem;
  margin: 0 auto;
  padding: var(--sp-6) var(--sp-5);
  display: grid;
  gap: var(--sp-3);
  text-align: center;
}
.footer__brand { display: flex; align-items: center; justify-content: center; gap: .5rem; color: var(--gold); }
.footer__name {
  margin: 0;
  font-family: var(--font-display);
  letter-spacing: .2em;
  font-size: var(--step--1);
  color: var(--gold);
}
.footer__name span { color: var(--text-faint); letter-spacing: .12em; }
.footer__note { margin: 0; color: var(--text-faint); font-size: var(--step--1); }
.footer__links { display: flex; flex-wrap: wrap; gap: var(--sp-4); justify-content: center; margin: 0; }
.footer__links a { color: var(--text-dim); font-size: var(--step--1); text-decoration: none; border-bottom: 1px solid var(--line-strong); }
.footer__links a:hover { color: var(--accent); border-color: var(--accent); }
.footer__dl { color: var(--accent) !important; }

.totop {
  position: fixed;
  right: 1.1rem;
  bottom: 1.1rem;
  z-index: 50;
  width: 2.5rem; height: 2.5rem;
  display: grid; place-items: center;
  background: var(--bg-card);
  color: var(--accent);
  border: 1px solid var(--accent-line);
  border-radius: 50%;
  box-shadow: var(--shadow-md);
  cursor: pointer;
  opacity: 0;
  transform: translateY(10px);
  pointer-events: none;
  transition: opacity .2s var(--ease), transform .2s var(--ease);
}
.totop.is-shown { opacity: 1; transform: none; pointer-events: auto; }


/* ==========================================================================
   4  PROSE
   ========================================================================== */

.prose h1, .prose h2, .prose h3, .prose h4, .prose h5, .prose h6 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.18;
  color: var(--text);
  scroll-margin-top: calc(var(--topbar-h) + 1rem);
  text-wrap: balance;
}

.prose h1 {
  margin: 0 0 var(--sp-5);
  font-size: var(--step-3);
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--navy-head);
}
.prose h1::after {
  content: "";
  display: block;
  width: 100%;
  height: 1px;
  margin-top: .7rem;
  background: linear-gradient(90deg, var(--accent), var(--accent-line) 40%, transparent);
}

.prose h2 {
  margin: var(--sp-7) 0 var(--sp-3);
  font-size: var(--step-2);
  letter-spacing: .04em;
  color: var(--navy-text);
  padding-bottom: .3rem;
  border-bottom: 1px solid var(--line);
}
.prose h3 { margin: var(--sp-6) 0 var(--sp-2); font-size: var(--step-1); letter-spacing: .03em; }
.prose h4 {
  margin: var(--sp-5) 0 var(--sp-2);
  font-size: var(--step-0);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-dim);
}
.prose h5, .prose h6 {
  margin: var(--sp-4) 0 var(--sp-2);
  font-size: var(--step--1);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.prose p { margin: 0 0 var(--sp-4); }
.prose strong { color: var(--text); font-weight: 600; }
.prose em { color: var(--text-dim); }
.prose a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px solid var(--accent-underline);
  transition: border-color .14s var(--ease), color .14s var(--ease);
}
.prose a:hover { color: var(--accent-bright); border-color: var(--accent); }

.prose ul, .prose ol { margin: 0 0 var(--sp-4); padding-left: 1.35rem; }
.prose li { margin-bottom: .35rem; }
.prose li > ul, .prose li > ol { margin: .35rem 0 .1rem; }
.prose ul { list-style: none; padding-left: 1.15rem; }
.prose ul > li { position: relative; }
.prose ul > li::before {
  content: "";
  position: absolute;
  left: -.95rem;
  top: .68em;
  width: 5px; height: 5px;
  background: var(--gold-soft);
  transform: rotate(45deg);
}
.prose ul ul > li::before { background: none; border: 1px solid var(--gold-soft); }

/* component lists opt out of the document list styling. Only lists belong
   here: .filterbar is a div and this rule was flattening its left padding. */
.prose .cardgrid, .prose .tilegrid, .prose .ladder,
.prose .hero__facts, .prose .table-strip {
  padding-left: 0;
  list-style: none;
}
.prose .cardgrid > li::before, .prose .tilegrid > li::before,
.prose .ladder > li::before, .prose .hero__facts > li::before,
.prose .table-strip > li::before { content: none; }

.prose code {
  font-family: var(--font-mono);
  font-size: .86em;
  padding: .12em .35em;
  background: var(--bg-inset);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--accent);
}
.prose pre {
  margin: 0 0 var(--sp-4);
  padding: var(--sp-4);
  overflow-x: auto;
  background: var(--bg-sunk);
  border: 1px solid var(--line);
  border-left: 2px solid var(--navy-text);
  border-radius: var(--r-md);
}
.prose pre code { padding: 0; background: none; border: 0; color: var(--text-dim); font-size: .84em; }

.prose blockquote {
  margin: 0 0 var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  border-left: 2px solid var(--accent-soft);
  background: var(--accent-wash);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  color: var(--text-dim);
}
.prose blockquote p:last-child { margin-bottom: 0; }

hr.rule, .prose hr {
  height: 1px;
  border: 0;
  margin: var(--sp-6) 0;
  background: linear-gradient(90deg, transparent, var(--line-strong) 20%, var(--line-strong) 80%, transparent);
}

/* ornamental divider */
.orn {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin: var(--sp-6) 0;
  color: var(--gold-soft);
}
.orn::before, .orn::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold-line));
}
.orn::after { background: linear-gradient(90deg, var(--gold-line), transparent); }
.orn__mark { font-size: .8rem; letter-spacing: .3em; }

.lede {
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--text-dim);
  font-weight: 300;
  text-wrap: pretty;
}


/* ==========================================================================
   5  COMPONENTS
   ========================================================================== */

/* --- data table ---------------------------------------------------------- */
.table-wrap {
  margin: 0 0 var(--sp-5);
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--bg-card);
  box-shadow: var(--shadow-sm);
  scrollbar-width: thin;
}
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums lining-nums;
}
.data-table th {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: .55rem .8rem;
  text-align: left;
  white-space: nowrap;
  font-family: var(--font-display);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--navy-text);
  background: var(--bg-inset);
  border-bottom: 1px solid var(--navy-line);
}
.data-table td {
  padding: .48rem .8rem;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}
.data-table tbody tr:nth-child(even) { background: color-mix(in srgb, var(--bg-inset) 45%, transparent); }
.data-table tbody tr:hover { background: var(--accent-wash); }
.data-table tbody tr:last-child td { border-bottom: 0; }
.data-table .ta-center { text-align: center; }
.data-table .ta-right { text-align: right; }
.data-table--compact td, .data-table--compact th { padding: .32rem .6rem; }

/* --- tier badge ---------------------------------------------------------- */
.tier-badge {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--gold-line);
  border-radius: var(--r-sm);
  overflow: hidden;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 600;
  line-height: 1;
  letter-spacing: .04em;
  white-space: nowrap;
  --tier-hue: var(--gold);
}
.tier-badge__t {
  padding: .34em .5em;
  background: color-mix(in srgb, var(--tier-hue) 20%, transparent);
  color: var(--tier-hue);
}
.tier-badge__die {
  padding: .34em .5em;
  background: var(--bg-inset);
  color: var(--text-dim);
  border-left: 1px solid var(--gold-line);
}
.tier-badge--t1 { --tier-hue: var(--stat-sense); }
.tier-badge--t2 { --tier-hue: var(--stat-mind); }
.tier-badge--t3 { --tier-hue: var(--stat-fate); }
.tier-badge--t4 { --tier-hue: var(--stat-body); }
.tier-badge--t5 { --tier-hue: var(--accent-bright); }
.tier-badge--t1, .tier-badge--t2, .tier-badge--t3,
.tier-badge--t4, .tier-badge--t5 { border-color: color-mix(in srgb, var(--tier-hue) 45%, transparent); }
.tier-badge--t1 .tier-badge__die, .tier-badge--t2 .tier-badge__die,
.tier-badge--t3 .tier-badge__die, .tier-badge--t4 .tier-badge__die,
.tier-badge--t5 .tier-badge__die { border-left-color: color-mix(in srgb, var(--tier-hue) 45%, transparent); }

/* --- role chip ----------------------------------------------------------- */
.role-chip {
  display: inline-flex;
  align-items: center;
  gap: .35em;
  padding: .3em .6em;
  border-radius: 999px;
  border: 1px solid;
  font-family: var(--font-display);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
}
.role-chip::before {
  content: "";
  width: 6px; height: 6px;
  background: currentColor;
  transform: rotate(45deg);
}
.role-chip--minor { color: var(--text-dim); border-color: var(--line-strong); background: var(--bg-inset); }
.role-chip--major { color: var(--gold); border-color: var(--gold-line); background: var(--gold-wash); }
.role-chip--sovereign {
  color: var(--accent-bright);
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  background: var(--accent-wash);
}
:root[data-theme="light"] .role-chip--sovereign { color: var(--accent); }

.tag {
  display: inline-block;
  padding: .18em .55em;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: var(--step--2);
  color: var(--text-faint);
  background: var(--bg-inset);
  white-space: nowrap;
}

.chiprow { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; }

/* --- statblock ----------------------------------------------------------- */
.statblock {
  position: relative;
  margin: 0 0 var(--sp-6);
  padding: var(--sp-5);
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
}
.statblock::before, .statblock::after {
  content: "";
  position: absolute;
  width: 14px; height: 14px;
  border: 1px solid var(--gold-soft);
  opacity: .75;
  pointer-events: none;
}
.statblock::before { top: 7px; left: 7px; border-right: 0; border-bottom: 0; border-radius: var(--r-md) 0 0 0; }
.statblock::after { bottom: 7px; right: 7px; border-left: 0; border-top: 0; border-radius: 0 0 var(--r-md) 0; }

.statblock__head { display: flex; gap: var(--sp-5); align-items: flex-start; flex-wrap: wrap; }
.statblock__portrait {
  width: 190px;
  flex: none;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border: 1px solid var(--gold-line);
  border-radius: var(--r-md);
  background: var(--bg-sunk);
  box-shadow: var(--shadow-sm);
}
.statblock__ident { flex: 1 1 16rem; min-width: 0; }
.statblock__name {
  margin: 0 0 .2rem;
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 700;
  color: var(--accent);
  line-height: 1.15;
}
.statblock__line {
  margin: 0 0 .7rem;
  font-style: italic;
  color: var(--text-dim);
  font-size: var(--step--1);
}
.statblock__flavor { margin: var(--sp-4) 0 0; color: var(--text-dim); }

/* Component headings live inside .prose, where `.prose h1-h3` out-specifies a
   single component class and would impose the document rhythm on them. These
   restate the component's own scale. Extend the list if another card type
   uses a heading tag. */
.prose .statblock__name { margin: 0 0 .2rem; font-size: var(--step-2); }
.prose .statblock__name::after { content: none; }
.prose .card__title { margin: 0; font-size: var(--step-0); }
.prose .ability__name { margin: 0; font-size: var(--step-0); }
.prose .spell__name { margin: 0; font-size: var(--step-0); }
.prose .tile__title { margin: .3rem 0 .4rem; font-size: var(--step-1); }

/* --- stat band ----------------------------------------------------------- */
.statband {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
  gap: 1px;
  margin: var(--sp-5) 0;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
}
.statband__item { padding: .55rem .75rem; background: var(--bg-inset); }
.statband__k {
  display: block;
  font-size: var(--step--2);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.statband__v {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--step-0);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.statband__v small {
  display: block;
  font-family: var(--font-body);
  font-weight: 400;
  color: var(--text-faint);
  font-size: .68em;
  line-height: 1.3;
}

/* --- six-stat table ------------------------------------------------------ */
.stat-table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.stat-table th, .stat-table td { padding: .4rem .7rem; border-bottom: 1px solid var(--line); text-align: center; }
.stat-table th {
  font-family: var(--font-display);
  font-size: var(--step--2);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-faint);
  font-weight: 600;
}
.stat-table td:first-child, .stat-table th:first-child { text-align: left; }
.stat-table td { font-family: var(--font-mono); font-size: var(--step--1); }
.stat-table td:first-child {
  font-family: var(--font-display);
  letter-spacing: .1em;
  text-transform: uppercase;
  font-size: var(--step--2);
  font-weight: 600;
}
.stat-table tr:last-child td { border-bottom: 0; }
.stat-table .stat--body td:first-child { color: var(--stat-body); }
.stat-table .stat--mind td:first-child { color: var(--stat-mind); }
.stat-table .stat--sense td:first-child { color: var(--stat-sense); }
.stat-table .stat--heart td:first-child { color: var(--stat-heart); }
.stat-table .stat--cunning td:first-child { color: var(--stat-cunning); }
.stat-table .stat--fate td:first-child { color: var(--stat-fate); }

/* --- ability cards ------------------------------------------------------- */
.ability {
  --kind-hue: var(--navy-text);
  position: relative;
  margin: 0 0 var(--sp-4);
  padding: var(--sp-4) var(--sp-4) var(--sp-4) calc(var(--sp-4) + 3px);
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
}
.ability::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--kind-hue);
  border-radius: var(--r-md) 0 0 var(--r-md);
}
.ability__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: .6rem; margin-bottom: .4rem; }
.ability__name {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--step-0);
  font-weight: 600;
  color: var(--text);
  letter-spacing: .02em;
}
.ability__kind {
  font-family: var(--font-display);
  font-size: var(--step--2);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--kind-hue);
  padding: .16em .5em;
  border: 1px solid color-mix(in srgb, var(--kind-hue) 40%, transparent);
  border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--kind-hue) 12%, transparent);
  line-height: 1;
}
.ability__meta { margin-left: auto; font-size: var(--step--2); color: var(--text-faint); font-family: var(--font-mono); }
.ability__body { color: var(--text-dim); font-size: var(--step--1); }
.ability__body > :last-child { margin-bottom: 0; }
.ability__body p { margin: 0 0 .6rem; }

.ability--passive     { --kind-hue: var(--stat-sense); }
.ability--maneuver    { --kind-hue: var(--stat-mind); }
.ability--declaration { --kind-hue: var(--stat-cunning); }
.ability--reaction    { --kind-hue: var(--stat-heart); }
.ability--deed        { --kind-hue: var(--gold); }
.ability--deed { background: linear-gradient(180deg, var(--gold-wash), transparent 55%), var(--bg-card); }

/* --- spell / prayer cards ------------------------------------------------ */
.spell {
  margin: 0 0 var(--sp-4);
  padding: var(--sp-4);
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-left: 2px solid var(--accent-soft);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  scroll-margin-top: calc(var(--topbar-h) + 1rem);
}
.spell__head { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin-bottom: .3rem; }
.spell__name {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--step-0);
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--accent);
}
.spell__tier {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--text-faint);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: .2em .6em;
  white-space: nowrap;
}
.spell__meta {
  margin: 0 0 .55rem;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--text-faint);
  letter-spacing: .02em;
}
.spell__meta span + span::before { content: " | "; color: var(--line-strong); }
.spell__body { font-size: var(--step--1); color: var(--text-dim); }
.spell__body > :last-child { margin-bottom: 0; }
.spell--prayer { border-left-color: var(--stat-sense); }
.spell--litany { border-left-color: var(--stat-heart); }
.spell--discipline { border-left-color: var(--stat-cunning); }
.spell--jutsu { border-left-color: var(--stat-body); }

/* --- rank ladder --------------------------------------------------------- */
.ladder { margin: 0 0 var(--sp-5); padding: 0; list-style: none; position: relative; }
.ladder::before {
  content: "";
  position: absolute;
  left: 1.05rem;
  top: .8rem;
  bottom: .8rem;
  width: 1px;
  background: linear-gradient(180deg, var(--gold-line), var(--line));
}
.ladder__rung {
  position: relative;
  display: flex;
  gap: var(--sp-4);
  padding: .45rem 0;
  margin: 0;
}
.ladder__rung::before { content: none; }
.ladder__tier {
  position: relative;
  z-index: 1;
  flex: none;
  width: 2.1rem; height: 2.1rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--bg-inset);
  border: 1px solid var(--gold-line);
  color: var(--gold);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-weight: 600;
}
.ladder__rung--ultimate .ladder__tier {
  background: var(--gold);
  color: var(--bg);
  border-color: var(--gold-bright);
  box-shadow: 0 0 0 3px var(--gold-wash);
}
:root[data-theme="light"] .ladder__rung--ultimate .ladder__tier { color: var(--bg-card); }
.ladder__text { padding-top: .15rem; color: var(--text-dim); font-size: var(--step--1); }
.ladder__text strong { color: var(--text); }
.ladder__text > :last-child { margin-bottom: 0; }

/* --- callouts ------------------------------------------------------------ */
.callout {
  --call-hue: var(--navy-text);
  position: relative;
  margin: 0 0 var(--sp-5);
  padding: var(--sp-4) var(--sp-4) var(--sp-4) var(--sp-5);
  background: color-mix(in srgb, var(--call-hue) 7%, var(--bg-card));
  border: 1px solid color-mix(in srgb, var(--call-hue) 28%, var(--line));
  border-left: 3px solid var(--call-hue);
  border-radius: 0 var(--r-md) var(--r-md) 0;
}
.callout__title {
  margin: 0 0 .4rem;
  font-family: var(--font-display);
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--call-hue);
}
.callout > :last-child { margin-bottom: 0; }
.callout p { font-size: var(--step--1); }
.callout--note    { --call-hue: var(--stat-mind); }
.callout--example { --call-hue: var(--stat-sense); }
.callout--gm      { --call-hue: var(--stat-cunning); }
.callout--danger  { --call-hue: var(--danger); }
.callout--rule    { --call-hue: var(--accent); }
.callout--wound   { --call-hue: var(--hp-wound); }
/* the two red hues sit at about 3:1 against their own tinted card in the dark
   theme, so the title takes the lighter sibling and the hue keeps the rule */
.callout--danger .callout__title { color: var(--danger-soft); }
.callout--wound .callout__title { color: var(--hp-wound-soft); }

/* --- filter bar ---------------------------------------------------------- */
/* site.js rearranges the authored markup into .filterbar__head (search box,
   Filters button, live count, Reset) plus .filterbar__panel (the pill rows).
   On wide screens the panel is always open and reads as the original stack;
   below the drawer breakpoint the panel is a disclosure that opens over the
   content, so the sticky stack stays near one row tall. */
.filterbar {
  position: sticky;
  top: var(--topbar-h);
  z-index: 30;
  display: grid;
  gap: var(--sp-3);
  margin: 0 0 var(--sp-5);
  padding: var(--sp-4);
  background: color-mix(in srgb, var(--bg-raise) 94%, transparent);
  backdrop-filter: blur(8px);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
}
.filterbar__row { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.filterbar__head { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.filterbar__head .filterbar__search { flex: 1 1 14rem; width: auto; }
.filterbar__panel { display: grid; gap: var(--sp-3); }
.filterbar__more { display: none; }

.filterbar__reset {
  flex: none;
  padding: .3em .75em;
  background: none;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  color: var(--text-dim);
  font-size: var(--step--2);
  letter-spacing: .06em;
  cursor: pointer;
  transition: color .14s var(--ease), border-color .14s var(--ease);
}
.filterbar__reset:hover { color: var(--accent); border-color: var(--accent-line); }
.filterbar__reset[hidden] { display: none; }
.filterbar__label {
  font-family: var(--font-display);
  font-size: var(--step--2);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-right: .3rem;
  min-width: 3.2rem;
}
.filterbar__search {
  width: 100%;
  padding: .55rem .8rem;
  background: var(--bg-sunk);
  border: 1px solid var(--line-input);
  border-radius: var(--r-md);
  color: var(--text);
  font-size: var(--step--1);
}
.filterbar__search::placeholder { color: var(--text-faint); }
.filterbar__search:focus { border-color: var(--accent); outline-offset: 0; }

.filter-pill {
  padding: .3em .75em;
  background: var(--bg-inset);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--text-dim);
  font-size: var(--step--2);
  letter-spacing: .06em;
  cursor: pointer;
  transition: color .14s var(--ease), background .14s var(--ease), border-color .14s var(--ease);
}
.filter-pill:hover { color: var(--accent); border-color: var(--accent-line); }
.filter-pill.is-on {
  color: var(--bg);
  background: var(--accent);
  border-color: var(--accent-bright);
  font-weight: 600;
}
:root[data-theme="light"] .filter-pill.is-on { color: var(--bg-card); }

.filter-count {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--text-faint);
  margin-left: auto;
  white-space: nowrap;
}
/* sort control: same shape as a pill, wide enough for its longest option.
   appearance:none so the native widget stops drawing over the pill styling */
.filterbar__select {
  appearance: none;
  -webkit-appearance: none;
  padding: .3em 1.7em .3em .6em;
  background-color: var(--bg-inset);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6' fill='none' stroke='%238a93a8' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right .55em center;
  background-size: .6em auto;
  border: 1px solid var(--line-input);
  border-radius: 999px;
  color: var(--text-dim);
  font-size: var(--step--2);
  letter-spacing: .06em;
  cursor: pointer;
}
/* The chevron is a data URI, and a data URI cannot read a custom property, so
   this stroke is the one colour in the file that has to be written literally.
   The dark slate is 5.4:1 on the dark select fill but only 2.4:1 on parchment,
   so the light theme restates the image with an ink stroke (5.0:1). */
:root[data-theme="light"] .filterbar__select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6' fill='none' stroke='%236a5c43' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1l4 4 4-4'/%3E%3C/svg%3E");
}
.filterbar__select:hover { color: var(--accent); border-color: var(--accent-line); }

.filter-empty {
  display: none;
  padding: var(--sp-6);
  text-align: center;
  color: var(--text-faint);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-md);
}
.is-empty .filter-empty { display: block; }
.filter-empty__reset {
  display: inline-block;
  margin-top: var(--sp-3);
  padding: .4em 1.1em;
  background: var(--bg-inset);
  border: 1px solid var(--accent-line);
  border-radius: 999px;
  color: var(--accent);
  font-family: var(--font-display);
  font-size: var(--step--2);
  letter-spacing: .12em;
  text-transform: uppercase;
  cursor: pointer;
}
.filter-empty__reset:hover { background: var(--accent-wash); color: var(--accent-bright); }

/* A heading plus the filterable cards under it (spell tiers, aspects,
   litany tiers). When a filter empties the group the heading goes with it
   instead of stranding a label over blank space. */
.filtergroup:not(:has([data-filter-item]:not([hidden]))) { display: none; }

/* --- card grid ----------------------------------------------------------- */
.cardgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: var(--sp-4);
  margin: 0 0 var(--sp-6);
  padding: 0;
  list-style: none;
}
.cardgrid > li::before { content: none; }
.card {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  color: inherit;
  text-decoration: none;
  box-shadow: var(--shadow-sm);
  transition: transform .18s var(--ease), border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.card:hover {
  transform: translateY(-2px);
  border-color: var(--accent-line);
  box-shadow: var(--shadow-md);
}
.card__thumb {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: var(--bg-sunk);
  border-bottom: 1px solid var(--line);
}
/* add --art when the image is a placeholder SVG from assets/img rather than a
   photographic portrait: line art must fit the box, not be cropped by it */
.card__thumb--art, .statblock__portrait--art {
  object-fit: contain;
  padding: 5%;
  background: var(--bg-sunk);
}
.card__body { padding: var(--sp-3) var(--sp-4) var(--sp-4); display: flex; flex-direction: column; gap: .4rem; flex: 1; }
.card__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--step-0);
  font-weight: 600;
  color: var(--accent);
  line-height: 1.2;
}
.card__meta { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; }
.card__desc {
  margin: 0;
  font-size: var(--step--2);
  color: var(--text-faint);
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card__type {
  font-size: var(--step--2);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/* --- section tiles ------------------------------------------------------- */
.tilegrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: var(--sp-4);
  margin: 0;
  padding: 0;
  list-style: none;
}
.tilegrid > li::before { content: none; }
.tile {
  position: relative;
  display: block;
  height: 100%;
  padding: var(--sp-5);
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  text-decoration: none;
  color: inherit;
  overflow: hidden;
  transition: transform .2s var(--ease), border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.tile::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(80% 60% at 0% 0%, var(--accent-wash), transparent 65%);
  opacity: 0;
  transition: opacity .25s var(--ease);
  pointer-events: none;
}
.tile:hover { transform: translateY(-3px); border-color: var(--accent-line); box-shadow: var(--shadow-md); }
.tile:hover::after { opacity: 1; }
.tile__num {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: .2em;
  color: var(--gold-soft);
}
.tile__title {
  margin: .3rem 0 .4rem;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  color: var(--accent);
  letter-spacing: .03em;
}
.tile__desc { margin: 0 0 .7rem; font-size: var(--step--1); color: var(--text-dim); }
.tile__links { display: flex; flex-wrap: wrap; gap: .35rem .8rem; font-size: var(--step--2); color: var(--text-faint); }

/* --- landing page -------------------------------------------------------- */
/* the landing page lives inside .prose, so switch off the document heading
   decoration that would otherwise double up on the hero and section titles */
.home h1::after { content: none; }
.home h1 { margin: 0; }
.home h2 { border-bottom: 0; padding-bottom: 0; }

.home { position: relative; z-index: 1; }
.home__section { max-width: 72rem; margin: 0 auto; padding: 0 var(--sp-5) var(--sp-7); }
.home__section--narrow { max-width: 50rem; }
.home .home__title {
  margin: 0 0 var(--sp-4);
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--navy-text);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}
.home .home__title::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, var(--navy-line), transparent);
}

.hero {
  position: relative;
  overflow: hidden;
  padding: clamp(3rem, 10vh, 7rem) var(--sp-5) clamp(3rem, 8vh, 5.5rem);
  text-align: center;
  border-bottom: 1px solid var(--line);
}
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(55% 45% at 50% 30%, var(--gold-wash), transparent 72%),
    radial-gradient(120% 60% at 50% 100%, var(--accent-wash), transparent 70%);
  pointer-events: none;
}
.hero__inner { position: relative; max-width: 52rem; margin: 0 auto; }
.hero__crown { color: var(--gold); display: flex; justify-content: center; margin-bottom: var(--sp-3); }
.hero__crown svg { width: 46px; height: auto; filter: drop-shadow(0 0 14px var(--gold-wash)); }
.hero__wordmark {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--step-4);
  font-weight: 800;
  letter-spacing: .28em;
  text-indent: .28em;
  line-height: 1;
  background: linear-gradient(180deg, var(--gold-bright), var(--gold) 55%, var(--gold-deep));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.hero__rule {
  width: min(24rem, 70%);
  height: 1px;
  margin: var(--sp-4) auto;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
}
.hero__sub {
  margin: 0 auto var(--sp-5);
  max-width: 34rem;
  font-size: var(--step-1);
  line-height: 1.5;
  color: var(--text-dim);
  text-wrap: pretty;
}
.hero__edition {
  display: inline-block;
  margin-bottom: var(--sp-4);
  padding: .3em .9em;
  border: 1px solid var(--gold-line);
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: var(--step--2);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--gold);
}
.hero__search {
  display: flex;
  align-items: center;
  gap: .7rem;
  width: min(30rem, 100%);
  margin: 0 auto var(--sp-5);
  padding: .8rem 1.1rem;
  background: var(--bg-card);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-lg);
  color: var(--text-dim);
  font-size: var(--step-0);
  cursor: pointer;
  box-shadow: var(--shadow-md);
  transition: border-color .18s var(--ease), transform .18s var(--ease), box-shadow .18s var(--ease);
}
.hero__search:hover { border-color: var(--accent); transform: translateY(-1px); box-shadow: var(--shadow-lg); }
.hero__search span:first-of-type { color: var(--accent); display: flex; }
.hero__search .searchbtn__keys { margin-left: auto; display: flex; gap: 3px; }

.hero__facts {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .5rem var(--sp-5);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--step--1);
  color: var(--text-faint);
}
.hero__facts > li::before { content: none; }
.hero__facts li { display: flex; align-items: baseline; gap: .4rem; }
.hero__facts b { font-family: var(--font-mono); color: var(--navy-text); font-weight: 600; }

/* one orchestrated entrance, landing page only */
.hero__reveal { opacity: 0; animation: reveal .7s var(--ease) forwards; }
.hero__reveal--1 { animation-delay: .05s; }
.hero__reveal--2 { animation-delay: .18s; }
.hero__reveal--3 { animation-delay: .30s; }
.hero__reveal--4 { animation-delay: .42s; }
.hero__reveal--5 { animation-delay: .54s; }
.hero__reveal--6 { animation-delay: .66s; }
@keyframes reveal { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.hero__rule.hero__reveal { animation-name: reveal-rule; }
@keyframes reveal-rule { from { opacity: 0; transform: scaleX(.2); } to { opacity: 1; transform: none; } }

/* at-the-table strip */
.table-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 1px;
  margin: 0 auto var(--sp-7);
  max-width: 72rem;
  background: var(--line);
  border-block: 1px solid var(--line);
  list-style: none;
  padding: 0;
}
.table-strip > li::before { content: none; }
.table-strip a {
  display: block;
  height: 100%;
  padding: var(--sp-5);
  background: var(--bg-raise);
  color: inherit;
  text-decoration: none;
  transition: background .18s var(--ease);
}
.table-strip a:hover { background: var(--bg-card); }
.table-strip strong {
  display: block;
  font-family: var(--font-display);
  font-size: var(--step-0);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: .3rem;
}
.table-strip span { font-size: var(--step--1); color: var(--text-faint); }

/* --- statline (KING.md Part 7B convention) ------------------------------- */
/* the whole point of the strip is that every fact is visible at a glance, so
   it wraps rather than hiding a third of itself behind a scrollbar. site.js
   groups each label with its value and adds --pairs, which turns the strip
   into a wrapping flex row where no pair ever splits across lines. */
.statline {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
  color: var(--text-dim);
  padding: .6rem .8rem;
  background: var(--bg-sunk);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  white-space: normal;
}
.statline b { color: var(--navy-text); font-weight: 600; }
.statline--pairs { display: flex; flex-wrap: wrap; column-gap: .55rem; row-gap: .3rem; }
.statline__pair { display: inline-flex; align-items: baseline; gap: .35rem; white-space: nowrap; }
.statline__pair + .statline__pair::before {
  content: "\00b7";
  margin-right: .55rem;
  color: var(--line-strong);
}
/* a phone gets one fact per line rather than a long value forced onto one */
@media (max-width: 700px) {
  .statline--pairs { display: block; }
  .statline__pair { display: block; white-space: normal; }
  .statline__pair + .statline__pair::before { content: none; }
}

/* --- jump row ------------------------------------------------------------ */
/* anchor links to the h2 sections of a long reference page (equipment, the GM
   monster guide, advancement). The right-hand TOC does this job on wide
   screens; the jump row is what a phone at the table gets instead. */
.jump { display: flex; flex-wrap: wrap; gap: .4rem; margin: 0 0 var(--sp-6); }
.prose .jump a {
  padding: .24em .75em;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-family: var(--font-display);
  font-size: var(--step--2);
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: var(--bg-inset);
}
.prose .jump a:hover,
.prose .jump a:focus-visible {
  color: var(--accent);
  border-color: var(--accent-line);
  background: var(--accent-wash);
}
@media print { .jump { display: none !important; } }

/* --- page nav (mobile in-page contents) ---------------------------------- */
/* The right-hand TOC is the wide-screen answer to "where am I in this
   chapter". Below its breakpoint every page that has one gets the same list
   as a disclosure under the h1, including the wide browsers that never get a
   TOC column. Plain <details>, so it works with scripting off. */
.pagenav { display: none; }
.pagenav[open] .pagenav__summary::after { transform: rotate(-135deg); }
.pagenav__summary {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .6rem .85rem;
  list-style: none;
  cursor: pointer;
  font-family: var(--font-display);
  font-size: var(--step--2);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-dim);
  background: var(--bg-inset);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.pagenav__summary::-webkit-details-marker { display: none; }
.pagenav__summary::after {
  content: "";
  width: 7px; height: 7px;
  margin-left: auto;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  transition: transform .2s var(--ease);
}
.pagenav__n { font-family: var(--font-mono); color: var(--text-faint); letter-spacing: 0; }
.prose .pagenav__list {
  list-style: none;
  margin: .4rem 0 0;
  padding: .3rem 0;
  max-height: 55vh;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--bg-card);
}
.prose .pagenav__list > li { margin: 0; }
.prose .pagenav__list > li::before { content: none; }
.prose .pagenav__list a {
  display: block;
  padding: .4rem .85rem;
  color: var(--text-dim);
  font-size: var(--step--1);
  line-height: 1.4;
  text-decoration: none;
  border-bottom: 0;
}
.prose .pagenav__list a:hover { color: var(--accent); background: var(--accent-wash); }
.pagenav__item--h3 a { padding-left: 1.9rem !important; color: var(--text-faint) !important; }

@media (max-width: 1180px) {
  .pagenav { display: block; margin: 0 0 var(--sp-5); }
}
@media print { .pagenav { display: none !important; } }


/* ==========================================================================
   6  PALETTE (command-palette search)
   ========================================================================== */

.palette { position: fixed; inset: 0; z-index: 200; }
.palette[hidden] { display: none; }
.palette__scrim {
  position: absolute;
  inset: 0;
  background: var(--scrim);
  backdrop-filter: blur(3px);
  border: 0;
}
.palette__panel {
  position: relative;
  max-width: 40rem;
  margin: 8vh auto 0;
  background: var(--bg-raise);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  animation: palette-in .16s var(--ease);
}
@keyframes palette-in { from { opacity: 0; transform: translateY(-8px) scale(.99); } }

.palette__bar {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .7rem .9rem;
  border-bottom: 1px solid var(--line);
  background: var(--bg-card);
}
.palette__icon { display: flex; color: var(--accent); }
.palette__input {
  flex: 1;
  min-width: 0;
  background: none;
  border: 0;
  outline: none;
  font-size: var(--step-0);
  color: var(--text);
}
.palette__input::placeholder { color: var(--text-faint); }
.palette__input::-webkit-search-cancel-button { display: none; }
.palette__esc { background: none; border: 0; cursor: pointer; padding: 0; }

.palette__body { max-height: min(60vh, 32rem); overflow-y: auto; overscroll-behavior: contain; }
.palette__results { list-style: none; margin: 0; padding: .35rem; }
.palette__group {
  padding: .55rem .75rem .2rem;
  font-family: var(--font-display);
  font-size: var(--step--2);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.palette__hit { border-radius: var(--r-md); }
.palette__hit a {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .45rem .7rem;
  border-radius: var(--r-md);
  color: var(--text);
  text-decoration: none;
}
.palette__hit.is-sel a, .palette__hit a:hover { background: var(--accent-wash); }
.palette__hit.is-sel a { box-shadow: inset 2px 0 0 var(--accent); }
.palette__t { font-weight: 600; }
.palette__t mark { background: none; color: var(--accent-bright); font-weight: 700; }
.palette__s {
  margin-left: auto;
  font-size: var(--step--2);
  color: var(--text-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 45%;
}
.palette__k {
  flex: none;
  width: 4.4rem;
  padding: .18em 0;
  text-align: center;
  font-family: var(--font-display);
  font-size: .62rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  color: var(--text-faint);
  background: var(--bg-inset);
}
.palette__k[data-kind="creature"] { color: var(--danger-soft); border-color: color-mix(in srgb, var(--danger) 45%, transparent); }
.palette__k[data-kind="spell"], .palette__k[data-kind="prayer"],
.palette__k[data-kind="litany"], .palette__k[data-kind="discipline"],
.palette__k[data-kind="jutsu"], .palette__k[data-kind="mystic"] { color: var(--stat-cunning); border-color: color-mix(in srgb, var(--stat-cunning) 45%, transparent); }
.palette__k[data-kind="martial"] { color: var(--stat-body); border-color: color-mix(in srgb, var(--stat-body) 45%, transparent); }
.palette__k[data-kind="skill"] { color: var(--stat-sense); border-color: color-mix(in srgb, var(--stat-sense) 45%, transparent); }
.palette__k[data-kind="rule"] { color: var(--accent); border-color: var(--accent-line); }
.palette__k[data-kind="equipment"] { color: var(--stat-mind); border-color: color-mix(in srgb, var(--stat-mind) 45%, transparent); }
.palette__k[data-kind="throne"], .palette__k[data-kind="path"],
.palette__k[data-kind="race"], .palette__k[data-kind="character"] { color: var(--stat-heart); border-color: color-mix(in srgb, var(--stat-heart) 45%, transparent); }

.palette__hint { margin: 0; padding: .6rem .9rem; border-top: 1px solid var(--line); color: var(--text-faint); font-size: var(--step--2); }
.palette__none { padding: var(--sp-5); text-align: center; color: var(--text-faint); }

body.is-locked { overflow: hidden; }


/* ==========================================================================
   7  UTILITIES
   ========================================================================== */

.u-body    { color: var(--stat-body); }
.u-mind    { color: var(--stat-mind); }
.u-sense   { color: var(--stat-sense); }
.u-heart   { color: var(--stat-heart); }
.u-cunning { color: var(--stat-cunning); }
.u-fate    { color: var(--stat-fate); }
.u-vitality, .stat-vitality { color: var(--hp-vitality); }
.u-stamina { color: var(--hp-stamina); }
.u-vigor   { color: var(--hp-vigor); }
.u-wound   { color: var(--hp-wound); }
.u-gold    { color: var(--gold); }
.u-accent  { color: var(--accent); }
.u-navy    { color: var(--navy-text); }
.u-dim     { color: var(--text-faint); }
.u-mono    { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.u-nowrap  { white-space: nowrap; }
.u-center  { text-align: center; }
.u-stack   { display: grid; gap: var(--sp-4); }
.u-mt-6    { margin-top: var(--sp-6); }
.u-mb-0    { margin-bottom: 0; }

.columns-2 { columns: 2; column-gap: var(--sp-6); }
.columns-2 > * { break-inside: avoid; }


/* ==========================================================================
   8  RESPONSIVE
   ========================================================================== */

@media (max-width: 1180px) {
  .layout.has-toc { grid-template-columns: var(--sidebar-w) minmax(0, 1fr); }
  .toc { display: none; }
}

@media (max-width: 880px) {
  :root { --topbar-h: 3.5rem; }
  .topbar { padding: 0 var(--sp-2); gap: var(--sp-1); }
  .topbar__menu { display: grid; }
  .wordmark__tag { display: none; }
  .searchbtn__label { display: none; }
  .searchbtn { flex: none; width: 2.75rem; height: 2.75rem; justify-content: center; padding: 0; }
  .searchbtn__keys { display: none; }
  /* one-handed at the table: the three header controls hit 44x44 */
  .iconbtn { width: 2.75rem; height: 2.75rem; }
  .totop { width: 2.75rem; height: 2.75rem; right: .9rem; bottom: 1.6rem; }
  .filter-pill { min-height: 2.5rem; padding: .5em .85em; }
  .filterbar__reset, .filterbar__more, .filterbar__select { min-height: 2.5rem; }

  .layout, .layout.has-toc { grid-template-columns: minmax(0, 1fr); }
  .sidebar {
    position: fixed;
    top: var(--topbar-h);
    left: 0;
    z-index: 56;
    width: min(20rem, 84vw);
    height: calc(100dvh - var(--topbar-h));
    background: var(--bg-raise);
    box-shadow: var(--shadow-lg);
    transform: translateX(-102%);
    transition: transform .22s var(--ease);
  }
  body.drawer-open .sidebar { transform: none; }
  .main { padding: var(--sp-5) var(--sp-4) var(--sp-7); }
  .statblock__portrait { width: 130px; }
  .columns-2 { columns: 1; }

  /* --- collapsed filter bar ---
     Four permanent pill rows ate more than half a phone screen. The sticky
     part is now one row: search, a Filters disclosure carrying the active
     count, and the live result count. The pills open over the page. */
  .filterbar { padding: var(--sp-2) var(--sp-3); gap: var(--sp-2); }
  .filterbar__head { gap: .4rem; }
  .filterbar__head .filterbar__search { flex: 1 1 8rem; }
  .filterbar__more {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    flex: none;
    min-height: 2.5rem;
    padding: .3em .8em;
    background: var(--bg-inset);
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    color: var(--text-dim);
    font-family: var(--font-display);
    font-size: var(--step--2);
    letter-spacing: .1em;
    text-transform: uppercase;
    cursor: pointer;
  }
  .filterbar__more[aria-expanded="true"] {
    color: var(--accent);
    border-color: var(--accent-line);
    background: var(--accent-wash);
  }
  .filterbar__more-n {
    display: none;
    min-width: 1.35em;
    padding: .1em .3em;
    border-radius: 999px;
    background: var(--accent);
    color: var(--bg);
    font-family: var(--font-mono);
    letter-spacing: 0;
    text-align: center;
  }
  .filterbar.has-filters .filterbar__more-n { display: inline-block; }
  .filterbar .filter-count { flex: 1 0 100%; margin-left: 0; text-align: right; }

  .filterbar__panel {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    z-index: 2;
    display: none;
    max-height: min(60vh, 26rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: var(--sp-3);
    background: var(--bg-raise);
    border: 1px solid var(--line);
    border-top: 0;
    border-radius: 0 0 var(--r-md) var(--r-md);
    box-shadow: var(--shadow-lg);
  }
  .filterbar.is-open .filterbar__panel { display: grid; }
  .filterbar__label { min-width: 100%; margin: 0 0 .1rem; }
}

@media (max-width: 460px) {
  .main { padding: var(--sp-4) var(--sp-3) var(--sp-6); }
  .statblock { padding: var(--sp-4); }
  .cardgrid { grid-template-columns: repeat(auto-fill, minmax(11.5rem, 1fr)); }
  .palette__panel { margin: 0; height: 100dvh; max-width: none; border-radius: 0; }
  .palette__body { max-height: calc(100dvh - 7rem); }
  .palette__s { display: none; }
}

@media (min-width: 2200px) {
  :root { --measure: 80ch; --sidebar-w: 19rem; --toc-w: 16rem; }
  .layout { max-width: 120rem; }
}


/* ==========================================================================
   9  PRINT
   ========================================================================== */

@media print {
  /* The no-flash boot script always stamps data-theme on <html>, so a bare
     :root here (0,1,0) loses to the theme blocks (0,2,0) and the page prints
     in whatever theme is on screen. Match their specificity and come later in
     the file, and print is black on white from either theme. */
  :root,
  :root[data-theme="dark"],
  :root[data-theme="light"] {
    color-scheme: light;
    --bg: #fff; --bg-raise: #fff; --bg-card: #fff; --bg-sunk: #fff; --bg-inset: #fff;
    --text: #000; --text-dim: #222; --text-faint: #444;
    --line: #bbb; --line-strong: #888; --line-input: #888;
    --gold: #6a5010; --gold-bright: #4a3808; --gold-soft: #6a5010; --gold-deep: #4a3808;
    --gold-line: #999; --gold-wash: transparent;

    --accent: #7a1c26; --accent-bright: #58121a; --accent-soft: #7a1c26;
    --accent-deep: #58121a; --accent-line: #999; --accent-wash: transparent;
    --accent-underline: #666;
    --navy-head: #16273f; --navy-text: #1e3457; --navy-line: #999; --navy-wash: transparent;

    /* the accent hues carry meaning (stat colours, health tracks), so they
       stay hued but drop to values that hold up as ink */
    --danger: #8c281f; --danger-soft: #6f1c16; --danger-wash: transparent;
    --stat-body: #8c3322; --stat-mind: #25497a; --stat-sense: #175a42;
    --stat-heart: #7f2a4d; --stat-cunning: #52307d; --stat-fate: #5e5011;
    --hp-vitality: #8c261d; --hp-stamina: #22486c; --hp-vigor: #17564b;
    --hp-wound: #6f1c16; --hp-wound-soft: #6f1c16;

    --scrim: transparent;
    --shadow-sm: none; --shadow-md: none; --shadow-lg: none;
    --grain-opacity: 0;
    --vignette: none;
  }
  body { background: #fff; color: #000; font-size: 10.5pt; }
  body::before, body::after { display: none; }
  .topbar, .sidebar, .toc, .footer, .totop, .palette, .scrim, .skiplink,
  .crumbs, .filterbar { display: none !important; }
  .layout, .layout.has-toc { display: block; max-width: none; }
  .main { padding: 0; }
  .prose { max-width: none; }
  .statblock, .ability, .spell, .callout, .table-wrap, .card {
    box-shadow: none;
    break-inside: avoid;
    border-color: #999;
  }
  .statblock::before, .statblock::after { display: none; }
  /* the band draws its cell separators with a background, which browsers drop
     from printed output unless told otherwise */
  .statband, .statband__item, .data-table th {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .statband { background: #888; }
  .statband__item { background: #fff; }
  .data-table th { position: static; background: #eee; color: #000; }
  .prose a { color: #000; border-bottom: 0; }
  .prose h1, .prose h2, .prose h3 { color: #000; break-after: avoid; }
  .callout__title, .callout--danger .callout__title, .callout--wound .callout__title { color: #000; }
}


/* ==========================================================================
   10  MOTION
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .hero__line, .hero__reveal { opacity: 1 !important; transform: none !important; }
}


/* ==========================================================================
   11  ADDITIONS - reference grid  (added by the rules/character renderer)
   ========================================================================== */

/* .refgrid / .refcard: a dense card grid for pages that are consulted rather
   than read in order. Used by rules/reference.html and by the six-stat opener
   on character/creation.html. Cards size to their content, hold a compact
   table, and never split across a printed page. */
.refgrid {
  display: grid;
  /* 22rem so the tables inside a card stop hard-wrapping every row, auto-fit so
     a section holding two cards fills the row instead of leaving a hole. The
     min() keeps the track from outgrowing a phone column, which otherwise
     pushes the whole document 4px sideways. */
  grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
  gap: var(--sp-4);
  align-items: start;
  margin: 0 0 var(--sp-6);
  padding: 0;
  list-style: none;
}
.refgrid > li::before { content: none; }
.refcard {
  padding: var(--sp-4);
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
}
.refcard--wide { grid-column: 1 / -1; }
/* ability pairs in a refgrid column are narrow enough that a long meta label
   wraps and a short one does not, which knocks the pair out of rhythm. Give
   the meta its own reserved line above the name in both cards. */
.refgrid > .ability > .ability__head > .ability__meta {
  order: -1;
  flex: 1 0 100%;
  margin-left: 0;
  text-align: right;
}
.prose .refcard__title {
  margin: 0 0 var(--sp-3);
  padding: 0 0 .35rem;
  font-size: var(--step-0);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--navy-text);
  border-bottom: 1px solid var(--navy-line);
}
.refcard__body { font-size: var(--step--1); color: var(--text-dim); }
.refcard__body > :last-child { margin-bottom: 0; }
.refcard__body p, .refcard__body ul, .refcard__body ol { margin: 0 0 .6rem; }
.refcard__body pre { margin: 0 0 .6rem; }
.refcard .table-wrap {
  margin: 0 0 .6rem;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}
.refcard .data-table th { background: var(--bg-card); }
.refcard__note { margin: .5rem 0 0; font-size: var(--step--2); color: var(--text-faint); }
.refcard__src { margin: .7rem 0 0; font-size: var(--step--2); }

/* a component heading inside .prose loses to .prose h3 / .prose h4 on
   specificity, so each card class has to restate its own scale. Restate the
   component, never someone else's: the spell name keeps its gilt small caps. */
.prose .ability__name {
  margin: 0;
  font-size: var(--step-0);
  text-transform: none;
  letter-spacing: .02em;
  color: var(--text);
}
.prose .spell__name {
  margin: 0;
  font-size: var(--step-0);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--accent);
}
/* The landing hero sits inside .prose, so .prose h1 (0,1,1) beats
   .hero__wordmark (0,1,0) and repaints the gilt gradient in the heading
   colour - the wordmark was rendering navy on parchment and near-white on the
   dark ground instead of gold. Restate the transparent fill at matching
   specificity: the wordmark is one of the few things gold still owns. */
.prose .hero__wordmark { color: transparent; }
.prose .tile__title { margin: .3rem 0 .4rem; font-size: var(--step-1); color: var(--accent); }
.prose .card__title { margin: 0; font-size: var(--step-0); color: var(--accent); }

/* an index of anchors above a long list of entries (paths, thrones) */
.prose a.tag {
  color: var(--text-dim);
  border: 1px solid var(--line-strong);
  text-decoration: none;
}
.prose a.tag:hover {
  color: var(--accent-bright);
  border-color: var(--accent-line);
  background: var(--accent-wash);
}

@media print {
  .refgrid { grid-template-columns: repeat(2, 1fr); gap: .45rem; }
  .refcard { break-inside: avoid; box-shadow: none; border-color: #999; }
  .refcard__src { display: none; }
  /* the .prose .hero__wordmark rule above holds the fill transparent so the
     gilt gradient shows through, but browsers drop background graphics on
     paper by default and the wordmark would print as nothing. Give it ink. */
  .prose .hero__wordmark { color: #000; background: none; }
}
