/* KASTURI — a contemplative literary object.
   One made thing across two pages: fine-book typography on a night ground,
   an instrument panel that reads like an instrument panel, and no astro-kitsch
   anywhere. Self-contained: system stacks only, no external fonts, no CDN. */

/* ------------------------------------------------------------------ tokens */

:root {
  --ink:        #0b0e14;
  --ink-2:      #10141d;
  --ink-3:      #171c27;
  --paper:      #e8e2d5;
  --paper-2:    #b6afa0;
  --paper-3:    #857f72;
  --rule:       rgba(232, 226, 213, 0.13);
  --rule-2:     rgba(232, 226, 213, 0.26);
  --brass:      #c8a45c;
  --brass-dim:  #8d763f;
  --ember:      #cd7550;
  --amber:      #d8a052;
  --slate:      #8296b4;
  --gold:       #ddc78d;
  --sage:       #7fa596;

  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua",
           Charter, Georgia, "Times New Roman", serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas,
          "Liberation Mono", monospace;

  --measure: 34rem;
  --step: clamp(1.75rem, 4.5vw, 2.75rem);
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--serif);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  line-height: 1.72;
  font-variant-numeric: oldstyle-nums proportional-nums;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

/* A night ground with a little dust in it. Two offset dot lattices at very low
   opacity plus a vignette — depth without a single gradient cliché. */
.starfield {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(circle at 50% 50%, rgba(232, 226, 213, 0.5) 0.6px, transparent 0.9px) 0 0 / 71px 89px,
    radial-gradient(circle at 50% 50%, rgba(200, 164, 92, 0.45) 0.5px, transparent 0.8px) 23px 41px / 137px 113px,
    radial-gradient(circle at 50% 50%, rgba(232, 226, 213, 0.32) 0.9px, transparent 1.3px) 59px 17px / 313px 251px,
    radial-gradient(ellipse 90% 60% at 50% 0%, rgba(46, 58, 84, 0.35), transparent 70%);
  opacity: 0.46;
}
.starfield::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 120% 90% at 50% 45%, transparent 30%, rgba(11, 14, 20, 0.85) 100%);
}

body > *:not(.starfield) { position: relative; z-index: 1; }

::selection { background: rgba(200, 164, 92, 0.28); }

a { color: inherit; text-decoration-color: var(--brass-dim); text-underline-offset: 0.22em; }
a:hover { text-decoration-color: var(--brass); }

:focus-visible {
  outline: 1px solid var(--brass);
  outline-offset: 3px;
}

/* --------------------------------------------------------------- primitives */

.label {
  font-family: var(--serif);
  font-size: 0.6875rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--brass);
  margin: 0 0 0.5rem;
  font-weight: 400;
}
.label-sm { font-size: 0.625rem; letter-spacing: 0.16em; color: var(--paper-3); }

.num {
  font-family: var(--mono);
  font-size: 0.92em;
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: -0.01em;
}

.dim { color: var(--paper-2); }
.ta-r { text-align: right; }

.wordmark {
  font-size: 0.8125rem;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--brass);
  margin: 0;
}
.wordmark a { text-decoration: none; }
.wordmark-sm { font-size: 0.6875rem; letter-spacing: 0.34em; }

/* -- the brand line ---------------------------------------------------------
   "Your future story", with the future struck out and story standing in its
   place (templates/_wordmark.html). The argument of the product, made in type
   instead of in a sentence about itself.

   Typographic, never pictorial. The stroke is real text-decoration, so it grows
   with the type, prints, selects and survives this file failing to load — and
   `skip-ink: none` runs it unbroken through the descender of the f, which is
   what a pen does and what a font's own skip-ink politely does not. */
.brandline {
  font-style: normal;
  text-transform: none;
  letter-spacing: normal;
}
.brandline-cut {
  color: var(--paper-3);
  text-decoration-line: line-through;
  text-decoration-color: var(--brass);
  text-decoration-thickness: 0.06em;
  text-decoration-skip-ink: none;
  /* the withdrawn word steps back a little without becoming illegible */
  opacity: 0.72;
}
.brandline-keep {
  /* <ins> is underlined by default, which here would read as a link */
  text-decoration: none;
  color: var(--brass);
  font-style: italic;
}
.brandline-stop { color: var(--paper-3); }

/* the hero, on the input page: the mark at full size, allowed to wrap */
.brandline-hero { display: inline; }

/* the report's left rail: the mark under the name, both very small */
.brandline-spine {
  display: block;
  margin-top: 0.55rem;
  font-size: 0.9em;
  letter-spacing: 0.06em;
  text-transform: none;
  color: var(--paper-3);
}
.brandline-spine .brandline-keep { font-style: italic; }

/* the report colophon, where the creed used to sit */
.brandline-creed { font-style: normal; }

/* the closing line: spec §2's agency clause, in the owner's words */
.sails { font-style: italic; color: var(--brass); }
.closing-line {
  margin: 2rem 0 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--rule-2);
  font-size: 1.0625rem;
  text-wrap: balance;
}

/* ================================================================ THRESHOLD */
/* the input page */

.threshold {
  max-width: 40rem;
  margin: 0 auto;
  padding: clamp(3rem, 12vh, 8rem) 1.5rem 5rem;
}

.threshold-head { margin-bottom: clamp(3rem, 8vh, 5rem); }

.tagline {
  font-size: clamp(2.75rem, 9.5vw, 4.75rem);
  line-height: 0.98;
  font-weight: 400;
  letter-spacing: -0.022em;
  margin: 1.75rem 0 0;
  text-wrap: balance;
}
.tagline-turn {
  display: inline-block;
  margin-left: 1.6ch;
  font-style: italic;
  color: var(--brass);
}

.creed {
  max-width: 30rem;
  margin: 1.75rem 0 0;
  color: var(--paper-2);
  font-size: 1.0625rem;
  border-left: 1px solid var(--rule-2);
  padding-left: 1.25rem;
}

/* the reveal: one orchestrated load, nothing after it */
.threshold-head > *, .ledger > *, .threshold-foot > * {
  animation: rise 900ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.threshold-head > *:nth-child(2) { animation-delay: 90ms; }
.threshold-head > *:nth-child(3) { animation-delay: 180ms; }
.ledger > *:nth-child(1) { animation-delay: 260ms; }
.ledger > *:nth-child(2) { animation-delay: 320ms; }
.ledger > *:nth-child(3) { animation-delay: 380ms; }
.ledger > *:nth-child(4) { animation-delay: 420ms; }
.ledger > *:nth-child(5) { animation-delay: 460ms; }
.threshold-foot > * { animation-delay: 540ms; }

@keyframes rise {
  from { opacity: 0; transform: translateY(0.65rem); }
  to   { opacity: 1; transform: none; }
}

/* -- the ledger form: ruled lines on paper, not boxes ---------------------- */

.ledger { display: block; }

.field {
  border: 0;
  padding: 0;
  margin: 0 0 2.75rem;
}

.rule-input {
  display: block;
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule-2);
  color: var(--paper);
  font-family: var(--serif);
  font-size: 1.375rem;
  line-height: 1.5;
  padding: 0.35rem 0 0.5rem;
  border-radius: 0;
  transition: border-color 200ms ease, background-color 200ms ease;
}
.rule-input.num { font-family: var(--mono); font-size: 1.0625rem; }
.rule-input::placeholder { color: var(--paper-3); font-style: italic; }
.rule-input:hover { border-bottom-color: var(--brass-dim); }
.rule-input:focus {
  outline: none;
  border-bottom-color: var(--brass);
  background: linear-gradient(to bottom, transparent 60%, rgba(200, 164, 92, 0.07));
}
.rule-input::-webkit-calendar-picker-indicator {
  filter: invert(0.72) sepia(0.5) saturate(3) hue-rotate(2deg);
  cursor: pointer;
  opacity: 0.75;
}

.hint, .aside {
  margin: 0.85rem 0 0;
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--paper-3);
}
.aside {
  color: var(--paper-2);
  border-left: 1px solid var(--brass-dim);
  padding-left: 1rem;
  margin-top: 1.1rem;
}
.aside em { color: var(--paper); }
.aside[hidden] { display: none; }

/* the honest tick-mark, not a toy switch */
.tick {
  position: relative;
  display: inline-flex;
  align-items: baseline;
  gap: 0.6rem;
  margin-top: 1rem;
  cursor: pointer;
  color: var(--paper-2);
  font-size: 0.9375rem;
}
/* the real control keeps its size and sits over the drawn mark — invisible,
   still hit-testable and still focusable */
.tick input {
  position: absolute;
  left: 0;
  top: 0.14em;
  width: 0.95rem;
  height: 0.95rem;
  margin: 0;
  opacity: 0;
  cursor: pointer;
  z-index: 1;
}
.tick-mark {
  position: relative;
  top: 0.14em;
  width: 0.95rem;
  height: 0.95rem;
  flex: none;
  border: 1px solid var(--rule-2);
  transition: border-color 180ms ease;
}
.tick:hover .tick-mark { border-color: var(--brass); }
.tick input:focus-visible + .tick-mark { outline: 1px solid var(--brass); outline-offset: 3px; }
.tick input:checked + .tick-mark { border-color: var(--brass); }
.tick input:checked + .tick-mark::after {
  content: "";
  position: absolute;
  inset: 2px;
  background: var(--brass);
}
.tick input:checked ~ .tick-text { color: var(--paper); }

/* the three honest states of a birth time: known, roughly known, not known.
   Round marks, because these are one-of-three and the square ticks elsewhere
   are not. */
.states { display: grid; gap: 0.15rem; margin-top: 1.1rem; }
.states .tick { margin-top: 0.35rem; }
.states .tick-mark, .choice .tick-mark { border-radius: 50%; }
.states .tick input:checked + .tick-mark::after,
.choice input:checked + .tick-mark::after { border-radius: 50%; }

/* "give or take" — a row of struck figures, not a slider pretending to precision */
.spread {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  border: 0;
  margin: 1.35rem 0 0;
  padding: 0;
}
.spread[hidden] { display: none; }
.spread legend { float: left; width: 100%; padding: 0; margin-bottom: 0.55rem; }
.spread-opt { position: relative; cursor: pointer; }
.spread-opt input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.spread-face {
  display: block;
  padding: 0.3rem 0.7rem 0.35rem;
  border: 1px solid var(--rule-2);
  color: var(--paper-2);
  font-size: 0.875rem;
  transition: border-color 180ms ease, color 180ms ease, background-color 180ms ease;
}
.spread-opt:hover .spread-face { border-color: var(--brass-dim); color: var(--paper); }
.spread-opt input:focus-visible + .spread-face { outline: 1px solid var(--brass); outline-offset: 3px; }
.spread-opt input:checked + .spread-face {
  border-color: var(--brass);
  color: var(--brass);
  background: rgba(200, 164, 92, 0.1);
}
.spread-unit { color: var(--paper-3); font-size: 0.875rem; }

/* place autocomplete. The staggered load animation gives every .field its own
   stacking context, so the place field needs an explicit one above its
   siblings or the submit button paints through the suggestion list. */
.field-place { position: relative; z-index: 20; }
.combo { position: relative; }
.suggestions {
  list-style: none;
  margin: 0;
  padding: 0;
  position: absolute;
  left: 0; right: 0; top: calc(100% + 1px);
  z-index: 5;
  background: var(--ink-3);
  border: 1px solid var(--rule-2);
  box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, 0.6);
  max-height: 17rem;
  overflow-y: auto;
}
.suggestions[hidden] { display: none; }
.suggestions li {
  padding: 0.6rem 0.9rem;
  cursor: pointer;
  border-bottom: 1px solid var(--rule);
  font-size: 0.9375rem;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: baseline;
}
.suggestions li:last-child { border-bottom: 0; }
.suggestions li[aria-selected="true"], .suggestions li:hover {
  background: rgba(200, 164, 92, 0.1);
  color: var(--paper);
}
.suggestions .sug-tz { color: var(--paper-3); font-family: var(--mono); font-size: 0.72rem; }

.manual { border-top: 1px solid var(--rule); padding-top: 1.5rem; }
.manual[hidden] { display: none; }
.manual legend { padding: 0; }
.manual-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  gap: 1.25rem;
  margin-top: 1rem;
}

/* the button: a struck seal, not a pill */
.cast {
  display: block;
  width: 100%;
  margin-top: 1rem;
  padding: 1.15rem 1.5rem;
  background: transparent;
  color: var(--paper);
  border: 1px solid var(--brass-dim);
  font-family: var(--serif);
  cursor: pointer;
  text-align: center;
  transition: background-color 220ms ease, border-color 220ms ease, color 220ms ease;
}
.cast:hover { background: rgba(200, 164, 92, 0.09); border-color: var(--brass); }
.cast:active { background: rgba(200, 164, 92, 0.16); }
.cast:disabled { opacity: 0.6; cursor: default; }
.cast-label {
  display: block;
  font-size: 0.8125rem;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--brass);
}
.cast-sub {
  display: block;
  margin-top: 0.4rem;
  font-style: italic;
  font-size: 0.9375rem;
  color: var(--paper-3);
}
.cast-inline { display: inline-block; width: auto; padding: 0.9rem 2rem; text-decoration: none; }
.threshold-back { margin-top: 3rem; }

.alert {
  margin: 0 0 2rem;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--ember);
  border-left-width: 3px;
  color: var(--paper);
  background: rgba(205, 117, 80, 0.08);
  font-size: 0.9375rem;
}

.threshold-foot {
  margin-top: clamp(3.5rem, 10vh, 6rem);
  border-top: 1px solid var(--rule);
  padding-top: 2rem;
}
.ladder-note {
  margin: 0 0 2rem;
  color: var(--paper-2);
  font-size: 0.9375rem;
}
.ladder-note em { color: var(--brass); font-style: italic; }

.fineprint { list-style: none; margin: 0; padding: 0; }
.fineprint li {
  display: grid;
  grid-template-columns: 8.5rem minmax(0, 1fr);
  gap: 0 1rem;
  font-size: 0.8125rem;
  line-height: 1.7;
  color: var(--paper-3);
  padding: 0.7rem 0;
  border-top: 1px solid var(--rule);
}
.fineprint-key {
  font-size: 0.625rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brass-dim);
  line-height: 2.2;
}

/* ================================================================= GALLERY */
/* the surface: the shapes a birth day could hold, offered for recognition */

.gallery {
  max-width: 46rem;
  margin: 0 auto;
  padding: clamp(2.5rem, 9vh, 5.5rem) 1.5rem 5rem;
}
.gallery-head { margin-bottom: clamp(2.5rem, 6vh, 3.5rem); }
.gallery-head .tagline { font-size: clamp(2.25rem, 7.5vw, 3.75rem); }
/* .aside carries no bottom margin by default; standing on its own here, it
   needs one or it collides with the brief beneath it */
.gallery > .aside { margin: 0 0 2.25rem; }

.link-quiet {
  color: var(--brass);
  font-size: 0.9375rem;
  text-decoration: none;
  border-bottom: 1px solid var(--brass-dim);
  padding-bottom: 0.1rem;
  transition: border-color 180ms ease, color 180ms ease;
}
.link-quiet:hover { color: var(--gold); border-bottom-color: var(--brass); }

.gallery-brief {
  margin: 0 0 2.25rem;
  padding-left: 1.25rem;
  border-left: 1px solid var(--brass-dim);
  color: var(--paper-2);
  font-size: 0.9375rem;
  max-width: 40rem;
}
.gallery-brief p { margin: 0 0 0.75rem; }
.gallery-brief p:last-child { margin: 0; font-size: 0.875rem; }

.gallery-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem 1.5rem;
  margin: 0 0 2rem;
  padding: 0.9rem 0;
  border-top: 1px solid var(--rule-2);
  border-bottom: 1px solid var(--rule);
}
.gallery-count { margin: 0; font-size: 0.9375rem; color: var(--paper-2); }
.gallery-acts { margin: 0; display: flex; flex-wrap: wrap; gap: 0.4rem 1.5rem; }

/* picker ---------------------------------------------------------------
   The owner's complaint (2026-09-19): "it should show/mark the facets that
   vary... ask to pick one of them." Reuses `.label`, `.num`, `.cell-mech`,
   `.link-quiet` and `.cast` wherever the picker means the same thing those
   already say elsewhere on this page; only genuinely new shapes (the facet
   groups, the choice labels, the settled list) get their own class. Mobile
   first: a facet's choices stack in one column until there is room for a
   row of them. */
.picker-zone { margin: 2.5rem 0 2rem; }
.picker-form { margin: 0; }
.picker-facets {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  margin: 0 0 1.5rem;
}
.picker-facet {
  margin: 0;
  padding: 0;
  border: 0;
  border-top: 1px solid var(--rule-2);
  padding-top: 1rem;
}
.picker-facet > legend {
  padding: 0 0 0.6rem;
  font-family: var(--serif);
  font-size: 0.9375rem;
  color: var(--paper);
}
.picker-choices {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.picker-choice {
  display: block;
  padding: 0.85rem 1rem;
  border: 1px solid var(--rule);
  cursor: pointer;
  transition: border-color 180ms ease, background 180ms ease;
}
.picker-choice:has(input:checked) {
  border-color: var(--brass);
  background: rgba(200, 164, 92, 0.07);
}
.picker-choice input[type="checkbox"] { margin-right: 0.6rem; }
.picker-reading { font-size: 0.9375rem; color: var(--paper); }
.picker-count { margin-left: 0.5rem; color: var(--paper-3); font-size: 0.8125rem; }
.picker-rest {
  display: block;
  margin: 0.3rem 0 0 1.6rem;
  font-size: 0.875rem;
  color: var(--paper-2);
}
.picker-fold { margin: 0.6rem 0 0 1.6rem; }
/* The facet's everyday question, and what every choice under it says alike. */
.picker-question {
  display: block;
  margin-top: 0.15rem;
  font-size: 1.0625rem;
  color: var(--paper);
}
.picker-settled-lines {
  margin: 0 0 0.75rem;
  font-size: 0.9375rem;
  color: var(--paper-2);
}
/* A fork: the shared prose once, the branches indented beneath it. A fork
   inside a fork drops its own border so the nesting reads as one indent, not
   a box in a box. */
.picker-fork {
  flex: 1 1 100%;
  padding: 0.85rem 1rem;
  border: 1px solid var(--rule);
}
.picker-fork .picker-fork {
  padding: 0;
  border: 0;
}
.picker-shared {
  margin: 0 0 0.6rem;
  font-size: 0.9375rem;
  color: var(--paper-2);
}
.picker-branches {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-left: 0.75rem;
  padding-left: 0.75rem;
  border-left: 1px solid var(--rule-2);
}
.picker-branches .picker-choice { border-color: var(--rule-2); }
.picker-signs {
  margin: 0 0 0.5rem;
  font-size: 0.8125rem;
  color: var(--paper-2);
  letter-spacing: 0.01em;
}
.picker-settled {
  list-style: none;
  margin: 0 0 1.5rem;
  padding: 0;
}
.picker-settled-fact {
  padding: 0.6rem 0;
  border-top: 1px solid var(--hairline, rgba(232, 226, 213, 0.09));
  font-size: 0.9375rem;
  color: var(--paper-2);
}
.picker-same {
  margin-left: 0.6rem;
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  color: var(--paper-3);
  font-style: italic;
}
/* `.row-band` (and, for the no-dimensions fallback list, `.candidate`) both
   carry their own author `display` rule, which beats the `[hidden]` UA
   default outright regardless of specificity — without this, a row a pick
   excludes would stay laid out even with the attribute set. */
.row-band[hidden], .candidate[hidden], .lineup-row[hidden] { display: none; }

@media (min-width: 80rem) {
  .picker-choices { flex-direction: row; flex-wrap: wrap; }
  .picker-choice { flex: 1 1 calc(33.333% - 0.5rem); }
}

/* -- one card per candidate ------------------------------------------------ */

.candidates { list-style: none; margin: 0; padding: 0; }

.candidate {
  margin: 0 0 1.5rem;
  padding: 1.4rem 1.5rem 1.35rem;
  border: 1px solid var(--rule);
  background: linear-gradient(var(--ink-2), var(--ink));
  transition: border-color 200ms ease;
}
.candidate:hover { border-color: var(--rule-2); }

/* the nakshatra fork: the loudest frame on the page, because it is the
   deepest cut the day makes */
.candidate-fork {
  margin: -0.4rem -0.5rem 1.25rem;
  padding: 0.9rem 1rem;
  border: 1px solid var(--amber);
  border-left-width: 3px;
  background: linear-gradient(rgba(216, 160, 82, 0.08), rgba(216, 160, 82, 0.02));
  color: var(--paper);
  font-size: 0.9375rem;
  line-height: 1.6;
}
.fork-mark { color: var(--amber); margin-right: 0.45rem; letter-spacing: 0.1em; }

.candidate-mark {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.9rem;
  margin: 0;
}
.candidate-window {
  font-size: 1.0625rem;
  color: var(--brass);
  letter-spacing: 0.02em;
}
.candidate-width { font-size: 0.75rem; color: var(--paper-3); letter-spacing: 0.04em; }

.candidate-title {
  margin: 0.4rem 0 0.75rem;
  font-size: 1.5rem;
  font-weight: 400;
  letter-spacing: -0.012em;
  line-height: 1.2;
}

.candidate-facts {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 1.4rem;
  margin: 0 0 1.1rem;
  padding: 0 0 1.1rem;
  border-bottom: 1px solid var(--rule);
  font-size: 0.875rem;
  color: var(--paper-2);
}
.fact-key {
  font-size: 0.625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--brass-dim);
  margin-right: 0.4rem;
}
.candidate-facts .num { font-size: 0.8125rem; }

.candidate-face { min-height: 3.25rem; }
.face-arrived { animation: rise 500ms cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.face-head {
  margin: 0 0 0.4rem;
  font-size: 1.125rem;
  font-weight: 400;
  font-style: italic;
  color: var(--gold);
  letter-spacing: -0.005em;
}
.face-sketch { margin: 0; color: var(--paper); max-width: 36rem; }
.face-diff {
  margin: 0.6rem 0 0;
  font-size: 0.875rem;
  color: var(--paper-3);
  max-width: 36rem;
}
.face-none { margin: 0; font-size: 0.9375rem; color: var(--paper-3); font-style: italic; }
.face-pending { margin: 0; color: var(--paper-3); opacity: 0.4; }

.candidate-acts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.5rem;
  margin-top: 1.25rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--rule);
}
.candidate-acts form { margin: 0; }
.cast-sm { padding: 0.55rem 1.4rem; }
.cast-sm .cast-label { font-size: 0.6875rem; letter-spacing: 0.22em; }

/* -- the standing refusal -------------------------------------------------- */

.refusal {
  margin: 3rem 0 0;
  padding: 1.6rem 1.5rem;
  border: 1px solid var(--rule-2);
}
.refusal p { margin: 0 0 1.1rem; color: var(--paper-2); font-size: 0.9375rem; max-width: 40rem; }
.refusal em { color: var(--paper); }
.refusal form { margin: 0; }
.refusal .cast { width: auto; display: inline-block; margin-top: 0; }

/* -- the narrowing questions ----------------------------------------------- */

.gallery-narrow .creed { max-width: 34rem; }
.gallery-narrow .aside-strong { margin-bottom: 2.75rem; }
.narrowing { margin: 0; }

/* a radiogroup rather than a fieldset: a legend is painted onto the top
   border, and this block wants an unbroken rule above it */
.question {
  border-top: 1px solid var(--rule-2);
  margin: 0 0 2rem;
  padding: 1.5rem 0 0;
}
.question-text {
  margin: 0 0 0.9rem;
  font-size: 1.1875rem;
  line-height: 1.45;
  max-width: 34rem;
  color: var(--paper);
}

.choice {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  padding: 0.5rem 0;
  cursor: pointer;
  color: var(--paper-2);
  font-size: 0.9375rem;
  max-width: 36rem;
}
.choice input {
  position: absolute;
  left: 0;
  top: 0.3em;
  width: 0.95rem;
  height: 0.95rem;
  margin: 0;
  opacity: 0;
  cursor: pointer;
  z-index: 1;
}
.choice .tick-mark { top: 0.16em; }
.choice:hover .tick-mark { border-color: var(--brass); }
.choice input:focus-visible + .tick-mark { outline: 1px solid var(--brass); outline-offset: 3px; }
.choice input:checked + .tick-mark { border-color: var(--brass); }
.choice input:checked + .tick-mark::after {
  content: "";
  position: absolute;
  inset: 2px;
  background: var(--brass);
}
.choice input:checked ~ .choice-text { color: var(--paper); }
.choice-abstain { color: var(--paper-3); font-style: italic; }

/* ================================================================ THE LINEUP */
/* the comparison grid: rows are the windows the day could hold, columns are the
   four computed dimensions. A fable alone is a poem; two poems are not a thing
   you can hold side by side. So the same candidates are also set as a ledger —
   and a ledger has to be honest about the columns that cannot tell its rows
   apart, which is what `.col-reach` and `.cell-tie` are for. */

/* The grid wants more room than the reading measure the rest of the page keeps.
   The whole zone breaks out together — picker, honesty line, contract and table
   sharing one left edge — so it reads as a deliberate spread rather than as a
   table that has slipped its column. */
.lineup-zone {
  position: relative;
  left: 50%;
  transform: translateX(-50%);
  width: min(calc(100vw - 3rem), 74rem);
  margin: 0 0 3rem;
}

/* -- picking a column ------------------------------------------------------ */

.lineup-pick { margin: 0 0 1.5rem; }

.dim-picks {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 0.9rem;
}
.dim-pick {
  display: inline-block;
  padding: 0.4rem 0.95rem;
  border: 1px solid var(--rule-2);
  color: var(--paper-2);
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-decoration: none;
  transition: border-color 180ms ease, color 180ms ease, background-color 180ms ease;
}
.dim-pick:hover { border-color: var(--brass-dim); color: var(--paper); }
.dim-pick.is-current {
  border-color: var(--brass);
  color: var(--ink);
  background: var(--brass);
}

/* Shown only where the grid has folded to one column, because only there is it
   true. Above the breakpoint all four are on screen at once. */
.lineup-narrow-note {
  display: none;
  margin: 0 0 0.9rem;
  font-size: 0.8125rem;
  color: var(--paper-3);
  max-width: 34rem;
}

/* The Mirror opt-in control (spec §7) — visible at every width, unlike
   `.lineup-narrow-note` above, which is deliberately mobile-only. */
.lineup-optin {
  margin: 0.9rem 0 0;
  font-size: 0.8125rem;
  color: var(--paper-3);
  max-width: 34rem;
}

/* The line that keeps the table from over-promising. A table is a claim that
   its columns discriminate; where they do not, it says so here first. */
.lineup-honesty {
  margin: 0;
  padding-left: 1rem;
  border-left: 1px solid var(--rule-2);
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--paper-2);
  max-width: 44rem;
}
.lineup-honesty.is-blunt { border-left-color: var(--amber); color: var(--paper); }

/* -- the column contract --------------------------------------------------- */

.lineup-contract {
  margin: 0 0 1.75rem;
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.lineup-contract > summary {
  list-style: none;
  cursor: pointer;
  padding: 0.7rem 0;
  color: var(--brass);
  font-size: 0.6875rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.lineup-contract > summary::-webkit-details-marker { display: none; }
.lineup-contract > summary::after {
  content: "+";
  float: right;
  color: var(--brass-dim);
  font-family: var(--mono);
}
.lineup-contract[open] > summary::after { content: "\2212"; }
.contract-rows { margin: 0 0 1rem; padding: 0; }
.contract-row {
  display: grid;
  grid-template-columns: 9rem minmax(0, 1fr);
  gap: 0 1.25rem;
  padding: 0.75rem 0;
  border-top: 1px solid var(--rule);
}
.contract-row dt {
  font-size: 0.6875rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--brass);
  padding-top: 0.2rem;
}
.contract-row dd { margin: 0; font-size: 0.875rem; line-height: 1.6; }
.contract-short {
  display: block;
  margin-bottom: 0.35rem;
  font-size: 0.75rem;
  line-height: 1.45;
  color: var(--paper-3);
}
.contract-reads { display: block; color: var(--paper-2); }
.contract-never {
  display: block;
  margin-top: 0.4rem;
  padding-left: 0.85rem;
  border-left: 2px solid var(--ember);
  color: var(--paper-3);
  font-size: 0.8125rem;
}

/* -- the table ------------------------------------------------------------- */

/* No `overflow` here on purpose. The zone is already sized to the viewport, and
   a scroll container of any axis would become the containing block for the
   sticky column heads — which would then never stick to anything, since this box
   does not scroll vertically. Fourteen rows without their column names is worse
   than a hypothetical wide cell. */
.lineup-wrap { min-width: 0; }

.lineup {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  table-layout: fixed;
}
.lineup caption { text-align: left; }

.col-head {
  position: sticky;
  top: 0;
  z-index: 3;
  text-align: left;
  vertical-align: bottom;
  font-weight: 400;
  background: var(--ink);
  padding: 0.9rem 1rem 0.7rem;
  border-bottom: 1px solid var(--rule-2);
}
.col-name {
  display: block;
  font-size: 1.0625rem;
  letter-spacing: 0.01em;
  color: var(--paper);
}
.col-reads {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.75rem;
  line-height: 1.45;
  color: var(--paper-3);
}
.col-head .cell-mech { margin: 0.15rem 0 0; }
.col-reach { display: block; margin-top: 0.55rem; }
.reach-bar {
  display: block;
  height: 2px;
  background: var(--rule-2);
  margin-bottom: 0.25rem;
}
.reach-bar i { display: block; height: 100%; background: var(--sage); }
.reach-text {
  display: block;
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--paper-3);
}
.col-reach.is-blunt .reach-bar i { background: var(--amber); }
.col-reach.is-blunt .reach-text { color: var(--amber); }

/* -- the row band: window, facts, fable, act ------------------------------- */

.row-fork > td { padding: 1.75rem 0 0; }
.lineup .candidate-fork { margin: 0; }

.row-head > th {
  text-align: left;
  font-weight: 400;
  padding: 1.25rem 1rem 1rem;
  border-top: 1px solid var(--rule-2);
  background: linear-gradient(var(--ink-2), rgba(16, 20, 29, 0));
}
.row-fork + .row-head > th { border-top: 0; }

.row-band {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "mark  acts"
    "facts facts"
    "face  face"
    "twin  twin";
  column-gap: 1.5rem;
  align-items: start;
}
.row-band-mark { grid-area: mark; display: flex; gap: 0.9rem; align-items: flex-start; }
.row-band .candidate-facts { grid-area: facts; }
.row-band .candidate-face { grid-area: face; }
.row-band .twin-note { grid-area: twin; }
.row-band .candidate-acts { grid-area: acts; margin-top: 0; padding-top: 0; border-top: 0; }

.row-emblem {
  flex: none;
  display: block;
  width: 2.4rem;
  height: 2.4rem;
  margin-top: 0.2rem;
  color: var(--brass);
  opacity: 0.75;
}
.row-emblem svg { display: block; width: 100%; height: 100%; }
.mark-text { min-width: 0; }
.row-band .candidate-title { margin: 0.25rem 0 0; font-size: 1.375rem; }
.row-band .candidate-facts { margin: 0.9rem 0 0.9rem; padding-bottom: 0.9rem; }
.row-band .candidate-face { min-height: 0; }

/* The grid saying where it runs out of resolution. Quieter than the nakshatra
   fork, which is a fact about the sky; this is a fact about the table. */
.twin-note {
  margin: 0.9rem 0 0;
  padding: 0.6rem 0.85rem;
  border: 1px dashed var(--rule-2);
  color: var(--paper-3);
  font-size: 0.8125rem;
  line-height: 1.55;
  max-width: 48rem;
}
.twin-mark { color: var(--slate); margin-right: 0.35rem; }
.twin-jump { color: var(--paper-2); }

/* -- one cell -------------------------------------------------------------- */

.cell {
  vertical-align: top;
  padding: 1rem 1rem 1.35rem;
  border-left: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule-2);
}
.cell:first-child { border-left: 0; }
.cell.is-tied { background: rgba(216, 160, 82, 0.05); }

/* The reading leads: what the configuration is like to live inside, in plain
   words. The gloss (the arithmetic in shorthand) sits folded under the
   mechanism, dimmed, above the full signature. */
.cell-reading {
  margin: 0;
  color: var(--paper);
  font-size: 0.9375rem;
  line-height: 1.45;
  letter-spacing: -0.005em;
}
.cell-reading-full {
  margin: 0.5rem 0 0;
  padding-left: 0.75rem;
  border-left: 1px solid var(--rule);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--paper-2);
}
.cell-mech .cell-gloss {
  margin: 0.5rem 0 0;
  padding-left: 0.75rem;
  border-left: 1px solid var(--rule);
}
.cell-mech .gloss-part,
.cell-mech .gloss-part:first-child,
.cell-mech .gloss-part + .gloss-part {
  margin-top: 0;
  color: var(--paper-3);
  font-size: 0.8125rem;
  line-height: 1.5;
  letter-spacing: 0;
}
.cell-mech .cell-gloss + .cell-sig { border-top: 1px dotted var(--rule-2); padding-top: 0.5rem; }

.cell-gloss { margin: 0; }
.gloss-part { display: block; }
.gloss-part:first-child {
  color: var(--paper);
  font-size: 1rem;
  line-height: 1.35;
  letter-spacing: -0.005em;
}
.gloss-part + .gloss-part {
  margin-top: 0.15rem;
  color: var(--paper-2);
  font-size: 0.875rem;
  line-height: 1.4;
}

/* The tradition's list, and it is never anything else: bare items under a
   caption that names whose list it is. No sentence is ever built out of these
   (spec §7), and nothing on the page puts one next to the word "you". */
.cell-trades { margin: 0.9rem 0 0; }
.trades-cap {
  margin: 0 0 0.4rem;
  font-size: 0.5625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brass);
  line-height: 1.5;
}
.trades {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin: 0;
  padding: 0;
}
.trade {
  border: 1px solid var(--rule-2);
  padding: 0.1rem 0.45rem;
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--paper-2);
}

.cell-tie {
  margin: 0.85rem 0 0;
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--amber);
}
.tie-mark { margin-right: 0.3rem; opacity: 0.8; }

.cell-mech { margin: 0.85rem 0 0; }
.cell-mech > summary {
  list-style: none;
  cursor: pointer;
  font-family: var(--mono);
  font-size: 0.5625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper-3);
}
.cell-mech > summary::-webkit-details-marker { display: none; }
.cell-mech > summary::before { content: "\203A\00a0"; color: var(--brass-dim); }
.cell-mech[open] > summary::before { content: "\2304\00a0"; }
.cell-mech > summary:hover { color: var(--brass); }
.cell-sig {
  margin: 0.5rem 0 0;
  padding-left: 0.75rem;
  border-left: 1px solid var(--rule);
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--paper-3);
}

.lineup-foot {
  margin: 1.5rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.65;
  color: var(--paper-3);
  max-width: 52rem;
}

/* -- one column at a time -------------------------------------------------- */
/* Below the breakpoint the grid is not squeezed and it does not scroll
   sideways: it becomes the one column the reader picked, with every window
   still on it. Comparison stays like-with-like. `?dim=` already does this
   server-side; this is the same fold applied to the default page, where no
   column has been picked yet and `work` leads. */

@media (max-width: 64rem) {
  .lineup-zone { left: auto; transform: none; width: 100%; }
  .lineup-narrow-note { display: block; }
  .dim-pick-all { display: none; }
  .lineup-zone[data-dim="all"] .dim-pick-work {
    border-color: var(--brass);
    color: var(--ink);
    background: var(--brass);
  }
  /* One column, so there is no table left to lay out: the rows linearise into
     the reading order they already have. This also frees the row header from
     its `colspan`, which would otherwise keep reserving the three columns that
     are no longer on screen. */
  .lineup,
  .lineup thead,
  .lineup tbody,
  .lineup tr,
  .lineup th,
  .lineup td { display: block; width: auto; }
  .lineup[data-dim="all"] .col-head:not([data-dim="work"]),
  .lineup[data-dim="all"] .cell:not([data-dim="work"]) { display: none; }
  .cell { border-left: 0; }
  .col-head, .cell, .row-head > th, .row-fork > td { padding-left: 0; padding-right: 0; }
  .row-band {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "mark" "facts" "face" "twin" "acts";
    row-gap: 0;
  }
  .row-band .candidate-acts { margin-top: 1rem; }
  .contract-row { grid-template-columns: minmax(0, 1fr); gap: 0.35rem 0; }
}

/* =================================================================== FOLIO */
/* the report page */

.folio {
  display: grid;
  grid-template-columns: 1fr;
  max-width: 78rem;
  margin: 0 auto;
  padding: 0 1.25rem;
}

.spine { display: none; }

@media (min-width: 62rem) {
  .folio {
    grid-template-columns: 13rem minmax(0, 1fr);
    gap: 3.5rem;
    padding: 0 2.5rem;
  }
  .spine {
    display: block;
    position: sticky;
    top: 0;
    align-self: start;
    height: 100vh;
    padding: 3.5rem 0 2rem;
    border-right: 1px solid var(--rule);
  }
  .wordmark-inline { display: none; }
}

.spine-list {
  list-style: none;
  margin: 3rem 0 0;
  padding: 0;
  counter-reset: none;
}
.spine-list a {
  display: grid;
  grid-template-columns: 2.2rem 1fr;
  align-items: baseline;
  gap: 0.4rem;
  padding: 0.5rem 0;
  text-decoration: none;
  color: var(--paper-3);
  transition: color 200ms ease;
  border-top: 1px solid transparent;
}
.spine-list a:hover { color: var(--paper); }
.spine-num {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  color: var(--brass-dim);
}
.spine-name { font-size: 0.9375rem; }
.spine-list a.is-current { color: var(--brass); }
.spine-list a.is-current .spine-num { color: var(--brass); }
.spine-foot {
  position: absolute;
  bottom: 2.5rem;
  font-size: 0.625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper-3);
  margin: 0;
  padding-right: 1.5rem;
}

.leaf {
  padding: clamp(2.5rem, 7vh, 4.5rem) 0 6rem;
  min-width: 0;
}

/* -- colophon -------------------------------------------------------------- */

.colophon { margin-bottom: clamp(3rem, 8vh, 5rem); }
.wordmark-inline { margin-bottom: 2rem; }

.report-title {
  font-size: clamp(2.25rem, 6.5vw, 3.5rem);
  line-height: 1.02;
  letter-spacing: -0.02em;
  font-weight: 400;
  margin: 0.5rem 0 1.25rem;
  text-wrap: balance;
}
.report-pending-note {
  margin: 0 0 1.1rem;
  color: var(--paper-3);
  font-size: 0.9375rem;
  line-height: 1.6;
}
.report-pending-url {
  color: var(--paper-2);
  word-break: break-all;
}
.colophon-line {
  margin: 0;
  color: var(--paper-2);
  font-size: 0.9375rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.55rem;
  align-items: baseline;
}
.colophon-line .sep { color: var(--brass-dim); }
.colophon-creed {
  margin: 1.5rem 0 0;
  font-style: italic;
  color: var(--brass);
  font-size: 1.0625rem;
  letter-spacing: 0.01em;
}
.aside-strong { border-left-color: var(--brass); color: var(--paper); margin-top: 1.75rem; }

/* the chosen-window banner: this report rests on a recognition, not a
   measurement, and the page says so for as long as it exists */
.chosen {
  margin: 1.75rem 0 0;
  padding: 1.3rem 1.5rem;
  border: 1px solid var(--brass-dim);
  border-left-width: 3px;
  background: linear-gradient(rgba(200, 164, 92, 0.08), rgba(200, 164, 92, 0.02));
  max-width: 44rem;
}
.chosen p { margin: 0; color: var(--paper-2); font-size: 0.9375rem; line-height: 1.65; }
.chosen .label { color: var(--brass); }
.chosen strong { font-weight: 400; color: var(--paper); border-bottom: 1px solid var(--brass); }
.chosen .num { color: var(--paper); }
.chosen-act { margin-top: 0.9rem !important; }
.chosen-act a { color: var(--brass); font-size: 0.875rem; text-decoration-color: var(--brass-dim); }

/* -- movements ------------------------------------------------------------- */

.movement {
  padding-top: clamp(3rem, 7vh, 4.5rem);
  margin-top: clamp(3rem, 7vh, 4.5rem);
  border-top: 1px solid var(--rule-2);
  position: relative;
}
.movement::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--rule);
}
.movement:first-of-type { border-top: 0; margin-top: 0; }
.movement:first-of-type::before { display: none; }

.movement-head { margin-bottom: 2.5rem; }
.folio-num {
  display: block;
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.3em;
  color: var(--brass);
  margin-bottom: 0.9rem;
}
.movement-title {
  font-size: var(--step);
  line-height: 1.1;
  letter-spacing: -0.015em;
  font-weight: 400;
  margin: 0;
}
.epigraph {
  max-width: var(--measure);
  margin: 0.9rem 0 0;
  font-style: italic;
  color: var(--paper-3);
  font-size: 1rem;
  line-height: 1.6;
}

/* -- the sensitivity note: this is the honesty, so it gets the loudest frame */

.sensitivity {
  margin: 0 0 2.5rem;
  padding: 1.4rem 1.5rem;
  border: 1px solid var(--amber);
  border-left-width: 3px;
  background:
    linear-gradient(rgba(216, 160, 82, 0.07), rgba(216, 160, 82, 0.02));
  max-width: 44rem;
}
.sensitivity .label { color: var(--amber); }
.sensitivity p:last-child { margin: 0; }
.sensitivity strong { color: var(--paper); font-weight: 400; border-bottom: 1px solid var(--amber); }

/* -- panels: the instrument ----------------------------------------------- */

.panel {
  margin: 0 0 2.25rem;
  border: 1px solid var(--rule);
  background: linear-gradient(var(--ink-2), var(--ink));
}
.panel-quiet { background: none; }

.panel-cap {
  margin: 0;
  padding: 0.85rem 1.1rem;
  border-bottom: 1px solid var(--rule);
  font-size: 0.6875rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--brass);
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.9rem;
  align-items: baseline;
}
.panel-cap-note {
  letter-spacing: 0.02em;
  text-transform: none;
  font-style: italic;
  color: var(--paper-3);
  font-size: 0.8125rem;
}
.panel-foot {
  margin: 0;
  padding: 0.9rem 1.1rem;
  border-top: 1px solid var(--rule);
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--paper-3);
}

.panel-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

/* -- positions table ------------------------------------------------------- */

.positions {
  width: 100%;
  min-width: 44rem;
  border-collapse: collapse;
  font-size: 0.9375rem;
}
.positions th, .positions td {
  padding: 0.55rem 0.75rem;
  text-align: left;
  vertical-align: baseline;
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}
/* degrees, padas and house numbers hang off a right edge so the columns of
   figures line up the way a table of figures should */
.positions th.ta-r, .positions td.ta-r { text-align: right; }
.positions thead th {
  font-size: 0.625rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper-3);
  font-weight: 400;
  padding-top: 0.9rem;
  padding-bottom: 0.7rem;
  border-bottom-color: var(--rule-2);
}
.positions tbody tr:last-child th,
.positions tbody tr:last-child td { border-bottom: 0; }
.positions tbody tr:hover td,
.positions tbody tr:hover th { background: rgba(232, 226, 213, 0.028); }
.positions th:first-child, .positions td:first-child { padding-left: 1.1rem; }
.positions th:last-child, .positions td:last-child { padding-right: 1.1rem; }

.body-name { font-weight: 400; color: var(--paper); letter-spacing: 0.01em; }
.row-lagna th, .row-lagna td {
  background: rgba(200, 164, 92, 0.05);
  border-bottom-color: var(--rule-2);
}
.row-lagna .body-name { color: var(--brass); }
.notes { white-space: normal; min-width: 12rem; }

/* badges: outlined, lowercase, honest — no candy chips */
.badge {
  display: inline-block;
  margin: 0.1rem 0.3rem 0.1rem 0;
  padding: 0.06rem 0.45rem 0.12rem;
  border: 1px solid currentColor;
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  line-height: 1.5;
  color: var(--paper-3);
  cursor: help;
  white-space: nowrap;
}
.badge-stationary    { color: var(--amber); }
.badge-retrograde    { color: var(--slate); }
.badge-combust       { color: var(--ember); }
.badge-deeply_combust{ color: var(--ember); border-width: 1px; box-shadow: inset 0 0 0 1px rgba(205, 117, 80, 0.22); }
.badge-exalted       { color: var(--gold); }
.badge-own           { color: var(--sage); }
.badge-mooltrikona   { color: var(--sage); }
.badge-debilitated   { color: var(--paper-3); border-style: dashed; }
.badge-dawn_conjunct_lagna { color: var(--brass); }
.badge-vargottama    { color: var(--gold); }

/* -- lists inside panels --------------------------------------------------- */

.plain-list { list-style: none; margin: 0; padding: 1rem 1.1rem; }
.plain-list li {
  max-width: 42rem;
  padding: 0.4rem 0;
  color: var(--paper-2);
}
.plain-list li::before {
  content: "—";
  color: var(--brass-dim);
  margin-right: 0.6rem;
}

.yogas { margin: 0; padding: 0.35rem 1.1rem 1.1rem; }
.yoga { padding: 0.9rem 0; border-bottom: 1px solid var(--rule); }
.yoga:last-child { border-bottom: 0; padding-bottom: 0.2rem; }
.yoga dt {
  font-size: 1.0625rem;
  color: var(--paper);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.8rem;
}
.yoga dd {
  margin: 0.35rem 0 0;
  max-width: 42rem;
  color: var(--paper-2);
  font-size: 0.9375rem;
}
.from-ref {
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brass-dim);
}

/* -- the dasha ribbon ------------------------------------------------------ */

.ribbon {
  position: relative;
  display: flex;
  height: 2.75rem;
  margin: 1.1rem 1.1rem 0.4rem;
  border: 1px solid var(--rule-2);
}
.band {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-right: 1px solid var(--rule-2);
  background: rgba(232, 226, 213, 0.02);
  /* Each band measures itself. The bands are proportional, so they are not
     equally wide and cannot hold equally much text; asking the band rather than
     the viewport means the answer is right at every width and every zoom. */
  container-type: inline-size;
  container-name: band;
}
.band:last-child { border-right: 0; }
.band-past { background: rgba(232, 226, 213, 0.07); }
.band-now {
  background: rgba(200, 164, 92, 0.2);
  box-shadow: inset 0 0 0 1px var(--brass);
}

/* -- what a band prints inside itself --------------------------------------
   Three tiers, and nothing is ever positioned, so nothing can ever overlap:
   the label is one centred row and the elements inside it are hidden whole.

     narrow    nothing at all (the band stays proportional and keeps its title)
     narrower  the opening year alone — the fact the rail is for
     wide      the lord's mark and the opening year

   A screen reader is given the whole label at every width, off `.u-hidden`. */
.band-face {
  display: flex;
  align-items: baseline;
  gap: 0.34em;
  min-width: 0;
  padding: 0 0.25rem;
  white-space: nowrap;
}
.band-lord,
.band-year,
.band-end {
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  color: var(--paper-3);
  text-transform: uppercase;
  display: none;
}
.band-year,
.band-end {
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums lining-nums;
  opacity: 0.92;
}
@container band (min-width: 2.6rem) { .band-year { display: inline; } }
@container band (min-width: 4.6rem) { .band-lord { display: inline; } }
/* A fourth tier, wider still: once a band has room for the lord, the opening
   year AND the closing one without crowding, it takes it — "RA 1990" becomes
   "RA 1990–2008" rather than staying cryptic for want of trying. Only the
   spine ever renders a `.band-end` at all (`_ribbon.html`'s `face()` macro);
   the plain ribbon (The Sky, the LIFE rung) never passes one. */
@container band (min-width: 7.5rem) { .band-end { display: inline; } }

/* A browser with no container queries keeps the rail it always had: the mark,
   at every width. Losing the years is a smaller loss than losing the label. */
@supports not (container-type: inline-size) {
  .band-lord { display: inline; }
}

.band-now .band-lord,
.band-now .band-year,
.band-now .band-end { color: var(--brass); }
.band-past .band-lord,
.band-past .band-year,
.band-past .band-end { color: var(--paper-2); }

.plumb {
  position: absolute;
  top: -0.45rem;
  bottom: -0.45rem;
  width: 1px;
  background: var(--paper);
  transform: translateX(-0.5px);
}
.plumb::before {
  content: "";
  position: absolute;
  top: -3px;
  left: -2.5px;
  width: 6px;
  height: 6px;
  background: var(--paper);
  transform: rotate(45deg);
}

.eras { list-style: none; margin: 0; padding: 0.75rem 1.1rem 1.1rem; }
.era {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.9rem;
  padding: 0.42rem 0;
  border-bottom: 1px solid var(--rule);
  color: var(--paper-3);
}
.era:last-child { border-bottom: 0; }
.era-past { color: var(--paper-2); }
.era-now {
  color: var(--paper);
  border-bottom-color: var(--rule-2);
  padding: 0.75rem 0;
}
.era-span { min-width: 7.5rem; color: inherit; opacity: 0.85; }
.era-lord { letter-spacing: 0.04em; }
/* direct child only — the antardashas nested inside the current era keep
   their own, quieter treatment */
.era-now > .era-lord { color: var(--brass); font-size: 1.125rem; }
.era-len { margin-left: auto; opacity: 0.6; }
.era-here {
  font-size: 0.625rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--brass);
  padding: 0.1rem 0.5rem 0.14rem;
  white-space: nowrap;
}

.subs { list-style: none; margin: 0.75rem 0 0.25rem; padding: 0 0 0 1.1rem; width: 100%; border-left: 1px solid var(--rule-2); }
.sub {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.9rem;
  padding: 0.3rem 0;
  color: var(--paper-3);
  font-size: 0.9375rem;
}
.sub-past { color: var(--paper-2); }
.sub-now { color: var(--paper); position: relative; }
.sub-now .era-lord { color: var(--brass); }
.sub-now::before {
  content: "";
  position: absolute;
  left: -1.35rem;
  top: 0.85em;
  width: 0.45rem;
  height: 0.45rem;
  background: var(--brass);
  transform: rotate(45deg);
}
.chidra {
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  font-style: italic;
  color: var(--ember);
}

/* -- panchanga + settings -------------------------------------------------- */

.panchanga {
  margin: 2.5rem 0 0;
  padding-left: 1.25rem;
  border-left: 1px solid var(--brass-dim);
  max-width: 40rem;
  color: var(--paper);
}
.panchanga .label { display: block; }

.instrument-settings {
  margin: 2rem 0 0;
  max-width: 42rem;
  font-size: 0.8125rem;
  line-height: 1.7;
  color: var(--paper-3);
}

/* -- composed sections ----------------------------------------------------- */

.prose {
  max-width: var(--measure);
  font-size: clamp(1.0625rem, 1rem + 0.28vw, 1.1875rem);
  line-height: 1.78;
}
.prose:empty { display: none; }
.prose > *:first-child { margin-top: 0; }
.prose p { margin: 0 0 1.35em; }
.prose h2, .prose h3, .prose h4 {
  font-weight: 400;
  letter-spacing: -0.008em;
  line-height: 1.22;
  margin: 2.4em 0 0.7em;
}
.prose h2 { font-size: 1.55em; }
.prose h3 {
  font-size: 1.22em;
  color: var(--brass);
}
.prose h3::before {
  content: "";
  display: block;
  width: 2.25rem;
  height: 1px;
  background: var(--brass-dim);
  margin-bottom: 0.8em;
}
.prose h4 { font-size: 1.05em; color: var(--paper-2); }
.prose em { font-style: italic; color: var(--gold); }
.prose strong { font-weight: 400; color: var(--paper); border-bottom: 1px solid var(--brass-dim); }
.prose blockquote {
  margin: 1.6em 0;
  padding-left: 1.4rem;
  border-left: 1px solid var(--brass-dim);
  font-style: italic;
  color: var(--paper-2);
}
.prose blockquote p:last-child { margin-bottom: 0; }
.prose hr {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 2.4em 0;
  width: 5rem;
}
/* verse: single newlines inside a paragraph stay as line breaks */
.prose br { line-height: 2; }

/* stream status */
.status {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 1.5rem 0 0;
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper-3);
}
.status[hidden] { display: none; }
.status-dot {
  width: 5px;
  height: 5px;
  background: var(--paper-3);
  border-radius: 50%;
  flex: none;
}
.status-live .status-dot { background: var(--brass); animation: pulse 1.6s ease-in-out infinite; }
.status-live { color: var(--brass); }
.status-failed { color: var(--ember); }
.status-failed .status-dot { background: var(--ember); }

/* the spinner: a turning ring, never a progress bar. Nothing on this server
   knows how far through a section the narrator is, so nothing pretends to. */
.spinner {
  width: 0.72rem;
  height: 0.72rem;
  flex: none;
  border: 1.5px solid var(--rule);
  border-top-color: var(--paper-3);
  border-radius: 50%;
  animation: spin 2.6s linear infinite;
}
.status-live .spinner {
  border-top-color: var(--brass);
  animation-duration: 900ms;
}

@keyframes spin { to { transform: rotate(360deg); } }

@keyframes pulse {
  0%, 100% { opacity: 0.25; transform: scale(0.8); }
  50%      { opacity: 1;    transform: scale(1.25); }
}

@media (prefers-reduced-motion: reduce) {
  .spinner { animation: none; border-top-color: var(--brass); }
  .status-live .status-dot { animation: none; }
}

/* the stage strip: written · judged · published — the reveal rule made
   visible. A step is either behind (dim), lit and settled (is-done), or the
   one thing actually happening right now (is-active, the only step that ever
   pulses or carries elapsed seconds). Never a percentage — nothing here
   claims to know how far through a stage a section is. */
.status-stage {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.55rem;
}
.stage-strip {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.stage-step {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  opacity: 0.5;
}
.stage-step::before {
  content: "";
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}
.stage-step:not(:last-child)::after {
  content: "";
  width: 0.8rem;
  height: 1px;
  background: var(--rule-2);
}
.stage-step.is-done { color: var(--paper-2); opacity: 1; }
.stage-step.is-active { color: var(--brass); opacity: 1; }
.stage-step.is-active::before { animation: pulse 1.6s ease-in-out infinite; }
.status-line {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0;
}
@media (prefers-reduced-motion: reduce) {
  .stage-step.is-active::before { animation: none; }
}

/* one beat on a phone: the strip's connecting rules are the first thing to
   go, so three settled words never wrap onto a second line. */
@media (max-width: 40rem) {
  .stage-strip { gap: 0.45rem; flex-wrap: wrap; }
  .stage-step:not(:last-child)::after { display: none; }
}

.section-failure[hidden] { display: none; }
.retry-line { margin: 0.9rem 0 0; }
.retry {
  font: inherit;
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  color: var(--paper-2);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 2px;
  padding: 0.45rem 0.9rem;
  cursor: pointer;
}
.retry:hover:not(:disabled) { border-color: var(--brass); color: var(--brass); }
.retry:disabled { opacity: 0.45; cursor: default; }

.failure {
  margin: 0;
  padding: 1.1rem 1.25rem;
  border: 1px solid var(--ember);
  border-left-width: 3px;
  color: var(--paper-2);
  background: rgba(205, 117, 80, 0.06);
  max-width: var(--measure);
  font-size: 1rem;
}

/* calibration invitation — static copy for v0 */
.calibration {
  margin: 2.75rem 0 0;
  padding: 1.5rem 0 0;
  border-top: 1px solid var(--rule);
  max-width: var(--measure);
}
.calibration p:last-child { margin: 0; color: var(--paper-2); font-size: 0.9375rem; }
.calibration-close .label { color: var(--paper-3); }
.closing-tagline { display: block; margin-top: 0.6rem; font-style: italic; color: var(--brass); }

/* ================================================================ THE SCALES */
/* The zoom ladder: one control, four panels, one visible. Deliberately quieter
   than the composed sections around it — a control panel set into a book, not a
   dashboard bolted onto one. Nothing here grows louder as the scale narrows;
   that would be the page arguing the opposite of what the copy says. */

.zoomer { margin: 0 0 2.5rem; }

.zoom-tabs {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border: 1px solid var(--rule);
}
.zoom-tabs li { min-width: 0; }
.zoom-tabs li + li .zoom-tab { border-left: 1px solid var(--rule); }

.zoom-tab {
  display: block;
  padding: 0.7rem 0.5rem 0.75rem;
  text-align: center;
  text-decoration: none;
  color: var(--paper-3);
  background: none;
}
.zoom-tab:hover { color: var(--paper); background: rgba(232, 226, 213, 0.03); }
.zoom-tab-name {
  display: block;
  font-size: 0.8125rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}
.zoom-tab-unit {
  display: block;
  margin-top: 0.2rem;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  color: var(--paper-3);
  opacity: 0.75;
}
.zoom-tab.is-current {
  color: var(--brass);
  background: rgba(200, 164, 92, 0.09);
  box-shadow: inset 0 -2px 0 var(--brass);
}
.zoom-tab.is-current .zoom-tab-unit { color: var(--brass-dim); opacity: 1; }

.zoom-creed {
  margin: 1rem 0 0;
  max-width: 42rem;
  font-size: 0.8125rem;
  line-height: 1.7;
  color: var(--paper-3);
}

.zoom-panel[hidden] { display: none; }

.zoom-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.3rem 1.5rem;
  margin: 0 0 1.1rem;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--rule);
}
.zoom-head-name {
  font-size: 0.75rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--brass);
}
.zoom-head-when { color: var(--paper-2); font-size: 0.875rem; }

.zoom-lede {
  margin: 0 0 1.5rem;
  max-width: var(--measure);
  color: var(--paper-2);
}
.zoom-lede strong { font-weight: 400; color: var(--paper); }

.zoom-note {
  margin: 1rem 0 0;
  max-width: 42rem;
  font-size: 0.8125rem;
  line-height: 1.7;
  color: var(--paper-3);
}
.zoom-note em { font-style: italic; color: var(--paper-2); }
.zoom-note-stale { border-left: 1px solid var(--amber); padding-left: 0.9rem; }

.zoom-act { margin: 1.4rem 0 0; font-size: 0.875rem; color: var(--paper-2); }
.zoom-act a { color: var(--brass); text-decoration-color: var(--brass-dim); }
.zoom-act .sep { color: var(--brass-dim); margin: 0 0.4rem; }

.ribbon-sm { height: 1.9rem; margin-left: 0; margin-right: 0; }

.zoom-eras { list-style: none; margin: 1.1rem 0 0; padding: 0; }
.zoom-era {
  padding: 0.36rem 0;
  border-bottom: 1px solid var(--rule);
  color: var(--paper-3);
  font-size: 0.9375rem;
}
.zoom-era:last-child { border-bottom: 0; }
/* The Life's ERA state (spec §12.1): every antardasha row is now a real
   link, not static text — so it is a flex row inside its own anchor rather
   than on the `<li>` itself. */
.zoom-era > a {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.9rem;
  width: 100%;
  color: inherit;
  text-decoration: none;
}
.zoom-era > a:hover,
.zoom-era > a:focus-visible { color: var(--paper); }
.zoom-era > a:focus-visible { outline: 1px solid var(--brass-dim); outline-offset: 2px; }
.zoom-era-past { color: var(--paper-2); }
.zoom-era-now { color: var(--paper); border-bottom-color: var(--rule-2); }
.zoom-era-now .era-lord { color: var(--brass); }
/* The antardasha a Road band's fallback link actually named (`era_sub`) —
   the period being READ, same idiom as `.ribbon-spine .band.is-current`, and
   a different fact from `.zoom-era-now` (the period standing over the reader
   TODAY); the two may co-occur. */
.zoom-era.is-current { color: var(--paper); border-bottom-color: var(--brass); }
.zoom-era.is-current .era-lord { color: var(--brass); }

/* The ERA panel, opened by following a life-clock band rather than the tabs
   above (`era-asked` — owner's ruling: the Scales landing must read as an
   answer, not a redirect). A brass accent on the heading itself, the same
   colour every other "this is the one" mark on the page already uses. */
.zoom-head.era-asked { border-bottom-color: var(--brass); }
.zoom-head.era-asked .zoom-head-name { color: var(--brass); }

/* the season's three nested lords, named plainly */
.zoom-lords {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.6rem;
  margin: 0 0 1.1rem;
  font-size: clamp(1.25rem, 1.1rem + 0.7vw, 1.6rem);
  line-height: 1.3;
  color: var(--paper);
}
.zoom-slash { color: var(--brass-dim); }

.zoom-prose { margin-top: 1.75rem; }
.zoom-prose:empty { display: none; }

.zoom-status {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 1.5rem 0 0;
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper-3);
}
.zoom-status[hidden] { display: none; }
.zoom-status-live { color: var(--brass); }

/* the same turning ring the report sections use — never a progress bar, since
   nothing on this server knows how far through a reading the narrator is */
.zoom-spinner {
  width: 0.72rem;
  height: 0.72rem;
  flex: none;
  border: 1.5px solid var(--rule);
  border-top-color: var(--paper-3);
  border-radius: 50%;
  animation: spin 2.6s linear infinite;
}
.zoom-status-live .zoom-spinner {
  border-top-color: var(--brass);
  animation-duration: 900ms;
}
@media (prefers-reduced-motion: reduce) {
  .zoom-spinner { animation: none; border-top-color: var(--brass); }
}

.zoom-failure { margin-top: 1.5rem; }
.zoom-failure[hidden] { display: none; }
.zoom-retry {
  font: inherit;
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  color: var(--paper-2);
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 2px;
  padding: 0.45rem 0.9rem;
  cursor: pointer;
}
.zoom-retry:hover:not(:disabled) { border-color: var(--brass); color: var(--brass); }
.zoom-retry:disabled { opacity: 0.45; cursor: default; }

/* what shifts — engine output, and rendered whatever the narrator does */
.zoom-shifts { margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid var(--rule); }
.shifts { list-style: none; margin: 0.9rem 0 0; padding: 0; }
.shift {
  display: grid;
  grid-template-columns: 6.5rem 7rem minmax(0, 1fr);
  gap: 0 1rem;
  align-items: baseline;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--rule);
  font-size: 0.9375rem;
}
.shift:last-child { border-bottom: 0; }
.shift-when { color: var(--paper); }
.shift-kind {
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper-3);
}
.shift-dasha_boundary .shift-kind { color: var(--brass-dim); }
.shift-ingress .shift-kind { color: var(--slate); }
.shift-station .shift-kind,
.shift-retrograde .shift-kind { color: var(--amber); }
.shift-detail { color: var(--paper-2); min-width: 0; }

.zoom-practice { margin-top: 2.25rem; padding-top: 1.5rem; border-top: 1px solid var(--rule); }
.zoom-practice-line { margin: 0; max-width: var(--measure); color: var(--paper); }

/* the day's own texture, said in five lines and no more */
.rhythm { margin: 0; padding: 0; }
.rhythm-row {
  display: grid;
  grid-template-columns: 9rem minmax(0, 1fr);
  gap: 0 1rem;
  padding: 0.42rem 0;
  border-bottom: 1px solid var(--rule);
}
.rhythm-row:last-child { border-bottom: 0; }
.rhythm dt {
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper-3);
  line-height: 2.2;
}
.rhythm dd { margin: 0; color: var(--paper); min-width: 0; }

.zoom-creed-now {
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
  max-width: var(--measure);
}

.leaf-foot {
  margin-top: clamp(4rem, 10vh, 6rem);
  padding-top: 2rem;
  border-top: 1px solid var(--rule);
  max-width: 42rem;
  font-size: 0.8125rem;
  line-height: 1.7;
  color: var(--paper-3);
}
.leaf-foot p { margin: 0 0 1rem; }

/* ================================================================== THE MAP */
/* The Dimensions — four computed readings of this chart, at the top of its own
   report, under the same contract the comparison grid publishes.

   It borrows the grid's own marks on purpose: .cell-gloss / .gloss-part for the
   reading, .cell-trades / .trade for the tradition's list, .cell-mech /
   .cell-sig for the folded instrument voice, .lineup-contract for the
   what-it-may-not-say rows. One dimension, one look, on both surfaces. */

.movement-map { }

.map-lede {
  margin: 0 0 1.75rem;
  max-width: 44rem;
  color: var(--paper-2);
  font-size: 0.9375rem;
  line-height: 1.7;
}

/* Two by two, then four across when there is room. Never three-and-an-orphan:
   the panel is one glance at four readings, and a stranded fourth card reads as
   an afterthought rather than as the fourth of a set. */
.map-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  margin: 0 0 1.75rem;
}
@media (min-width: 62rem) {
  .map-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.map-card {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 1.1rem 1.15rem 1.2rem;
  background: linear-gradient(var(--ink-2), var(--ink) 70%);
  min-width: 0;
}
.map-card-head { margin-bottom: 0.9rem; }
.map-name {
  margin: 0;
  font-size: 0.6875rem;
  font-weight: 400;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--brass);
}
.map-reads {
  margin: 0.35rem 0 0;
  font-size: 0.75rem;
  line-height: 1.55;
  color: var(--paper-3);
  font-style: italic;
}
.map-gloss { margin: 0; }
.map-trades { margin-top: 0.95rem; }
.map-mech { margin-top: 0.95rem; }

.map-contract { margin-bottom: 1.5rem; }
.map-foot {
  margin: 0;
  max-width: 52rem;
  font-size: 0.8125rem;
  line-height: 1.65;
  color: var(--paper-3);
}

/* ------------------------------------------------------------- THE OPENER
   Spec §12.1 Wave A #1: the facet scan stays a compact grid — no card ever
   renders inside a `.map-card` cell — and this is the cell's only pointer
   down into the full-width depth region below, where the facet's own
   myth-card(s) actually live. Quiet by design: a bare line, brass on hover,
   never a button. */
.myth-opener { margin: 0.75rem 0 0; font-size: 0.75rem; }
.myth-opener[hidden] { display: none; }
.myth-opener a {
  color: var(--brass);
  text-decoration-color: var(--brass-dim);
}

/* ---------------------------------------------------------- THE MYTH-DEPTH
   Spec §12.1 Wave A #1: "the facet is the overview, the myth is its depth."
   THE DEFECT THIS REPLACES — a facet's own Instrument card(s) used to be
   folded INSIDE the four-column `.map-card` cell, so the full-width card
   design (built for a page width, `clamp()` padding, generous type) wrapped
   one word per line in a ~230px column. They render here instead: full
   width, below the whole grid, one facet's group at a time, with the
   shared `.card` chrome left completely alone — no stripped-down "single
   top rule" hack, because there is no cramped column left to compensate
   for. */
.myth-depth { margin: 2.25rem 0 0; }
.myth-group { margin-top: 2.25rem; }
.myth-group:first-child { margin-top: 0; }
.myth-group[hidden] { display: none; }
.myth-group-head {
  margin: 0 0 0.85rem;
  font-size: 0.6875rem;
  font-weight: 400;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--brass);
}
.myth-group .card + .card { margin-top: 1.75rem; }

/* -------------------------------------------------- THE REST OF THE INSTRUMENT
   Every composed card bound to no facet — spec §12.1's promise that no
   composed card is ever lost. Set apart from the facet grid, not inside it:
   this is the part of the Instrument the facet scan above could not place. */
.the-rest-of-instrument { margin: 2rem 0 0; max-width: var(--measure); }
.the-rest-of-instrument[hidden] { display: none; }
.person-rest-cap {
  margin: 0 0 0.85rem;
  font-size: 0.6875rem;
  font-weight: 400;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--brass);
}
.the-rest-of-instrument .card + .card { margin-top: 1.75rem; }

/* The one quiet line for the whole Instrument while its myth-depth is still
   composing (spec §12.1: "per-facet spinner or a single quiet pending
   line" — this report keeps one). The facet scan above it needs no spinner
   of its own; it is already finished. */
.myth-pending { margin: 1.5rem 0 0; }
.myth-pending-line { margin: 0 0 0.6rem; }

/* -------------------------------------------------------------- CARRY THIS
   Spec §12.1: the Practice's own landing line, reachable from The Person and
   The Life before a reader ever gets there — quiet, the same `.link-quiet`
   idiom as every other cross-section link on this report. */
.carry-this { margin: 1.75rem 0 0; font-size: 0.9375rem; }

/* ------------------------------------------------------------- CARRY A CARD
   Spec §12.5: couplet cards are an export from Person/Practice, not their
   own destination — a quiet line in a myth card's own footer (`_card.html`)
   and on The Practice (`_practice.html`), both pointing at the same
   `/chart/{key}/cards` page. Distinct from `.carry-this` above, which is a
   different feature (a cross-section link to the Practice's own landing
   instruction). */
.carry-card { margin: 1.25rem 0 0; font-size: 0.8125rem; }

/* ------------------------------------------------------------ LIFE DEFAULT
   Spec §12.1 Wave A #2: on first load, below the master timeline, the
   default LIFE view tells the story rather than waiting for a band to be
   clicked — the current era's own card, the era just closed, the weather
   ahead. Quiet captions, the same brass-uppercase idiom `.person-rest-cap`
   and `.myth-group-head` already use for "here is a group of what follows". */
.life-default { margin: 1.75rem 0 0; }
.life-default-cap {
  margin: 0 0 0.85rem;
  font-size: 0.6875rem;
  font-weight: 400;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--brass);
}
.life-default-next { margin-top: 1.75rem; }

/* On-ramp definitions (spec §12.1 Wave A #3): plain-word glosses of
   vimshottari/mahadasha/antardasha/pratyantardasha at each term's own first
   appearance on the page — information, not a sermon, so they borrow
   `.zoom-note`'s own quiet register rather than standing out as a callout. */
.onramp-note a { color: var(--brass); text-decoration-color: var(--brass-dim); }

/* ================================================================ THE SPINE */
/* The rail under an era deck: the vimshottari mahadashas laid end to end,
   proportional to their real lengths, today marked, the era being read lit.

   It is the SAME ribbon The Sky prints and the LIFE rung of the ladder shows —
   same macro (_ribbon.html), same rows, same widths, same plumb — so the three
   cannot drift into three different pictures of one life. What is added here is
   binding: a band whose era this deck tells is a link to that card.

   And the line that must not blur: everything on this rail is the LIFE clock,
   brass and solid. A transit window is the sky's clock — slate, dashed,
   hatched — and it appears in a card's MECHANISM block, never here. */

.spine-rail {
  margin: 0 0 1.9rem;
  padding: 0.9rem 1rem 1rem;
  border: 1px solid var(--rule);
  border-left: 2px solid var(--brass-dim);
  background: rgba(11, 14, 20, 0.55);
  max-width: 48rem;
}
.spine-rail-cap {
  margin: 0 0 0.85rem;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.2rem 0.7rem;
}
.spine-rail-key {
  font-size: 0.5875rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--brass);
}
.spine-rail-note {
  font-size: 0.75rem;
  font-style: italic;
  color: var(--paper-3);
}
.spine-rail-span { margin-left: auto; font-size: 0.75rem; color: var(--paper-3); }

/* the ribbon, in its bound form */
.ribbon-spine {
  height: 2.25rem;
  margin: 0 0 0.15rem;
}
.ribbon-spine .band { text-decoration: none; transition: background-color 160ms ease; }
.band-told { cursor: pointer; }
.band-told:hover { background: rgba(200, 164, 92, 0.16); }
.band-told:hover .band-lord { color: var(--brass); }
.band-untold { opacity: 0.55; }
/* An untold band is quieter, not inert: it still opens the Era view for its
   own mahadasha (`web/cards.build_spine`'s fallback href), so a link that
   reaches one gets the same pointer and a lighter hover than a card-bound
   band — enough to read as clickable without competing with the four that are
   actually narrated here. The rare defensive `<span>` (no href at all) picks
   up neither, being nothing to click. */
a.band-untold { cursor: pointer; }
a.band-untold:hover {
  opacity: 0.85;
  background: rgba(232, 226, 213, 0.09);
}
a.band-untold:hover .band-lord { color: var(--paper); }

/* being READ is not the same fact as being the era standing over you TODAY, so
   the two are marked differently and are allowed to co-occur: `band-now` fills
   brass, `is-current` raises a brass lip and brightens the lord. */
.ribbon-spine .band.is-current {
  background: rgba(200, 164, 92, 0.3);
  box-shadow: inset 0 3px 0 0 var(--brass), inset 0 0 0 1px var(--brass-dim);
  opacity: 1;
}
.ribbon-spine .band.is-current .band-lord {
  color: var(--gold);
  font-size: 0.6875rem;
}

/* The Road's rail runs over antardashas, so a band that opens a new mahadasha
   carries the heavier rule — the era boundaries stay legible at the finer
   scale, and the run does not read as one undivided stretch. */
.ribbon-road .band-opens { border-left: 2px solid var(--brass-dim); }
.ribbon-road .band-lord { font-size: 0.5625rem; }

/* The scale under a rail, wherever a rail is drawn: birth at one end, the last
   computed year at the other, today under its own plumb and named as the day it
   is rather than only the year it falls in. */
.ribbon-axis {
  position: relative;
  display: flex;
  justify-content: space-between;
  margin: 0.15rem 1.1rem 0.9rem;
  font-size: 0.6875rem;
  color: var(--paper-3);
  overflow: hidden;
}
/* inside a spine the rail runs full-bleed, so its axis does too */
.spine-rail .ribbon-axis { margin-left: 0; margin-right: 0; margin-bottom: 0.7rem; }
.ribbon-sm + .ribbon-axis { margin-left: 0; margin-right: 0; }
.axis-end { opacity: 0.75; }
/* Today's label sits under its own plumb line. Near either end it would hang
   off the rail, so it anchors by its near edge instead of its centre — the
   label still points at the plumb, it just stops overflowing. */
.axis-now {
  position: absolute;
  transform: translateX(-50%);
  white-space: nowrap;
  color: var(--paper);
}
.axis-now-left { transform: none; }
.axis-now-right { transform: translateX(-100%); }

/* -- The Life's master timeline (spec §12.1) -------------------------------
   The one picture of the whole 120 years, always on screen whatever the zoom
   state — grown out of the plain ribbon rather than built fresh. Past,
   present and future are three different bands, not one style with a label
   change: remembered history is filled and quiet, the era running now is lit
   in brass exactly as `.band-now` already was, and a future band carries a
   fine diagonal hatch — texture that reads as weather not yet arrived,
   deliberately unlike the solid fill of a lived year. */
.life-timeline { margin: 0 0 1.75rem; }
.ribbon-master { height: 3.25rem; margin-left: 0; margin-right: 0; }
.ribbon-master .band,
.ribbon-master a.band {
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  transition: background-color 160ms ease;
}
.ribbon-master a.band:hover,
.ribbon-master a.band:focus-visible {
  background: rgba(200, 164, 92, 0.14);
}
.ribbon-master a.band:hover .band-lord,
.ribbon-master a.band:focus-visible .band-lord {
  color: var(--brass);
}
.ribbon-master a.band:focus-visible {
  outline: 1px solid var(--brass-dim);
  outline-offset: -2px;
}

/* The band the reader actually followed here — a different fact from
   `band-now` (the era standing over them TODAY) and allowed to co-occur with
   it, same idiom `.ribbon-spine .band.is-current` already uses for "being
   READ": a brass lip on top of whatever fill the band already carries
   (quiet/brass/hatched), rather than a fourth fill of its own. */
.ribbon-master .band.is-asked {
  box-shadow: inset 0 3px 0 0 var(--brass), inset 0 0 0 1px var(--brass-dim);
}
.ribbon-master .band.is-asked .band-lord {
  color: var(--gold);
}
.band-future {
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(232, 226, 213, 0.05) 0,
    rgba(232, 226, 213, 0.05) 1px,
    transparent 1px,
    transparent 6px
  );
}
.band-future .band-lord,
.band-future .band-year,
.band-future .band-end { color: var(--paper-3); }

.life-timeline-key {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1.4rem;
  margin: 0.6rem 1.1rem 0;
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--paper-3);
}
.life-key { display: inline-flex; align-items: center; gap: 0.4em; }
.life-key-swatch {
  display: inline-block;
  width: 0.75em;
  height: 0.75em;
  border: 1px solid var(--rule-2);
}
.life-key-past .life-key-swatch { background: rgba(232, 226, 213, 0.07); }
.life-key-now .life-key-swatch {
  background: rgba(200, 164, 92, 0.2);
  border-color: var(--brass);
}
.life-key-future .life-key-swatch {
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(232, 226, 213, 0.12) 0,
    rgba(232, 226, 213, 0.12) 1px,
    transparent 1px,
    transparent 4px
  );
}

/* One period's content, embedded inside the ERA state rather than its own
   chapter — the async degrade (spinner, retry) for a canto or road card
   still composing while the reader is already looking at it. */
.life-period { margin-top: 1.5rem; max-width: 48rem; }
.life-period-body .prose { margin-top: 0; }
/* A canto/road card standing alone in the ERA state, not inside a `.deck` —
   the same measure the deck gives every other card on the report. */
.zoom-panel > .card { max-width: 48rem; margin-top: 1.5rem; }

/* What is lit, in words. The rail carries two marks — the period standing over
   the reader today, and the period being read — and this line removes any need
   to learn which shading is which. */
/* `display: flex` outranks the browser's own `[hidden] { display: none }`, and
   this line is hidden whenever the open card is about no period at all. */
.spine-reading[hidden] { display: none; }
.spine-reading {
  margin: 0 0 0.55rem;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.15rem 0.6rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--rule);
  font-size: 0.8125rem;
}
.spine-reading-key {
  font-size: 0.5875rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--brass);
}
.spine-reading-name { color: var(--paper); }
.spine-reading-when { color: var(--paper-2); font-size: 0.75rem; }
.spine-reading-card {
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  color: var(--paper-3);
}
.spine-reading-here {
  font-size: 0.5875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--brass);
  padding: 0.05rem 0.4rem 0.1rem;
  white-space: nowrap;
}

.spine-note {
  margin: 0;
  font-size: 0.75rem;
  line-height: 1.6;
  color: var(--paper-3);
  max-width: 42rem;
}

/* ================================================================= THE DECK */
/* A composed section, cut into page-sized cards (web/cards.py, _deck.html).
   Three kinds of content share this card and must never share a voice:

     INSTRUMENT  .mech      — computed. Tabular figures, small-caps keys, ruled
                              rows. The voice The Sky already speaks.
     STORY       .card-story— written. Serif, generous measure, the emblem.
     CAVEAT      .card-caveat — fine print. At the foot, quiet, behind a rule.

   The rule this whole file is under: a dasha ERA and a transit WINDOW are two
   unrelated clocks, and a reader once read one as the other because they were
   set identically. So .mech-era and .mech-transit differ in colour, in rule
   style, in range glyph and in label, and nothing may collapse that difference
   back together. */

.u-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* The deck is held to a book width rather than the column's: a card frame that
   runs a hand's width past the end of every line stops reading as a page. */
.deck { margin: 0; max-width: 48rem; }

/* -- the deck head: where you are, and how far it runs --------------------- */

.deck-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--rule-2);
  margin-bottom: 1.75rem;
}
.deck-where {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 0.85rem;
  min-width: 0;
}
.deck-where-name {
  font-size: 0.6875rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--brass);
}
.deck-where-pos {
  font-size: 0.75rem;
  color: var(--paper-3);
  font-variant-numeric: tabular-nums lining-nums;
  white-space: nowrap;
}

/* A rail of NAMES, not dots. Card 3 of 8 has to be able to see that the other
   seven exist and read what they are — a deck is a table of contents, not a
   slideshow. It takes its own line under the deck's heading, wraps rather than
   scrolling sideways, and each entry ellipsises rather than widening the page. */
.deck-rail { min-width: 0; flex: 1 1 100%; }
.rail {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 0.3rem;
  margin: 0;
  padding: 0;
}
/* The `li` is the flex item, so it is the box that has to be capped — a cap on
   the anchor inside it lets the item grow to the title's full width and pushes
   the page sideways on a phone. */
.rail > li {
  display: flex;
  min-width: 0;
  max-width: min(15rem, 100%);
}
.rail-card {
  display: flex;
  flex: 1 1 auto;
  align-items: baseline;
  gap: 0.45rem;
  min-width: 0;
  padding: 0.28rem 0.6rem 0.32rem;
  border: 1px solid var(--rule);
  border-bottom-color: var(--rule-2);
  text-decoration: none;
  color: var(--paper-3);
  transition: color 160ms ease, border-color 160ms ease, background-color 160ms ease;
}
.rail-card:hover { color: var(--paper); border-color: var(--brass-dim); }
.rail-num {
  flex: none;
  font-size: 0.625rem;
  color: var(--brass-dim);
  font-variant-numeric: tabular-nums lining-nums;
}
.rail-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.8125rem;
  line-height: 1.5;
}
.rail-card.is-current {
  color: var(--paper);
  border-color: var(--brass-dim);
  border-bottom-color: var(--brass);
  background: rgba(200, 164, 92, 0.1);
}
.rail-card.is-current .rail-num { color: var(--brass); }

/* -- the card ------------------------------------------------------------- */

.card {
  border: 1px solid var(--rule-2);
  border-left-width: 2px;
  border-left-color: var(--brass-dim);
  background: linear-gradient(var(--ink-2), var(--ink) 60%);
  padding: clamp(1.4rem, 3.5vw, 2.25rem) clamp(1.15rem, 3.5vw, 2.25rem) 0;
  animation: turn 420ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.card[hidden] { display: none; }

@keyframes turn {
  from { opacity: 0; transform: translateX(0.55rem); }
  to   { opacity: 1; transform: none; }
}

.card-head {
  display: flex;
  align-items: flex-start;
  gap: 1.1rem;
  margin-bottom: 1.6rem;
}
.card-naming { min-width: 0; }

/* the emblem: line art, currentColor, sized in type units so it sits with the
   title rather than beside a box */
.card-emblem {
  flex: none;
  display: block;
  width: 3.25rem;
  height: 3.25rem;
  color: var(--brass);
  opacity: 0.85;
}
.card-emblem svg { display: block; width: 100%; height: 100%; }

.card-kicker {
  margin: 0 0 0.45rem;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.5rem;
  font-size: 0.625rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--paper-3);
}
.card-kicker-section { color: var(--brass-dim); }
.card-kicker-sep { color: var(--brass-dim); }
.card-kicker-pos { letter-spacing: 0.08em; font-variant-numeric: tabular-nums lining-nums; }

.card-title {
  margin: 0;
  font-size: clamp(1.5rem, 1.15rem + 1.5vw, 2.05rem);
  font-weight: 400;
  line-height: 1.14;
  letter-spacing: -0.016em;
  text-wrap: balance;
}
/* The era's own years, appended once by web/cards.py so "the upstream years"
   always says which ones — set apart from the title's own type, the same
   dimming the kicker already uses for its separator. */
.card-title .sep,
.card-title .num {
  font-size: 0.55em;
  color: var(--brass-dim);
}
.card-obj {
  margin: 0.5rem 0 0;
  font-style: italic;
  color: var(--gold);
  font-size: 1.0625rem;
  line-height: 1.4;
}

/* -- LAYER 1 · INSTRUMENT: computed, tabular, ruled ------------------------ */

.mech {
  margin: 0 0 1.9rem;
  border: 1px solid var(--rule);
  background: rgba(11, 14, 20, 0.55);
}
.mech-cap {
  margin: 0;
  padding: 0.6rem 0.9rem 0.55rem;
  border-bottom: 1px solid var(--rule);
  font-size: 0.625rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--brass);
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.7rem;
  align-items: baseline;
}
.mech-rows { margin: 0; padding: 0; }
.mech-row {
  display: grid;
  grid-template-columns: 7.5rem minmax(0, 1fr);
  gap: 0 1rem;
  padding: 0.65rem 0.9rem;
  border-bottom: 1px solid var(--rule);
  align-items: baseline;
}
.mech-row:last-child { border-bottom: 0; }
.mech-key {
  font-size: 0.5875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper-3);
  line-height: 2.1;
}
.mech-val { margin: 0; min-width: 0; }
.mech-value {
  display: block;
  color: var(--paper);
  font-size: 0.9375rem;
  line-height: 1.5;
}
.mech-span,
.mech-unit {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums lining-nums;
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
}
.mech-span { color: var(--paper-2); margin-right: 0.75rem; }
.mech-unit { color: var(--paper-3); }
.mech-note {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.75rem;
  line-height: 1.55;
  color: var(--paper-3);
  font-style: italic;
}

/* the full-sky link (spec §12.2): every provenance affordance on the report
   — a card's own MECHANISM block, a facet's folded "mechanism", the Season
   and Now zoom panels — opens onto the same full computed sky, not just its
   own fields. Quiet by default (a footnote, not a call to action); a
   bordered row when it closes a `.mech` box, inline wherever it stands on
   its own. */
.sky-link {
  display: inline-block;
  margin-top: 0.6rem;
  font-size: 0.8125rem;
  color: var(--paper-3);
  text-decoration: none;
}
.sky-link:hover { color: var(--brass); }
.mech > .sky-link {
  display: block;
  margin: 0;
  padding: 0.55rem 0.9rem 0.6rem;
  border-top: 1px solid var(--rule);
}

/* the two clocks, deliberately unalike ------------------------------------ */

/* THE LIFE CLOCK — a dasha era. Solid brass edge, brass figures, an en-dash
   range, and the length of the era stated so it cannot read as a moment. */
.mech-era {
  border-left: 3px solid var(--brass);
  background: linear-gradient(90deg, rgba(200, 164, 92, 0.09), transparent 60%);
}
.mech-era .mech-key { color: var(--brass); }
.mech-era .mech-value { color: var(--paper); font-size: 1.0625rem; letter-spacing: 0.01em; }
.mech-era .mech-span {
  color: var(--brass);
  font-size: 1rem;
  border-bottom: 1px solid var(--brass-dim);
  padding-bottom: 0.05rem;
}

.mech-sub {
  border-left: 3px solid var(--brass-dim);
  background: linear-gradient(90deg, rgba(200, 164, 92, 0.04), transparent 50%);
}
.mech-sub .mech-key { color: var(--brass-dim); }
.mech-sub .mech-span { color: var(--gold); border-bottom: 1px solid var(--rule-2); }

/* THE SKY'S CLOCK — a transit window. Dashed slate edge, slate figures, an
   arrow range, and it says out loud that it overlaps eras rather than dividing
   them. Nothing here may be allowed to look like the block above. */
.mech-transit {
  border-left: 3px dashed var(--slate);
  background: repeating-linear-gradient(
    -45deg,
    rgba(130, 150, 180, 0.055) 0 6px,
    transparent 6px 12px
  );
}
.mech-transit .mech-key { color: var(--slate); }
.mech-transit .mech-value { color: var(--paper-2); }
.mech-transit .mech-span {
  color: var(--slate);
  font-size: 1rem;
  border-bottom: 1px dashed var(--slate);
  padding-bottom: 0.05rem;
}
.mech-transit .mech-unit {
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 0.5875rem;
  color: var(--slate);
}

.mech-signature .mech-value { color: var(--paper); }
.mech-position .mech-span { color: var(--paper-2); }

/* -- LAYER 2 · STORY: written, serif, generous ---------------------------- */

.card-story { margin: 0; }
.card-story > *:first-child { margin-top: 0; }
.card-story p:last-child { margin-bottom: 0; }

/* -- the landing act ------------------------------------------------------ */

.do {
  margin: 1.9rem 0 0;
  padding: 1rem 1.15rem 1.05rem;
  border: 1px solid var(--brass-dim);
  border-left-width: 3px;
  background: linear-gradient(rgba(200, 164, 92, 0.07), rgba(200, 164, 92, 0.015));
  max-width: var(--measure);
}
.do-cap {
  margin: 0 0 0.4rem;
  font-size: 0.5875rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--brass);
}
.do-line { margin: 0; color: var(--paper); font-size: 1.0625rem; line-height: 1.6; }
.do-sutra { border-color: var(--rule-2); border-left-color: var(--gold); background: none; }
.do-sutra .do-cap { color: var(--gold); }
.do-sutra .do-line { font-style: italic; color: var(--gold); }

/* -- THE PRACTICE (spec §12.1) ---------------------------------------------
   The capstone's own landing act, set first and primary rather than after
   the verse: no top margin (it opens the card), and one size up from every
   other `.do` on this report so it reads as the reason the section exists,
   not a footnote to the poem beneath it. The tying sentence between the two
   (`web/app.py::_practice_tie`) is deterministic prose, so it takes the
   report's plain paragraph voice — never the instrument's gold sutra tone,
   which belongs to the model's own closing line alone. */
.do-primary { margin-top: 0; }
.do-primary .do-line { font-size: 1.1875rem; }
.practice-tie {
  margin: 1.1rem 0 0;
  max-width: var(--measure);
  color: var(--paper-2);
  font-size: 0.9375rem;
  line-height: 1.7;
}
.practice-verse { margin-top: 1.9rem; }

/* -- THE TRADITION'S GENERAL READ ------------------------------------------
   corpus/data/dasha_eras.json — the tradition's texture and instruction for
   ANY era of this lord, rendered verbatim and deterministically. Never the
   model's prose, and never allowed to look like it: the landing act above
   (.do) is brass, personal, addressed to this one chart; this box is slate,
   the same "this is not the personal clock" signal .mech-transit already
   carries, borrowed here for an impersonal *text* instead of an impersonal
   *clock*. Present only on an era card (a card whose era_lord was bound). */
.trad {
  margin: 1.9rem 0 0;
  padding: 1rem 1.15rem 1.05rem;
  border: 1px solid var(--rule-2);
  border-left: 3px dashed var(--slate);
  background: repeating-linear-gradient(
    -45deg,
    rgba(130, 150, 180, 0.05) 0 6px,
    transparent 6px 12px
  );
  max-width: var(--measure);
}
.trad-cap {
  margin: 0 0 0.55rem;
  font-size: 0.5875rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--slate);
}
.trad-texture {
  margin: 0;
  color: var(--paper-2);
  font-size: 0.9375rem;
  line-height: 1.65;
  font-style: italic;
}
.trad-instruction {
  margin: 0.75rem 0 0;
  padding-top: 0.75rem;
  border-top: 1px solid var(--rule);
  color: var(--paper);
  font-size: 1rem;
  line-height: 1.6;
}

/* -- LAYER 3 · CAVEAT: fine print, at the foot, subordinate ---------------- */

.card-caveat {
  margin: 2rem calc(clamp(1.15rem, 3.5vw, 2.25rem) * -1) 0;
  padding: 0.85rem clamp(1.15rem, 3.5vw, 2.25rem) 0.95rem;
  border-top: 1px solid var(--rule);
  background: rgba(0, 0, 0, 0.22);
}
.card-caveat p {
  margin: 0;
  font-size: 0.75rem;
  line-height: 1.7;
  color: var(--paper-3);
  max-width: 44rem;
}
.caveat-link { color: var(--paper-2); white-space: nowrap; }
.caveat-link:hover { color: var(--brass); }

/* -- turning the page ----------------------------------------------------- */

.deck-nav {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  margin-top: 1.25rem;
  background: var(--rule);
  border: 1px solid var(--rule);
}
.deck-step {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.95rem 1.1rem;
  min-height: 3.4rem;
  text-decoration: none;
  color: var(--paper-2);
  background: var(--ink);
  transition: background-color 180ms ease, color 180ms ease;
  min-width: 0;
}
.deck-next { justify-content: flex-end; text-align: right; }
.deck-step:hover { background: rgba(200, 164, 92, 0.08); color: var(--paper); }
.deck-step.is-spent { color: var(--paper-3); opacity: 0.4; cursor: default; }
.deck-step.is-spent:hover { background: var(--ink); color: var(--paper-3); }
.deck-step-arrow { flex: none; color: var(--brass); font-size: 1rem; }
.deck-step.is-spent .deck-step-arrow { color: var(--paper-3); }
.deck-step-text { min-width: 0; }
.deck-step-label {
  display: block;
  font-size: 0.5875rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--paper-3);
}
.deck-step-name {
  display: block;
  font-size: 0.9375rem;
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.deck-hint {
  margin: 0.8rem 0 0;
  font-size: 0.75rem;
  color: var(--paper-3);
  font-style: italic;
}

/* ============================================================== THE GLOSSARY */
/* A mark in the prose is a real link to the glossary page; the script upgrades
   it to open the short definition in place. Quiet by design — a dotted rule
   under the word, never a colour that pulls the eye out of the sentence. */

.gloss {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dotted var(--brass-dim);
  cursor: help;
  transition: border-color 160ms ease, color 160ms ease;
}
.gloss:hover, .gloss:focus-visible { color: var(--gold); border-bottom-color: var(--brass); }

/* A dated instruction, dated and clickable (review #12) — a real link into
   The Life, styled quietly like `.gloss` (same dotted underline) but with
   the ordinary pointer cursor of a link that goes somewhere, not a
   definition that opens in place. */
.date-link {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px dotted var(--brass-dim);
  transition: border-color 160ms ease, color 160ms ease;
}
.date-link:hover, .date-link:focus-visible { color: var(--gold); border-bottom-color: var(--brass); }

.gloss-host { position: relative; }

.gloss-pop {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  z-index: 40;
  display: block;
  width: min(21rem, 78vw);
  padding: 0.85rem 1rem 0.9rem;
  background: var(--ink-3);
  border: 1px solid var(--rule-2);
  border-top: 1px solid var(--brass-dim);
  box-shadow: 0 1.25rem 2.75rem rgba(0, 0, 0, 0.65);
  font-family: var(--serif);
  font-style: normal;
  color: var(--paper-2);
}
.gloss-pop[hidden] { display: none; }
.gloss-term {
  display: block;
  font-size: 0.625rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--brass);
  margin-bottom: 0.4rem;
}
.gloss-short { display: block; font-size: 0.9375rem; line-height: 1.6; color: var(--paper); }
.gloss-more {
  display: block;
  margin-top: 0.7rem;
  font-size: 0.8125rem;
  color: var(--brass);
  text-decoration-color: var(--brass-dim);
}

/* ================================================================== A TRACT */
/* The two pages behind every card: the glossary, and how this was made. Set as
   a tract rather than a report — one column, no instruments, nothing to poll. */

.tract {
  max-width: 44rem;
  margin: 0 auto;
  padding: clamp(2.5rem, 9vh, 5.5rem) 1.5rem 5rem;
}
.tract-head { margin-bottom: clamp(2.5rem, 7vh, 4rem); }
.tract-title {
  font-size: clamp(2.25rem, 7.5vw, 3.5rem);
  line-height: 1.04;
  letter-spacing: -0.02em;
  font-weight: 400;
  margin: 1.5rem 0 0;
  text-wrap: balance;
}
.tract-lede {
  margin: 1.5rem 0 0;
  max-width: 34rem;
  color: var(--paper-2);
  font-size: 1.0625rem;
  border-left: 1px solid var(--rule-2);
  padding-left: 1.25rem;
}

.tract-section {
  margin-top: clamp(2.75rem, 6vh, 3.75rem);
  padding-top: 1.75rem;
  border-top: 1px solid var(--rule-2);
}
.tract-section > h2 {
  font-size: 1.5rem;
  font-weight: 400;
  letter-spacing: -0.012em;
  line-height: 1.2;
  margin: 0 0 1.1rem;
}
.tract-section p {
  margin: 0 0 1.1rem;
  max-width: var(--measure);
  color: var(--paper-2);
}
.tract-section p:last-child { margin-bottom: 0; }
.tract-section strong { font-weight: 400; color: var(--paper); border-bottom: 1px solid var(--brass-dim); }
.tract-section em { font-style: italic; color: var(--gold); }

/* a disputed point: both positions named, and what we do said plainly */
.disputes { list-style: none; margin: 0; padding: 0; }
.dispute {
  padding: 1rem 0;
  border-top: 1px solid var(--rule);
}
.dispute:first-child { border-top: 0; padding-top: 0; }
.dispute-name {
  margin: 0 0 0.45rem;
  font-size: 1.0625rem;
  color: var(--paper);
}
.dispute-body { margin: 0 0 0.5rem; font-size: 0.9375rem; color: var(--paper-2); }
.dispute-ours {
  margin: 0;
  font-size: 0.875rem;
  color: var(--paper-3);
  padding-left: 0.9rem;
  border-left: 1px solid var(--brass-dim);
}
.dispute-ours b { font-weight: 400; color: var(--brass); }

.tract-foot {
  margin-top: clamp(3rem, 8vh, 4.5rem);
  padding-top: 1.75rem;
  border-top: 1px solid var(--rule);
  font-size: 0.8125rem;
  color: var(--paper-3);
}
.tract-foot p { margin: 0 0 0.8rem; max-width: 40rem; }
.tract-acts { display: flex; flex-wrap: wrap; gap: 0.6rem 1.5rem; margin-top: 1.5rem; }

/* -- the glossary page ---------------------------------------------------- */

.gloss-groups { margin: 0; padding: 0; }
.gloss-group { margin-top: 2.5rem; }
.gloss-group:first-child { margin-top: 0; }
.gloss-letter {
  margin: 0 0 0.75rem;
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.3em;
  color: var(--brass);
  border-bottom: 1px solid var(--rule-2);
  padding-bottom: 0.5rem;
}
.gloss-entries { list-style: none; margin: 0; padding: 0; }
.gloss-entry { padding: 1.1rem 0; border-bottom: 1px solid var(--rule); scroll-margin-top: 2rem; }
.gloss-entry:last-child { border-bottom: 0; }
.gloss-entry:target { border-left: 2px solid var(--brass); padding-left: 1rem; margin-left: -1rem; }
.gloss-head {
  margin: 0 0 0.4rem;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 0.85rem;
}
.gloss-name { font-size: 1.1875rem; color: var(--paper); letter-spacing: 0.005em; }
.gloss-deva { font-size: 1.0625rem; color: var(--brass); }
.gloss-long { margin: 0; color: var(--paper-2); font-size: 0.9375rem; max-width: 40rem; }
.gloss-see {
  margin: 0.5rem 0 0;
  font-size: 0.8125rem;
  color: var(--paper-3);
}
.gloss-see .from-ref { margin-right: 0.5rem; }
.gloss-empty {
  margin: 0;
  padding: 1.25rem 1.35rem;
  border: 1px solid var(--rule-2);
  color: var(--paper-2);
  font-size: 0.9375rem;
}

.leaf-foot-acts { display: flex; flex-wrap: wrap; gap: 0.6rem 1.5rem; margin-top: 1.25rem; }

/* ------------------------------------------------------------ narrow screens */

@media (max-width: 40rem) {
  .card-head { gap: 0.85rem; }
  .card-emblem { width: 2.5rem; height: 2.5rem; }
  .mech-row { grid-template-columns: minmax(0, 1fr); gap: 0; padding: 0.7rem 0.8rem; }
  .mech-key { line-height: 1.6; margin-bottom: 0.15rem; }
  .mech-era, .mech-sub, .mech-transit { border-left-width: 3px; }
  .deck-nav { grid-template-columns: minmax(0, 1fr); }
  .deck-step { padding: 0.85rem 0.95rem; }
  .deck-head { gap: 0.5rem 1rem; }
  .card-caveat { margin-left: -1.15rem; margin-right: -1.15rem; padding-left: 1.15rem; padding-right: 1.15rem; }
  .gloss-pop { width: min(21rem, 84vw); }
  .tract { padding-left: 1.15rem; padding-right: 1.15rem; }

  /* the map: one reading per row on a phone, at full width */
  .map-grid { grid-template-columns: minmax(0, 1fr); }
  .map-card { padding: 1rem 1rem 1.1rem; }

  /* the spine: the ribbon keeps its proportions (that is the whole point of
     it), so what gives is the padding and the label sizes — never the widths */
  .spine-rail { padding: 0.8rem 0.85rem 0.9rem; }
  .spine-rail-span { margin-left: 0; }
  .ribbon-spine { height: 2rem; }
  .band-lord { font-size: 0.5625rem; }

  /* The Life's master timeline: same rule — the widths stay real, only the
     chrome shrinks — and its own key wraps onto its own lines rather than
     crowding the ribbon it explains. */
  .ribbon-master { height: 2.35rem; }
  .life-timeline-key { gap: 0.3rem 1rem; margin: 0.5rem 0 0; }

  /* the card rail keeps names — a phone reader needs the table of contents
     more, not less — but each entry takes the row it needs */
  .rail { gap: 0.25rem; }
  .rail > li { max-width: 100%; flex: 1 1 9rem; }
}

@media (prefers-reduced-motion: reduce) {
  .card { animation: none; }
}

@media (max-width: 40rem) {
  .tagline-turn { margin-left: 0; }
  .era-len { margin-left: 0; }
  .gallery { padding-left: 1.15rem; padding-right: 1.15rem; }
  .candidate { padding: 1.15rem 1.1rem; }
  .candidate-fork { margin-left: -0.35rem; margin-right: -0.35rem; }
  .candidate-facts { gap: 0.35rem 1.1rem; }
  .gallery-bar { display: block; }
  .gallery-acts { display: block; margin-top: 0.6rem; }
  .gallery-acts .link-quiet { display: inline-block; margin-top: 0.4rem; }
  .candidate-acts { gap: 0.9rem; }
  .refusal .cast { width: 100%; }
  .era-span { min-width: 6.5rem; }
  /* one fact per line beats separators stranded at the end of a wrap */
  .colophon-line { display: block; }
  .colophon-line .sep { display: none; }
  .colophon-line > span { display: block; }
  .fineprint li { grid-template-columns: minmax(0, 1fr); }
  .fineprint-key { line-height: 1.6; margin-bottom: 0.2rem; }
  /* the ladder keeps its four columns on a phone — a tab strip that wraps
     stops reading as a scale — but the rows under it stack rather than
     scroll sideways */
  .zoom-tab { padding: 0.6rem 0.25rem 0.65rem; }
  .zoom-tab-name { font-size: 0.6875rem; letter-spacing: 0.1em; }
  .zoom-tab-unit { font-size: 0.5625rem; letter-spacing: 0.02em; }
  .zoom-era .era-len { margin-left: 0; }
  .shift { grid-template-columns: minmax(0, 1fr); gap: 0.1rem; padding: 0.65rem 0; }
  .shift-kind { order: -1; }
  .rhythm-row { grid-template-columns: minmax(0, 1fr); gap: 0; padding: 0.55rem 0; }
  .rhythm dt { line-height: 1.6; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

@media print {
  .starfield, .spine, .status { display: none; }
  body { background: #fff; color: #111; }
}

/* The common ground: what every candidate window agrees on, shown before the
   reader is asked to choose between them. One quiet zone — the grid below it
   is the choice; this is the floor it stands on. */
.settled-zone {
  margin: 3rem 0 1rem;
  padding: 1.5rem 1.75rem 1.75rem;
  border: 1px solid var(--hairline, rgba(232, 226, 213, 0.14));
  border-left: 3px solid var(--brass, #c8a45c);
}
.settled-lede { max-width: 56ch; margin: 0.5rem 0 1.1rem; color: var(--bone, #e8e2d5); }
.settled-facts { list-style: none; margin: 0; padding: 0; }
.settled-fact {
  padding: 0.4rem 0;
  border-top: 1px solid var(--hairline, rgba(232, 226, 213, 0.09));
  max-width: 62ch;
}
.settled-facts-quiet .settled-fact { font-size: 0.9rem; opacity: 0.8; }
.settled-more { margin: 0.75rem 0 0; }
.settled-more summary { cursor: pointer; font-size: 0.85rem; letter-spacing: 0.04em; opacity: 0.75; }
.settled-readings {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1.25rem; margin-top: 1.5rem;
}
.settled-obj { font-style: italic; color: var(--brass, #c8a45c); font-weight: 400; margin: 0 0 0.35rem; font-size: 1.05rem; }
.settled-procl { margin: 0 0 0.5rem; font-size: 0.92rem; }
.settled-do { font-size: 0.88rem; opacity: 0.9; margin: 0; }
.settled-do .do-key { font-variant: small-caps; letter-spacing: 0.08em; color: var(--brass, #c8a45c); margin-right: 0.4rem; }
.settled-open { margin-top: 1.5rem; }
@media (max-width: 40rem) {
  .settled-zone { padding: 1.1rem 1rem 1.25rem; }
  .settled-readings { grid-template-columns: 1fr; }
}

/* rituals -------------------------------------------------------------------
   Idea Triage + The Pressing (spec §10 v0.3): two standalone, chart-optional
   companion practices. Dressed in exactly the primitives already used
   everywhere else on this site (.threshold/.ledger/.field/.label/.rule-input/
   .tick/.card/.link-quiet, spec §12.2.1's own "reuse before you add") — this
   block adds only what those primitives do not already cover: the one frame
   line, the flavor paragraph, the vault's three columns, and one Pressing's
   own stage cards and live stream. Fluid by the same clamp()-first discipline
   the rest of this file uses; every rule below already reads correctly at
   390px, so only the vault's three columns need a narrow-screen override. */

.ritual-page { max-width: 38rem; }

.ritual-title { font-size: clamp(2.25rem, 8vw, 3.25rem); }

.ritual-frame { font-style: italic; color: var(--paper); }

.ritual-flavor {
  margin: 1.1rem 0 0;
  padding-left: 1.1rem;
  border-left: 1px solid var(--rule-2);
  color: var(--paper-2);
  font-size: 0.9375rem;
  line-height: 1.7;
}

.ritual-textarea { min-height: 8rem; resize: vertical; font-size: 1.0625rem; }

.ritual-section { margin-top: 2.5rem; }
.ritual-section + .ritual-section { margin-top: 2rem; }

.ritual-card { margin-bottom: 1.25rem; padding-bottom: 1.4rem; }
.ritual-card:last-child { margin-bottom: 0; }

.ritual-idea-text {
  margin: 0 0 0.5rem;
  color: var(--paper);
  font-size: 1.0625rem;
  line-height: 1.6;
}

.ritual-bhishma {
  margin: 0 0 0.75rem;
  color: var(--brass);
  font-size: 0.8125rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.ritual-bhishma-tag {
  margin-left: 0.5rem;
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brass);
}

.ritual-proposal {
  margin: 0 0 1.1rem;
  padding-left: 1rem;
  border-left: 1px solid var(--brass-dim);
  color: var(--paper-2);
  font-size: 0.9375rem;
  font-style: italic;
}

.ritual-ratify .field { margin-bottom: 1rem; }

.ritual-columns {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.5rem;
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule-2);
}
.ritual-column .ritual-idea-text { font-size: 0.9375rem; }

@media (max-width: 40rem) {
  .ritual-columns { grid-template-columns: 1fr; gap: 2rem; }
}

/* -- The Pressing's own rite page ------------------------------------------ */

.ritual-work { margin-bottom: 2rem; }
.ritual-work summary { cursor: pointer; }
.ritual-work-text {
  margin: 0.75rem 0 0;
  color: var(--paper-2);
  font-size: 0.9375rem;
  line-height: 1.7;
  white-space: pre-wrap;
}

.ritual-stage-card { margin-bottom: 1.75rem; }
.ritual-stage-card .label { margin-bottom: 1rem; }

.ritual-stage-form, .ritual-confirm, .ritual-correct { margin-bottom: 1.5rem; }

.ritual-stream {
  margin-bottom: 1rem;
  padding: 1rem 1.15rem;
  border: 1px solid var(--rule-2);
  border-left: 2px solid var(--brass-dim);
  background: var(--ink-2);
  color: var(--paper-2);
  font-size: 0.9375rem;
  line-height: 1.7;
  white-space: pre-wrap;
}
.ritual-stream[hidden] { display: none; }

/* a .link-quiet used on a <button> (Ratify / Remove / Say it again / Discard)
   must read exactly like the <a> version everywhere else on this site — the
   button's own UA chrome is stripped first, then the class's usual border. */
button.link-quiet {
  appearance: none;
  background: none;
  border: none;
  border-bottom: 1px solid var(--brass-dim);
  padding: 0 0 0.1rem;
  margin: 0 0 1rem;
  font: inherit;
  cursor: pointer;
}

/* -- entry points ------------------------------------------------------------
   index.html's one quiet line, and The Practice's own link onto whichever
   rite its bound deck names (web/app.py::_practice_link, _practice.html). */

.ritual-entry { margin: 1.5rem 0 0; color: var(--paper-2); font-size: 0.9375rem; }

.ritual-practice-link { margin: 1.5rem 0 0; }

/* Calculation records stay one step beneath the reading. */
.reading-settings, .evidence-record, .candidate-uncertainty {
  margin: 1.5rem 0;
  padding: 1rem 0;
  border-block: 1px solid var(--brass-dim);
}
.reading-settings summary, .evidence-record summary, .candidate-uncertainty summary {
  cursor: pointer;
  color: var(--paper);
}
.evidence-record dl, .evidence-interpretation {
  display: grid;
  grid-template-columns: minmax(8rem, 1fr) minmax(0, 3fr);
  gap: .5rem 1rem;
}
.evidence-record dd, .evidence-interpretation dd { margin: 0; overflow-wrap: anywhere; }
.evidence-record dt, .evidence-interpretation dt { color: var(--paper-2); }
.tract-systems, .tract-compare { max-width: 82rem; }
.system-columns { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 23rem), 1fr)); gap: 2rem; }
.system-chart { min-width: 0; }
.table-scroll { overflow-x: auto; margin-block: 1rem; }
.comparison-table { width: 100%; border-collapse: collapse; }
.comparison-table td, .comparison-table th { padding: .75rem; text-align: left; vertical-align: top; }
.comparison-diff { background: var(--ink-2); border-left: 2px solid var(--brass); }
.candidate-offset { display: block; color: var(--paper-2); font-size: .875rem; }
.candidate-acts label { display: inline-flex; align-items: center; gap: .5rem; }
.reading-settings select { background: var(--ink-2); color: var(--paper); padding: .65rem; border: 1px solid var(--brass-dim); font: inherit; }
.card-evidence { font-size: .85rem; margin-top: 1rem; }
.tract-acts { display: flex; flex-wrap: wrap; gap: 1rem; }

/* one question at a time (2026-09-21): the trail of answers above the one
   question on the page. Each step is one line — question, the answer(s)
   ticked, how many windows it left, and a real link to change it. */
.picker-trail {
  list-style: none;
  margin: 0 0 1.25rem;
  padding: 0;
  border-left: 1px solid var(--rule-2);
}
.picker-step {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 0.75rem;
  padding: 0.35rem 0 0.35rem 0.9rem;
  font-size: 0.92rem;
}
.picker-step-q { color: var(--paper-3); }
.picker-step-a { color: var(--paper); }
.picker-step-n { font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--paper-3); }
.picker-step-change { font-size: 0.8rem; }
.picker-hint { margin: 0 0 0.75rem; font-size: 0.85rem; color: var(--paper-3); }
.picker-acts {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  margin: 1rem 0 0;
}
.picker-skip {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  cursor: pointer;
}
.picker-done { margin: 0.5rem 0 0; color: var(--paper-2); }
.picker-done a { margin-left: 0.75rem; }
@media (max-width: 40rem) {
  .picker-step { font-size: 0.88rem; }
}

/* the coarse question (arrival families): no mechanism to fold, so the
   options are plain and wide rather than grid cards. */
.picker-coarse { display: grid; gap: 0.5rem; grid-template-columns: 1fr; }
.picker-coarse .picker-choice { padding: 0.85rem 1rem; }

/* the threshold, 2026-09-22: three fields and nothing to read. How well the
   time is known was three stacked rows of sentence; it is one line of three
   words now, sitting under the time it qualifies. */
.precision {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  border: 0;
  margin: 0.85rem 0 0;
  padding: 0;
}
.precision-opt { cursor: pointer; }
.precision-opt input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.precision-word {
  font-size: 0.9375rem;
  color: var(--paper-3);
  padding-bottom: 0.15rem;
  border-bottom: 1px solid transparent;
}
.precision-opt input:checked + .precision-word {
  color: var(--brass);
  border-bottom-color: var(--brass);
}
.precision-opt input:focus-visible + .precision-word {
  outline: 2px solid var(--brass);
  outline-offset: 3px;
}
.threshold-links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  margin: 0 0 1rem;
}
.threshold-foot .fineprint {
  margin: 0 0 1.5rem;
  max-width: 34rem;
  font-size: 0.8125rem;
  line-height: 1.6;
  color: var(--paper-3);
}
