@charset "utf-8";
/* =====================================================================
   May the Force Be With You — design system
   Dark space theme. System fonts only. No external requests.
   ===================================================================== */

/* ---------- 1. tokens ---------------------------------------------- */
:root {
  /* surfaces */
  --space:        #05070b;
  --panel:        #0c1119;
  --raised:       #131b27;
  --raised-2:     #1a2432;

  /* accents */
  --gold:         #ffc94a;   /* hologram gold — primary */
  --ion:          #5ad2ff;   /* ion blue — secondary */
  --crimson:      #ff5566;   /* alert */
  --canon:        #47e0a0;   /* canon green */
  --legend:       #c9a7ff;   /* legends violet */

  /* accent tints for backgrounds (AA-safe when paired with --ink) */
  --gold-dim:     rgba(255, 201, 74, 0.13);
  --ion-dim:      rgba(90, 210, 255, 0.13);
  --canon-dim:    rgba(71, 224, 160, 0.13);
  --crimson-dim:  rgba(255, 85, 102, 0.13);
  --legend-dim:   rgba(201, 167, 255, 0.13);

  /* text */
  --ink:          #e7ecf5;
  --muted:        #93a1b8;
  --faint:        #6d7c94;
  --ink-invert:   #05070b;

  /* hairlines */
  --line:         rgba(231, 236, 245, 0.10);
  --line-strong:  rgba(231, 236, 245, 0.18);
  --line-accent:  rgba(90, 210, 255, 0.30);

  /* type stacks — system only */
  /* Display face. Every entry after the first is a REAL condensed face that
     exists on some non-Apple platform, so a Windows/Android/Linux visitor
     gets condensed type too instead of a 30% wider heading. */
  --f-display: "Avenir Next Condensed", "HelveticaNeue-CondensedBold",
               "Roboto Condensed", "Liberation Sans Narrow", "Arial Narrow",
               "Helvetica Neue", "Segoe UI", Roboto, system-ui, Helvetica, Arial, sans-serif;
  --f-body:    "Helvetica Neue", -apple-system, BlinkMacSystemFont, "Segoe UI",
               Roboto, Helvetica, Arial, sans-serif;
  --f-mono:    ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas,
               "Liberation Mono", monospace;

  /* fluid type scale */
  --t-xs:   clamp(0.69rem, 0.66rem + 0.12vw, 0.75rem);
  --t-sm:   clamp(0.81rem, 0.78rem + 0.14vw, 0.88rem);
  --t-base: clamp(1rem,    0.96rem + 0.20vw, 1.09rem);
  --t-lg:   clamp(1.13rem, 1.05rem + 0.38vw, 1.31rem);
  --t-xl:   clamp(1.33rem, 1.18rem + 0.70vw, 1.75rem);
  --t-2xl:  clamp(1.63rem, 1.34rem + 1.35vw, 2.5rem);
  /* Ceilings are ~15% below where they sat when the site was only ever seen
     with Avenir Next Condensed loaded, so a non-condensed fallback still fits. */
  --t-3xl:  clamp(1.95rem, 1.50rem + 1.95vw, 2.95rem);
  --t-4xl:  clamp(2.30rem, 1.55rem + 3.30vw, 4.25rem);

  /* spacing */
  --s-1: 0.25rem;  --s-2: 0.5rem;   --s-3: 0.75rem;  --s-4: 1rem;
  --s-5: 1.5rem;   --s-6: 2rem;     --s-7: 3rem;     --s-8: 4rem;
  --s-9: 6rem;     --s-10: 8rem;

  --radius:    3px;
  --radius-lg: 5px;
  --wrap:      76rem;
  --wrap-text: 44rem;
  --nav-h:     4rem;
  --ease:      cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* ---------- 2. reset ------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }

/* The [hidden] attribute is how site.js hides filtered-out rows (glossary
   terms, library cards, the search topic picks). The UA rule that backs it
   is `[hidden] { display: none }` — a single attribute selector, which any
   author rule that sets `display` (e.g. `.deflist__item { display: grid }`)
   silently outranks, leaving "hidden" rows fully visible. Restate it here
   with !important so hiding works regardless of the element's own display. */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--space);
  color: var(--ink);
  font-family: var(--f-body);
  font-size: var(--t-base);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  /* faint vertical gradient so the page never reads as flat black */
  background-image:
    radial-gradient(90rem 55rem at 78% -12%, rgba(90, 210, 255, 0.07), transparent 62%),
    radial-gradient(70rem 45rem at 8% 4%,  rgba(255, 201, 74, 0.05), transparent 60%);
  background-attachment: fixed;
}

img, svg, canvas, video { display: block; max-width: 100%; }
img { height: auto; }
/* Markers are opt-in: only long-form prose and the source lists want them. */
ul, ol { margin: 0; padding: 0; list-style: none; }
figure, blockquote, p, h1, h2, h3, h4 { margin: 0; }

a { color: var(--ion); text-decoration: none; text-underline-offset: 0.18em; }
a:hover { color: var(--gold); text-decoration: underline; }

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
  border-radius: 2px;
}
:focus:not(:focus-visible) { outline: none; }

::selection { background: var(--gold); color: var(--ink-invert); }

/* ---------- 3. headings & prose ------------------------------------- */
h1, h2, h3, h4 {
  font-family: var(--f-display);
  font-weight: 700;
  font-stretch: 87.5%;          /* pulls in variable/multi-width fallbacks */
  line-height: 1.05;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  text-wrap: balance;
}
h1 { font-size: var(--t-3xl); letter-spacing: 0.015em; }
h2 { font-size: var(--t-2xl); }
h3 { font-size: var(--t-xl); letter-spacing: 0.03em; }
h4 { font-size: var(--t-lg); letter-spacing: 0.05em; }

.mono {
  font-family: var(--f-mono);
  font-size: var(--t-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.kicker {
  font-family: var(--f-mono);
  font-size: var(--t-xs);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--gold);
  margin: 0 0 var(--s-3);
}
/* Uppercase + 0.24em tracking is a label treatment, not a text treatment.
   Anything longer than about four words uses this instead. */
.kicker--sentence {
  font-family: var(--f-body);
  font-size: var(--t-sm);
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.55;
  color: var(--gold);
  max-width: 62ch;
}

/* long-form article body */
.prose { max-width: var(--wrap-text); font-size: var(--t-lg); line-height: 1.75; }
/* On a 335px column an 18px body gives ~37 characters per line, well under the
   45ch comfortable minimum. Drop to the base size so the rag settles down. */
@media (max-width: 34rem) { .prose { font-size: var(--t-base); } }
.prose > * + * { margin-top: var(--s-5); }
.prose h2 {
  font-size: var(--t-xl);
  margin-top: var(--s-7);
  padding-top: var(--s-4);
  border-top: 1px solid var(--line);
  color: var(--ink);
}
.prose h3 { font-size: var(--t-lg); margin-top: var(--s-6); color: var(--gold); }
.prose ul { padding-left: 1.35em; list-style: disc; }
.prose ol { padding-left: 1.35em; list-style: decimal; }
.prose li + li { margin-top: var(--s-2); }
.prose li::marker { color: var(--ion); }
.prose strong { color: #fff; font-weight: 700; }
.prose em { color: var(--gold); font-style: italic; }
.prose a { border-bottom: 1px solid var(--line-accent); }
.prose blockquote {
  margin: var(--s-6) 0;
  padding: var(--s-4) var(--s-5);
  border-left: 2px solid var(--gold);
  background: linear-gradient(90deg, var(--gold-dim), transparent 70%);
  font-family: var(--f-display);
  font-size: var(--t-xl);
  line-height: 1.3;
  letter-spacing: 0.01em;
  color: var(--ink);
}
.prose blockquote p + p { margin-top: var(--s-3); }
/* A mono run inside long-form prose is always an editorial note, never a
   label — uppercase at 0.24em was carrying 153-character sentences. Keep the
   machine voice, drop the shouting. */
.prose p.mono, .prose .mono {
  font-size: var(--t-sm);
  letter-spacing: 0.04em;
  text-transform: none;
  line-height: 1.7;
  max-width: 68ch;
  color: var(--muted);
  border-left: 2px solid var(--gold);
  padding: var(--s-2) 0 var(--s-2) var(--s-4);
  background: linear-gradient(90deg, var(--gold-dim), transparent 55%);
}
.prose figure { margin: var(--s-6) 0; }
.prose figcaption {
  margin-top: var(--s-2);
  font-family: var(--f-mono);
  font-size: var(--t-xs);
  letter-spacing: 0.1em;
  color: var(--muted);
  text-transform: uppercase;
}

/* ---------- 4. layout ----------------------------------------------- */
.wrap { width: min(100% - 2.5rem, var(--wrap)); margin-inline: auto; }
@media (min-width: 48rem) { .wrap { width: min(100% - 4rem, var(--wrap)); } }

.section { padding-block: var(--s-8); }
.section--tight { padding-block: var(--s-6); }
.section + .section { border-top: 1px solid var(--line); }

.stack > * + * { margin-top: var(--s-5); }
.stack-lg > * + * { margin-top: var(--s-7); }

.split {
  display: grid;
  gap: var(--s-7);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 62rem) {
  .split { grid-template-columns: minmax(0, 1fr) 20rem; }
  .split--wide-right { grid-template-columns: 20rem minmax(0, 1fr); }
  /* A sidebar must never outrun the column it sits beside. */
  .split > aside { position: sticky; top: calc(var(--nav-h) + 1rem); }
}

.grid { display: grid; gap: var(--s-5); list-style: none; }
.grid--auto { grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }
.grid--wide { grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr)); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fill, minmax(13.5rem, 1fr)); }

.skiplink {
  position: absolute; left: var(--s-4); top: -4rem; z-index: 100;
  background: var(--gold); color: var(--ink-invert);
  padding: var(--s-2) var(--s-4);
  font-family: var(--f-mono); font-size: var(--t-sm);
  text-transform: uppercase; letter-spacing: 0.1em;
  transition: top 0.15s var(--ease);
}
.skiplink:focus { top: var(--s-3); text-decoration: none; color: var(--ink-invert); }
.skiplink { min-height: 44px; display: inline-flex; align-items: center; }
/* Activating the skip link must visibly confirm that focus moved. */
main:focus { outline: none; }
main:focus-visible { outline: 2px dashed var(--gold); outline-offset: -4px; }

/* ---------- 5. masthead --------------------------------------------- */
.masthead {
  position: sticky; top: 0; z-index: 50;
  background: rgba(5, 7, 11, 0.78);
  border-bottom: 1px solid var(--line);
}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .masthead {
    background: rgba(5, 7, 11, 0.6);
    -webkit-backdrop-filter: saturate(150%) blur(14px);
    backdrop-filter: saturate(150%) blur(14px);
  }
}
.masthead__inner {
  display: flex; align-items: center; gap: var(--s-5);
  min-height: var(--nav-h);
  flex-wrap: wrap;
}
/* Above the drawer breakpoint the bar is one row or nothing — it can never
   silently grow to two or three rows the way it used to at 768–1150px. */
@media (min-width: 72rem) {
  .masthead__inner { flex-wrap: nowrap; }
  .primary-nav ul { flex-wrap: nowrap; }
}

.wordmark {
  display: flex; flex-direction: column; gap: 1px;
  font-family: var(--f-display); text-transform: uppercase;
  line-height: 0.95; color: var(--ink); text-decoration: none;
  margin-right: auto; padding-block: var(--s-2);
}
.wordmark:hover { text-decoration: none; color: var(--ink); }
.wordmark__a {
  font-size: var(--t-lg); font-weight: 700; letter-spacing: 0.16em;
  color: var(--gold);
}
.wordmark__b {
  font-size: var(--t-xs); font-weight: 600; letter-spacing: 0.26em;
  color: var(--muted);
}
.wordmark:hover .wordmark__b { color: var(--ion); }

.primary-nav ul {
  display: flex; flex-wrap: wrap; gap: var(--s-5); list-style: none;
}
.primary-nav a {
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--muted); padding-block: var(--s-2);
  display: inline-block; position: relative;
}
.primary-nav a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 1px; background: var(--gold);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.2s var(--ease);
}
.primary-nav a:hover, .primary-nav a[aria-current="page"] { color: var(--ink); text-decoration: none; }
.primary-nav a:hover::after, .primary-nav a[aria-current="page"]::after { transform: scaleX(1); }
.primary-nav a[aria-current="page"] { color: var(--gold); }

.navtoggle {
  display: none;
  min-height: 44px;
  align-items: center; gap: var(--s-2);
  background: transparent; border: 1px solid var(--line-strong);
  color: var(--ink); font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.16em; text-transform: uppercase;
  padding: var(--s-2) var(--s-3); cursor: pointer; border-radius: var(--radius);
}
.navtoggle:hover { border-color: var(--gold); color: var(--gold); }
.navtoggle__bars, .navtoggle__bars::before, .navtoggle__bars::after {
  display: block; width: 16px; height: 1.5px; background: currentColor;
  transition: transform 0.2s var(--ease), opacity 0.2s var(--ease);
}
.navtoggle__bars { position: relative; }
.navtoggle__bars::before, .navtoggle__bars::after { content: ""; position: absolute; left: 0; }
.navtoggle__bars::before { top: -5px; }
.navtoggle__bars::after { top: 5px; }
.navtoggle[aria-expanded="true"] .navtoggle__bars { background: transparent; }
.navtoggle[aria-expanded="true"] .navtoggle__bars::before { transform: translateY(5px) rotate(45deg); }
.navtoggle[aria-expanded="true"] .navtoggle__bars::after { transform: translateY(-5px) rotate(-45deg); }

/* JS-enhanced mobile drawer. Without JS the nav simply wraps and stays visible.
   The breakpoint is 72rem, not 48rem: the wordmark plus nine nav items do not
   fit on one row until roughly 1150px, so the whole wrap-prone band gets the
   hamburger rather than a three-row masthead on an iPad in landscape. */
@media (max-width: 71.99rem) {
  .js .navtoggle { display: inline-flex; }
  .js .primary-nav {
    flex-basis: 100%;
    display: grid; grid-template-rows: 0fr;
    transition: grid-template-rows 0.25s var(--ease);
  }
  /* The 0fr→1fr drawer clips the list but would leave its links in the tab
     order while collapsed, so a keyboard user tabs into an invisible menu.
     visibility:hidden removes them from the tab order; the delayed transition
     keeps them painted for the length of the close animation. */
  .js .primary-nav > ul {
    overflow: hidden; flex-direction: column; gap: 0;
    visibility: hidden; transition: visibility 0s linear 0.25s;
  }
  .js .primary-nav[data-open="true"] { grid-template-rows: 1fr; }
  .js .primary-nav[data-open="true"] > ul { visibility: visible; transition-delay: 0s; }
  .js .primary-nav li { border-top: 1px solid var(--line); }
  .js .primary-nav a { display: block; padding: var(--s-3) 0; font-size: var(--t-sm); min-height: 44px; }
}

/* ---------- 6. hero -------------------------------------------------- */
.hero {
  position: relative; isolation: isolate; overflow: hidden;
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(60rem 34rem at 72% 8%, rgba(90, 210, 255, 0.16), transparent 65%),
    radial-gradient(46rem 30rem at 12% 92%, rgba(255, 201, 74, 0.10), transparent 62%),
    linear-gradient(180deg, #060910 0%, var(--space) 100%);
}
.hero__stars {
  position: absolute; inset: 0; width: 100%; height: 100%;
  z-index: -2; opacity: 0.75;
}
.hero__scan {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: repeating-linear-gradient(
    180deg, rgba(5, 7, 11, 0) 0 2px, rgba(5, 7, 11, 0.32) 2px 4px);
  opacity: 0.5;
}
.hero__inner {
  position: relative;
  display: grid; gap: var(--s-7); align-items: center;
  padding-block: var(--s-8);
}
.hero--home .hero__inner { padding-block: clamp(3rem, 9vw, 7rem); }
@media (min-width: 62rem) {
  .hero--home .hero__inner { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
}
.hero__title { font-size: var(--t-4xl); margin-bottom: var(--s-4); }
.hero--page .hero__title { font-size: var(--t-3xl); }
@media (min-width: 62rem) {
  .hero--page .hero__inner { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); }
}

/* section stat rail — the right half of every interior hero */
.statrail {
  display: grid; gap: var(--s-3);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.statrail__item {
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: linear-gradient(160deg, rgba(12, 17, 25, 0.85), rgba(12, 17, 25, 0.35));
  padding: var(--s-4);
}
.statrail__n {
  display: block; font-family: var(--f-display); font-weight: 700;
  font-size: var(--t-2xl); line-height: 1; color: var(--gold);
  font-variant-numeric: tabular-nums; letter-spacing: 0.01em;
}
.statrail__l {
  display: block; margin-top: var(--s-2);
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted);
}
.statrail__item--wide { grid-column: 1 / -1; }
.statrail__item--wide .statrail__n { font-size: var(--t-xl); }
.hero__lead {
  font-size: var(--t-lg); color: var(--muted); max-width: 52ch; line-height: 1.6;
}
.hero__lead strong { color: var(--ink); font-weight: 600; }
.hero__meta { margin-top: var(--s-4); color: var(--faint); }
.hero__meta a { color: var(--muted); }
/* Each stat is one unbreakable unit; the separator carries the only break
   opportunity, so the line wraps BETWEEN stats and never inside one. */
.hero__meta { display: flex; flex-wrap: wrap; align-items: baseline; }
.hero__meta .stat { white-space: nowrap; }
.hero__meta .sep { color: var(--faint); white-space: pre; }
.hero__meta .stat strong { color: var(--ink); }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-top: var(--s-6); }
.hero__media { position: relative; }
.hero__media img {
  width: 100%; border: 1px solid var(--line-strong); border-radius: var(--radius-lg);
}
.hero__media--tilt img {
  box-shadow: 0 0 0 1px rgba(90, 210, 255, 0.18);
  transform: perspective(60rem) rotateY(-7deg) rotateX(2deg);
}
@media (prefers-reduced-motion: reduce) { .hero__media--tilt img { transform: none; } }

/* ---------- 7. buttons ---------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.16em; text-transform: uppercase;
  padding: var(--s-3) var(--s-5);
  min-height: 44px;
  border: 1px solid transparent; border-radius: var(--radius);
  background: transparent;
  -webkit-appearance: none; appearance: none;
  transition: background 0.18s var(--ease), color 0.18s var(--ease), border-color 0.18s var(--ease);
  cursor: pointer;
}
.btn--primary { background: var(--gold); color: var(--ink-invert); font-weight: 700; }
.btn--primary:hover { background: #ffe08a; color: var(--ink-invert); text-decoration: none; }
.btn--ghost { border-color: var(--line-strong); color: var(--ink); background: transparent; }
.btn--ghost:hover { border-color: var(--ion); color: var(--ion); text-decoration: none; background: var(--ion-dim); }

/* ---------- 8. badges, pills, chips --------------------------------- */
.badge {
  display: inline-block;
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.14em; text-transform: uppercase;
  padding: 0.15em 0.55em;
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  color: var(--muted); background: rgba(231, 236, 245, 0.04);
  white-space: nowrap;
}
.badge--canon   { color: var(--canon);   border-color: rgba(71, 224, 160, 0.4);  background: var(--canon-dim); }
.badge--legends { color: var(--legend);  border-color: rgba(201, 167, 255, 0.4); background: var(--legend-dim); }
.badge--noncanon{ color: #f0a868;        border-color: rgba(240, 168, 104, 0.4); background: rgba(240, 168, 104, 0.13); }
.badge--kind    { color: var(--ion);     border-color: rgba(90, 210, 255, 0.32); background: var(--ion-dim); }
.badge--era     { color: var(--gold);    border-color: rgba(255, 201, 74, 0.34); background: var(--gold-dim); }
.badge--alert   { color: var(--crimson); border-color: rgba(255, 85, 102, 0.4);  background: var(--crimson-dim); }
/* Opinion and roundups are labelled on the card, not only on the article. */
.badge--opinion { color: var(--gold);    border-color: rgba(255, 201, 74, 0.55); background: var(--gold-dim); font-weight: 700; }
.badge--roundup { color: var(--legend);  border-color: rgba(201, 167, 255, 0.45); background: var(--legend-dim); }

.pill {
  display: inline-flex; align-items: center;
  min-height: 44px;
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.12em; text-transform: uppercase;
  padding: 0.55em 1em; border-radius: 999px;
  border: 1px solid var(--line-strong); color: var(--muted);
  background: rgba(231, 236, 245, 0.02);
}
a.pill:hover { border-color: var(--gold); color: var(--gold); text-decoration: none; }

.chips { display: flex; flex-wrap: wrap; gap: var(--s-2); list-style: none; }
.chip {
  display: inline-block; font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.08em; padding: 0.25em 0.7em;
  border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--muted); background: rgba(231, 236, 245, 0.03);
}
.chip:hover { color: var(--gold); border-color: rgba(255, 201, 74, 0.4); text-decoration: none; }
.chip::before { content: "#"; color: var(--faint); margin-right: 0.15em; }

/* tag cloud on the topic index and the library foot */
.chips--cloud { gap: var(--s-2) var(--s-3); }
.chips--cloud .pill { min-height: 44px; padding: 0.4em 0.9em; }
.pill .mono { margin-left: 0.55em; color: var(--faint); font-size: 0.85em; letter-spacing: 0.08em; }
.pill--hot { border-color: rgba(255, 201, 74, 0.5); color: var(--gold); background: var(--gold-dim); }

/* ---------- 9. rating meter ----------------------------------------- */
.rating {
  display: flex; align-items: center; gap: var(--s-3);
  font-family: var(--f-mono);
}
.rating__value {
  font-size: var(--t-lg); font-weight: 700; letter-spacing: 0.02em;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
.rating__track {
  flex: 1 1 4rem; min-width: 3rem; height: 5px;
  background: rgba(231, 236, 245, 0.10); border-radius: 999px; overflow: hidden;
}
.rating__fill { display: block; height: 100%; border-radius: 999px; background: var(--gold); width: 0; }
.rating__fill--0 { width: 0%; }
.rating__fill--5 { width: 5%; }
.rating__fill--10 { width: 10%; }
.rating__fill--15 { width: 15%; }
.rating__fill--20 { width: 20%; }
.rating__fill--25 { width: 25%; }
.rating__fill--30 { width: 30%; }
.rating__fill--35 { width: 35%; }
.rating__fill--40 { width: 40%; }
.rating__fill--45 { width: 45%; }
.rating__fill--50 { width: 50%; }
.rating__fill--55 { width: 55%; }
.rating__fill--60 { width: 60%; }
.rating__fill--65 { width: 65%; }
.rating__fill--70 { width: 70%; }
.rating__fill--75 { width: 75%; }
.rating__fill--80 { width: 80%; }
.rating__fill--85 { width: 85%; }
.rating__fill--90 { width: 90%; }
.rating__fill--95 { width: 95%; }
.rating__fill--100 { width: 100%; }
.rating__scale { font-size: var(--t-xs); color: var(--faint); letter-spacing: 0.1em; }
.rating--high .rating__fill { background: linear-gradient(90deg, var(--canon), #9df3cd); }
.rating--high .rating__value { color: var(--canon); }
.rating--mid  .rating__fill { background: linear-gradient(90deg, var(--gold), #ffe08a); }
.rating--mid  .rating__value { color: var(--gold); }
.rating--low  .rating__fill { background: linear-gradient(90deg, #ffa14a, var(--gold)); }
.rating--low  .rating__value { color: #ffa14a; }
.rating--poor .rating__fill { background: linear-gradient(90deg, var(--crimson), #ff9aa5); }
.rating--poor .rating__value { color: var(--crimson); }
.rating--compact { margin-top: var(--s-3); }
.rating--compact .rating__value { font-size: var(--t-base); }
.rating--large { gap: var(--s-2); }
.rating--large .rating__value { font-size: var(--t-2xl); }
/* The score meter is a score, not a progress bar: cap it so 8.8 and /10 stay
   one readable unit instead of being pushed three-quarters of a column apart. */
.rating--large .rating__track { flex: 0 1 14rem; height: 8px; margin-left: var(--s-3); }
.rating--large .rating__scale { font-size: var(--t-sm); margin-right: var(--s-1); order: -1; }
.rating--large .rating__value { order: -2; }

/* ---------- 10. cards ------------------------------------------------ */
.card {
  position: relative; height: 100%;
  display: flex; flex-direction: column;
  background: linear-gradient(180deg, var(--panel), rgba(12, 17, 25, 0.55));
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: border-color 0.2s var(--ease), transform 0.2s var(--ease), background 0.2s var(--ease);
}
.card:hover { border-color: var(--line-accent); background: linear-gradient(180deg, var(--raised), var(--panel)); }
.card:focus-within { border-color: var(--gold); }
@media (prefers-reduced-motion: no-preference) {
  .card:hover { transform: translateY(-2px); }
}
.card__media { display: block; background: var(--space); overflow: hidden; border-bottom: 1px solid var(--line); }
.card__media img { width: 100%; transition: transform 0.4s var(--ease); }
@media (prefers-reduced-motion: no-preference) {
  .card:hover .card__media img { transform: scale(1.03); }
}
.card__media--cover  { aspect-ratio: 2 / 3; }
.card__media--plate  { aspect-ratio: 1 / 1; }
.card__media--banner { aspect-ratio: 8 / 3; }
.card__media--wide   { aspect-ratio: 40 / 21; }
.card__media img { height: 100%; object-fit: cover; }

.card__body {
  display: flex; flex-direction: column; gap: var(--s-2);
  padding: var(--s-4); flex: 1;
}
.card__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
.card__title { font-size: var(--t-lg); letter-spacing: 0.03em; }
.card__title a { color: var(--ink); }
/* full-card click target without nesting interactive elements */
.card__title a::after { content: ""; position: absolute; inset: 0; }
.card__title a:hover { color: var(--gold); text-decoration: none; }
.card__byline { font-size: var(--t-sm); color: var(--muted); }
.card__blurb {
  font-size: var(--t-sm); color: var(--muted); line-height: 1.55;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  overflow: hidden;
}
.card--era .card__title { font-size: var(--t-xl); }
/* Pin the score to the foot of the card so a row of scores reads as a row. */
.card--book .rating { margin-top: auto; padding-top: var(--s-3); }
.card--character .card__blurb, .card--article .card__blurb { margin-bottom: auto; }

/* horizontal list row variant */
.rowcard {
  display: grid; grid-template-columns: 4.5rem minmax(0, 1fr); gap: var(--s-4);
  align-items: start; position: relative;
  padding: var(--s-4) 0; border-top: 1px solid var(--line);
}
.rowcard:last-child { border-bottom: 1px solid var(--line); }
.rowcard__media img { border: 1px solid var(--line); border-radius: 2px; }
.rowcard__title { font-size: var(--t-lg); }
.rowcard__title a { color: var(--ink); }
.rowcard__title a::after { content: ""; position: absolute; inset: 0; }
.rowcard__title a:hover { color: var(--gold); text-decoration: none; }
.rowcard > div:last-child { max-width: 68ch; }
.rowcard:hover { background: rgba(231, 236, 245, 0.025); }

/* ---------- 11. panels, callouts, quotes ----------------------------- */
.panel {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius-lg); padding: var(--s-5);
}
.panel--raised { background: var(--raised); }
.panel ul { list-style: none; }
.panel li + li { margin-top: var(--s-2); }
/* compact link list used in sidebars */
.linklist li { border-top: 1px solid var(--line); padding-top: var(--s-2); }
.linklist li:first-child { border-top: 0; padding-top: 0; }
.linklist a { display: block; padding-block: 0.35rem; color: var(--ink); }
.linklist a:hover { color: var(--gold); }
.linklist .mono { display: block; margin-top: 1px; }
.panel__sub {
  margin-top: var(--s-4); padding-top: var(--s-3); border-top: 1px solid var(--line);
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--faint);
}
.panel__more {
  margin-top: var(--s-4); padding-top: var(--s-3); border-top: 1px solid var(--line);
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.16em; text-transform: uppercase;
}
.panel__h {
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--gold); margin-bottom: var(--s-3);
  padding-bottom: var(--s-3); border-bottom: 1px solid var(--line);
}

.callout {
  border: 1px solid var(--line-strong); border-left-width: 2px;
  border-left-color: var(--ion);
  background: linear-gradient(90deg, var(--ion-dim), transparent 60%);
  padding: var(--s-4) var(--s-5); border-radius: var(--radius);
  font-size: var(--t-base);
}
.callout--warn { border-left-color: var(--crimson); background: linear-gradient(90deg, var(--crimson-dim), transparent 60%); }
.callout--tip  { border-left-color: var(--canon);   background: linear-gradient(90deg, var(--canon-dim), transparent 60%); }
.callout--spoiler { border-left-color: var(--gold); background: linear-gradient(90deg, var(--gold-dim), transparent 60%); }
.callout__title {
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--gold); margin-bottom: var(--s-2);
}
.callout__body > * + * { margin-top: var(--s-3); }

.pullquote { margin: var(--s-7) 0; padding-left: var(--s-5); border-left: 2px solid var(--gold); }
.pullquote blockquote p {
  font-family: var(--f-display); font-size: var(--t-2xl);
  line-height: 1.15; letter-spacing: 0.01em; color: var(--ink);
}
.pullquote figcaption {
  margin-top: var(--s-3); font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted);
}

/* ---------- 12. data table ------------------------------------------ */
/* The wrapper is focusable (see build.mjs: tabindex="0" role="region"), so a
   keyboard-only user can reach the columns that are clipped on a phone. The
   right-edge fade is the visual cue that the table continues off-screen. */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background:
    linear-gradient(270deg, var(--panel), rgba(12, 17, 25, 0)) 100% 0 / 2.5rem 100% no-repeat local,
    linear-gradient(270deg, rgba(90, 210, 255, 0.28), rgba(90, 210, 255, 0)) 100% 0 / 2.5rem 100% no-repeat scroll;
}
.table-wrap:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
@media (min-width: 48rem) { .table-wrap { background-image: none; } }

/* Why the database tables get a bounded height.
   `.table-wrap` sets `overflow-x: auto` so a 62rem table can scroll sideways
   instead of squeezing. CSS then blockifies the other axis: `overflow-y`
   computes to `auto` too, which makes the wrapper a scroll container in BOTH
   directions. A `position: sticky` header inside it therefore resolves against
   the wrapper's scrollport, not the page's — and because the wrapper's height
   was `auto` it never scrolled vertically, so the sticky header had nothing to
   stick to and simply scrolled off with the page. Measured on the issue index:
   a 61,716px-tall wrapper, 250 rows, and eight unlabelled columns the moment
   the header left the screen.
   `overflow-y: clip` does not rescue it (it computes to `hidden` and the box is
   still a scroll container), so the only fix that keeps horizontal scrolling is
   to give the wrapper a real, viewport-bounded height. The header then has a
   scrollport to pin to, and `top: 0` on the cell is correct precisely BECAUSE
   the wrapper already sits below the masthead — the offset is expressed here,
   once, in the same `var(--nav-h)` terms as `.azbar` and `.split > aside`, so
   all three sticky layers stay in sync if the masthead height changes.
   Phones keep the natural flow: a nested vertical scroll region under a thumb
   is worse than a header that scrolls away. */
@media (min-width: 48rem) {
  /* max-height only: a short table (a character's three-row Appearances list)
     keeps its natural height, while a 250-row issue index caps and scrolls.
     A min-height here would pad the short ones out with dead space. */
  .table-wrap--db {
    max-height: calc(100vh - var(--nav-h) - 7rem);
    scrollbar-width: thin;
  }
}
table.data { width: 100%; border-collapse: collapse; font-size: var(--t-sm); min-width: 32rem; }
table.data caption {
  text-align: left; padding: var(--s-3) var(--s-4);
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--gold);
  border-bottom: 1px solid var(--line);
}
table.data th, table.data td { padding: var(--s-3) var(--s-4); text-align: left; vertical-align: top; }
table.data thead th {
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted); font-weight: 500;
  border-bottom: 1px solid var(--line-strong);
  background: rgba(231, 236, 245, 0.03);
}
table.data tbody tr + tr td { border-top: 1px solid var(--line); }
table.data tbody tr:hover td { background: rgba(231, 236, 245, 0.025); }
table.data td.num { font-family: var(--f-mono); font-variant-numeric: tabular-nums; color: var(--muted); }

/* ---------- database tables (comics, issues, collections) ---------- */
/* Same visual language as table.data, but these carry hundreds to thousands
   of rows, so: tabular numerals, a sticky header, and a minimum width that
   forces horizontal scroll inside .table-wrap rather than squeezing eight
   columns into 320px of phone. */
.dbtable { width: 100%; border-collapse: collapse; font-size: var(--t-sm); min-width: 48rem; }
.dbtable--issues { min-width: 62rem; }
.dbtable caption {
  text-align: left; padding: var(--s-3) var(--s-4);
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--gold);
}
.dbtable th, .dbtable td { padding: var(--s-3) var(--s-4); text-align: left; vertical-align: top; }
/* top: 0 is the wrapper's own top, not the page's — see the .table-wrap--db
   note above for why that is the correct value here. */
.dbtable thead th {
  position: sticky; top: 0; z-index: 2;
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted); font-weight: 500; white-space: nowrap;
  border-bottom: 1px solid var(--line-strong);
  /* Must be fully opaque: rows scroll underneath it. */
  background: var(--raised);
  box-shadow: 0 1px 0 var(--line-strong), 0 6px 12px -8px rgba(0, 0, 0, 0.8);
}
.dbtable tbody tr + tr th, .dbtable tbody tr + tr td { border-top: 1px solid var(--line); }
.dbtable tbody tr:hover td { background: rgba(231, 236, 245, 0.03); }

/* Pinned row-identity column.
   These tables are wider than any phone and several are wider than a laptop,
   so the reader scrolls sideways — and the moment the first column leaves the
   screen, every remaining cell is an orphan: a creator credit with no idea
   which series it belongs to. Both database tables mark that first cell
   `<th scope="row">`, which is already the correct semantics for "this is what
   the row is about", so it is also the right thing to pin.
   The backgrounds here MUST be opaque hex (--panel / --raised), never the
   translucent row-hover rgba, because live cells scroll underneath them. */
.dbtable thead th:first-child,
.dbtable tbody th[scope="row"] {
  position: sticky; left: 0;
  background: var(--panel);
}
.dbtable tbody th[scope="row"] { z-index: 1; }
/* The top-left cell is pinned on both axes, so it has to outrank both the
   sticky header row (2) and the sticky first column (1). */
.dbtable thead th:first-child { z-index: 3; background: var(--raised); }
.dbtable tbody tr:hover th[scope="row"] { background: #121826; }
/* The seam. A flat hairline alone reads as a table border; the short shadow
   makes the scrolling cells look like they pass UNDER the pinned column, which
   is what actually happens. The header corner has to carry its own bottom
   shadow too, so it restates both in one declaration. */
.dbtable tbody th[scope="row"] {
  box-shadow: 1px 0 0 var(--line), 7px 0 11px -8px rgba(0, 0, 0, 0.9);
}
.dbtable thead th:first-child {
  box-shadow: 1px 0 0 var(--line), 7px 0 11px -8px rgba(0, 0, 0, 0.9),
              0 1px 0 var(--line-strong), 0 6px 12px -8px rgba(0, 0, 0, 0.8);
}
.dbtable .num { text-align: right; font-family: var(--f-mono); font-variant-numeric: tabular-nums; }
.dbtable .nowrap { white-space: nowrap; }
.dbrow__title { font-weight: 600; min-width: 14rem; }
.dbrow__title a { color: var(--ink); }
.dbrow__title a:hover { color: var(--gold); }
.dbrow__sub {
  display: block; font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--faint); margin-top: 2px;
}
.dbrow__creators, .dbrow__notes { color: var(--muted); max-width: 26rem; }
.dbrow__notes { max-width: 30rem; }

/* ---------- server-rendered pagination ---------------------------- */
.pagenav {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3);
  margin-top: var(--s-6); padding-top: var(--s-5); border-top: 1px solid var(--line);
}
.pagenav ol { display: flex; flex-wrap: wrap; gap: var(--s-2); list-style: none; margin-inline: auto; }
.pagenav a, .pagenav__cur, .pagenav__gap, .pagenav__step {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px; padding: 0 var(--s-3);
  font-family: var(--f-mono); font-size: var(--t-xs); letter-spacing: 0.1em;
  border: 1px solid var(--line); border-radius: var(--radius);
}
.pagenav a { color: var(--ink); }
.pagenav a:hover { border-color: var(--gold); color: var(--gold); text-decoration: none; }
.pagenav__cur { background: var(--gold-dim); border-color: rgba(255, 201, 74, 0.45); color: var(--gold); font-weight: 700; }
.pagenav__gap { border-color: transparent; color: var(--faint); min-width: 2rem; }
.pagenav__step--off { color: var(--faint); border-color: transparent; }

/* ---------- encyclopedia list ------------------------------------- */
/* A list rather than a grid of cards: five hundred plus entries have to stay
   scannable and the page has to stay under a megabyte. */
.dbcards { list-style: none; display: grid; gap: 0; }
.dbcard {
  display: grid; grid-template-columns: 3.5rem minmax(0, 1fr); gap: var(--s-4);
  align-items: center; padding: var(--s-4) 0; border-top: 1px solid var(--line);
  position: relative;
}
@media (min-width: 48rem) {
  .dbcard { grid-template-columns: 4.5rem minmax(0, 1fr) 9rem; }
}
.dbcard:hover { background: rgba(231, 236, 245, 0.025); }
.dbcard__media {
  display: block; border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; background: var(--space); aspect-ratio: 1 / 1;
}
.dbcard__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Tier-3 art is a 440x300 landscape card: cropped to a square from the centre
   you get a slice of the name and no sigil. Anchor it left instead, so the
   thumbnail shows the heraldic mark — which is the identifying half. */
.dbcard__media--card img { object-position: left center; }
.dbcard__name { font-family: var(--f-display); font-size: var(--t-lg); letter-spacing: 0.03em; }
.dbcard__name a { color: var(--ink); }
.dbcard__name a::after { content: ""; position: absolute; inset: 0; }
.dbcard__name a:hover { color: var(--gold); text-decoration: none; }
.dbcard__meta { font-size: var(--t-xs); color: var(--faint); letter-spacing: 0.1em; text-transform: uppercase; margin-top: 2px; }
.dbcard__blurb { font-size: var(--t-sm); color: var(--muted); margin-top: var(--s-2); max-width: 60ch; }
.dbcard__tier { grid-column: 2 / -1; margin-top: var(--s-2); }
@media (min-width: 48rem) {
  .dbcard__tier { grid-column: 3; margin-top: 0; justify-self: end; }
}
.azlist > .deflist__letter:first-child { margin-top: 0; }

/* tier badges — the promise about depth, printed */
.badge--tier1 { color: var(--gold);   border-color: rgba(255, 201, 74, 0.4);  background: var(--gold-dim); }
.badge--tier2 { color: var(--ion);    border-color: rgba(90, 210, 255, 0.32); background: var(--ion-dim); }
.badge--tier3 { color: var(--muted);  border-color: var(--line-strong);       background: transparent; }

/* a disabled letter in the A-Z bar: present, so the bar does not reflow */
.pill--off { color: var(--faint); border-color: transparent; opacity: 0.5; cursor: default; }

/* ---------- comics ------------------------------------------------ */
.card__media--comic { aspect-ratio: 600 / 920; }
.card__media--cardart { aspect-ratio: 440 / 300; }
.detail-head__media--comic { max-width: 19rem; }
.detail-head__media--card { max-width: 22rem; }
.creatorname { display: block; padding-block: 0.35rem; color: var(--ink); }
.notelist { list-style: none; margin-top: var(--s-4); font-size: var(--t-sm); color: var(--muted); }
.notelist li + li { margin-top: var(--s-2); }
.notelist strong { color: var(--ink); }

/* publishing-history timeline */
.pubtimeline { list-style: none; display: grid; gap: var(--s-7); }
.pubrow { display: grid; gap: var(--s-5); }
@media (min-width: 48rem) { .pubrow { grid-template-columns: 7rem minmax(0, 1fr); } }
.pubrow__mark img {
  width: 100%; max-width: 7rem; border: 1px solid var(--line); border-radius: var(--radius); display: block;
}
.pubrow__h { font-size: var(--t-xl); letter-spacing: 0.03em; }
.pubrow__years { color: var(--gold); margin-top: var(--s-2); }
.pubrow__body .linklist { margin-top: var(--s-4); }

/* faction / species browse blocks */
/* the jump list is a disclosure, not a sticky bar: a hundred and fifty
   faction names pinned to the top would cover the page they navigate */
.jumpshell { margin-bottom: var(--s-6); }
.jumpshell nav { margin-top: var(--s-4); }
.groupblock { scroll-margin-top: calc(var(--nav-h) + 2rem); }
.groupblock__head { display: flex; gap: var(--s-4); align-items: center; margin-bottom: var(--s-4); }
.groupblock__sigil { width: 4rem; height: 4rem; border: 1px solid var(--line); border-radius: var(--radius); flex: none; }
.groupblock__h { font-size: var(--t-lg); letter-spacing: 0.04em; }

/* definition list — used by the glossary */
.deflist { display: grid; gap: 0; }
.deflist__item {
  padding: var(--s-4) 0; border-top: 1px solid var(--line);
  display: grid; gap: var(--s-2);
}
@media (min-width: 48rem) {
  .deflist__item { grid-template-columns: 14rem minmax(0, 1fr); gap: var(--s-5); }
}
.deflist__term {
  font-family: var(--f-display); font-size: var(--t-lg);
  text-transform: uppercase; letter-spacing: 0.05em; color: var(--gold);
}
.deflist__def { color: var(--muted); margin: 0; max-width: 68ch; }

/* ---------- 13. timeline rail ---------------------------------------- */
.timeline { position: relative; list-style: none; padding-left: var(--s-6); }
.timeline::before {
  content: ""; position: absolute; left: 6px; top: 0.5em; bottom: 0.5em;
  width: 1px; background: linear-gradient(180deg, transparent, var(--line-accent) 12%, var(--line-accent) 88%, transparent);
}
.timeline__item { position: relative; padding-bottom: var(--s-5); }
.timeline__item::before {
  content: ""; position: absolute; left: calc(-1 * var(--s-6) + 2px); top: 0.55em;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--space); border: 1.5px solid var(--gold);
}
.timeline__year {
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--ion);
}
.timeline__title { font-size: var(--t-lg); margin-top: var(--s-1); }
.timeline__note { font-size: var(--t-sm); color: var(--muted); margin-top: var(--s-1); }

/* ---------- 14. breadcrumb & pager ----------------------------------- */
.breadcrumb { padding-block: var(--s-4); }
.breadcrumb ol { display: flex; flex-wrap: wrap; gap: var(--s-2); list-style: none; }
.breadcrumb li, .breadcrumb a {
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted);
}
.breadcrumb a:hover { color: var(--gold); }
.crumb + .crumb::before { content: "/"; margin-right: var(--s-2); color: var(--faint); }
.breadcrumb [aria-current="page"] { color: var(--ink); }

.pager {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-4);
  margin-top: var(--s-7); padding-top: var(--s-5); border-top: 1px solid var(--line);
}
.pager__link {
  display: flex; flex-direction: column; gap: var(--s-1);
  padding: var(--s-4); border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--ink);
}
.pager__link:hover { border-color: var(--line-accent); text-decoration: none; background: rgba(90, 210, 255, 0.05); }
.pager__link--next { text-align: right; }
.pager__dir {
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--gold);
}
.pager__label { font-family: var(--f-display); font-size: var(--t-base); letter-spacing: 0.03em; text-transform: uppercase; }
.pager__spacer { display: block; }

/* ---------- 15. filter bar ------------------------------------------- */
.filterbar {
  display: grid; gap: var(--s-4);
  padding: var(--s-5); margin-bottom: var(--s-6);
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-lg);
}
@media (min-width: 48rem) {
  .filterbar { grid-template-columns: minmax(12rem, 1.5fr) repeat(auto-fit, minmax(8.5rem, 1fr)); align-items: end; }
}
.field { display: grid; gap: var(--s-2); }
.field > label {
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted);
}
.field input, .field select {
  font-family: var(--f-body); font-size: var(--t-sm);
  min-height: 44px;
  color: var(--ink); background: var(--space);
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  padding: var(--s-3); width: 100%;
  -webkit-appearance: none; appearance: none;
}
.field select {
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
                    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 16px) calc(50% + 1px), calc(100% - 11px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: var(--s-7);
}
.field input:focus, .field select:focus { border-color: var(--ion); outline-offset: 1px; }
.field input::placeholder { color: var(--faint); }
.filterbar__actions { display: flex; gap: var(--s-2); align-items: end; }
.resultcount {
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted);
  margin-bottom: var(--s-4);
}
.noscript-note {
  font-size: var(--t-sm); color: var(--muted);
  border: 1px dashed var(--line-strong); border-radius: var(--radius);
  padding: var(--s-3) var(--s-4);
}
.js-only { display: none; }
html.js .js-only { display: block; }
html.js .filterbar.js-only { display: grid; }
.no-js-only { display: none; }
html:not(.js) .no-js-only { display: block; }

/* Collapsible filter shell. On a phone the open filter bar was 508px tall and
   pushed the first book below two full screens; here it is a single 44px row
   until the reader asks for it, and it is open by default from 48rem up. */
.filtershell { margin-bottom: var(--s-6); }
.filtershell > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: var(--s-3);
  min-height: 44px; padding: var(--s-2) var(--s-4);
  border: 1px solid var(--line-strong); border-radius: var(--radius-lg);
  background: var(--panel);
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink);
}
.filtershell > summary::-webkit-details-marker { display: none; }
.filtershell > summary::after {
  content: "+"; margin-left: auto; color: var(--gold);
  font-size: var(--t-lg); line-height: 1;
}
.filtershell[open] > summary::after { content: "\2212"; }
.filtershell > summary:hover { border-color: var(--gold); color: var(--gold); }
.filtershell .filterbar { margin-top: var(--s-3); margin-bottom: 0; }
.filtershell__n { color: var(--muted); }

/* Facet chips under the search box. These report the TRUE per-kind match
   count for the current query, so the reader can see the shape of the corpus
   before deciding what to narrow to. They drive the <select> rather than
   holding their own state, so there is exactly one source of truth. */
.chips--facets {
  margin: calc(var(--s-4) * -1) 0 var(--s-4);
  padding-bottom: var(--s-3);
  border-bottom: 1px solid var(--line);
}
.pill--facet {
  cursor: pointer; font: inherit;
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.12em; text-transform: uppercase;
  transition: border-color 120ms ease, color 120ms ease, background-color 120ms ease;
}
.pill--facet:hover { border-color: var(--gold); color: var(--gold); }
.pill--facet[aria-current="true"] {
  border-color: rgba(255, 201, 74, 0.55); color: var(--gold);
  background: var(--gold-dim);
}
.pill--facet[aria-current="true"] .mono { color: var(--gold); opacity: 0.8; }

/* On a phone, ten wrapped facet chips pushed the first actual result about
   130px down the page. One scrollable row keeps the whole result set in reach
   without hiding the filter. Tabbing still reaches every chip — the browser
   scrolls a focused button into view — so nothing is keyboard-only-invisible.
   The right-edge fade is the same cue .table-wrap uses for the same reason. */
@media (max-width: 47.99rem) {
  .chips--facets {
    flex-wrap: nowrap; overflow-x: auto;
    scrollbar-width: none;
    padding-right: var(--s-5);
    background:
      linear-gradient(270deg, var(--space), rgba(5, 7, 11, 0)) 100% 0 / 2rem 100% no-repeat local,
      linear-gradient(270deg, rgba(90, 210, 255, 0.22), rgba(90, 210, 255, 0)) 100% 0 / 2rem 100% no-repeat scroll;
  }
  .chips--facets::-webkit-scrollbar { display: none; }
  .chips--facets > li { flex: 0 0 auto; }
}

/* "Show more" under the result list. The search page paints 40 rows at a time;
   this is how the other 445 are reachable rather than silently dropped. */
.searchmore {
  display: flex; justify-content: center;
  margin-top: var(--s-5); padding-top: var(--s-5);
  border-top: 1px solid var(--line);
}
.searchmore .btn { min-width: 16rem; justify-content: center; }

/* start-state suggestions on the search page */
.startpicks { margin-top: var(--s-5); }
.startpicks__h {
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--muted);
  margin-bottom: var(--s-3);
}

/* ---------- 16. section head ---------------------------------------- */
/* Flex row, not an absolutely positioned link over a guessed 7rem reserve:
   the "view all" link can never overlap the title however long either gets. */
/* Explicit grid tracks, not an absolutely positioned link over a guessed 7rem
   reserve: the "view all" link cannot overlap the title however long either
   string gets, and the lead always gets its own full-width row. */
.sec-head {
  margin-bottom: var(--s-6);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--s-3) var(--s-5);
}
.sec-head .kicker { grid-column: 1 / -1; margin-bottom: 0; }
.sec-head__title { grid-column: 1; font-size: var(--t-2xl); }
.sec-head__more {
  grid-column: 2; justify-self: end;
  min-height: 44px; display: inline-flex; align-items: center;
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.16em; text-transform: uppercase;
}
.sec-head__lead { grid-column: 1 / -1; color: var(--muted); margin-top: 0; max-width: 62ch; }
@media (max-width: 34rem) {
  .sec-head { grid-template-columns: minmax(0, 1fr); }
  .sec-head__more { grid-column: 1; justify-self: start; }
}
.sec-head__more::after { content: " \2192"; }

/* ---------- 17. detail page furniture -------------------------------- */
.detail-head { display: grid; gap: var(--s-6); align-items: start; }
/* Two columns from 34rem with a narrow media column, rather than an
   all-or-nothing switch at 55rem that let the cover become a 704x1055 poster. */
@media (min-width: 34rem) {
  .detail-head { grid-template-columns: 11rem minmax(0, 1fr); gap: var(--s-5) var(--s-6); }
}
@media (min-width: 55rem) {
  .detail-head { grid-template-columns: 17rem minmax(0, 1fr); gap: var(--s-7); }
}
/* A cover stays a cover at every width. */
.detail-head__media { max-width: 17rem; justify-self: start; }
.detail-head__media img {
  width: 100%; border: 1px solid var(--line-strong); border-radius: var(--radius-lg);
}
.detail-head__media .mono { margin-top: var(--s-2); }
.detail-head__title { font-size: var(--t-3xl); margin-block: var(--s-3); }
/* Sentence-length text, so no uppercase: the display face and the gold already
   do the work, and all-caps was removing the word shapes. */
.detail-head__tagline {
  font-size: var(--t-lg); color: var(--gold);
  font-family: var(--f-display); font-stretch: 87.5%;
  letter-spacing: 0.015em; line-height: 1.25; max-width: 46ch;
}
.detail-head__blurb { color: var(--muted); margin-top: var(--s-4); max-width: 55ch; }
.metalist { display: grid; gap: var(--s-2); margin-top: var(--s-5); }
@media (min-width: 34rem) { .metalist { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* A sidebar panel is ~20rem wide: two columns there gives the term 6.5rem and
   the value 3.5rem, which is how "22 BBY – 19 BBY" ended up on four lines. */
.panel .metalist { grid-template-columns: minmax(0, 1fr) !important; margin-top: 0; }
.panel .metalist div { justify-content: space-between; gap: var(--s-4); }
.panel .metalist dt { min-width: 0; }
.panel .metalist dd { text-align: right; }
.metalist div { display: flex; gap: var(--s-3); align-items: baseline; border-top: 1px solid var(--line); padding-top: var(--s-2); }
.metalist dt {
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--faint);
  min-width: 6.5rem;
}
.metalist dd { margin: 0; font-size: var(--t-sm); color: var(--ink); }

.verdict {
  margin-top: var(--s-5); padding: var(--s-5);
  border: 1px solid rgba(255, 201, 74, 0.28); border-radius: var(--radius-lg);
  background: linear-gradient(135deg, var(--gold-dim), transparent 70%);
}
.verdict__h {
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--gold);
  margin-bottom: var(--s-2);
}
.verdict__text { font-family: var(--f-display); font-size: var(--t-xl); line-height: 1.25; letter-spacing: 0.02em; }

.sources { font-size: var(--t-sm); color: var(--muted); }
.sources ol { padding-left: 1.3em; list-style: decimal; }
.sources li + li { margin-top: var(--s-2); }
.sources li::marker { color: var(--faint); font-family: var(--f-mono); }

.quotecard {
  border-top: 1px solid var(--line); padding-top: var(--s-4); margin-top: var(--s-4);
}
.quotecard p { font-family: var(--f-display); font-size: var(--t-lg); letter-spacing: 0.02em; line-height: 1.3; }
.quotecard cite { display: block; margin-top: var(--s-2); font-family: var(--f-mono); font-size: var(--t-xs); letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); font-style: normal; }

/* Glossary cross-links. A real anchor to the glossary entry — not a
   tabindex span with a native title tooltip that touch users never see. */
.prose a.gloss {
  color: inherit;
  border-bottom: 1px dotted var(--gold);
  text-decoration: none;
}
.prose a.gloss:hover, .prose a.gloss:focus-visible { color: var(--gold); border-bottom-style: solid; }

/* A–Z jump bar on the glossary */
.azbar {
  position: sticky; top: calc(var(--nav-h) + 0.25rem); z-index: 20;
  padding-block: var(--s-3); margin-bottom: var(--s-4);
  background: linear-gradient(180deg, var(--space) 70%, rgba(5, 7, 11, 0));
}
.azbar ul { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.azbar .pill { min-width: 44px; min-height: 44px; justify-content: center; padding: 0.35em 0.6em; }
.deflist__letter {
  font-size: var(--t-xl); color: var(--gold);
  margin-top: var(--s-6); padding-bottom: var(--s-2);
  border-bottom: 1px solid var(--line-strong);
  scroll-margin-top: calc(var(--nav-h) + 4rem);
}

/* ---------- 18. footer ----------------------------------------------- */
.site-foot {
  margin-top: var(--s-9);
  border-top: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(12, 17, 25, 0.5), var(--space));
  padding-block: var(--s-8) var(--s-7);
  font-size: var(--t-sm);
}
.site-foot__inner { display: grid; gap: var(--s-7); }
@media (min-width: 48rem) {
  .site-foot__inner { grid-template-columns: 1.4fr 1fr 1.4fr; gap: var(--s-7); }
}
.wordmark--foot { display: flex; flex-direction: column; }
.site-foot__tagline { color: var(--muted); margin-top: var(--s-3); max-width: 34ch; }
.site-foot__feeds { margin-top: var(--s-3); font-family: var(--f-mono); font-size: var(--t-xs); letter-spacing: 0.12em; text-transform: uppercase; }
.site-foot__h {
  font-family: var(--f-mono); font-size: var(--t-xs);
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--gold);
  margin-bottom: var(--s-3);
}
.site-foot__nav ul { list-style: none; display: grid; gap: 0; }
.site-foot__nav a { color: var(--muted); display: flex; align-items: center; min-height: 44px; padding-block: 0.6rem; }
.site-foot__nav a:hover { color: var(--gold); }
.site-foot__legal p { color: var(--faint); font-size: var(--t-xs); line-height: 1.7; }
.site-foot__legal p + p { margin-top: var(--s-3); }
.site-foot__credit { color: var(--muted) !important; }
.site-foot__copy { letter-spacing: 0.12em; }

/* ---------- 19. 404 & empty states ----------------------------------- */
.bigcode {
  font-family: var(--f-display); font-size: clamp(5rem, 22vw, 14rem);
  line-height: 0.85; letter-spacing: 0.04em; color: var(--gold);
  opacity: 0.9;
}
.empty {
  text-align: center; padding: var(--s-8) var(--s-4);
  border: 1px dashed var(--line-strong); border-radius: var(--radius-lg);
  color: var(--muted);
}

/* ---------- 20. utilities -------------------------------------------- */
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
.text-center { text-align: center; }
.muted { color: var(--muted); }
.lead { font-size: var(--t-lg); color: var(--muted); line-height: 1.6; }
.divider { border: 0; border-top: 1px solid var(--line); margin-block: var(--s-7); }
.flow-tight > * + * { margin-top: var(--s-3); }

/* ---------- 21. responsive overrides (last, so they always win) ------- */

/* Library grid goes 2-up on a phone instead of one 335x688 card per row —
   73 single-column cards was a ~50,000px page. */
@media (max-width: 34rem) {
  .grid--3 { grid-template-columns: repeat(auto-fill, minmax(min(9.5rem, 100%), 1fr)); gap: var(--s-4); }
  .grid--3 .card__body { padding: var(--s-3); gap: var(--s-1); }
  .grid--3 .card__title { font-size: var(--t-base); }
  .grid--3 .card__blurb { display: none; }
  .grid--3 .card__meta .badge--kind { display: none; }
  .hero__lead { font-size: var(--t-base); max-width: none; }
  .lead { font-size: var(--t-base); }
  /* Four selects 2x2 rather than four stacked full-width rows. */
  .filterbar { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: var(--s-4); }
  .filterbar .field:first-child, .filterbar__actions { grid-column: 1 / -1; }
}

/* Two hero CTAs at two different content widths read as a mistake. */
@media (max-width: 30rem) {
  .hero__actions { display: grid; gap: var(--s-3); }
  .hero__actions .btn { justify-content: center; width: 100%; }
  .pager { grid-template-columns: 1fr; }
}

/* ---------- 22. motion preferences ----------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .hero__stars { display: none; }
}

/* ---------- 23. print ------------------------------------------------ */
@media print {
  :root { --ink: #111; --muted: #444; --space: #fff; }
  body {
    background: #fff; color: #111;
    font-family: Georgia, "Times New Roman", serif; font-size: 11pt; line-height: 1.5;
  }
  .masthead, .site-foot__nav, .hero__stars, .hero__scan, .navtoggle,
  .filterbar, .pager, .skiplink, .breadcrumb, .chips, .sec-head__more { display: none !important; }
  .hero { background: none; border: 0; padding-top: 0; }
  .hero__inner { padding-block: 0 1rem; }
  h1, h2, h3, h4 { font-family: Georgia, serif; text-transform: none; letter-spacing: 0; color: #000; }
  a { color: #000; text-decoration: underline; }
  .prose a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; word-break: break-all; }
  .card, .panel, .callout, .verdict { border: 1px solid #ccc; background: none; break-inside: avoid; }
  .card__media, .detail-head__media { display: none; }
  .site-foot { border-top: 1px solid #ccc; margin-top: 2rem; }
  .site-foot__legal p { color: #444; }
  img { max-width: 3in; }
}
