/* components.css — the reusable ledger parts: header + nav, the ticket button, ledger rows
   and worked-example insets, the running total, rule-off / stamp / highlighter marks, the
   rate card, method postings, the green proof panel, the signed note, and the receipt
   footer. Page-specific composition lives in css/pages/*. */

/* =========================================================================
   HEADER — sticky, translucent paper, two states (top / scrolled)
   ========================================================================= */
.site-header {
  position: sticky;
  top: 0;
  z-index: 1000;
  /* Box height is CONSTANT so the sticky header never reflows the document on scroll-state
     change. The condensed feel comes from the inner bar's padding (below), which is
     transform/padding only — zero layout shift. */
  height: var(--header-top);
  background: color-mix(in srgb, var(--paper) 94%, transparent);
  border-bottom: 1px solid transparent;
  transition: border-color var(--d-m) var(--ease-ledger),
              background var(--d-m) var(--ease-ledger);
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .site-header {
    background: color-mix(in srgb, var(--paper) 82%, transparent);
    -webkit-backdrop-filter: saturate(1.05) blur(10px);
    backdrop-filter: saturate(1.05) blur(10px);
  }
}
.site-header.is-scrolled {
  border-bottom-color: var(--rule-strong);
}
/* While the mobile menu is open, lift the header (and the hamburger→X close control inside it)
   ABOVE the opaque menu sheet (z 2000) so the only visible way out stays visible and clickable —
   nav.js also excludes the header from its inert sweep for the same reason. Opaque paper-raised
   to match the sheet, and no bottom rule, so the bar reads as the top of the sheet with the
   wordmark left and the X right. (Higher specificity than the plain/@supports .site-header
   backgrounds and .is-scrolled border, so it wins regardless of source order.) */
body.menu-open .site-header {
  z-index: 2001;
  background: var(--paper-raised);
  border-bottom-color: transparent;
}

.site-header__inner {
  max-width: var(--shell-max);
  margin-inline: auto;
  padding-inline: var(--side-pad);
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
}
/* Scrolled: the bar visually condenses by insetting its content — the box stays 64px, so the
   page below never moves (was: animating the header height, which shifted content ~8px). The
   4px inset is applied instantly, NOT transitioned: padding-block is a layout property, and the
   visual delta is too small to be worth animating a reflow-triggering property every scroll. */
.is-scrolled .site-header__inner { padding-block: 4px; }

.wordmark {
  font-family: var(--font-display);
  font-variation-settings: "wght" 460, "SOFT" 0, "WONK" 0;
  font-size: 1.25rem;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.wordmark:hover { color: var(--ink); }

.primary-nav { display: flex; align-items: center; gap: var(--s-5); }
.primary-nav__links { display: flex; align-items: center; gap: var(--s-5); }
.primary-nav__link {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--t-meta);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-2);
  text-decoration: none;
  padding-block: 4px;
  border-bottom: 1px solid transparent;
  transition: color var(--d-xs) var(--ease-settle),
              border-color var(--d-xs) var(--ease-settle);
}
.primary-nav__link:hover { color: var(--ink); border-bottom-color: var(--margin-rule); }

/* Running total mirrored into the header's right edge once scrolled. */
.header-total {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  color: var(--green);
  font-variant-numeric: tabular-nums lining-nums;
  opacity: 0;
  transform: translateY(-2px);
  transition: opacity var(--d-m) var(--ease-ledger),
              transform var(--d-m) var(--ease-ledger);
  white-space: nowrap;
}
.is-scrolled .header-total { opacity: 1; transform: none; }
@media (max-width: 720px) { .header-total { display: none; } }

/* 2px green scroll-progress rule along the header's bottom edge (scrubbed by JS). */
.header-progress {
  position: absolute;
  left: 0;
  bottom: -1px;
  height: 2px;
  width: 100%;
  transform-origin: left center;
  transform: scaleX(0);
  background: var(--green);
  opacity: 0;
  transition: opacity var(--d-m) var(--ease-ledger);
}
.is-scrolled .header-progress { opacity: 1; }

/* =========================================================================
   NAV TOGGLE + MOBILE MENU
   ========================================================================= */
.nav-toggle { display: none; }

@media (max-width: 860px) {
  .primary-nav__links, .primary-nav .ticket--sm { display: none; }
  .nav-toggle {
    display: inline-flex;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 44px;
    height: 44px;
    padding: 10px;
    background: transparent;
    border: 0;
    cursor: pointer;
  }
  .nav-toggle__bar {
    display: block;
    height: 1.5px;
    width: 100%;
    background: var(--ink);
    transition: transform var(--d-m) var(--ease-carriage),
                opacity var(--d-s) var(--ease-carriage);
  }
  .nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
  .nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) { opacity: 0; }
  .nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }
}

.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 2000;
  background: var(--paper-raised);
  padding: calc(var(--header-top) + 24px) var(--side-pad) 40px;
  display: flex;
  flex-direction: column;
  /* Clip-reveal: a paper sheet drawn down from the top. JS toggles [hidden]; the transform
     is animated in nav.js under full-motion, and simply shown under reduced-motion. */
  transform-origin: top center;
  overflow-y: auto;
}
.mobile-menu[hidden] { display: none; }
.mobile-menu__list { border-top: 1px solid var(--rule-strong); margin-bottom: auto; }
.mobile-menu__item {
  display: flex;
  align-items: baseline;
  gap: 16px;
  padding: 20px 0;
  border-bottom: 1px solid var(--rule);
  text-decoration: none;
}
.mobile-menu__num {
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  color: var(--oxblood);
  font-variant-numeric: tabular-nums lining-nums;
}
.mobile-menu__label {
  font-family: var(--font-display);
  font-variation-settings: "wght" 420, "SOFT" 0, "WONK" 0;
  font-size: 1.75rem;
  color: var(--ink);
}
.mobile-menu .ticket { margin-top: 32px; width: 100%; justify-content: center; }
.mobile-menu__email {
  margin-top: 24px;
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: 0.04em;
}

/* =========================================================================
   TICKET — the one button shape (never a pill)
   ========================================================================= */
.ticket {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 14px 26px;
  background: var(--green);
  color: var(--paper);
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 0.9375rem;
  letter-spacing: 0.04em;
  text-decoration: none;
  border: 0;
  border-radius: 0;
  cursor: pointer;
  box-shadow: inset 0 0 0 1px var(--green-deep);
  transition: background var(--d-xs) var(--ease-settle),
              transform var(--d-xs) var(--ease-settle);
}
.ticket__tick {
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--marker);
  line-height: 1;
}
.ticket:hover { background: var(--green-deep); transform: translateY(1px); color: var(--paper); }
.ticket:active { transform: translateY(1px) scale(0.98); box-shadow: inset 0 0 0 1px var(--green-deep), inset 0 2px 4px var(--ink-shadow); }
.ticket:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; box-shadow: inset 0 0 0 1px var(--green-deep), 0 0 0 6px var(--marker-swipe); }
.ticket--sm { padding: 9px 16px; font-size: 0.8125rem; gap: 8px; }

/* Microline that rides under a ticket. */
.microline {
  margin-top: 12px;
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.kicker {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--t-meta);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
/* A kicker followed by its section heading sets the standard 16px gap. */
.kicker + h2 { margin-top: var(--s-4); }
.panel .kicker { color: var(--panel-accent); }

/* =========================================================================
   MARKS — highlighter, rule-off, stamp, status, divider, perforation
   ========================================================================= */

/* Highlighter swipe: a marker smear that DRAWS left→right behind a token. isolate lets the
   ::before sit behind the text but above paper; text stays AA over the 42% wash. */
/* Draws by default (no-JS / reduced-motion see it applied). The undrawn scaleX(0) start is
   set only for .js + no-preference in motion.css, then GSAP animates it in. */
.hl { position: relative; isolation: isolate; }
.hl::before {
  content: "";
  position: absolute;
  left: -0.12em; right: -0.12em;
  top: 0.08em; bottom: 0.02em;
  z-index: -1;
  background: var(--marker-swipe);
  mix-blend-mode: multiply;
  transform-origin: left center;
  transform: scaleX(var(--draw, 1));
}

/* Rule-off: 1px rule, 3px gap, 2px rule — ONLY under a total. Drawn via scaleX. */
.rule-off {
  height: 6px;
  border-top: 1px solid var(--rule-strong);
  border-bottom: 2px solid var(--ink);
  transform-origin: left center;
}

/* Plain drawn rule (used by the strike / rule-off draws) */
.rule-draw { transform-origin: left center; }

/* Rubber stamp: oxblood double keyline, rotated −4°, slight ink spread, drops via Stamp. */
.stamp {
  display: inline-block;
  padding: 8px 16px;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--oxblood);
  border: 2px solid var(--oxblood);
  box-shadow: inset 0 0 0 1px var(--oxblood-deep);
  transform: rotate(-4deg);
  mix-blend-mode: multiply;
  opacity: 0.92;
  /* faint ink-spread */
  text-shadow: 0 0 0.4px var(--oxblood), 0.3px 0.2px 0.6px var(--stamp-ink);
  line-height: 1.1;
}
.stamp--lg { font-size: 1rem; padding: 10px 20px; letter-spacing: 0.16em; }

/* Tiny inline status stamp (green panel) */
.status {
  display: inline-block;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--oxblood);
  border: 1.5px solid var(--oxblood);
  padding: 3px 8px;
  transform: rotate(-3deg);
}
.on-green .status { color: var(--panel-accent); border-color: var(--panel-accent); }

.blink { display: inline-block; }
.blink::after {
  content: "▮";
  margin-left: 2px;
  animation: caret-blink 1.05s steps(1, end) infinite;
}

/* Receipt perforation with punched notch circles */
.perforation {
  position: relative;
  height: 20px;
  border-top: 2px dashed var(--rule-strong);
  margin-top: 8px;
}
.perforation::before, .perforation::after {
  content: "";
  position: absolute;
  top: -11px;
  width: 20px; height: 20px;
  border-radius: 50%;
  background: var(--paper);
  box-shadow: inset 0 0 0 1px var(--rule-strong);
}
.perforation::before { left: -10px; }
.perforation::after { right: -10px; }

/* =========================================================================
   RUNNING TOTAL — the signature figure
   ========================================================================= */
.running-total { position: relative; }
.running-total__label,
.running-total__caption {
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.running-total__figure {
  display: block;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: var(--t-total);
  line-height: 0.95;
  letter-spacing: -0.01em;
  color: var(--green);
  font-variant-numeric: tabular-nums lining-nums;
  margin-block: 8px 4px;
}
.running-total__unit {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--ink-3);
  letter-spacing: 0.06em;
  vertical-align: baseline;
}
.running-total__caption { text-transform: none; letter-spacing: 0.02em; color: var(--ink-3); }

/* Tooltip on the total (worked examples — not a quote) */
.tooltip { position: relative; }
.tooltip__bubble {
  position: absolute;
  left: 0;
  top: calc(100% + 8px);
  max-width: 240px;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.03em;
  padding: 8px 10px;
  opacity: 0;
  pointer-events: none;
  transform: translateY(-2px);
  transition: opacity var(--d-s) var(--ease-settle), transform var(--d-s) var(--ease-settle);
  z-index: 20;
}
.tooltip:hover .tooltip__bubble,
.tooltip:focus-within .tooltip__bubble { opacity: 1; transform: none; }

/* Permanent honesty caption */
.caption-honesty {
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: 0.02em;
  color: var(--ink-3);
  border-left: 2px solid var(--margin-rule);
  padding-left: 12px;
}

/* =========================================================================
   WORKED EXAMPLE INSET — ITEM / WORKING / RESULT
   ========================================================================= */
.working {
  background: var(--paper-sunk);
  padding: var(--s-4) var(--s-5);
  margin-top: var(--s-4);
  box-shadow: inset 0 0 0 1px var(--rule-ink);
}
.working__head {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px 16px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--rule-strong);
}
.working__col {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.working__col--fig { text-align: right; }

.eq {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35em;
  padding-top: 12px;
  font-family: var(--font-mono);
  font-size: var(--t-figure);
  color: var(--ink-2);
  font-variant-numeric: tabular-nums lining-nums;
}
/* Each factor rides in a clip mask so it can slide up from behind the rule. */
.eq__mask { display: inline-flex; overflow: hidden; }
.eq__term { display: inline-block; color: var(--ink); }
.eq__op { color: var(--ink-3); }
.eq__result {
  margin-left: auto;
  font-weight: 600;
  color: var(--ink);
  padding-left: 1em;
}

/* the ×12 conversion aside */
.eq-aside {
  margin-top: 10px;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums lining-nums;
}
.eq-aside .figure { color: var(--ink-2); }

/* =========================================================================
   LEDGER ROW (problems / work entries)
   ========================================================================= */
.ledger-row { padding-block: var(--s-6) var(--s-6); border-top: 1px solid var(--rule); }
.ledger-row:first-of-type { border-top: 0; }
.ledger-row__code {
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: 0.08em;
  color: var(--oxblood);
  font-variant-numeric: tabular-nums lining-nums;
}
.ledger-row__title {
  margin-top: 6px;
  font-family: var(--font-display);
  font-variation-settings: "wght" 460, "SOFT" 0, "WONK" 0;
  font-size: var(--t-h3);
  line-height: 1.12;
  color: var(--ink);
}
.ledger-row__body { margin-top: 10px; color: var(--ink-2); max-width: 60ch; }
.ledger-row__body em { color: var(--ink); }

/* Debit (failure / cost) row — oxblood strikethrough that pointedly does NOT total. */
.debit-row {
  margin-top: var(--s-5);
  padding: 14px 16px;
  background: var(--paper-sunk);
  box-shadow: inset 0 0 0 1px var(--debit-keyline);
  color: var(--oxblood-deep);
  font-family: var(--font-serif);
  font-size: 1rem;
}
.debit-row .strike { position: relative; }
.debit-row__strike-rule { position: absolute; left: 0; right: 0; top: 52%; height: 2px; background: var(--oxblood); }
.debit-row__tag {
  display: inline-block;
  margin-right: 10px;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--oxblood);
}
.debit-row__no-add {
  display: inline-block;
  margin-left: 8px;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  color: var(--oxblood);
  border: 1px solid var(--debit-keyline-strong);
  padding: 1px 6px;
}

/* =========================================================================
   METHOD — three postings
   ========================================================================= */
.postings { margin-top: var(--s-6); }
.posting {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0 28px;
  padding-block: var(--s-6);
  border-top: 1px solid var(--rule);
  position: relative;
}
.posting:first-child { border-top: 0; }
.posting__mark { display: flex; flex-direction: column; align-items: center; }
.posting__num {
  font-family: var(--font-display);
  font-variation-settings: "wght" 340, "SOFT" 0, "WONK" 0;
  font-size: clamp(2.5rem, 1.4rem + 4vw, 4rem);
  line-height: 0.9;
  color: var(--oxblood);
  font-feature-settings: "tnum" 1, "lnum" 1;
}
/* hairline connector drawn between postings */
.posting__connector {
  width: 1px;
  height: 34px;
  margin-top: 12px;
  background: var(--rule-strong);
}
.posting__title {
  font-family: var(--font-display);
  font-variation-settings: "wght" 460, "SOFT" 0, "WONK" 0;
  font-size: var(--t-h3);
  color: var(--ink);
}
.posting__body { margin-top: 8px; color: var(--ink-2); max-width: 56ch; }
/* debit/credit two-liner on the audit posting */
.dc {
  margin-top: 14px;
  font-family: var(--font-mono);
  font-size: var(--t-figure);
  font-variant-numeric: tabular-nums lining-nums;
  display: grid;
  gap: 3px;
  max-width: 340px;
}
.dc__line { display: flex; justify-content: space-between; gap: 16px; }
.dc__debit { color: var(--ink); }
.dc__credit { color: var(--oxblood); }
.dc__net { color: var(--green); border-top: 1px solid var(--rule-strong); padding-top: 4px; }

/* =========================================================================
   RATE CARD — one itemised table (native <details> rows for the accordion)
   ========================================================================= */
.rate-card { margin-top: var(--s-6); }
.rate-card__head {
  display: grid;
  grid-template-columns: 1.1fr 1.3fr auto;
  gap: 16px;
  padding: 0 16px 10px;
  border-bottom: 1px solid var(--rule-strong);
}
.rate-card__col {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.rate-card__col--fee { text-align: right; }
.rate-card__row { border-bottom: 1px solid var(--rule); }
.rate-card__summary {
  display: grid;
  grid-template-columns: 1.1fr 1.3fr auto;
  gap: 16px;
  align-items: baseline;
  padding: 18px 16px;
  cursor: pointer;
  list-style: none;
}
.rate-card__summary:hover .rate-card__service { color: var(--green-deep); }
.rate-card__summary::-webkit-details-marker { display: none; }
.rate-card__service {
  font-family: var(--font-display);
  font-variation-settings: "wght" 460, "SOFT" 0, "WONK" 0;
  font-size: 1.125rem;
  color: var(--ink);
  position: relative;
}
.rate-card__who { color: var(--ink-2); font-size: 1rem; }
.rate-card__fee {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: var(--t-figure);
  text-align: right;
  color: var(--ink);
  font-variant-numeric: tabular-nums lining-nums;
  white-space: nowrap;
}
.rate-card__fee small { display: block; font-weight: 400; color: var(--ink-3); font-size: 0.75rem; margin-top: 3px; }
.rate-card__detail {
  padding: 0 16px 18px;
  color: var(--ink-2);
  max-width: 64ch;
}
.rate-card__detail .walk-away {
  margin-top: 8px;
  font-style: italic;
  color: var(--ink-2);
}
.rate-card__expand {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  color: var(--green);
  text-transform: uppercase;
}
details[open] .rate-card__expand .more { display: none; }
details:not([open]) .rate-card__expand .less { display: none; }

/* Ease the disclosure open (~200ms on the settle curve) via the grid-template-rows 0fr→1fr
   technique, keeping native <details> semantics. An ANIMATION (not a transition) is used
   because native details reveals the content from display:none, which a transition can't
   catch; the animation replays each time a row opens. Instant under reduced motion. */
.rate-card__row { display: grid; grid-template-rows: auto 1fr; }
.rate-card__detail { overflow: hidden; min-height: 0; }
@media (prefers-reduced-motion: no-preference) {
  .rate-card__row[open] { animation: rate-card-open var(--d-s) var(--ease-settle); }
}
@keyframes rate-card-open {
  from { grid-template-rows: auto 0fr; }
  to   { grid-template-rows: auto 1fr; }
}

/* ---- Mobile (<=640px): the 3-column table (Service / Who it's for / Fee) collapses to
   stacked rows. Root cause of the pre-fix overflow: .rate-card__head/__summary shared a
   `1.1fr 1.3fr auto` grid with NO breakpoint at all, and the `auto` fee column combined with
   .rate-card__fee's white-space:nowrap (inherited by its <small>) forced that column to the
   fee text's full unwrapped max-content width (up to ~346px for the longest "· credited to a
   build within 30 days" string alone) — so the row could never shrink under ~500px. Here the
   head row (already aria-hidden, purely decorative) is dropped since one column needs no
   labels; the summary grid becomes a single column so service name and its "who" line each
   take the full row width; the fee (already text-align:right from the desktop column) drops
   nowrap so its longer notes wrap onto their own right-aligned line instead of pushing the
   row wider than the viewport. Accordion (<details>) and hairline rules are untouched. ---- */
@media (max-width: 640px) {
  .rate-card__head { display: none; }
  .rate-card__summary {
    grid-template-columns: 1fr;
    align-items: start;
    gap: var(--s-2);
  }
  .rate-card__fee { white-space: normal; }
}

/* hand-drawn oxblood annotation circle + "most start here" note on the build row */
.annotate { position: relative; }
.annotate__ring {
  position: absolute;
  inset: -6px -10px;
  pointer-events: none;
  overflow: visible;
}
.annotate__ring path { fill: none; stroke: var(--oxblood); stroke-width: 1.5; stroke-linecap: round; }
.annotate__note {
  display: inline-block;
  margin-left: 10px;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 0.9rem;
  color: var(--oxblood);
}

/* ChatGPT objection — oxblood-bracketed margin annotation */
.objection {
  margin-top: var(--s-7);
  padding: var(--s-5) var(--s-6);
  border-left: 3px solid var(--oxblood);
  background: var(--paper-raised);
}
.objection__q {
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--t-h3);
  color: var(--ink);
}
.objection__body { margin-top: 12px; font-style: italic; color: var(--ink-2); max-width: 68ch; }

/* =========================================================================
   PROOF PANEL — the one deep-accent (green) section
   ========================================================================= */
.panel { background: var(--green-panel); color: var(--paper-on-green); }
.panel { --margin-rule: color-mix(in srgb, var(--paper) 28%, transparent); --rule: color-mix(in srgb, var(--paper) 18%, transparent); --rule-strong: color-mix(in srgb, var(--paper) 32%, transparent); }
.panel .ledger__num { color: var(--panel-accent); }
.panel h2, .panel h3 { color: var(--paper-on-green); }
.panel .prose p, .panel .proof-entry__body { color: color-mix(in srgb, var(--paper) 90%, transparent); }
.pull-quote {
  font-family: var(--font-display);
  font-style: italic;
  font-variation-settings: "wght" 420;
  font-size: var(--t-h2);
  line-height: 1.14;
  color: var(--paper-on-green);
  max-width: 20ch;
  position: relative;
}
.pull-quote__underline {
  display: block;
  height: 2px;
  width: 100%;
  max-width: 320px;
  margin-top: 14px;
  background: var(--marker);
  transform-origin: left center;
}
.pull-quote { margin-top: var(--s-6); }
.proof-entry { padding-block: var(--s-5); border-top: 1px solid color-mix(in srgb, var(--paper) 18%, transparent); }
.proof-entry:first-of-type { border-top: 0; }
.proof-entry--lead { margin-top: var(--s-7); }
.proof-link { margin-top: var(--s-4); }
.proof-entry__body { max-width: 58ch; }
.proof-entry__status { margin-top: 12px; display: flex; align-items: center; gap: 12px; }
.proof-honesty {
  margin-top: var(--s-6);
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: 0.06em;
  color: color-mix(in srgb, var(--paper) 72%, transparent);
}
.panel a { color: var(--marker); text-decoration-color: color-mix(in srgb, var(--marker) 50%, transparent); }
.panel a:hover { color: var(--panel-gold); }

/* =========================================================================
   ABOUT — signed note
   ========================================================================= */
.signed-note .prose { max-width: 60ch; margin-top: var(--s-5); }
.place { position: relative; isolation: isolate; }
.place::before {
  content: "";
  position: absolute;
  left: -0.1em; right: -0.1em; top: 0.15em; bottom: 0.05em;
  z-index: -1;
  background: var(--marker-swipe);
  mix-blend-mode: multiply;
  transform-origin: left center;
  transform: scaleX(var(--draw, 1));
}
.signature {
  display: inline-block;
  margin-top: var(--s-5);
  font-family: var(--font-display);
  font-style: italic;
  font-variation-settings: "wght" 400, "SOFT" 4, "WONK" 1;
  font-size: clamp(1.8rem, 1.3rem + 2vw, 2.6rem);
  color: var(--ink);
}

/* =========================================================================
   FOOTER — closing balance
   ========================================================================= */
.site-footer { background: var(--paper-sunk); }
.site-footer__inner { padding-block: var(--s-8) var(--s-6); }
.footer-rows {
  margin-top: var(--s-6);
  display: grid;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  letter-spacing: 0.06em;
  color: var(--ink-2);
}
.footer-rows a { color: var(--green); }
.footer-balance {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: var(--s-4);
  color: var(--ink);
}
.footer-tick { color: var(--green); font-weight: 700; }
.footer-final-rule { height: 1px; background: var(--ink); margin-top: var(--s-4); }

/* =========================================================================
   PROGRESS — mobile top hairline (rail replacement ≤640px)
   ========================================================================= */
.mobile-progress {
  position: fixed;
  top: 0; left: 0;
  height: 2px; width: 100%;
  transform: scaleX(0);
  transform-origin: left center;
  background: var(--oxblood);
  z-index: 1500;
  display: none;
}
@media (max-width: 640px) { .mobile-progress { display: block; } }

/* =========================================================================
   SHARED PAGE FRAGMENTS — used across more than one page, so they live here
   (intro copy, the numbered book list, the centred CTA close)
   ========================================================================= */
.problems__intro { margin-top: var(--s-4); color: var(--ink-2); max-width: 60ch; }

.book-list { margin: var(--s-6) 0 0; padding: 0; list-style: none; display: grid; gap: 0; max-width: 60ch; }
.book-list__item {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 16px;
  padding: 16px 0;
  border-top: 1px solid var(--rule);
  text-decoration: none;
}
/* .book-list__item sits directly on the <li> (book page) or on an <a> wrapped in an
   unclassed <li> (404 page, where <a> can't be a direct <ol> child) — cover both so only
   the true first row loses its top rule. */
.book-list__item:first-child,
.book-list > li:first-child .book-list__item { border-top: 0; }
.book-list__n {
  font-family: var(--font-mono);
  font-size: var(--t-meta);
  color: var(--oxblood);
  font-variant-numeric: tabular-nums lining-nums;
}
.book-list__t { color: var(--ink-2); }
a.book-list__item:hover .book-list__t { color: var(--green-deep); }

/* Centred CTA close — the ONE place centring is allowed */
/* This section's ledger spans the full shell (rail through gutter): centred within the
   offset body track the close landed left of viewport centre. The rail number keeps its
   place absolutely in the margin strip, and the oxblood spine continues uninterrupted. */
.section--cta .ledger { grid-template-columns: [body] minmax(0, 1fr); }
.section--cta .ledger__rail { position: absolute; left: 0; top: 0; width: var(--rail-w); }
.section--cta .ledger__gutter { display: none; }
.cta-close { text-align: center; }
.cta-close .rule-off { max-width: 220px; margin: 0 auto var(--s-6); }
.cta-close__h2 { margin-inline: auto; max-width: 20ch; }
.cta-close__sub {
  margin: var(--s-5) auto 0;
  max-width: 46ch;
  font-family: var(--font-serif);
  font-size: var(--t-lead);
  color: var(--ink-2);
}
/* B1 — the running-total figure and the ticket are both atomic inline-level boxes (inline-block
   / inline-flex), so at desktop widths they had room to sit on the SAME line box inside this
   text-align:center container — centring the pair as a group instead of each on its own line
   (the $19,900 landing left-of-centre with the ticket beside it). Block + shrink-to-fit width +
   auto inline margins puts the figure on its own line, centred on its own box; the ticket (still
   inline-flex, still centred by the inherited text-align) then starts a fresh line beneath it. */
.cta-close__cta { margin-top: var(--s-6); display: inline-flex; flex-direction: column; align-items: center; }
.cta-close .running-total { display: block; width: max-content; margin: var(--s-6) auto 0; }
.cta-close .running-total__figure { color: var(--green); }
.cta-close__stamp { margin-top: var(--s-6); }

/* =========================================================================
   404 — unbalanced entry
   ========================================================================= */
.error-title {
  font-family: var(--font-display);
  font-variation-settings: "wght" 400, "SOFT" 0, "WONK" 0;
  font-size: var(--t-h2);
  line-height: 1.06;
  letter-spacing: -0.012em;
  color: var(--oxblood-deep);
  margin-top: var(--s-4);
}
/* Strike the title per line-box with a real line-through, so a two-line wrap gets a rule
   THROUGH each line — not one absolute bar floating in the gap between them (the old
   .debit-row__strike-rule mechanism, which only works on a single-line row). No-JS and
   reduced-motion render this struck final state; full motion wipes the whole struck line in
   left-to-right (see [data-strike] in motion.css / motion.js) — never a re-added absolute bar. */
.error-title .strike-line {
  text-decoration-line: line-through;
  text-decoration-color: var(--oxblood);
  text-decoration-thickness: 2px;
}
.error-links { margin-top: var(--s-6); }
.error-cta { margin-top: var(--s-7); }

@keyframes caret-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
