/* ══════════════════════════════════════════════════════════════════════
   §ED549 · THE LANDING SHEET, REBUILT FOR THE VOICE PRODUCT.

   REPLACES css/landing-a2.css on index.html and nothing else. a2 styled a
   daily-FACT publication — a hero photograph strip, a six-beat "one day"
   sequence, a coming-soon culture band, an archive, a pricing tray driven
   by pricing-state. That product is cut. Every one of those selectors
   addressed markup that no longer exists, so the sheet is REPLACED rather
   than trimmed: a rule that styles nothing is not smaller, it is dead, and
   dead CSS is what the next pass mistakes for a spec (a2's own words, and
   they apply to a2).

   WHAT IS CARRIED OVER VERBATIM, AND WHY IT IS NOT RE-DERIVED:
     · the motion / shape / room / measure token ladders
     · the warm-neutral light and dark ramps (§ED294 reverted the cool one;
       a single cool grey is a defect under §ED440 and none is introduced)
     · the three Nohemi @font-face rules, which live HERE and nowhere else
       in the repo — see the block at the foot of this file
   These are ratified values. Re-typing them by eye is how a palette drifts.

   §ED440 LAW, AS IT APPLIES TO THIS PAGE:
     · hue 72 locked — --lime #CCFF00 is the only chroma on the page
     · ONE large-area accent per view, and it belongs to the primary CTA.
       Enumerated at each block below: hero -> "Answer today's question";
       the app block -> the record affordance (so its email submit is an
       OUTLINE button, not a second lime field); pricing -> the Member
       card's CTA; closing -> the repeated primary. No view carries two.
     · 16px type floor — --t-micro is 1rem and nothing goes under it
     · glass on chrome, never content — backdrop-filter appears exactly
       once, on the masthead
     · transform and opacity only

   DEPTH COMES FROM LIGHT, NOT GEOMETRY. One light source, above and
   slightly in front. Every shadow on this page is one of --shadow-1/2/3,
   all three of which are y-positive and un-offset in x. There is no
   per-element box-shadow literal anywhere below, which is what makes the
   light source a fact about the sheet rather than a habit.

   THERE IS NO SCROLL REVEAL. a2 faded sections in on IntersectionObserver
   and needed a failsafe script (§ED192 ruling 7) because the failure mode
   is a section stuck invisible with no error anywhere. This page has no
   reveal, so it has no failsafe and no way to lose a block. The only
   motion left is hover/press feedback on controls.
   ══════════════════════════════════════════════════════════════════════ */

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

:root {
  /* ── MOTION ─────────────────────────────────────────────────────── */
  --m-instant: 90ms;
  --m-fast:   160ms;
  --m-base:   300ms;

  --e-out:    cubic-bezier(.16, 1, .3, 1);
  --e-spring: cubic-bezier(.34, 1.4, .64, 1);

  --amp-sm:  4px;

  /* ── SHAPE ──────────────────────────────────────────────────────── */
  --r-sm: 10px;
  --r-md: 18px;
  --r-lg: 26px;
  --r-xl: 40px;
  --gutter: clamp(20px, 5vw, 72px);

  /* ── ROOM — the hierarchy lever. Sections are RANKED by the space
     around them; --room-xl is spent on the hero and the closing only.

     §ED551 · FOUR INDEPENDENT CLAMPS BECAME ONE STEP AND FOUR MULTIPLES.
     The four rungs were declared separately and agreed with each other
     nowhere. Measured at a 900px-tall viewport they rendered 45 / 90 /
     135 / 216: the first three are 1×, 2× and 3× of 45, and the fourth
     is 4.8× — so three quarters of the ladder looked like a scale and
     the rung spent on the two most important blocks on the page did not
     belong to it. The anchors were no better: the floors ran 34 / 60 /
     92 / 132 (gaps of 26, 32, 40) and the ceilings 56 / 112 / 176 / 280,
     where 176 is 3.14× the base.

     A gap that is not a multiple of anything is what makes generous
     space read as accidental rather than composed, which is the defect
     being fixed here — NOT the generosity itself. Every rung below is
     larger than the value it replaces at the floor, at the ceiling, and
     at a 900px viewport; nothing on this page got tighter. Checked by
     scripts/audit-ed549.js §10, which measures the rendered section gaps
     and asserts each is an exact multiple of the step.

     THE STEP STAYS VIEWPORT-RELATIVE. 5vh is what made the old ladder
     breathe on a tall screen and compress on a laptop, and that was
     right; it is the only term that survives unchanged.

     §ED556 · THE LADDER COMES DOWN ONE NOTCH — AND NOTHING ELSE ABOUT IT
     CHANGES. §ED551 above was told not to reduce generosity and did not;
     that instruction was WITHDRAWN on §ED555's evidence, which measured
     block padding as the largest single term on this page and the only
     one composition could not reach.

     ONE NUMBER, NOT FOUR. --room-notch is a multiplier on the §ED551
     clamp, which is left standing above it verbatim. That is the whole
     mechanism, and it is the mechanism ON PURPOSE:

       ·  THE RATIOS SURVIVE BY CONSTRUCTION, not by arithmetic anyone has
          to check. sm/md/lg/xl are multiples of --room-step and stay
          1 : 2 : 3 : 5 for every possible value of the notch. A pass that
          retyped four clamps could put the ladder back out of true by a
          rounding, which is the exact defect §ED551 existed to fix.
       ·  THE VIEWPORT-RELATIVE TERM SURVIVES. Scaling the clamp scales
          floor, preferred and ceiling together, so the step still breathes
          on a tall screen and compresses on a laptop.
       ·  THE TRIM IS ONE LEGIBLE NUMBER, reversible in one edit.

     WHY 0.8 IS "ONE NOTCH" AND NOT A ROUND-DOWN. The ladder's top rung is
     5 steps. At 0.8 the top rung falls by exactly ONE OLD STEP (225px →
     180px at a 900px viewport) and every rung below falls in proportion.
     "One notch" is therefore a measured quantity on this page's own scale
     rather than a percentage picked to look modest.

     NO SECTION IS RETUNED. Not one padding-block below changed. A ladder
     whose rungs are adjusted individually is not a ladder, and the whole
     value of this being one token is that the page moves together. */
  --room-notch: 0.8;
  --room-step: calc(clamp(36px, 5vh, 60px) * var(--room-notch));
  --room-sm: var(--room-step);
  --room-md: calc(var(--room-step) * 2);
  --room-lg: calc(var(--room-step) * 3);
  --room-xl: calc(var(--room-step) * 5);

  /* ── MEASURE — reading columns, ranked ──────────────────────────── */
  --measure:        1080px;
  --measure-narrow:  820px;

  --glass-blur: 18px;

  /* ── COLOUR — LIGHT (warm neutral) ──────────────────────────────── */
  --bg:        #F5F3EE;
  --bg-deep:   #EAE6DE;
  --surface:   #FFFDFA;
  --surface-2: #F0EDE6;
  --glass:     rgba(255, 253, 250, .72);
  --glass-line:rgba(255, 253, 250, .9);
  --ink:       #14120E;
  --ink-2:     #56514A;
  --ink-3:     #8B857B;
  --line:      rgba(20, 18, 14, .13);
  --line-2:    rgba(20, 18, 14, .06);

  --lime:      #CCFF00;
  --lime-ink:  #3D4D00;   /* lime is unreadable AS TEXT on the light ground */
  --focus:     #14120E;
  --on-lime:   #0A0C00;
  --sheen:     rgba(255,255,255,.26);
  --danger:    #B3241C;

  --shadow-1: 0 1px 2px rgba(20,18,14,.05), 0 4px 12px rgba(20,18,14,.05);
  --shadow-2: 0 2px 6px rgba(20,18,14,.06), 0 14px 40px rgba(20,18,14,.10);
  --shadow-3: 0 4px 12px rgba(20,18,14,.08), 0 30px 70px rgba(20,18,14,.16);

  /* ── TYPE ────────────────────────────────────────────────────────
     Nohemi 400 all-caps is the display voice (§ED428, untouched).
     Fraunces is editorial — the wordmark, and the question itself.
     Hanken Grotesk is every reading string. Mono carries eyebrows and
     labels. --f-display is declared ONCE, here, with Nohemi first: a2
     declared it twice (system stack at :root, Nohemi 1,600 lines later)
     and the second won by document order, which is not a decision. */
  --f-display: 'Nohemi', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --f-edit:    'Fraunces', Georgia, 'Times New Roman', serif;
  --f-ui:      'Hanken Grotesk', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --f-mono:    ui-monospace, "SF Mono", SFMono-Regular, Menlo, "JetBrains Mono", "Cascadia Mono", Consolas, monospace;

  /* ── THE FLOOR (§ED306, §ED440) ─────────────────────────────────
     The audience skews older and includes people buying for parents and
     grandparents. --t-micro is the absolute floor and nothing on this
     page is set below it. In rem, so browser zoom actually moves it. */
  --t-micro: 1rem;        /* 16px */
  --t-body:  1.125rem;    /* 18px */
  --lh-body: 1.7;

  /* ── THE RAMP: FIVE RUNGS, AND EVERY ROLE POINTS AT ONE ────────
     §ED551 · MEASURED BEFORE IT WAS CHANGED. The page rendered NINE
     distinct font-sizes at 1440 — 76 / 44 / 36 / 22 / 21.6 / 20 / 18 /
     16, plus the 10px device status bar — and eight at 390. Three of
     those nine existed only because a role declared its own size
     instead of naming a rung: .ln-hero-sub had a clamp of its own that
     landed on 21.6px beside a 22px .ln-step-k; .ln-plan-n sat at 20px
     between them; .ln-plan-price had a fourth clamp at 44px. Nine sizes
     is noise. Five is a decision.

     WHAT MERGED, AND INTO WHAT:
       21.6 (.ln-hero-sub) ┐
       22   (.ln-wordmark, .ln-step-k, .ln-screen-q) ├→ --t-lead (20→22)
       20   (.ln-plan-n)   ┘
       44   (.ln-plan-price) ─────────────────────→ --t-head (24→36)
       36   (.ln-h2)       ┘
     THE COST, STATED: the price is no longer larger than the section
     heading. It is still the largest string inside its card by two
     rungs, which is where the comparison actually happens.

     §ED560 · TWO OF THE FIVE NAMES ABOVE NO LONGER EXIST. .ln-plan-n and
     .ln-plan-price left with the pricing section (section 8 below). The
     record of what merged is kept as written, because it is the reason
     --t-lead and --t-head hold the values they hold — but neither rung
     lost its last tenant: --t-lead still carries .ln-wordmark,
     .ln-hero-sub, .ln-step-k and .ln-screen-q, and --t-head still
     carries .ln-h2. The ramp is still five rungs and still measured.

     THE 10px DEVICE STATUS BAR IS NOT ON THIS RAMP AND IS NOT MEANT TO
     BE. It is aria-hidden chrome inside a picture of a phone, already
     the single declared exception to the §ED440 16px floor. It is a
     SIXTH rendered size and is reported as one rather than hidden. */
  --t-lead: clamp(1.25rem, 1.6vw, 1.375rem);   /* 20 → 22 */
  --t-head: clamp(1.5rem,  2.6vw, 2.25rem);    /* 24 → 36 */
  --t-hero: clamp(2.25rem, 5.6vw, 4.75rem);    /* 36 → 76 */

  /* ── SPACE INSIDE A BLOCK. Section room is the ladder above; this is
     the rhythm within one. §ED551 found 18 / 22 / 26 / 30 / 34 / 38 /
     15 / 5 px typed by eye across the sheet — every one of them now a
     multiple of 4. The waveform bar pitch (2px) and the status bar's
     own geometry are DRAWN ORNAMENT, not spacing, and are deliberately
     not on this ladder. */
  --s-xs:  8px;
  --s-sm: 12px;
  --s-md: 16px;
  --s-lg: 24px;
  --s-xl: 32px;
  --s-2xl: 40px;
}

/* ── COLOUR — DARK (warm neutral, NOT navy) ────────────────────────
   Byte-identical to the ramp css/landing-a2.css carried. Light is the
   default at every width (§ED192 ruling 2); dark is reached only by a
   stored 'culturily-theme' preference, which the head script reads and
   stamps in both spellings. There is deliberately no
   @media (prefers-color-scheme: dark) block: it would need a second copy
   of this ramp, and two copies is where a palette drifts. */
html[data-theme="dark"] { color-scheme: dark; }
html[data-theme="dark"] {
  --bg:#100E0C; --bg-deep:#080706; --surface:#191714; --surface-2:#211E1A;
  --glass:rgba(25,23,20,.72); --glass-line:rgba(255,252,245,.10);
  --ink:#F5F2EC; --ink-2:#ACA69C; --ink-3:#7A746A;
  --line:rgba(255,252,245,.13); --line-2:rgba(255,252,245,.06);
  --lime-ink:#CCFF00; --focus:#CCFF00; --sheen:rgba(255,255,255,.16); --danger:#FF8A80;
  --shadow-1:0 1px 2px rgba(0,0,0,.5), 0 4px 14px rgba(0,0,0,.4);
  --shadow-2:0 2px 8px rgba(0,0,0,.5), 0 18px 44px rgba(0,0,0,.55);
  --shadow-3:0 6px 16px rgba(0,0,0,.55), 0 36px 80px rgba(0,0,0,.7);
}
html[data-theme="light"] { color-scheme: light; }
html[data-theme="light"] {
  --bg:#F5F3EE; --bg-deep:#EAE6DE; --surface:#FFFDFA; --surface-2:#F0EDE6;
  --glass:rgba(255,253,250,.72); --glass-line:rgba(255,253,250,.9);
  --ink:#14120E; --ink-2:#56514A; --ink-3:#8B857B;
  --line:rgba(20,18,14,.13); --line-2:rgba(20,18,14,.06);
  --lime-ink:#3D4D00; --focus:#14120E; --sheen:rgba(255,255,255,.26); --danger:#B3241C;
  --shadow-1:0 1px 2px rgba(20,18,14,.05), 0 4px 12px rgba(20,18,14,.05);
  --shadow-2:0 2px 6px rgba(20,18,14,.06), 0 14px 40px rgba(20,18,14,.10);
  --shadow-3:0 4px 12px rgba(20,18,14,.08), 0 30px 70px rgba(20,18,14,.16);
}

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--f-ui);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  letter-spacing: -0.008em;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: inherit; }

:where(a, button, input, [tabindex]):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: 4px;
}

/* The page column. The bottom margin clears js/consent.js's fixed bar,
   whose real height is measured at the foot of index.html and rests at
   0px when no banner exists. Declared INSIDE the shorthand — a separate
   margin-bottom rule above a `margin: 0` is reset by it (§ED440 defect
   class; a2 paid for this one). */
.ln-page {
  position: relative;
  z-index: 1;
  width: 100%;
  margin: 0 0 var(--consent-h, 0px);
  padding: 0 var(--gutter);
}

/* ══════════════════════════════════════════════════════════════════
   MASTHEAD — the mark and one door.
   §ED549 · every other link is an exit ramp off the only action this
   page exists for. GLASS LIVES HERE AND NOWHERE ELSE (§ED440).
   ══════════════════════════════════════════════════════════════════ */
.ln-masthead {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-md);
  margin: 0 calc(var(--gutter) * -1);
  padding: var(--s-md) var(--gutter);
  border-bottom: 1px solid transparent;
  transition: background-color var(--m-base) var(--e-out),
              border-color var(--m-base) var(--e-out);
}
.ln-masthead.is-stuck {
  background: var(--glass);
  border-bottom-color: var(--line-2);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
}
.ln-wordmark {
  font-family: var(--f-edit);
  font-weight: 500;
  font-size: var(--t-lead);
  letter-spacing: -0.014em;
  text-decoration: none;
  color: var(--ink);
}
.ln-login {
  font-family: var(--f-mono);
  font-size: var(--t-micro);
  letter-spacing: 0.01em;
  text-decoration: none;
  color: var(--ink-2);
  transition: color var(--m-fast) var(--e-out);
}
.ln-login:hover { color: var(--ink); }

/* ── THE APPEARANCE TOGGLE (§ED551, REBUILT §ED563) ────────────────
   §ED551 SHIPPED THIS AS THE WORD "Dark" IN A HAIRLINE PILL, and argued
   that a sun/moon pair would be a second motif on a page that carries one
   (the waveform). THAT ARGUMENT IS WITHDRAWN BY RULING, and the §ED551
   text is recorded here rather than deleted so the reversal is legible.

   THE WORD HAD A DEFECT THE TRACK CANNOT HAVE. A one-word button names
   only the mode you are NOT in, so it must be rewritten on every flip —
   and index.html's §ED551 handler never rewrote it. The button read
   "Dark" in light mode and "Dark" in dark mode, and its own comment
   claimed "the visible label is always the mode being offered". A track
   shows both destinations at once and has no label to go stale.

   ONE STATE VARIABLE, AND IT IS aria-pressed. The thumb's position and
   both glyph inks are selected off [aria-pressed] below. There is no
   class to keep in sync and no second copy of the answer, so the picture
   cannot disagree with what a screen reader is told — the same
   one-decision-two-stamps discipline the head script uses for the theme
   itself.

   SUN LEFT, MOON RIGHT. The thumb travels left-to-right as the page goes
   light-to-dark, which is the direction the two glyphs already read in.

   appearance:none IS STILL LOAD-BEARING: Safari paints its own chrome
   under a <button> otherwise and the track loses its edge in dark. The
   frame moved from the button to .ln-theme-track so the button itself
   contributes no box — a border on both would be two edges. */
.ln-mast-r { display: flex; align-items: center; gap: var(--s-md); }
.ln-theme {
  appearance: none;
  -webkit-appearance: none;
  display: inline-flex;
  padding: 0;
  border: 0;
  background: transparent;
  line-height: 0;
  cursor: pointer;
}
.ln-theme-track {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  width: 58px;
  height: 30px;
  padding: 0 6px;
  border-radius: 999px;
  border: 1px solid var(--line);
  transition: border-color var(--m-fast) var(--e-out);
}
.ln-theme:hover .ln-theme-track { border-color: var(--ink-3); }
.ln-theme:focus-visible { outline: none; }
.ln-theme:focus-visible .ln-theme-track { outline: 2px solid var(--ink); outline-offset: 3px; }
/* THE THUMB IS THE ONLY MOVING PART, AND IT MOVES ON transform — §ED440's
   motion law, and the reason the track never reflows mid-flip. Its travel
   is the track's inner width minus its own width: 58 - 2 - 12 - 22 = 22. */
.ln-theme-thumb {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  background: var(--ink);
  transition: transform var(--m-base) var(--e-out);
}
.ln-theme[aria-pressed="true"] .ln-theme-thumb { transform: translateX(28px); }
/* z-index, not opacity: the glyph the thumb is standing on is KNOCKED OUT
   of it in --surface, which is legible in both themes without asking the
   ink ramp for a third value. 15px is a GLYPH, not copy — it carries no
   text node, so §ED440's 16px floor (which is measured on elements with a
   direct text child) does not reach it and is not being bent here.

   §ED565 · THESE ARE <svg> ELEMENTS NOW, NOT AN ICON FONT'S ::before.
   WHAT DID NOT CHANGE IS THE WHOLE POINT: the box is still 16px wide, the
   painted glyph is still 15px, and the ink is still `color` — so
   [aria-pressed] below still drives the two inks through exactly the same
   property, and audit-ed563.js's ink assertions read the same value off
   the same declaration. `fill: currentColor` is what carries `color`
   across into the drawing; without it an SVG ignores the ink ramp and
   paints black in both themes.

   height IS DECLARED, not left to the aspect ratio. An <svg> with only a
   width resolves its height from the viewBox in most engines and from the
   replaced-element default (150px) in some — a 150px tall glyph inside a
   30px track is a layout the toggle never recovers from. Both axes are
   stated so there is nothing to resolve.

   display:block kills the inline baseline gap: an inline <svg> sits ON the
   text baseline and carries the descender space below it, which pushed
   both glyphs 3px low inside a track that centres on its own box. */
.ln-theme-i {
  position: relative;
  z-index: 1;
  display: block;
  width: 16px;
  height: 15px;
  line-height: 1;
  color: var(--ink-3);
  fill: currentColor;
  transition: color var(--m-base) var(--e-out);
}
.ln-theme[aria-pressed="false"] .ln-theme-i--sun,
.ln-theme[aria-pressed="true"]  .ln-theme-i--moon { color: var(--surface); }
@media (prefers-reduced-motion: reduce) {
  .ln-theme-thumb, .ln-theme-i { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════
   SHARED TYPE ROLES
   ══════════════════════════════════════════════════════════════════ */
.ln-h1 {
  margin: 0;
  font-family: var(--f-display);
  font-weight: 400;                /* §ED428 · all-caps Nohemi ships at 400 */
  text-transform: uppercase;
  letter-spacing: 0.004em;         /* §ED428 · measured zero-merge threshold */
  line-height: 0.98;
  font-size: var(--t-hero);
  color: var(--ink);
  text-wrap: balance;
}
.ln-hl { color: var(--lime-ink); }

.ln-h2 {
  margin: 0;
  font-family: var(--f-display);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.004em;
  line-height: 1.06;
  font-size: var(--t-head);
  color: var(--ink);
}
.ln-eyebrow {
  margin: 0 0 var(--s-md);
  font-family: var(--f-mono);
  font-size: var(--t-micro);
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-3);
}
/* §ED551 · .ln-lead was DELETED — it matched nothing. The markup's
   lede carries .ln-lede, styled 200 lines below, and .ln-lead was the
   near-miss left behind. A rule that styles nothing is not smaller than
   one that does, it is dead, and dead CSS is what the next pass mistakes
   for a spec (this sheet's own words, applied to this sheet). */

/* ── SECTION RHYTHM ─────────────────────────────────────────────── */
.ln-sec {
  max-width: var(--measure);
  margin-inline: auto;
  padding-block: var(--room-lg);
}
/* §ED551 · .ln-sec--tight was DELETED — no element on the page carries
   it. Same reason as .ln-lead above. --room-md is still live: the hero's
   own padding uses it. */
.ln-sec--narrow { max-width: var(--measure-narrow); }

/* ══════════════════════════════════════════════════════════════════
   BUTTONS
   THE ACCENT RULE IS ENFORCED BY HAVING ONLY ONE FILLED VARIANT.
   .ln-btn-accent is the lime one. Everything else is an outline or a
   quiet link, so a second large lime area cannot appear in a view by
   accident — it has to be typed.
   ══════════════════════════════════════════════════════════════════ */
.ln-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-sm);
  padding: var(--s-md) 28px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink);
  font-family: var(--f-ui);
  font-size: var(--t-body);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.004em;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--m-fast) var(--e-spring),
              opacity var(--m-fast) var(--e-out);
}
.ln-btn:hover { transform: translateY(calc(var(--amp-sm) * -1)); }
.ln-btn:active { transform: translateY(0); }
.ln-btn-accent {
  border-color: transparent;
  background: var(--lime);
  color: var(--on-lime);
  box-shadow: var(--shadow-2);
}
.ln-btn-quiet {
  padding: 0;
  border: 0;
  border-radius: 0;
  font-family: var(--f-mono);
  font-size: var(--t-micro);
  font-weight: 400;
  color: var(--ink-2);
  text-decoration: underline;
  text-underline-offset: 5px;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--line);
}
.ln-btn-quiet:hover { transform: none; color: var(--ink); text-decoration-color: currentColor; }

/* ══════════════════════════════════════════════════════════════════
   1 · HERO   — accent: "Answer today's question"
   ══════════════════════════════════════════════════════════════════ */
.ln-hero {
  max-width: var(--measure);
  margin-inline: auto;
  /* §ED551 · THE ONE SECTION EDGE THAT WAS NOT ON THE LADDER. This was
     clamp(56px, 9vh, 120px), which renders 81px at a 900px-tall viewport
     — 1.8 steps, the only section padding on the page that was not a
     whole multiple of one. It is now --room-md (2 steps, 90px there), so
     it is larger than it was AND it is on the scale. */
  padding-block: var(--room-md);
  /* §ED613 · WAVEFORM BACKGROUND. A CSS background-image, not an <img> —
     decorative by construction: it never enters the accessibility tree
     and can never intercept a click on .ln-hero-ctas, so neither of the
     brief's two guards needed enforcing by hand. background-image never
     affects box height, so it cannot push anything below the fold.
     Theme switch reuses the page's one mechanism, html[data-theme], same
     as the colour ramp above — no second theming path introduced. */
  background-repeat: no-repeat;
  background-position: center center;
  background-size: cover;
}
html[data-theme="dark"] .ln-hero { background-image: url("/assets/ui/wave-dark-1280.webp"); }
html[data-theme="light"] .ln-hero { background-image: url("/assets/ui/wave-light-1280.webp"); }
/* -1280 below 900px, the full 1920 at/above it — the same breakpoint this
   sheet already switches .ln-becomes/.ln-app columns on (§ED590), not a
   new number. */
@media (min-width: 900px) {
  html[data-theme="dark"] .ln-hero { background-image: url("/assets/ui/wave-dark.webp"); }
  html[data-theme="light"] .ln-hero { background-image: url("/assets/ui/wave-light.webp"); }
}
/* §ED563 · THE ONE GAP IN THE HERO THAT WAS NOT ON THE LADDER.
   It was --s-lg (24px) — a rung of the SPACING scale, which is what this
   sheet spends on form rows and button gaps. Under a display-size H1
   (76px at 1440) 24px is less than a third of one line of the headline,
   so the sub read as a wrapped continuation of it rather than as a
   separate sentence.

   IT IS NOW --room-sm: the ladder's BASE STEP, 36px at a 900px viewport.
   That rung and not another because --room-sm is what this page already
   spends on separations INSIDE a block — .ln-becomes and .ln-app grid
   gaps, and .ln-seam's own top margin above the recorder — while
   --room-md and above are section boundaries. The headline and the sub
   are one block; the space between them is an internal seam, so it takes
   the internal rung. No one-off margin is introduced: it is a token off
   the same ladder audit-ed549.js §10 asserts is whole-multiple. */
.ln-hero-sub {
  margin: var(--room-sm) 0 0;
  max-width: 30ch;
  font-size: var(--t-lead);
  line-height: 1.45;
  color: var(--ink-2);
  text-wrap: pretty;
}
/* §ED563 · .ln-hero-ctas IS BACK, BECAUSE THE ELEMENT IS BACK. §ED553
   deleted it when the recorder took the hero's one accent and the page's
   own button had to go (§ED440: 13,188px² beside the recorder's
   155,134px²). The recorder has left the hero for #ln-answer, so the hero
   has an accent to spend again and one thing to press — and this time the
   thing it points at is on this page.

   --s-2xl, NOT A ROOM RUNG. A control row is spaced on the SPACING scale,
   and this is the same value .ln-closing-cta already uses for the same
   job: the page's other repeat of this exact button. One precedent, no
   new number. */
.ln-hero-ctas { margin-top: var(--s-2xl); }

/* ══════════════════════════════════════════════════════════════════
   1b · §ED590 — THE QUESTION GRID. No accent; the questions ARE the
   headline, so there is no h2 to give the roughly-.ln-h2 type role to —
   they carry the size directly instead of a shared class that implies a
   heading landmark six times in a row.

   ONE COLUMN BELOW 900px, TWO AT AND ABOVE IT — the same breakpoint
   .ln-becomes and .ln-app already switch on, so this is the third section
   on the page to change its column count there, not a new number.

   THE GAP IS THE LADDER'S OWN RUNGS. Row gap is --room-sm — the same rung
   .ln-becomes and .ln-app spend on grid gaps INSIDE a block; column gap at
   the two-column width is the same clamp(--s-xl, 4vw, 64px) .ln-becomes
   uses for its own column gap, so a third grid on this page does not
   invent a fourth gap value. */
.ln-asks-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--room-sm) 0;
  margin: var(--s-xl) 0 0;
  padding: 0;
  list-style: none;
}
@media (min-width: 900px) {
  .ln-asks-list { grid-template-columns: 1fr 1fr; gap: var(--room-sm) clamp(var(--s-xl), 4vw, 64px); }
}
/* LARGE AND QUIET. --t-lead is the same rung .ln-hero-sub and .ln-step-k
   already carry — a display beat, not a caption, but not H2-scale either:
   six of these stacked at --t-head would out-weigh the section above it,
   which is exactly the "near .ln-h2 scale" the brief asked for without
   handing six lines of body copy the page's biggest non-hero role. */
/* DEFAULT STATE IS VISIBLE — opacity 1, no transform declared at all. The
   class the IntersectionObserver in index.html adds is what ANIMATES the
   entrance; it is not what reveals the content. A reader with JavaScript
   disabled, or whose observer never fires, sees all six questions
   immediately — that is what scripts/audit-ed590.js's no-JS check
   asserts, and it is true here without a rule to state it: opacity and
   transform are only ever SET below, inside the no-preference query. */
.ln-ask-q {
  margin: 0;
  max-width: 34rem;
  font-family: var(--f-ui);
  font-weight: 500;
  font-size: var(--t-lead);
  line-height: 1.4;
  color: var(--ink);
  letter-spacing: -0.006em;
}
/* html.js, NOT .ln-ask-q ALONE (§ED590). The hide-then-reveal pair only
   ever applies once BOTH conditions hold: script executed (html.js, set
   synchronously in index.html's <head>, before this sheet or the body
   paint) AND the reader has not asked for reduced motion. Either one
   absent — no script, or script present but motion reduced — leaves the
   bare .ln-ask-q rule above as the only match: no opacity, no transform,
   ordinary static text from first paint. */
@media (prefers-reduced-motion: no-preference) {
  html.js .ln-ask-q {
    opacity: 0;
    transform: translateY(8px);
    transition: opacity var(--m-base) var(--e-out), transform var(--m-base) var(--e-out);
  }
  html.js .ln-ask-q.ln-ask-q--in { opacity: 1; transform: none; }
}

/* ══════════════════════════════════════════════════════════════════
   2 · THE SEAM — where the live question and recorder MOUNT.

   §ED553 FILLED IT. The paragraph that stood here described a box that
   "paints nothing today and that is deliberate", held open by an explicit
   min-height so that mounting the question later would be an insertion
   rather than a reflow. That mounting has happened: js/reader-answer.js
   renders the whole §ED548 recording moment into this node, styled by
   css/briefing.css's .ba-* family, which this sheet neither duplicates nor
   overrides. What remains here is PLACEMENT ONLY.
   ══════════════════════════════════════════════════════════════════ */
.ln-seam {
  display: block;
  width: 100%;
  max-width: var(--measure-narrow);
  margin: var(--room-sm) 0 0;
}

/* ── THE TRUST LINE ABOVE THE RECORDER (§ED563) ────────────────────
   ONE LINE, AND EVERY CLAUSE OF IT IS CHECKED IN CODE — index.html's own
   comment beside it names the file and line for each, and
   scripts/audit-ed563.js §5 asserts them against the page. §ED560 cut a
   permanence claim this product could not keep; the replacement rule for
   this page is that a reassurance is written to the code, not to the plan.

   IT IS --t-micro AND --ink-3, WHICH IS THE PAGE'S FINE-PRINT ROLE —
   the same treatment .ln-form-sub gets under the email captures. A trust
   line set at body size would rank itself above the question, and the
   question is the only thing in this block a reader came for. --t-micro
   is 1rem, so this is ON §ED440's floor and not under it. */
.ln-answer-trust {
  margin: 0;
  max-width: var(--measure-narrow);
  color: var(--ink-3);
  font-size: var(--t-micro);
  line-height: 1.6;
}

/* ── THE ACCOUNT ASK ──────────────────────────────────────────────────────
   Hidden in the markup and revealed only after a SERVER-CONFIRMED answer.
   `[hidden]` is restated because this sheet sets .ln-ask to grid, and a bare
   `display:` on the class beats the UA sheet's `[hidden] { display: none }` —
   the exact specificity trap §ED527b's law is about, so it is closed here
   rather than discovered later.

   IT IS A QUIET BLOCK, NOT A CARD AND NOT A BANNER. A visitor has just spoken;
   the page's job at that moment is to say what an account keeps and then stop.
   No box, no shadow, no accent fill — one hairline above it, which is the same
   device .ln-steps and .ln-nevers use. The accent stays where §ED440 puts it
   (one large-area accent per view, and the vault owns it on this page). */
.ln-ask[hidden] { display: none; }
.ln-ask {
  display: grid;
  justify-items: start;
  gap: var(--s-xs);
  width: 100%;
  max-width: var(--measure-narrow);
  margin: var(--s-xl) 0 0;
  padding: var(--s-lg) 0 0;
  border-top: 1px solid var(--line-2);
}
/* --t-lead and the display face in caps: the same treatment .ln-step-k gets,
   which is this page's voice for a short label that heads a block. §ED551 cut
   the type ramp to five sizes and this introduces no sixth. */
.ln-ask-h {
  margin: 0;
  font-family: var(--f-display);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.004em;
  font-size: var(--t-lead);
  line-height: 1.2;
  color: var(--ink);
}
.ln-ask-sub {
  margin: 0;
  font-size: var(--t-body);
  line-height: 1.5;
  color: var(--ink-2);
}
.ln-ask-cta {
  margin: var(--s-sm) 0 0;
  font-size: var(--t-body);
  line-height: 1.2;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 0.25em;
}
.ln-ask-cta:hover { color: var(--ink-2); }
.ln-ask-cta:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

/* ══════════════════════════════════════════════════════════════════
   3 · HOW IT WORKS — three beats, one line each. No accent in this view.
   ══════════════════════════════════════════════════════════════════ */
.ln-steps {
  display: grid;
  gap: 0;
  margin: var(--s-xl) 0 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--line-2);
}
.ln-step {
  display: grid;
  grid-template-columns: minmax(0, 8rem) minmax(0, 1fr);
  gap: var(--s-xs) var(--s-xl);
  align-items: baseline;
  padding: var(--s-lg) 0;
  border-bottom: 1px solid var(--line-2);
}
.ln-step-k {
  font-family: var(--f-display);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.004em;
  font-size: var(--t-lead);
  color: var(--ink);
}
/* 36rem caps this at 66 average characters. Uncapped it measured 76 —
   just over the band, and the only line on the page that was over it
   rather than under. */
.ln-step-v {
  margin: 0;
  max-width: 36rem;
  font-size: var(--t-body);
  line-height: 1.55;
  color: var(--ink-2);
}
@media (max-width: 639.98px) {
  .ln-step { grid-template-columns: 1fr; gap: 4px; }
}


/* ══════════════════════════════════════════════════════════════════
   4 · WHAT WE'LL NEVER DO — five promises. No accent in this view; the
   weight is the repetition of the word "Never" down the left edge.

   §ED551 · THIS WAS FIVE CARDS AND IS NOW ONE LIST.

   THE MEASURED DEFECT. The grid was
     repeat(auto-fit, minmax(min(100%, 19rem), 1fr))
   inside the 1080px measure. 19rem is 304px, 1080/304 resolves to three
   tracks, and five items fill 3 + 2 — an EMPTY THIRD SLOT on the second
   row at every desktop width. An empty grid cell beside two filled ones
   reads as a card that failed to load, which is a particularly bad thing
   for the block whose whole argument is that this product keeps its
   promises.

   THE FORM WAS ALSO WRONG, INDEPENDENTLY OF THE HOLE. Cards imply
   comparable options — that is what the pricing row two blocks down is
   for, and it uses the same shape. Five promises are not options; they
   are a stance, and a stance reads as a list. So: no boxes, no borders,
   no shadows, one hairline between items, and the type and the rhythm
   carry it.

   THE MARK IS THE PAGE'S ONE MOTIF. Five different waveforms, one per
   promise — the same drawn shape as the vault rows, the day span and the
   phone. Not an icon set: five generic glyphs beside five lines is what
   a template looks like, and a waveform is honest here because it is
   literally what a recording is. RULED: outside the vault card the motif
   is --ink-3, and .ln-mark is --ink-3.
   ══════════════════════════════════════════════════════════════════ */
/* §ED563 · .ln-ledger-turn IS DELETED. It was §ED556's ONE rule — the
   --room-md seam between HOW IT WORKS and WHAT WE'LL NEVER DO after the
   two were merged into one block. §ED563's order puts the recorder, the
   app and the family block between them, so the merge is unwound, the
   wrapper div is gone from index.html, and this rule matches nothing.

   DELETED RATHER THAN KEPT AS A RECORD, which is this sheet's own
   standing law (see .ln-lead and .ln-sec--tight above): a rule that
   styles nothing is not smaller, it is dead, and dead CSS is what the
   next pass mistakes for a spec. The two lists' own rules — .ln-steps
   and .ln-nevers — were never touched by the merge and are not touched
   by the unwind either.

   NOTHING REPLACES IT. #ln-never is a top-level .ln-sec now, so the space
   above it is --room-lg section padding, on the ladder by construction. */

.ln-nevers {
  display: grid;
  gap: 0;
  margin: var(--s-xl) 0 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--line-2);
}
/* The mark spans both text rows and centres against the pair. 'baseline'
   is meaningless for an item spanning two rows — it resolves to the
   first row's baseline and hangs the mark off the top — so the row is
   'start' and the mark aligns itself. */
.ln-never {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: var(--s-lg);
  row-gap: 4px;
  align-items: start;
  padding: var(--s-lg) 0;
  border-bottom: 1px solid var(--line-2);
}
.ln-mark {
  grid-row: 1 / 3;
  align-self: center;
  width: 34px;
  height: 16px;
  color: var(--ink-3);
}
/* 34rem, not a ch value. 'ch' measures the ZERO glyph, which in Hanken
   is narrower than the average letter, so a 34ch cap rendered 39 average
   characters — the number the eye actually counts. Measured: 544px holds
   62 average characters at --t-body and 70 at --t-micro, both inside the
   60–75 band this pass was asked to hit. */
.ln-never-h {
  grid-column: 2;
  margin: 0;
  max-width: 34rem;
  font-family: var(--f-ui);
  font-weight: 500;
  font-size: var(--t-body);
  line-height: 1.35;
  color: var(--ink);
}
.ln-never-p {
  grid-column: 2;
  margin: 0;
  max-width: 34rem;
  font-size: var(--t-micro);
  line-height: 1.6;
  color: var(--ink-2);
}

/* ══════════════════════════════════════════════════════════════════
   5 · WHAT IT BECOMES — copy beside a vault shown filling.
   THE VAULT IS A COMPOSITION, NOT A COMPONENT. Every row below is
   static markup; nothing here reads a database, and no row is a real
   answer. No accent in this view.
   ══════════════════════════════════════════════════════════════════ */
.ln-becomes {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--room-sm);
  align-items: center;
}
/* §ED551 · THE COPY COLUMN IS THE WIDER ONE, AND THE GAP IS NARROWER.
   At 1fr/1fr with an 88px gap the copy track measured 496px, which holds
   57 average characters — under the 60–75 band this pass was asked to
   hit, and structurally unreachable without moving one of the two terms.
   1.1fr against 1fr, with the gap capped at 64px, puts the copy at 535px
   (61 characters) and still leaves the vault card 487px, which is 25px
   MORE than the 462px it would have had at 1fr with the old gap. Both
   columns gained; the measure was bought from the gutter, not from the
   picture. */
@media (min-width: 900px) {
  .ln-becomes { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); gap: clamp(var(--s-xl), 4vw, 64px); }
}
/* ── BODY COPY IS ADDRESSED BY CLASS, NEVER BY `p` ────────────────
   These two rules were `.ln-becomes-copy p` and
   `.ln-becomes-copy p:first-of-type`, and the descendant selector took
   with it every <p> in the block — including ones that already had a
   role. Measured, not suspected:

     the eyebrow in WHAT IT BECOMES painted --ink (#14120E), because it
       IS the first <p> in its block and :first-of-type counts elements,
       not intentions;
     the eyebrow in THE APP painted --ink-2, because `.ln-app-copy p`
       is (0,2,0) and `.ln-eyebrow` is (0,1,0);
     and the capture's own sub-line went with it, so the two identical
       sub-lines under the two identical captures rendered a full rung
       apart in ink — and in THE APP the Privacy Policy link came out
       pixel-identical to the sentence around it.

   Six eyebrows, three different colours, none of it typed on purpose.
   The fix is that a paragraph now says what it is. */
/* §ED551 · THE MEASURE, RAISED OFF 34ch INTO THE 60–75 BAND.
   34ch rendered 39 AVERAGE characters, because the 'ch' unit measures
   the ZERO glyph and Hanken's zero is narrower than its average letter.
   The cap is now in rem so what is being set is the number that was
   measured. 34rem = 544px = 62 average characters at --t-body. */
.ln-lede { margin: var(--s-lg) 0 0; max-width: 34rem; color: var(--ink); line-height: 1.6; }
.ln-body { margin: var(--s-lg) 0 0; max-width: 34rem; color: var(--ink-2); line-height: 1.6; }

/* §ED563 · THE PARAGRAPH THAT CLOSES THE THREE STEPS. Type is .ln-body —
   this rule sets ROOM and nothing else, so no sixth font-size can enter
   through it. --room-sm because the paragraph is a turn INSIDE the block,
   the same rung the hero's own internal seam takes; --s-lg (.ln-body's own
   default) would sit it as close to the last step as a step value sits to
   its key.

   IT IS DECLARED HERE, AFTER .ln-body, AND THAT POSITION IS LOAD-BEARING.
   Both selectors are one class, so specificity is a tie and SOURCE ORDER
   decides. Written up beside .ln-steps — its logical home — it lost to
   .ln-body's shorthand `margin` and rendered 24px where 36px was declared;
   audit-ed556.js §5b measured 0.67 x step and went red, which is the arm
   working. It is not written as #ln-how .ln-how-close: an id in this sheet
   to win a tie is a specificity race, and this sheet's own note says
   nothing here depends on one. */
.ln-how-close { margin-top: var(--room-sm); }

/* §ED551 · THE CARD SHOWS ACCUMULATION INSTEAD OF DESCRIBING IT.

   WHAT WAS ALREADY HERE, so this is not read as a rebuild from nothing:
   five rows of question + waveform + duration. What it did not have is
   the thing the block is named for. Five rows are five answers; they are
   not five weeks, and "what it becomes" is a claim about TIME.

   THREE THINGS WERE ADDED, and each is the same motif rather than a new
   visual language:
     · .ln-vault-span — one bar per day for thirty-five days, oldest at
       the left, today at the right and still empty. A calendar drawn as
       audio. A dot grid or a streak strip would have been a second
       language competing with the waveform in the same 300px.
     · .ln-vault-d — a day label per row, so the rows are DATED entries.
       Weekday words rather than calendar dates: this markup is static
       and a composed "Mar 4" is wrong the day after it ships.
     · four visibly different waveform SHAPES. The old five all ran
       mid-range, so "different recordings" was asserted by the durations
       and contradicted by the picture beside them.

   RULED BY JAKE: the audio symbolism IN THIS CARD is the lime accent,
   and it is spelt --lime-ink. That token IS #CCFF00 in dark. In light it
   is #3D4D00, because literal #CCFF00 on the --surface ground measures
   1.16:1 — the same reason --lime-ink exists at all, stated at :root.
   Two-pixel bars are line work and line work needs the readable tier.
   The area is measured per section and reported (§ED440). */
.ln-vault {
  padding: var(--s-lg);
  border-radius: var(--r-lg);
  background: var(--surface);
  border: 1px solid var(--line-2);
  box-shadow: var(--shadow-2);
}
.ln-vault-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-md);
  margin: 0 0 var(--s-md);
}
.ln-vault-cap {
  font-family: var(--f-mono);
  font-size: var(--t-micro);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
}
/* The count is the one number that says "this accumulates". It is a
   rung of ink ABOVE the caption beside it — the caption names the card,
   the count is the fact. */
.ln-vault-count {
  font-family: var(--f-mono);
  font-size: var(--t-micro);
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--ink-2);
  white-space: nowrap;
}

/* ── THE THIRTY-FIVE-DAY SPAN ────────────────────────────────────
   preserveAspectRatio="none" on the SVG, so the bars stretch to whatever
   width the card gets and the span always covers exactly the card. That
   is right for this one and wrong for the row waves: a day column that
   widens with the card still reads as a day column, where a stretched
   ROW wave would claim a different recording at a different breakpoint. */
.ln-vault-span { margin: 0 0 var(--s-lg); }
.ln-span { display: block; width: 100%; height: 40px; }
.ln-day { fill: var(--lime-ink); }
.ln-day--off { fill: var(--line); }
.ln-vault-span-x {
  display: flex;
  justify-content: space-between;
  gap: var(--s-md);
  margin-top: var(--s-xs);
  font-family: var(--f-mono);
  font-size: var(--t-micro);
  line-height: 1.2;
  color: var(--ink-3);
}

.ln-vault-list { margin: 0; padding: 0; list-style: none; display: grid; gap: 0; }
.ln-vault-row {
  display: grid;
  grid-template-columns: 4rem minmax(0, 1fr) auto auto;
  align-items: center;
  gap: var(--s-md);
  padding: var(--s-sm) 0;
  border-top: 1px solid var(--line-2);
}
.ln-vault-d {
  font-family: var(--f-mono);
  font-size: var(--t-micro);
  line-height: 1.2;
  color: var(--ink-3);
}
/* Below 480 the row is day + question + duration. The waveform is the
   first thing to go because it is the only cell carrying no information
   the reader needs — it says "this is audio", which the duration beside
   it already says in words a screen reader can read out. The DAY stays:
   it is the cell that makes these dated entries rather than a list. */
@media (max-width: 479.98px) {
  .ln-vault-row { grid-template-columns: 3.25rem minmax(0, 1fr) auto; gap: var(--s-sm); }
  .ln-vault-row .ln-wave { display: none; }
}
.ln-vault-row:first-child { border-top: 0; }
/* §ED551 · TWO LINES, NOT ONE LINE WITH AN ELLIPSIS. Measured: at 1440
   the question cell is 210px, which is 26 characters of Fraunces at the
   16px floor — so single-line-plus-ellipsis truncated every composed
   question MID-WORD ("What did your grandmothe...") and at 390 it cut
   them at 22 characters. A vault row that cannot show its own question
   is not showing a vault. Two lines hold 52 characters at 1440 and 44 at
   390, which is longer than every string in this card; the clamp stays
   so that a longer REAL question degrades to an ellipsis at a word
   boundary instead of overflowing the row. */
.ln-vault-q {
  min-width: 0;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  overflow-wrap: break-word;
  font-family: var(--f-edit);
  font-size: var(--t-micro);
  line-height: 1.4;
  color: var(--ink);
}
.ln-vault-dur {
  font-family: var(--f-mono);
  font-size: var(--t-micro);
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--ink-3);
}
/* The row still to come. Ink only — no dashed "empty state" frame. Its
   waveform is a flat line at the silence floor, which is what an
   unanswered question looks like: present, and carrying nothing. */
.ln-vault-row--open .ln-vault-q { color: var(--ink-3); font-style: italic; }

/* ══════════════════════════════════════════════════════════════════
   THE WAVEFORM — THE PAGE'S ONE MOTIF, DRAWN ONCE.

   §ED551 · IT WAS DIV BARS AND IS NOW INLINE SVG. Each bar used to be an
   <i> with an inline `--h` percentage; it is now a <rect> in a viewBox
   0 0 N 100. Three things that bought:
     · it scales. The thirty-five-day span has to fill a fluid card;
       percentage-height flex children cannot stretch horizontally.
     · one implementation. The motif now draws the promises, the vault
       rows, the span and the phone from the same markup and the same
       four rules below, instead of existing in one block and nowhere
       else.
     · no icon font and no raster, which is what "sharp at any density"
       requires and what the probe asserts.

   COLOUR TRAVELS AS `color`, NOT AS `fill`. Every rect is
   fill:currentColor, so a container sets the whole motif with one
   property and the cascade does the rest — which is what lets the vault
   card override it in ONE place below, per ruling.

   preserveAspectRatio="none" plus a fixed CSS width/height is deliberate
   for the row waves: the bars are drawn on a 0–100 scale and squashed
   into 22px, so every wave on the page shares one vertical scale
   regardless of how many bars it has. */
.ln-wave { display: block; width: 72px; height: 22px; color: var(--ink-3); flex: none; }
.ln-wave rect, .ln-mark rect { fill: currentColor; }
.ln-wave--lime { color: var(--lime-ink); }
/* RULED: lime is the audio symbolism INSIDE the vault card, and only
   there. This is (0,2,0) so it beats .ln-wave (0,1,0) — and the open
   row's rule below is also (0,2,0) and comes AFTER, which is what keeps
   an unanswered day at --line rather than repainting it lime. Document
   order settles it; nothing here depends on a specificity race. */
.ln-vault .ln-wave { color: var(--lime-ink); }
.ln-vault .ln-wave--open { color: var(--line); }

/* ══════════════════════════════════════════════════════════════════
   6 · THE APP — a device frame, and an honest CTA.
   ACCENT FOR THIS VIEW IS THE RECORD AFFORDANCE INSIDE THE PHONE, so
   the email submit beside it is .ln-btn (outline), never .ln-btn-accent.
   Two lime fields in one view is the §ED440 breach this block is most
   likely to acquire, and the outline button is how it is prevented.

   NOTHING IN THIS BLOCK IS A DOWNLOAD BUTTON. There is no Apple badge,
   no storefront link and no app yet — the probe asserts Apple's
   storefront name appears zero times in the page.
   ══════════════════════════════════════════════════════════════════ */
/* THE COLUMNS STRETCH; ONLY THE PHONE IS CENTRED IN ITS OWN.
   An earlier draft used `justify-items: center` / `start` on the grid,
   which shrink-wraps EVERY item to its content: the copy column measured
   385.7px inside a 496.8px track at 1440, and the email row — 224 + 10 +
   163 = 397px of content — wrapped its button onto a second line inside a
   column that had 100px of unused room. Measured, not spotted: the shot
   showed a stacked form and the cause was two tracks away from it. */
.ln-app {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--room-sm);
  align-items: center;
  justify-items: stretch;
}
.ln-app-figure { justify-self: center; }
/* §ED565 · 1.1 / 0.9, NOT 1 / 1, AND THE REASON IS THE MEASURE.
   The columns were even, which gave the copy a 496.8px track at 1440.
   The merged block's reading line (.ln-pick-v) sits inside that track
   behind a checkbox indent, and 496.8 − indent measured 59 average
   characters against audit-ed549.js §15's 60–75 band — one character
   under, on a page whose whole typographic ruling is that band. The
   even split was never a decision; it was the default.
   The figure gives up what the copy needs: .ln-device is
   min(300px, 76vw) and centres in its own track, so a 447px column
   holds it with 147px to spare. Measured after the change and printed
   in §ED565's report, not assumed. */
@media (min-width: 900px) {
  .ln-app {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
    gap: clamp(40px, 6vw, 88px);
  }
  .ln-app-copy { order: 1; }
  .ln-app-figure { order: 2; }
}
.ln-app-copy .ln-body { margin: var(--s-lg) 0 0; }

/* ── §ED565 · THE ONE ADMISSION. This is #ln-family's .ln-family-note
   rule, kept whole and renamed for the block it now lives in: the same
   rung, the same micro size, the same --ink-3. What changed is the
   name and the max-width — the 34rem cap was written for a
   .ln-sec--narrow measure and would never bind inside a 546px grid
   track, so it is dropped rather than kept as a number that cannot
   fire. The track is the cap now, and §15 measures it. */
.ln-coming-note {
  margin: var(--s-lg) 0 0;
  font-size: var(--t-micro);
  line-height: 1.6;
  color: var(--ink-3);
}

/* ── THE DEVICE. Drawn entirely in CSS — no screenshot, no raster — so
   it is sharp at any pixel density and follows the theme for free.
   Aspect ratio 393:852 is the iPhone 15/16 logical viewport. */
.ln-device {
  position: relative;
  width: min(300px, 76vw);
  aspect-ratio: 393 / 852;
  padding: 10px;
  border-radius: 46px;
  background: var(--bg-deep);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-3);
}
/* The bezel highlight. ONE light source, above and slightly in front —
   so the catch-light sits along the TOP edge and fades before the
   bottom, in both themes. */
.ln-device::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(180deg, var(--sheen), transparent 42%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask-composite: exclude;
  pointer-events: none;
}
/* THE SCREEN IS --surface, NOT --bg. First draft used --bg and the probe
   measured the screen ground as byte-identical to the page ground behind
   it in BOTH themes: the phone dissolved into the section and only the
   bezel ring proved it was there. A lit screen is lighter than the room
   in light mode and lighter than the night in dark mode, which is what
   --surface is in both. */
.ln-screen {
  position: relative;
  height: 100%;
  border-radius: 37px;
  overflow: hidden;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  padding: 14px 18px 20px;
}
/* Dynamic Island. A real device paints it black in both themes. */
.ln-island {
  position: absolute;
  top: 9px;
  left: 50%;
  transform: translateX(-50%);
  width: 33%;
  height: 22px;
  border-radius: 999px;
  background: #0A0908;
}
.ln-statusbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 22px;
  font-family: var(--f-mono);
  font-size: 10px;              /* device chrome, aria-hidden — not page copy */
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  letter-spacing: 0;
}
.ln-status-r { display: flex; align-items: flex-end; gap: 4px; }
.ln-bars { display: flex; align-items: flex-end; gap: 1.5px; height: 9px; }
.ln-bars > i { display: block; width: 2px; border-radius: .5px; background: var(--ink-2); }
.ln-bars > i:nth-child(1) { height: 40%; }
.ln-bars > i:nth-child(2) { height: 60%; }
.ln-bars > i:nth-child(3) { height: 80%; }
.ln-bars > i:nth-child(4) { height: 100%; }
.ln-batt {
  width: 20px; height: 10px;
  border: 1px solid var(--ink-3);
  border-radius: 3px;
  padding: 1.5px;
}
.ln-batt > i { display: block; height: 100%; width: 68%; border-radius: 1px; background: var(--ink-2); }

.ln-screen-head {
  margin: 20px 0 0;
  font-family: var(--f-mono);
  font-size: var(--t-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
/* The question, in Fraunces — the same editorial face the vault rows and
   the real question surface use.

   IT IS THE LARGEST THING ON THE SCREEN, because on the real screen it
   is. It first shipped at --t-micro (16px), which is the page's FLOOR —
   a size chosen for labels and microcopy — and inside a 300px frame that
   made the one string the whole block exists to show read as caption
   text sitting under a bigger eyebrow. The frame is drawn at ~76% of an
   iPhone's 393pt width, so 22px here is roughly 29pt on the device: the
   scale a question meant to be read across a kitchen actually wants.
   The ramp is a clamp so the phone keeps its proportions when the
   figure shrinks under the 900px breakpoint. */
.ln-screen-q {
  margin: 14px 0 0;
  font-family: var(--f-edit);
  font-weight: 400;
  font-size: var(--t-lead);
  line-height: 1.3;
  letter-spacing: -0.008em;
  color: var(--ink);
}
.ln-screen-wave { margin: auto 0 0; }
/* Full width of the screen and 42px tall, on the same axis as the record
   button below it — left-aligned or shrink-wrapped, the two read as
   unrelated objects that happen to share a screen.

   GEOMETRY ONLY. `color` is deliberately NOT set here: .ln-wave--lime on
   the element itself is what paints it, so the phone and the vault name
   the same token in the same way. Setting it here would be (0,2,0)
   silently outranking the modifier class and the next reader would have
   two places to look. */
.ln-screen-wave .ln-wave { width: 100%; height: 42px; }

/* The record affordance — THIS VIEW'S ONE LARGE-AREA ACCENT. */
.ln-record {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-sm);
  margin: var(--s-lg) 0 0;
}
.ln-record-dot {
  width: 66px;
  height: 66px;
  border-radius: 50%;
  background: var(--lime);
  box-shadow: var(--shadow-2);
  position: relative;
}
/* Lit from above and slightly in front, agreeing with every other
   shadow on the page. */
.ln-record-dot::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(180deg, rgba(255,255,255,.45), rgba(255,255,255,0) 58%);
}
.ln-record-cap {
  font-family: var(--f-mono);
  font-size: var(--t-micro);
  color: var(--ink-3);
}

/* ── The email capture. REUSES js/waitlist.js — .wl-form / .wl-email /
   .wl-submit / .wl-error is that script's whole contract, and
   data-source tags this surface in waitlist_emails.source. No second
   capture was built. */
.ln-form { margin: var(--s-lg) 0 0; max-width: 30rem; width: 100%; }
.ln-form-row { display: flex; gap: var(--s-sm); flex-wrap: wrap; }
.ln-input {
  /* 12rem, not 14. At 900 the two-column grid gives this block a 385px
     track and the row's content came to 397px at a 14rem basis — the
     button wrapped for 12px. The basis is the only term that can move
     without shortening the button's label, and 12rem + gap + button =
     365px clears the narrowest track the two-column layout ever hands it. */
  flex: 1 1 12rem;
  min-width: 0;
  padding: var(--s-md) 20px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  font-family: var(--f-ui);
  font-size: var(--t-body);
  line-height: 1.2;
}
.ln-input::placeholder { color: var(--ink-3); }
.ln-error { margin: var(--s-sm) 0 0; min-height: 0; color: var(--danger); font-size: var(--t-micro); }
.ln-error:empty { margin: 0; }
.ln-form-sub { margin: var(--s-sm) 0 0; color: var(--ink-3); font-size: var(--t-micro); line-height: 1.6; }
/* THE POLICY LINK HAS TO LOOK LIKE ONE. It inherited --ink-3 from the
   line and carried no underline, so it was pixel-identical to the words
   around it. That was survivable while it read "See our Privacy Policy."
   — the lead-in did the signalling. §ED549d ends the line with the bare
   label, so the only thing left to say "this is a link" is the link's
   own styling, and there wasn't any. One rung of ink above the sentence,
   plus a hairline underline. */
.ln-form-sub a {
  color: var(--ink-2);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--line);
}
.ln-form-sub a:hover { color: var(--ink); text-decoration-color: currentColor; }
/* On the phone the row genuinely cannot hold both — 397px of content in a
   350px column — so the button takes the full second line rather than
   sitting as a short stub under a full-width field. */
@media (max-width: 479.98px) {
  .ln-form-row .ln-btn { width: 100%; }
}

/* ── The success state. js/waitlist.js REPLACES the submitted form with
   this markup, so it inherits nothing from .ln-form and must stand
   alone. It is the screen a reader sees ONLY after converting — an
   unstyled callout would never appear in any screenshot taken before
   conversion, and the one person who found it would be the one person
   who had just signed up (§ED462's lesson, carried over deliberately). */
.wl-callout {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin-top: var(--s-md);
  padding: var(--s-md) 20px;
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: var(--surface-2);
}
/* waitlist.js hard-codes stroke="#1f1b12" on the tick — a dark ink with
   no contrast on a dark ground. The lime chip puts the literal it
   hard-codes on the surface it was chosen for, in BOTH themes, without
   forking the shared script. */
.wl-callout-ico {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--lime);
}
.wl-callout-txt { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.wl-callout-h { font-family: var(--f-ui); font-weight: 500; font-size: var(--t-body); color: var(--ink); }
.wl-callout-p { color: var(--ink-2); font-size: var(--t-micro); line-height: 1.6; }
.wl-callout-p strong { color: var(--ink); font-weight: 500; }

/* ══════════════════════════════════════════════════════════════════
   7 · THE PICKS — four lines that are CONTROLS, inside the capture.

   §ED565 · WHAT STOOD HERE. Section 7 dressed #ln-family:
   .ln-family-lines (a 34rem grid of three plain <li>), .ln-family-note
   (the "not built yet" sentence) and `#ln-family .ln-form`. The section
   is merged into #ln-app and every one of those rules went with it —
   .ln-family-note survives as .ln-coming-note in section 6 above, and
   the other two are replaced by what is below rather than carried
   forward as rules with no subject, which is this sheet's standing law.

   THE BOX IS THE NATIVE CHECKBOX. accent-color paints the checked fill
   and the tick with ONE declaration in both themes, so there is no
   hand-drawn tick, no ::before, and nothing to keep in sync with the
   control's real state — the picture cannot disagree with what is
   checked because the browser draws it from what is checked.

   IT IS --ink, NOT --lime, AND THAT IS §ED440 NOT TASTE. This block
   already spends its one large-area accent on the record affordance
   inside the phone. Four checked lime boxes beside it would be the
   second accent field audit-ed556.js's `accent` arm exists to catch —
   the same breach, at a site the arm does not point at. (Each box is
   ~324px², well under the 4000px² the census calls large, so the
   census would not have caught this one; the rule is being kept
   because it is the rule, not because a probe is watching.)

   THE WHOLE ROW IS THE HIT AREA. The <label> wraps its own input and
   is a grid, so a tap anywhere on either line toggles the box. 44px is
   the floor and the two-line rows clear it on their own; min-height
   holds it if a line ever gets shorter.
   ══════════════════════════════════════════════════════════════════ */
.ln-picks {
  margin: var(--s-xl) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--s-sm);
}
.ln-pick {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 14px;
  min-height: 44px;
  padding: 6px 0;
  cursor: pointer;
}
/* 20px, and it is a real <input type=checkbox>. appearance is NOT
   removed: the native control is the one that is announced, focusable
   and checked, and accent-color is the supported way to ink it. */
.ln-pick-box {
  width: 20px;
  height: 20px;
  margin: 0;
  flex-shrink: 0;
  accent-color: var(--ink);
  cursor: pointer;
  /* The key line is 18px/1.5 = 27px tall; centring the box on it takes
     (27 − 20) / 2 = 3.5px of nudge. Stated so it is a derivation and not
     a magic number. */
  margin-top: 3.5px;
}
.ln-pick:focus-within .ln-pick-k { text-decoration: underline; text-underline-offset: 3px; }
.ln-pick-t { display: grid; gap: 2px; min-width: 0; }
/* The key is .ln-step-k's role in this block — a short named thing —
   and it is set like one so the two lists read as one page. */
.ln-pick-k {
  font-family: var(--f-ui);
  font-weight: 500;
  font-size: var(--t-body);
  line-height: 1.5;
  color: var(--ink);
}
/* THE READING LINE OF THIS BLOCK, and the one audit-ed549.js §15
   measures against the 60–75 band. --t-micro, not --t-body: at 18px
   the 546px track holds 57 characters and at 16px it holds 66. The
   band chose the size; nothing here was set by eye. */
.ln-pick-v {
  font-size: var(--t-micro);
  line-height: 1.6;
  color: var(--ink-2);
}
/* The picks sit INSIDE .ln-form, so the form's own top rung would stack
   with .ln-picks' — the row of field + button takes the seam instead. */
.ln-form--coming { margin-top: 0; max-width: 34rem; }
.ln-form--coming .ln-form-row { margin-top: var(--s-lg); }

/* ══════════════════════════════════════════════════════════════════
   8 · PRICING — DELETED BY §ED560, WITH THE MARKUP IT DRESSED.

   Section 8 of index.html is gone (see the note where it stood), so the
   171 lines that styled it are gone rather than left as rules with no
   subject: .ln-sec--priced, .ln-priced-head, .ln-plans, .ln-plan,
   .ln-plan--feature, .ln-plan-tag, .ln-plan-n, .ln-plan-price,
   .ln-plan-per, .ln-plan-p, .ln-plan-cta and the 760px/900px media
   queries that laid them out. §ED551's ruling on .ln-lead, applied
   again: a rule that styles nothing is a rule the next pass revives.

   THE TYPE RAMP DID NOT MOVE. .ln-plan-n named --t-lead and
   .ln-plan-price named --t-head; both rungs are still declared and both
   are still used (.ln-wordmark, .ln-hero-sub, .ln-step-k, .ln-screen-q
   on --t-lead; .ln-h2 on --t-head). Five rungs before, five after —
   scripts/audit-ed549.js §11 counts the RENDERED sizes and stays green.

   .ln-btn-accent SURVIVES: the closing CTA is still an accent button,
   and it was never a pricing rule.
   ══════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════════════
   9 · CLOSING — accent: the repeated primary CTA.

   §ED614 · FULL-BLEED DARK BAND. The photograph sits on a ::before, not
   an <img> — decorative by construction, same reasoning as the hero's
   own §ED613 background-image: it never enters the accessibility tree
   and (at z-index:-1 inside this section's own stacking context) can
   never paint over .ln-closing-cta, so it can never intercept a click
   on it either. .ln-closing itself stays the max-width/centered column
   it always was, for the text; the ::before is what actually bleeds to
   the viewport edge, via the standard 50%/-50vw idiom, which reaches
   full width regardless of any ancestor's own max-width — the
   masthead's negative-gutter trick (line 306) only cancels .ln-page's
   own padding and would not reach the edge from inside this section's
   narrower centred box.

   ONE ASSET, NO THEME PAIR — deliberate (§ED614 brief): the image has
   no light variant, so unlike the hero's wave-light/wave-dark switch
   there is nothing here keyed to html[data-theme].

   THE EDGE FADE. #100E0C is not a new colour invented for this band —
   it is the dark theme's own --bg (line 236), used here as a literal
   because this section is dark in BOTH themes and must not become a
   third copy of that ramp. Four layers, listed top-to-bottom in paint
   order (first listed paints on top): a flat scrim so the text has a
   readable ground even over the image's busy centre; a bottom fade,
   strongest of the four, because the bottom edge is the seam into
   .ln-footer; a lighter top ease; and a radial vignette that pulls the
   left/right/corner ground to solid #100E0C so the photograph reads as
   bleeding into the band rather than sitting in it as a rectangle. */
.ln-closing {
  position: relative;
  /* isolation:isolate, NOT a bare z-index. .ln-page (line 289) already
     carries z-index:1, and .ln-closing's own ::before needs to be
     z-index:-1 relative to a stacking context THIS section owns —
     without one, position:relative alone does not create one, and the
     negative z-index escapes to .ln-page's context and paints behind
     body's own background, i.e. invisible. isolation says "contain
     stacking here" without also claiming a z-index value that could
     collide with something else on the page. */
  isolation: isolate;
  max-width: var(--measure);
  margin-inline: auto;
  padding-block: var(--room-xl);
  text-align: center;
}
.ln-closing::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 100vw;
  margin-left: -50vw;
  z-index: -1;
  background-image:
    linear-gradient(rgba(16, 14, 12, .38), rgba(16, 14, 12, .38)),
    linear-gradient(to bottom, rgba(16, 14, 12, 0) 55%, #100E0C 100%),
    linear-gradient(to top, rgba(16, 14, 12, .55) 0%, rgba(16, 14, 12, 0) 22%),
    radial-gradient(ellipse 75% 75% at center, rgba(16, 14, 12, 0) 32%, #100E0C 100%),
    url("/assets/ui/hands.webp");
  background-repeat: no-repeat;
  background-position: center center;
  background-size: cover;
}
/* THE LIGHT-MODE FLIP, SCOPED HERE ONLY. .ln-h1's --ink and .ln-hl's
   --lime-ink are correct for a light ground and become illegible on
   this section's dark one in light mode — dark mode already reads
   correctly, because its --ink/--lime-ink ARE these values (lines
   238/240), so this rule changes nothing there. These are literal
   hex, not a token redeclaration: the brief is explicit that the
   theme tokens themselves stay untouched, so this section carries its
   own copy of the two values instead of re-pointing --ink globally. */
.ln-closing .ln-h1 { max-width: 18ch; margin-inline: auto; color: #F5F2EC; }
.ln-closing .ln-hl { color: #CCFF00; }
/* The focus ring is the same trap one layer down: var(--focus) is
   #14120E in light mode, drawn with a 3px offset that lands it on this
   section's dark ground, not on the lime button — effectively
   invisible. Scoped to .ln-closing only, same as the two rules above. */
.ln-closing :where(a, button, input, [tabindex]):focus-visible { outline-color: #CCFF00; }
.ln-closing-cta { margin-top: var(--s-2xl); }

/* ── FOOTER — the two links a paid product is required to carry. ── */
.ln-footer {
  max-width: var(--measure);
  margin-inline: auto;
  padding: var(--room-sm) 0 calc(var(--room-sm) + var(--s-sm));
  border-top: 1px solid var(--line-2);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-sm) var(--s-lg);
  align-items: baseline;
  justify-content: space-between;
  font-family: var(--f-mono);
  font-size: var(--t-micro);
  color: var(--ink-3);
}
.ln-footer a { color: var(--ink-3); text-decoration: none; }
.ln-footer a:hover { color: var(--ink); }
.ln-footer-links { display: flex; gap: var(--s-lg); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .ln-btn, .ln-masthead, .ln-login { transition: none; }
  .ln-btn:hover { transform: none; }
}

/* ══════════════════════════════════════════════════════════════════
   NOHEMI — THE ONLY DECLARATION OF THIS FAMILY IN THE REPO.

   §ED437 IS CLOSED AND ITS PREMISE IS NO LONGER TRUE. The note that
   Nohemi is unreachable in production described a page pointing at
   /prototype/fonts/, which netlify.toml:315 force-404s. The three files
   below are under /assets/fonts/, are TRACKED IN GIT, and /assets/* is a
   cached, served path (netlify.toml:590). scripts/audit-ed549.js asserts
   the H1 actually RASTERISES in Nohemi via CDP CSS.getPlatformFontsForNode
   — a computed font-family string says 'Nohemi' whether or not the file
   loaded, so it cannot see this failure and is not the instrument used.

   Only two weights ship (400 and 500). 300 is declared because the file
   is on disk and licensed, and is referenced by nothing on this page.
   ══════════════════════════════════════════════════════════════════ */
@font-face {
  font-family: 'Nohemi';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/assets/fonts/Nohemi-Regular.woff2) format('woff2');
}
@font-face {
  font-family: 'Nohemi';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/assets/fonts/Nohemi-Medium.woff2) format('woff2');
}
@font-face {
  font-family: 'Nohemi';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(/assets/fonts/Nohemi-Light.woff2) format('woff2');
}
/* Fraunces and Hanken Grotesk are NOT declared here. css/global.css
   already declares all four faces (ext + base for each) and index.html
   loads it before this sheet. Two sheets declaring one family is how one
   of them drifts and drops the Czech carons — the -ext subsets carry
   9/9 of čřšžěůňťď and the base subsets carry 0/9 (§ED462, measured with
   fontTools on the binaries). One declaration cannot drift. */
