/* Forget The Forms — marketing site.

   PALETTE: "Clay & Rust", Ethan's choice, 2026-08-25. Replaces the previous petrol/ochre pair
   that was itself lifted from `dashboard.py`. He built `index.html` by hand in a warm paper-and-
   gold direction and then gave this exact palette to be ported to the other eleven pages and
   both stylesheets, verbatim:
     accent  #b0501e burnt rust    (brand / primary / "needs you" -- ONE family now, not two)
     ok      #1f7a4d green         (proven / matched, unchanged -- not part of the given palette)
   The app (`dashboard.py`) was recoloured to match on 2026-08-26 (session-180) -- both now share
   this palette (dashboard.py's --accent/--surface are the same hex as this file's). Keep them in
   sync going forward: a future palette change here needs the same change there. The shared-mark
   rule still applies everywhere the brand mark is drawn: a context must set BOTH `color` and the
   check's own stroke colour, or a bright slash renders on a dark band.
   Self-contained: no webfonts, no CDN, no external asset of any kind. */

:root {
  --accent:       #b0501e;
  /* The rust it is safe to set small TEXT in. --accent itself is the MARK colour -- borders,
     icons, large display type, badges on a card -- where the 3:1 (or, on a raised --surface
     card, the 4.5:1-but-passing) floor applies; measured 4.29:1 on --paper and 3.78:1 on
     --surface-2, both UNDER the 4.5:1 small-text floor. --accent-strong is the same family,
     darker, measured 6.24:1 on --paper and 7.11:1 on --surface -- safe everywhere. Same shape as
     the ochre split this replaces (see the old --warn/--warn-text comment this one replaces). */
  --accent-strong:#8a3d15;
  --ok:           #1f7a4d;
  /* --warn/--warn-text now SHARE --accent/--accent-strong's values rather than a second hue --
     that is Ethan's own homepage design (the "needs you" badge and the ordinary accent link are
     literally the same colour there), not a change made here. Kept as separate custom
     properties so call sites don't need editing, and so a future session CAN split them again
     without hunting every reference. */
  --warn:         #b0501e;
  --warn-text:    #8a3d15;

  --paper:        #f1e7dd;
  --surface:      #fdf6f0;
  --surface-2:    #e7d9cb;
  --ink:          #2e1f18;
  --ink-soft:     #5b483c;
  --muted:        #7d6558;
  --line:         #dcc7b3;
  --line-strong:  #b6a291;
  --on-accent:    #ffffff;

  /* ---------- type scale ----------
     ONE ladder, seven steps, and every `font-size` in this sheet and in styles-home.css is one
     of them. Before 2026-08-20 there were THIRTY distinct sizes across the two files -- twenty
     of them crammed between 0.60rem and 1.00rem, in steps of 1-3%. A 1-3% step is below the
     size difference a reader can actually see, so nothing on the page led anything else: the
     footer, the nav, a card's body copy, a caption and a legal line were all "about the same
     size" and the eye had nothing to sort them by. That flatness, not the typeface, is the
     measurable half of why the site read as machine-made.

     Every step below is at least 8% above the one under it, which is roughly where a size
     difference stops being noise and starts being hierarchy. Guarded by
     tests/test_site_type_scale.py: a raw `font-size: 0.94rem` added anywhere in either sheet
     fails there, and so does a new token that lands inside an existing gap.

     `--fs-body` is the only fluid one, and it is the READING size -- prose grows with the
     viewport, furniture does not. A `clamp()` may still be used directly for display type
     (h1/h2 and the two ledes), but its MAXIMUM may never fall below --fs-base, so a small
     stray cannot be smuggled in wearing a clamp. */
  --fs-micro:  0.7rem;    /* tracked-caps mono labels, breadcrumbs, tags          */
  --fs-fine:   0.78rem;   /* fine print, counters, the mono field labels         */
  --fs-ui:     0.88rem;   /* nav, buttons, captions, card body, footer           */
  --fs-base:   1rem;      /* the fixed base step                                  */
  --fs-title:  1.15rem;   /* card and list titles, the wordmark                   */
  --fs-title2: 1.35rem;   /* the larger card titles and the founder's note        */
  --fs-price:  2.6rem;    /* the price -- the one display size that is not fluid   */
  --fs-body:   clamp(1rem, 0.4vw + 0.92rem, 1.09rem);   /* reading size          */

  --serif: "Palatino Linotype", "Book Antiqua", Palatino, "Iowan Old Style", Georgia, serif;
  --sans:  "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --mono:  "Cascadia Code", Consolas, ui-monospace, monospace;

  /* SQUARED 2026-09-03 (session-266a): the diagnosed cause of "AI slop" was one radius token
     doing ten different jobs (WEBSITE_DESIGN_BRIEF.md item 3) -- the homepage carries none at
     all. Kept as tokens rather than deleted, so a future session can find every consumer by
     searching var(--r)/var(--r-sm) instead of hunting literals again. */
  --r: 0;
  --r-sm: 0;
  --shadow: 0 1px 2px rgba(20,22,28,.05), 0 10px 26px -14px rgba(20,22,28,.30);

  --measure: 33rem;
  --gutter: clamp(1.25rem, 5vw, 4rem);
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper:       #1a120c;
    --surface:     #241a13;
    --surface-2:   #2c2119;
    --ink:         #ece4da;
    --ink-soft:    #c9bcae;
    --muted:       #9c8f82;
    --line:        #3a2c22;
    --line-strong: #4a3a2c;
    /* Derived, not given -- Ethan's palette is nine light-mode values with no dark pair. Same
       family as --accent, lightened toward white until it clears 4.5:1 on --paper (measured
       7.71:1) and --surface (7.10:1); the dark-mode --on-accent below is measured against it,
       not carried over from the petrol pair it replaces. */
    --accent:      #d99a63;
    --accent-strong:#e6b083;
    --ok:          #4fbb84;
    --warn:        #d99a63;
    --warn-text:   #d99a63;   /* already safe here; the mark/text split only matters in light mode */
    --on-accent:   #241a13;
    --shadow: 0 1px 2px rgba(0,0,0,.3), 0 10px 26px -14px rgba(0,0,0,.6);
  }
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--fs-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; }
::selection { background: color-mix(in srgb, var(--accent) 22%, var(--surface)); }

.wrap { max-width: 60rem; margin: 0 auto; padding-inline: var(--gutter); }
/* INSET 2026-09-03 (session-266a): this used to run genuinely edge to edge on every inner page
   (measured: the hairline colour sat within 6px of both viewport edges on a 1280px screen) --
   the second device the owner's own diagnosis named alongside the radius (WEBSITE_DESIGN_BRIEF.md
   item 8). index.html never lets a divider leave its 1180px `.sheet`. `.rule` is only ever used
   on the eleven `body.inner` pages (index.html hand-styles its own inset hairlines instead), so
   --wide/--hgut always resolve to `body.inner`'s pair (styles-home.css:235-236, 1180px/52px) --
   calc() reproduces the exact width `.wrap`'s own CONTENT sits at (wide minus both gutters),
   because padding cannot narrow a border-top LINE the way it narrows content: a border draws at
   the outer edge of the padding box, so only margin moves it. */
.rule { border: 0; border-top: 1px solid var(--line); margin-block: 0; max-width: calc(var(--wide) - 2 * var(--hgut)); margin-inline: auto; }
section { padding-block: clamp(2.75rem, 6vw, 4.75rem); }

/* ---------- masthead ---------- */

.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1.15rem;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}

.brand { display: flex; align-items: center; gap: 0.5rem; text-decoration: none; color: var(--ink); }
/* THE BRAND MARK is a drawn SVG since 2026-08-21, not the typed diamond it replaced. The
   BOX is `currentColor`, so one `color:` line recolours the whole mark per band exactly as
   the glyph did; the CHECK is knocked through in the colour of whatever band it sits on, so
   every context must set BOTH -- a band that sets only `color` gets a check in the default
   surface colour, which on a dark band is a bright slash. .mast2 and .hfoot in
   styles-home.css are the two that matter today; this pair is the fallback. Sized in rem
   rather than em because it is no longer a glyph and has no font-size to inherit from. */
.brand-mark { color: var(--accent); width: 1.2rem; height: 1.2rem; flex: none; display: block; }
.brand-mark .tick { stroke: var(--surface); }
.brand-name {
  font-family: var(--serif);
  font-size: var(--fs-title);
  font-weight: 600;
  letter-spacing: -0.01em;
}
.brand-name .thin { color: var(--muted); font-weight: 400; }

.masthead nav { display: flex; gap: 1.4rem; font-size: var(--fs-ui); }
.masthead nav a {
  text-decoration: none;
  color: var(--ink-soft);
  padding-bottom: 2px;
  border-bottom: 1.5px solid transparent;
  /* No colour transition here either, for the reason spelled out in full on `.btn` below: a
     transition toward a value that a media query just changed never completes and pins the old
     scheme's colour. Found 2026-08-10 by the forced-fail run of the test written for `.btn` --
     the nav had the same defect and nobody had looked. Nav links have nothing scheme-independent
     worth animating, so they simply snap, which is what nav links normally do. */
}
.masthead nav a:hover, .masthead nav a[aria-current] { color: var(--ink); border-color: var(--accent); }

/* ---------- hero ---------- */

.hero { padding-block: clamp(3rem, 8vw, 5.5rem) clamp(2.25rem, 5vw, 3.5rem); }

h1 {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(2.3rem, 6vw, 4rem);
  line-height: 1.06;
  letter-spacing: -0.022em;
  margin: 0 0 1.15rem;
  max-width: 15ch;
  text-wrap: balance;
}
h1 em { font-style: normal; color: var(--accent); }

.standfirst {
  font-size: clamp(1.06rem, 0.8vw + 0.92rem, 1.25rem);
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: var(--measure);
  margin: 0 0 2rem;
  text-wrap: pretty;
}

h2 {
  font-family: var(--serif);
  font-weight: 600;
  font-size: clamp(1.6rem, 2.6vw, 2.2rem);
  line-height: 1.14;
  letter-spacing: -0.016em;
  margin: 0 0 1.4rem;
  max-width: 20ch;
  text-wrap: balance;
}

.lede { color: var(--ink-soft); max-width: var(--measure); margin: 0 0 1.6rem; }

/* ---------- numbered points ---------- */

.points { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; }
.points li {
  display: grid;
  gap: 0.15rem 1.5rem;
  padding-block: 1.25rem;
  border-top: 1px solid var(--line);
  align-items: baseline;
}
@media (min-width: 46rem) {
  .points li { grid-template-columns: 2.5rem minmax(0, 17ch) minmax(0, 1fr); }
}
/* --accent-strong, not --accent: this sits directly on --paper (claim-check.html's ".wrap", no
   card underneath), and --accent measures 4.29:1 there -- under the 4.5:1 floor for text this
   size. Measured with the browser-rendered contrast walk, same trap as --warn on --paper below. */
.points .n { font-family: var(--mono); font-size: var(--fs-fine); color: var(--accent-strong); }
.points .h {
  font-family: var(--serif);
  font-size: var(--fs-title);
  font-weight: 600;
  letter-spacing: -0.01em;
}
.points .d { color: var(--ink-soft); margin: 0; }

/* ---------- fine print (pricing) ----------
   Deliberately NOT `.points`. That numbered 01/02/03 component sitting identically on both pages
   was one of the things that made the site read as machine-made, and numbering only earns its
   place where the items are a sequence. "How it works" is a sequence; three unrelated billing
   facts are not. Keep these two components apart. */

.terms { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.4rem; max-width: 42rem; }
.terms li { position: relative; padding-left: 1.4rem; }
.terms li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.66em;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 0;
  background: var(--accent);
  opacity: 0.5;
}
.terms .h {
  display: block;
  font-family: var(--serif);
  font-size: var(--fs-title);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 0.15rem;
}
.terms .d { color: var(--ink-soft); margin: 0; }

/* ---------- ledger variant of .terms (nursing-license-questions.html,
   finra-license-questions.html ONLY) ----------
   ADDED 2026-09-03 (session-266a). These two explainers are lists, so they lead with the site's
   ledger device -- mono tag, serif label, hairline between rows, the same vocabulary as
   index.html's own "answer file" table (index.html:292-317) -- instead of the bulleted
   prose-then-box shape. Scoped to `.terms.ledger` so pricing.html's fine-print `.terms` (still a
   plain bulleted list, per the brief's own "keep .terms intact" instruction there) is untouched.
   Contrast unchanged from the base rules it borrows from: .tag is --accent-strong on --paper,
   6.24:1 (same pairing as `.points .n`); .h/.d keep the base rule's colours. */
.terms.ledger { gap: 0; max-width: none; }
.terms.ledger li {
  position: static;
  padding: 0;
  padding-block: 1.1rem;
  border-top: 1px solid var(--line);
  display: grid;
  grid-template-columns: 2.75rem 1fr;
  column-gap: 1rem;
}
.terms.ledger li::before { content: none; }
.terms.ledger .tag {
  grid-column: 1;
  grid-row: 1 / 3;
  font-family: var(--mono);
  font-size: var(--fs-fine);
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--accent-strong);
  padding-top: 0.2em;
}
.terms.ledger .h { grid-column: 2; margin-bottom: 0.15rem; }
.terms.ledger .d { grid-column: 2; }

/* ---------- plain feature list ---------- */

.does { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.72rem; max-width: 42rem; }
.does li {
  display: grid;
  grid-template-columns: 1.3rem 1fr;
  gap: 0.7rem;
  align-items: baseline;
  color: var(--ink-soft);
}
.does li::before {
  content: "\2713";
  color: var(--ok);
  font-size: var(--fs-ui);
}
.does b { color: var(--ink); font-weight: 600; }

/* ---------- pricing ---------- */

.tiers { display: grid; gap: 0.9rem; margin-block: 1.75rem; }
@media (min-width: 48rem) { .tiers { grid-template-columns: repeat(3, 1fr); } }

/* RECOLOURED 2026-09-03 (session-268, finishing session-266a's C.6) to the homepage's own pricing
   cards, index.html:368 (non-featured) and :399 (featured). These three cards sit INSIDE
   `<section class="band band--petrol hero3">`, a FIXED dark field: `--band` #2e1f18 has no
   dark-scheme override anywhere (styles-home.css carries no prefers-color-scheme block at all),
   so nothing that flips may paint on it. Until today they were pale `--surface` cards with
   `--ink` text -- the one component on the site that did not match the page it was copied from.
   EVERY colour below is a LITERAL. `--surface`/`--ink`/`--ink-soft`/`--accent`/`--line` all flip
   in this sheet's dark block; put one back here and light mode paints, e.g., --ink #2e1f18 on
   #3b2419 = 1.10:1 while dark mode looks fine (WEBSITE_DESIGN_BRIEF.md section 6 item 2, the
   same trap `.band--sand.hero3` records). A card that paints its own background owns the text
   colour on it, which is why `.tier` sets `color`: `.tier .price` sets none of its own and
   inherits (before 2026-08-20 it inherited the band's cream onto a pale card at 1.11:1).
   Measured with tests/test_site_contrast.py's own contrast_ratio(); one number covers both
   schemes because neither side flips:
     #f1e7dd  (price, inherited from .tier)          on #3b2419  11.85:1
     rgba(241,231,221,.8) -> #cdc0b6  (.n)            on #3b2419   8.13:1  (index.html:382's own)
     #d09678  (.per, the dark-field accent, --gold)   on #3b2419   5.73:1  (--accent is 2.76:1)
     #fdf6f0  (.n, price, .per on the featured card)  on #b0501e   4.89:1  (index.html:402-408's
              own fix: the most headroom this accent allows; #f1e7dd is 4.29:1, under the floor)
   Nothing accent-coloured can sit on the featured card's own accent fill (#d09678 on #b0501e
   is 2.07:1), so it takes the homepage's answer and sets all three lines to #fdf6f0. The
   homepage's featured card carries no shadow, so `--shadow` (a flipping token) is gone too. */
.tier {
  background: #3b2419;
  color: #f1e7dd;
  border: 1px solid rgba(241,231,221,.16);
  border-radius: var(--r);
  padding: 1.4rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.tier.feature { background: #b0501e; color: #fdf6f0; border-color: #d09678; }
.tier .n { font-size: var(--fs-ui); color: rgba(241,231,221,.8); }
.tier.feature .n { color: #fdf6f0; }
.tier .price {
  font-family: var(--serif);
  font-size: var(--fs-price);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.03em;
}
/* The $ sits on the baseline like the homepage's own price lines (index.html:380 etc. write the
   figure as plain text, no <sup> at all) rather than raised -- markup stays `<sup>$</sup>9`
   because `tests/test_credit_packs.py:54-55` regexes that exact adjacency, so only the styling
   of the existing tag changes. */
.tier .price sup { font-size: 1em; vertical-align: baseline; }
.tier .per { font-family: var(--mono); font-size: var(--fs-fine); color: #d09678; }
.tier.feature .per { color: #fdf6f0; }
/* `.tier .what` (the "a day or two of applying" / "about a week of it" line under each pack)
   was REMOVED 2026-08-18 (session 116, 5th pass) -- Ethan showed the cards to someone who read
   the timing language as a subscription period, exactly the thing the page's own copy insists
   is not true ("You buy applications, not months"). Real user confusion, acted on directly; the
   rule stays gone rather than reworded, since the underlying problem is that ANY time-shaped
   phrase next to a price reads as a billing period. If a "how far this goes" hint is wanted
   again, it needs a shape that cannot be misread as a renewal window. */

/* The "it never submits" line, directly under the price cards on pricing.html. Deliberately NOT
   a card: session 165's finding was that one rounded rectangle was doing ten jobs, so this is a
   plain line on the band. It sits inside `.band--petrol hero3` (#0b3a58 in BOTH schemes -- none
   of --band/--cream/--gold is redefined in the dark block), so one measurement covers both:
   the .82 cream resolves to #cad0d0 = 7.64:1, the solid --cream lead-in = 10.58:1. Sets no
   font-size, so it inherits --fs-body and cannot add a step to the seven-step scale. */
.nosubmit {
  color: rgba(241,231,221,.82);
  max-width: var(--measure);
  margin-block: 0 1.75rem;
}
.nosubmit b { color: var(--cream); font-weight: 600; }

.freebar {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 1.1rem 1.4rem;
  color: var(--ink-soft);
}
.freebar b { color: var(--ink); }

/* the "needs you" colour, used only where the app uses it */
.flagline {
  border-left: 3px solid var(--warn);
  background: var(--surface-2);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  padding: 0.85rem 1.1rem;
  margin: 1.5rem 0;
  color: var(--ink-soft);
  max-width: 42rem;
}
.flagline b { color: var(--ink); }

/* ---------- prose + flagline margin note (seven explainers) ----------
   ADDED 2026-09-03 (session-266a), EXTENDED 2026-09-03 (session-266d). `.prose` caps at 42rem
   inside a 1180px `body.inner` page, leaving roughly 586px of empty paper to its right at 1440px
   (measured, CONTINUE_HERE_WEBSITE.md 2026-08-27). Below 1100px `.note-grid` does nothing, so the
   flagline stays exactly where it is in the flow -- plain stack, same as before. At >=1100px the
   section becomes a two-column grid and the flagline moves into the empty column as an unboxed
   margin note: no border, no fill, no left bar, set in --fs-ui/--ink-soft (7.06:1 on --paper) with
   a short inset rule above it rather than the accent left-bar. `.flagline`'s own rule and
   `.flagline a` (pinned standalone by CLAUDE.md) are untouched, only overridden here for the wider
   box. Class added to the `<section class="wrap">` on the SEVEN pages where `.flagline` follows
   either `.prose` or `.terms.ledger` with nothing between them: greenhouse-lever-ashby.html,
   salary-question.html, sponsorship-question.html, in-progress-degree.html, eeo-questions.html
   (session-266a, `.prose` + `.flagline` only, two children) and finra-license-questions.html,
   nursing-license-questions.html (session-266d, added below). Not applied to claim-check.html
   (its `.flagline` sits after `.does`, not `.prose` or `.terms.ledger`).

   THE TWO NEW PAGES HAVE A THIRD SIBLING, `.terms.ledger` (session-266a's C.8 ledger treatment),
   AND THAT IS WHY IT NEEDS ITS OWN ROW RULES RATHER THAN REUSING `.prose`'s. nursing has exactly
   two children in the section (`.terms.ledger`, `.flagline` -- no `.prose` at all); finra has all
   three (`.prose`, then `.terms.ledger`, then `.flagline`). The baseline rule below puts
   `.terms.ledger` at column 1 row 1, which is already correct for nursing (nothing else claims
   that cell). The two adjacent-sibling overrides exist only to correct finra, where `.prose` gets
   row 1 first: `.prose + .terms.ledger` bumps the ledger to row 2 so it doesn't overlap `.prose`,
   and the three-part chain `.prose + .terms.ledger + .flagline` moves the note down to row 2 with
   it, so the note stays top-aligned with the list it actually comments on ("The rule that covers
   all of it") rather than floating beside the unrelated intro paragraph above. Both overrides are
   adjacent-sibling selectors keyed to the real DOM shape of each page, not a page-specific class,
   so nursing's two-child structure is untouched by them (no `.prose` there to match against). */
@media (min-width: 1100px) {
  .note-grid { display: grid; grid-template-columns: minmax(0, 42rem) minmax(16rem, 1fr); column-gap: 3rem; align-items: start; }
  .note-grid .prose { grid-column: 1; grid-row: 1; }
  .note-grid .terms.ledger { grid-column: 1; grid-row: 1; }
  .note-grid .prose + .terms.ledger { grid-row: 2; }
  .note-grid .flagline {
    grid-column: 2;
    grid-row: 1;
    border-left: none;
    background: transparent;
    border-radius: 0;
    padding: 0;
    margin: 0;
    max-width: none;
    font-size: var(--fs-ui);
    color: var(--ink-soft);
  }
  .note-grid .prose + .terms.ledger + .flagline { grid-row: 2; }
  .note-grid .flagline::before {
    content: "";
    display: block;
    width: 2.5rem;
    height: 1px;
    background: var(--line);
    margin-bottom: 0.9rem;
  }
}

/* ---------- CTA + buttons ---------- */

/* "Not open yet" / "Not for sale yet" -- RESTYLED 2026-09-03 (session-266a) to the homepage's own
   device (index.html:449-459): a mono tracked-caps label, a hairline that fills the row, then the
   sentence with its link, on paper, no fill, no heading weight. Was a banded `--surface-2`
   section with a heading and a filled button -- exactly the box-plus-heading-plus-button shape
   the owner's own diagnosis named (WEBSITE_DESIGN_BRIEF.md item 8). Markup is untouched (still
   `<h2>`/`.lede`/`a.btn`): the `<h2>` keeps its tag for structure but is restyled to look like the
   label, and the hairline is a `::after` on it rather than a new element. `.btn` on the CTA link
   stays because pricing.html needs it in a FLIPPING context for
   tests/test_site_fixed_field_contrast.py's own guard (its masthead's `.btn--gold` supplies the
   FIXED side) -- only its fill/border/padding are stripped here so it reads as plain text.
   Bottom padding added 2026-09-03 (session-266c): was `0`, matching the homepage strip's own
   zero bottom padding (index.html:433), but the homepage strip is followed by a sibling that
   supplies its OWN 40px margin-top before the footer's border (index.html:456) -- `.hfoot` here
   carries no such margin, so the link sat flush against the footer's border-top. `2.5rem` (40px)
   mirrors that homepage margin directly on `.cta` instead, since `.cta` is the only thing that
   precedes `.hfoot` on these two pages. No colour changed. */
.cta { background: transparent; border-block: none; padding-block: clamp(1.75rem, 4vw, 2.5rem) 2.5rem; }
.cta h2 {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  font-family: var(--mono);
  font-size: var(--fs-micro);
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 1.1rem;
  max-width: none;
}
.cta h2::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.cta .lede { margin: 0 0 0.9rem; }
.cta .btn {
  background-color: transparent;
  border-color: transparent;
  color: var(--accent-strong);
  padding: 0;
  font-weight: 700;
}
.cta .btn:hover { background-color: transparent; border-color: transparent; color: var(--accent-strong); text-decoration: underline; transform: none; }

.btn-row { display: flex; flex-wrap: wrap; gap: 0.7rem; align-items: center; }

.btn {
  display: inline-block;
  appearance: none;
  cursor: pointer;
  font-family: inherit;
  font-size: var(--fs-ui);
  font-weight: 600;
  text-decoration: none;
  padding: 0.72rem 1.35rem;
  border-radius: var(--r-sm);
  border: 1.5px solid var(--accent);
  background-color: var(--accent);
  color: var(--on-accent);
  /* TRANSITION NOTHING THAT CHANGES WITH THE COLOUR SCHEME. Only `transform` is scheme-independent,
     so only `transform` may be transitioned here. Colour snaps on hover, which is what most
     buttons do anyway.

     History, because this has now been got wrong twice. 2026-08-04 the `background` shorthand was
     narrowed to `background-color` on the theory that the shorthand was failing to re-resolve the
     custom property. That was the wrong diagnosis and the bug survived it. Re-measured 2026-08-10
     in a real browser, light mode, after a full reload:

       --accent resolved #0f5f8f, and .brand-mark / .points .n / h1 em ALL painted #0f5f8f
       ...while .btn painted #4aa3d8, the DARK accent, at 2.79:1 against its white label
       btn.getAnimations() -> background-color + all four border-colors stuck in state "running"
       forcing a reflow (display:none, read offsetHeight, restore) snapped it to #0f5f8f

     So the property is declared correctly and the cascade is right; the transition simply never
     completes when its target value comes from a custom property that a media query just changed,
     and it pins the old scheme's colour until something forces a recalc. Longhand vs shorthand was
     never the variable. Anyone re-adding a colour to this transition reintroduces a wrong-brand,
     sub-3:1 button for every user whose OS switches theme on a schedule.
     Guarded by tests/test_site_button_transition.py. Same failure class as ISSUES Z17. */
  transition: transform 0.18s;
}
.btn:hover { background-color: var(--accent-strong); border-color: var(--accent-strong); transform: translateY(-1px); }

/* Everything that MOVES in this sheet, switched off for a reader who has asked their OS not to
   animate things. The entrance animations were already guarded (they are written as
   `no-preference` blocks, so they simply never start); the hover lifts were not, and neither was
   `.guide` in styles-home.css. A `transition` is motion in the same sense an `animation` is, and
   vestibular triggers do not care which property name produced the movement. The hover still
   changes colour, so the affordance survives with nothing left to move. */
@media (prefers-reduced-motion: reduce) {
  .btn, .btn:hover { transition: none; transform: none; }
}

.btn.quiet { background-color: transparent; color: var(--ink); border-color: var(--line-strong); }
.btn.quiet:hover { border-color: var(--accent); color: var(--accent); background-color: transparent; }

/* Real work isn't hosted yet for these, so they're a native <button disabled> rather than an
   <a href="#">  a disabled button is honestly inert; a link that goes nowhere looks broken. */
.btn:disabled {
  cursor: default;
  background-color: transparent;
  border-color: var(--line-strong);
  color: var(--muted);
}
.btn:disabled:hover {
  background-color: transparent;
  border-color: var(--line-strong);
  color: var(--muted);
  transform: none;
}

/* ---------- footer ---------- */

footer { padding-block: 2.5rem 3.5rem; font-size: var(--fs-ui); color: var(--muted); }
footer a { color: var(--ink-soft); text-decoration: none; border-bottom: 1px solid var(--line); }
footer a:hover { color: var(--accent); border-color: var(--accent); }

/* ---------- entrance ---------- */

/* Same `backwards` rule as the hero graphic: the resting state is visible, so content can never
   be stranded at opacity 0 if the animation doesn't play. */
@media (prefers-reduced-motion: no-preference) {
  .rise { animation: rise 0.7s cubic-bezier(0.2,0.7,0.25,1) backwards; }
  .d1 { animation-delay: 0.04s; }
  .d2 { animation-delay: 0.14s; }
  .d3 { animation-delay: 0.26s; }
}
@keyframes rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* ---------- resume read-through (claim-check.html) ----------

   The colour choice is the honest one and is not decoration: findings use --warn, the ochre
   this product reserves for "needs you", and NEVER --ok or a red. Green would read as a pass
   the page cannot give, and red would read as a verdict about a person, which is the one
   thing claim-check.js exists to never do. Ochre says "look at this yourself", which is
   exactly what a finding is. Same meaning the app gives it, so the two read as one product. */

.cc-tool { padding-block: 0 clamp(2.75rem, 6vw, 4.5rem); }

.cc-label {
  display: block;
  font-size: var(--fs-fine);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  /* --ink-soft, not --muted: the new Clay & Rust --muted (#7d6558) measures 4.44:1 on --paper --
     a real, if tiny, miss of the 4.5:1 AA floor for normal-size text, measured in a real browser
     (tests/browser/test_site_rendered_contrast.py). Same fix already applied to `.crumbs`,
     `.getcard .fine` and `.points .n` -- see styles.css's own comment above `.crumbs` for why
     --muted itself is not redefined (it is a recorded decision of Ethan's on OTHER surfaces). */
  color: var(--ink-soft);
  margin-bottom: 0.55rem;
}

#resume {
  width: 100%;
  font-family: var(--mono);
  font-size: var(--fs-ui);
  line-height: 1.65;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r);
  padding: 0.95rem 1.05rem;
  resize: vertical;
}
#resume:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
#resume::placeholder { color: var(--muted); }

.cc-tool .btn-row { margin-top: 0.9rem; }

.cc-privacy {
  margin: 1rem 0 0;
  font-size: var(--fs-ui);
  color: var(--ink-soft);
  max-width: 40rem;
  line-height: 1.7;
}

/* Empty until the button is pressed. A results panel that is present-but-blank looks like a
   thing that ran and found nothing, which is a claim; nothing is drawn until there is a
   readout to draw. */
.cc-readout:empty { display: none; }
.cc-readout { margin-top: 1.9rem; display: grid; gap: 0.85rem; }

.cc-count {
  font-family: var(--mono);
  font-size: var(--fs-fine);
  letter-spacing: 0.02em;
  color: var(--warn);
  margin: 0;
}

.cc-find {
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--warn);
  border-radius: var(--r-sm);
  padding: 1.05rem 1.15rem;
}
.cc-kind {
  display: block;
  font-family: var(--sans);
  font-size: var(--fs-fine);
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--warn);
  margin-bottom: 0.6rem;
}
.cc-quote {
  font-family: var(--mono);
  font-size: var(--fs-ui);
  line-height: 1.7;
  color: var(--ink);
  background: var(--surface-2);
  border-radius: var(--r-sm);
  padding: 0.6rem 0.75rem;
  margin: 0 0 0.8rem;
  overflow-wrap: anywhere;
}
.cc-quote mark {
  background: color-mix(in srgb, var(--warn) 26%, var(--surface));
  color: inherit;
  border-radius: 3px;
  padding: 0.05em 0.15em;
}
.cc-body { margin: 0; color: var(--ink-soft); line-height: 1.7; }
.cc-note { margin: 0.55rem 0 0; font-size: var(--fs-ui); color: var(--muted); }

.cc-none {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 1.05rem 1.15rem;
  color: var(--ink-soft);
  line-height: 1.7;
}
.cc-none p { margin: 0; }
.cc-none-h { font-weight: 600; color: var(--ink); margin-bottom: 0.45rem !important; }

.cc-foot {
  margin: 0.4rem 0 0;
  font-size: var(--fs-ui);
  /* --ink-soft, not --muted -- same measured miss and same fix as `.cc-label` above (4.44:1 on
     --paper, under the 4.5:1 floor). This element only exists after a visitor pastes text and
     clicks "Read it back" with at least one finding, so the everyday rendered-contrast walk
     cannot see it; measured by hand by driving that interaction (fill #resume, click #read). */
  color: var(--ink-soft);
  line-height: 1.7;
  max-width: 40rem;
}

/* --accent-strong, not --accent: `.flagline` sits on --surface-2, and --accent measures 3.78:1
   there -- under the 4.5:1 floor. Same fix as `.points .n` / `.prose a`. */
.flagline a { color: var(--accent-strong); text-decoration: none; border-bottom: 1px solid var(--line-strong); }
.flagline a:hover { border-color: var(--accent-strong); }

/* ---------- explainer pages (the SEO set, 2026-08-18) ----------
   Eight pages that answer the question somebody types into a search box before they have ever
   heard of this product. They are built almost entirely out of the components above -- .terms,
   .lede, .flagline, .btn -- because a page that looks like a different
   website is a page that reads as a different website. What was genuinely missing was a body
   text style: every existing block is either a card, a list or a one-paragraph lede, and these
   pages have two or three paragraphs of prose in a row.

   No new colour token. No transition (see tests/test_site_button_transition.py -- a transition
   on a scheme-dependent colour pins the previous theme's value when the OS flips).

   .crumbs used to reuse the pre-recolour --muted, which relied on a rendered-contrast test's
   exemption for that colour. The 2026-08-25 Clay & Rust recolour moved --muted to #7d6558
   (4.44:1 on --paper -- a real miss of the 4.5:1 floor), and Ethan retired the exemption
   entirely on 2026-09-02 (ISSUES LT) rather than carry it across: no colour on this site is
   excused from the readability floor. --ink-soft is used here instead, same fix already applied
   to `.getcard .fine` and `.points .n` above: it always clears 4.5:1, so no exemption is needed.
   It is navigation furniture rather than reading matter, hence still visually the quieter of the
   two text colours available, just not the faintest one. */

.crumbs {
  font-family: var(--mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 1rem;
}
.crumbs a { color: var(--ink-soft); text-decoration: none; border-bottom: 1px solid var(--line); }
.crumbs a:hover { color: var(--accent-strong); border-color: var(--accent-strong); }

.prose { max-width: 42rem; }
.prose p { color: var(--ink-soft); margin: 0 0 1.1rem; }
.prose p:last-child { margin-bottom: 0; }
.prose b { color: var(--ink); font-weight: 600; }
/* --accent-strong, not --accent: `.prose` sits directly on --paper on every explainer page, and
   --accent measures 4.29:1 there -- under the 4.5:1 floor. Same fix as `.points .n`. */
.prose a { color: var(--accent-strong); text-decoration: none; border-bottom: 1px solid var(--line-strong); }
.prose a:hover { border-color: var(--accent-strong); }

/* ---------- capture figure (greenhouse-lever-ashby.html only) ----------
   ADDED 2026-09-03 (session-266a). The one figure slot outside the homepage's plate, given the
   same corner-tick/border idiom (index.html:360-374) so the two don't read as different shapes.
   No capture exists yet: the placeholder is the same labelled, in-palette `div[role="img"]` idiom
   as index.html:364-366, never a broken `<img>`. .figshot-label repeats index.html's own
   placeholder pairing (--accent text on --surface, 4.89:1); .figcap .tag is --accent-strong on
   --surface-2, 5.50:1; .figcap .txt is --ink-soft on --paper, 7.06:1. */
.figplate { position: relative; border: 1px solid var(--line); margin: 1.75rem 0 0; }
.figshot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 16 / 10;
  background: repeating-linear-gradient(135deg, var(--surface-2), var(--surface-2) 11px, #ddccb9 11px, #ddccb9 22px);
}
.figshot-label {
  font-family: var(--mono);
  font-size: var(--fs-fine);
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--accent);
  background: var(--surface);
  border: 1px solid var(--accent);
  padding: 7px 14px;
}
.figtick { position: absolute; width: 0; height: 0; border: 11px solid transparent; }
.figtick--tl { top: 0; left: 0; border-top-color: #e8cdb5; border-left-color: #e8cdb5; }
.figtick--tr { top: 0; right: 0; border-top-color: #e8cdb5; border-right-color: #e8cdb5; }
.figtick--bl { bottom: 0; left: 0; border-bottom-color: #e8cdb5; border-left-color: #e8cdb5; }
.figtick--br { bottom: 0; right: 0; border-bottom-color: #e8cdb5; border-right-color: #e8cdb5; }
.figcap { display: flex; align-items: center; gap: 12px; padding: 11px 2px 0; margin: 0; }
.figcap .tag { font-family: var(--mono); font-size: var(--fs-micro); font-weight: 700; letter-spacing: 0.14em; color: var(--accent-strong); background: var(--surface-2); padding: 3px 7px; }
.figcap .txt { font-size: var(--fs-ui); color: var(--ink-soft); }

/* The row of sibling pages at the foot of each explainer. A list, not cards: cards here would
   compete with the page's own content for the reader's eye, and these are an exit, not an offer. */
.related { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.55rem 1.5rem; font-size: var(--fs-ui); }
.related a { color: var(--ink-soft); text-decoration: none; border-bottom: 1px solid var(--line); }
.related a:hover { color: var(--accent); border-color: var(--accent); }
