/* ============================================================================
   Tax Penalty Reply - the design system for all three public pages.
   WO-TPR-REDESIGN-2.

   WHAT CHANGED, AND WHY. Pass 1 (WO-TPR-REDESIGN) built this file from design
   RULES and produced a page that was correct and still read dated. This pass was
   built from REFERENCES: optimataxrelief.com (the category leader a stressed
   taxpayer measures us against), turbotax.intuit.com (best in class consumer tax
   trust design, whose Intuit DDMS 3.0 token file was read directly), and
   lemonade.com (the consumer brand whose thesis is "our business model does not
   conflict with yours", and the proof that a wholly ILLUSTRATED, photograph free
   page carries financial trust at the top of the market).

   The five things those references do that pass 1 did not:

   1. THEY PUT A SUBJECT IN THE HERO. All three anchor the first screen on a
      drawn or photographed thing, not on a text block. We have no photography
      and may not hotlink any, so this page draws its own: see the "scene" rules
      below and the inline SVG in the pages. Lemonade's entire hero is SVG.
   2. THEY VARY THE CONTAINER PER SECTION. Pass 1 rendered nine sections as the
      same white rounded card with the same hairline and the same shadow, which
      is exactly what a dated template looks like. Optima runs eleven distinct
      treatments in eleven sections. So does this file now: full bleed bands,
      bare rule lists, a raised card, a flat panel, a document, an accordion on
      rules.
   3. THEY SPEND WEIGHT ON THEIR TRUST SIGNALS. Optima gives three statistics a
      whole coloured band. Lemonade gives three institutional facts a whole
      strip. TurboTax makes one word a link to its own substantiation and prints
      a wall of disclosure. Our trust signals are better than theirs and were set
      as ordinary body copy: the flat price, the refusal policy, the "you could
      do this yourself for free" section, and the Commitment statement. Each one
      now gets a treatment of its own.
   4. THEY SET NUMBERS AS NUMBERS. "$3 Billion". "90 seconds". "4.7 out of 5".
      We already own $99, $149, sixty seconds and $25,000 and had every one of
      them buried inside a sentence. --fig exists for that.
   5. THEY AUTHOR THE PHONE FIRST. Pass 1 was desktop first: the base rules were
      the desktop layout and two max-width queries collapsed it, which makes the
      phone the least designed state of a product whose reader is holding an IRS
      notice in one hand. Every rule below is the phone; min-width: 640px and
      min-width: 1000px upgrade it.

   WHAT THIS FILE MAY NOT DO. Every class name, id and data- attribute on these
   pages is load bearing: the page JS selects on them and 14 test files assert on
   them by exact string. This file restyles those hooks and requires no new
   markup that carries meaning. The .commitment / .wrap / .commitment-in /
   .commitment-domain block in particular is generated byte for byte by
   scripts/gen_commitment_block.py and pinned by
   tests/acceptance/test_tpr_commitment.py, so it is styled from out here and
   edited nowhere.

   COLOUR IS AUTHORED IN HEX, CHOSEN ON AN OKLCH RAMP, AND MEASURED. Every text
   pair in use clears 4.5:1 and every large display pair clears 3:1; the awkward
   ones carry their measured ratio in a comment beside them.
   ========================================================================== */

/* --- The two voices ------------------------------------------------------
   BOTH SELF HOSTED, NEITHER FETCHED. tests/acceptance/test_marketing_sites.py
   bans fonts.googleapis.com and fonts.gstatic.com on these pages, and it is
   right to: a public page that phones a third party for its type hands that
   third party a log of every visitor. Both src values below are relative paths
   to files Caddy serves off the same directory mount as the pages.

   THE DISPLAY VOICE is Newsreader (SIL Open Font License), a variable face where
   one file covers weights 400 to 700, latin subset. It stays from pass 1 and it
   was the right call: all three references set their headlines in a serif or a
   distinctive proprietary face, and two of the three use a newspaper lineage
   serif specifically (Optima: Libre Caslon Text; Lemonade: Merriweather).

   THE UI VOICE IS NEW, AND IT IS THE ONE VISIBLE CHANGE PASS 1 MOST NEEDED.
   Pass 1 set the interface in the platform grotesque, which means this page
   rendered in Segoe UI on Windows: the single most reliable tell of an unstyled
   template. Two of the three references pair their serif with a distinctive self
   hosted sans. Ours is PUBLIC SANS (SIL Open Font License, variable 400 to 700,
   latin subset, 27 KB) and the choice is not arbitrary: it is the typeface of
   the U.S. Web Design System. A service whose entire product is a document
   addressed to a federal agency is set in the face that agency's own web estate
   uses. The system stack stays as the fallback, so nothing regresses if the file
   is ever missing.

   font-display: swap on both, with metric-near fallbacks first, so text is
   readable from the first paint. */
@font-face {
  font-family: 'Newsreader';
  src: url('newsreader-latin.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Public Sans';
  src: url('publicsans-latin.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* --- Surface -------------------------------------------------------------
     COOLER AND CLEANER THAN PASS 1, ON PURPOSE. Pass 1 reasoned that warm paper
     reads as "document" and set the canvas to a warm off white. The verdict on
     that page was that it still read dated, and the warm cast is part of why: it
     is an editorial-blog signal, not an institutional one. Every reference here
     runs a white or near white page and lets colour arrive as CONTAINERS
     instead. TurboTax is the extreme case: its page background tokens, primary
     through accent, are all #FFFFFF, and every tint on the page is a container
     with a matched pale border. This palette follows that. */
  --paper:      #FFFFFF;
  --paper-2:    #F4F7FA;
  --surface:    #FFFFFF;
  --surface-2:  #FAFBFD;
  --line:       #E4E9EF;
  --line-2:     #C9D2DC;

  /* Ink. A deep navy-black rather than black, so long passages of legal posture
     read as considered rather than severe. ink-3 is the metadata tint and is
     this dark on purpose: it measures 4.99:1 on --paper-2, which is where it is
     used most, and 5.42:1 on white. The obvious value one step lighter came in
     at 4.20:1 and was rejected. */
  --ink:        #0E1A2B;
  --ink-2:      #4A5766;
  --ink-3:      #5F6B7A;

  /* Institutional navy. This is the colour that says "a real business does
     this", so it owns whole REGIONS rather than appearing as an accent: the
     proof band, the refusal band, the shell headers, the footer. Three full
     bleed regions on the landing page and no more, which is roughly the share
     of coloured scroll height Optima runs. */
  --navy:       #12283F;
  --navy-2:     #0B1B2C;
  --on-navy:    #B9CBE0;    /* 9.07:1 on --navy */
  --on-navy-hi: #FFFFFF;

  /* Action. ONE decisive blue, spent only on the primary action, on links, and
     on the drawn line work that belongs to us rather than to the IRS. It is
     deliberately not the navy: if the button and the header are the same colour
     then nothing on the page is the obvious next step. 7.59:1 on white. */
  --action:     #17539E;
  --action-hi:  #1E68C4;
  --action-bg:  #EEF4FC;
  --action-line:#C8DCF5;

  /* Semantics, on TurboTax's container model: a pale fill with a matched pale
     border, never a saturated block. Relief is what the customer came for,
     alarm is the notice they are holding, caution is a qualified answer. The
     meanings are fixed and nothing else may borrow them. */
  --relief:      #0A6B45;   /* 6.55:1 on white */
  --relief-bg:   #E7F4EE;
  --relief-line: #A9D6BF;
  --alarm:       #A3271A;   /* 7.34:1 on white */
  --alarm-bg:    #FCEEEB;
  --alarm-line:  #F0C9BF;
  --caution:     #7E5206;   /* 6.79:1 on white */
  --caution-bg:  #FDF5E6;
  --caution-line:#E9D4A6;

  /* The wordmark's warm accent, and the one gold on the page. Lightened from
     pass 1 because it sits on the action blue inside the nav button, where the
     old value measured 3.58:1 against text that is not large. This one measures
     4.63:1 there and 9.16:1 on the navy. */
  --gold:       #F0C46A;

  --display: 'Newsreader', Georgia, 'Iowan Old Style', 'Times New Roman', serif;
  --sans: 'Public Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI',
          'Helvetica Neue', Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;

  /* --- Type ladder ---------------------------------------------------------
     Rebuilt on TurboTax's three-tier model. Its ladder steps 48/40/34/28/24/20
     over a body of 20/16/14/12, and every rung is legibly apart from its
     neighbours. Pass 1's ladder was mushy in the middle: h2 at 2.5rem, h3 at
     1.2rem and body at 1.0625rem left h3 barely larger than the paragraph under
     it, so nothing between the section heading and the body had any rank at all.
     clamp() carries the three tiers in one declaration. */
  --t-display: clamp(2.6rem, 7.4vw, 4rem);
  /* The hero's answer line, at EXACTLY 0.75 of --t-display at every width: each
     of the three clamp terms is three quarters of the display term, so the ratio
     holds on a phone, at the clamp's own breakpoints and at full width without a
     media query. See .hero-line for the measurement that chose 0.75. */
  --t-hero-sub: clamp(1.95rem, 5.55vw, 3rem);
  --t-h2:      clamp(1.9rem, 4.6vw, 2.8rem);
  --t-h3:      1.35rem;
  --t-h4:      1.12rem;
  --t-sub:     1.14rem;
  --t-body:    1.0625rem;
  --t-small:   .9375rem;
  --t-micro:   .8125rem;
  --t-nano:    .72rem;
  /* The numeral display size. The two package prices are the largest thing on
     the landing page after the headline, which is the single cheapest gap in the
     analysis to close: Optima prints "$3 Billion", Lemonade prints "90 seconds",
     and we had $99 set at roughly the size of a subheading. */
  --fig:       clamp(3rem, 9vw, 4.25rem);
  --fig-sm:    clamp(2.2rem, 6vw, 2.9rem);

  /* Spacing, on a 4px base. */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px; --s5: 24px;
  --s6: 32px; --s7: 48px; --s8: 64px; --s9: 96px;

  /* Radius, on TurboTax's ladder (action 4, large 8, x-large 12, full 9999).
     Pass 1 sat at 6px with a soft two layer shadow, which is the Bootstrap era
     midpoint: too round to read as precise and too square to read as friendly.
     Both ends of the reference range read current; the middle does not. */
  --r-sm:  4px;
  --r:     8px;
  --r-lg:  12px;
  --r-xl:  16px;
  --r-pill: 999px;

  /* Depth, on TurboTax's four level elevation ladder at its 0.2 shadow opacity,
     tinted with the ink hue. Used sparingly so that being raised still means
     something: on the landing page exactly three things are raised, and each one
     is a thing the reader is meant to act on. */
  --shadow-1: 0 1px 4px rgba(14,26,43,.07);
  --shadow-2: 0 2px 8px rgba(14,26,43,.09);
  --shadow-3: 0 4px 16px rgba(14,26,43,.10);
  --shadow-4: 0 6px 24px rgba(18,40,63,.14);

  /* Motion, on the reference durations and curves. Never ease-in on a UI
     transition: it delays the first frame, which is the moment the user is
     watching most closely, so the same duration feels slower. */
  --ease-out:    cubic-bezier(0, 0, .25, 1);
  --ease-in-out: cubic-bezier(.35, 0, .25, 1);
  --t-press: 120ms;
  --t:       180ms;
  --t-enter: 250ms;
}

/* --- Reset and base ------------------------------------------------------ */
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

/* body is a full height flex column on ALL THREE PAGES so the Commitment
   statement can take the slack and sit on the bottom edge. See the .commitment
   rule near the end of this file. Flex on body is safe BECAUSE of the
   *{margin:0} reset: every gap on these pages is padding, so there are no
   collapsing margins for a flex context to change. */
body {
  font-family: var(--sans);
  font-size: var(--t-body);
  line-height: 1.62;
  color: var(--ink);
  background: var(--paper);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

.wrap { max-width: 1140px; margin: 0 auto; padding: 0 var(--s4); width: 100%; }
@media (min-width: 640px)  { .wrap { padding: 0 var(--s6); } }
@media (min-width: 1000px) { .wrap { padding: 0 var(--s7); } }

a { color: var(--action); text-decoration-thickness: 1px; text-underline-offset: 2px; }

/* A visible, high contrast focus ring is not optional on a form that ends in a
   signed IRS document. */
:focus-visible {
  outline: 2.5px solid var(--action-hi);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

.num { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1; }
.hidden { display: none; }

/* --- The drawn icon system -----------------------------------------------
   ONE STROKE LANGUAGE FOR THE WHOLE SITE. Pass 1 drew its checks and crosses as
   CSS pseudo-elements: a rotated box with two borders for a tick, two rotated
   bars for a cross. That works, but it caps the vocabulary at two marks and the
   marks cannot share a grid with anything else. Every reference runs a real icon
   set instead (Optima's line art above its three steps, TurboTax's 24px
   currentColor SVGs, Lemonade's drawn everything), so these pages now carry
   inline SVG on a 24 unit grid at a single 1.75 stroke with round caps and
   joins.

   They are decoration in the accessibility sense: every icon sits beside frozen
   copy that already says what it means, so each one is aria-hidden and nothing
   is lost by not rendering it. */
.ic {
  width: 22px;
  height: 22px;
  flex: none;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.ic-sm { width: 18px; height: 18px; }
.ic-lg { width: 28px; height: 28px; }
.ic-relief { color: var(--relief); }
.ic-alarm  { color: var(--alarm); }
.ic-action { color: var(--action); }

/* --- Typography ---------------------------------------------------------- */
h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 600;
  line-height: 1.22;
  letter-spacing: -.012em;
  color: var(--ink);
  text-wrap: balance;
}

h1 {
  font-size: var(--t-display);
  line-height: 1.08;
  letter-spacing: -.022em;
}

h2 {
  font-size: var(--t-h2);
  line-height: 1.14;
  letter-spacing: -.018em;
  margin-bottom: var(--s4);
  max-width: 22ch;
}

h3 { font-size: var(--t-h3); }
h4 { font-size: var(--t-h4); }

p { text-wrap: pretty; }

/* The lead paragraph under a section heading. Measure held inside the readable
   range rather than running the full container width. */
.lead {
  color: var(--ink-2);
  max-width: 60ch;
  font-size: var(--t-sub);
  margin-bottom: var(--s6);
}
.lead strong { color: var(--ink); font-weight: 600; }
@media (min-width: 1000px) { .lead { margin-bottom: var(--s7); } }

/* The section kicker and the page eyebrow.

   A floating label above a heading is normally the first thing to cut. It stays
   because the copy on these pages is frozen and, on the form page, the eyebrow's
   text is written by pinned JS (applyState(name,eyebrow) sets
   pageStep.textContent). So it is set as a typographic lead-in that clearly
   belongs to the heading block beneath it: small, tracked, tinted, and joined to
   the heading by a short rule. */
.kicker, .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  font-family: var(--sans);
  font-size: var(--t-nano);
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--action);
  margin-bottom: var(--s3);
}
.kicker::before, .eyebrow::before {
  content: "";
  width: 20px;
  height: 2px;
  background: var(--action);
  flex-shrink: 0;
}

/* --- Nav -----------------------------------------------------------------
   Near white on a hairline rather than pass 1's tinted glass. Every reference
   runs a plain, quiet, sticky bar and spends nothing on it; the only decorated
   thing in the row is the call to action. */
nav {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(255,255,255,.88);
  backdrop-filter: saturate(1.4) blur(12px);
  -webkit-backdrop-filter: saturate(1.4) blur(12px);
  border-bottom: 1px solid var(--line);
}
.nav-in {
  max-width: 1140px;
  margin: 0 auto;
  padding: var(--s3) var(--s4);
  display: flex;
  align-items: center;
  gap: var(--s3);
}
@media (min-width: 640px)  { .nav-in { padding: var(--s3) var(--s6); gap: var(--s4); } }
@media (min-width: 1000px) { .nav-in { padding: var(--s3) var(--s7); } }

/* The wordmark. Set in the display face, with the middle word carrying the
   brand accent, and the seal tile given a drawn rule under its letters, which is
   the mark a prepared document carries. */
.logo {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.16rem;
  letter-spacing: -.018em;
  color: var(--ink);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: var(--s3);
  white-space: nowrap;
}
@media (min-width: 640px) { .logo { font-size: 1.3rem; } }
.logo-mark {
  position: relative;
  width: 34px;
  height: 34px;
  border-radius: var(--r-sm);
  background: var(--navy);
  color: var(--on-navy-hi);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--sans);
  font-size: .64rem;
  font-weight: 700;
  letter-spacing: .08em;
  flex-shrink: 0;
  padding-bottom: 5px;
}
.logo-mark::after {
  content: "";
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 9px;
  height: 1.5px;
  background: var(--gold);
  border-radius: 1px;
}
.logo em { font-style: normal; color: var(--ink); }
.logo-accent { color: var(--alarm); }

.nav-tag {
  font-size: var(--t-nano);
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--ink-3);
  border-left: 1px solid var(--line-2);
  padding-left: var(--s4);
  display: none;
}
@media (min-width: 1000px) { .nav-tag { display: block; } }

/* A pill, which is where both Optima and Lemonade land their one call to action.
   It is the only pill on the site. */
.nav-cta {
  margin-left: auto;
  background: var(--action);
  color: #FFFFFF;
  text-decoration: none;
  font-weight: 600;
  font-size: var(--t-small);
  padding: 10px 18px;
  border-radius: var(--r-pill);
  white-space: nowrap;
  transition: background var(--t) var(--ease-out), box-shadow var(--t) var(--ease-out);
}
.nav-accent { color: var(--gold); }   /* 4.63:1 on --action */
.nav-back {
  margin-left: auto;
  font-size: var(--t-small);
  font-weight: 600;
  color: var(--action);
  text-decoration: none;
  white-space: nowrap;
}

/* --- Buttons -------------------------------------------------------------
   A crisp 4px action radius on TurboTax's ladder, with its 2px border token and
   a real minimum width, instead of pass 1's 6px pill-adjacent shape with a soft
   halo under it. The primary button carries elevation 2 and nothing else on the
   page at that level competes with it. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  font-family: var(--sans);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.2;
  min-width: 120px;
  padding: 14px 24px;
  border-radius: var(--r-sm);
  border: 2px solid transparent;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--t) var(--ease-out), border-color var(--t) var(--ease-out),
              box-shadow var(--t) var(--ease-out), transform var(--t-press) var(--ease-out);
}
.btn-primary {
  background: var(--action);
  border-color: var(--action);
  color: #FFFFFF;
  box-shadow: var(--shadow-2);
}
/* Currently unused in markup: its last two instances were the hero's second
   button (removed by 3) and the second package card's (removed by 3b). KEPT
   deliberately, unlike the packages rules that went with that section. This is a
   variant of the button system, not section furniture, and the next surface that
   needs a secondary action should find it here rather than reinvent it. */
.btn-quiet {
  background: var(--surface);
  border-color: var(--line-2);
  color: var(--navy);
}
.btn[disabled] { opacity: .5; cursor: default; }

/* Press feedback is the fastest thing on the page: the interface confirming it
   heard the tap. Hover is gated so a touch tap does not latch a hover state. */
.btn:active { transform: translateY(1px); }
@media (hover: hover) and (pointer: fine) {
  .btn-primary:hover { background: var(--action-hi); border-color: var(--action-hi); box-shadow: var(--shadow-3); }
  .btn-quiet:hover { border-color: var(--navy); background: var(--paper-2); }
  .nav-cta:hover { background: var(--action-hi); box-shadow: var(--shadow-2); }
}

/* --- Hero ----------------------------------------------------------------
   Phone first and stacked, the way Lemonade's is, upgrading to Optima's
   asymmetric split at 1000px with the drawn subject in the right column. */
/* WO-TPR-REDESIGN-2b. THE HERO IS A BOUNDED BAND, NOT A FADE.

   Reviewed against optimataxrelief.com on desktop, pass 2 left too much empty
   vertical space between the nav and the headline, and there were two causes.

   The first was the background. It was a gradient that started at --paper-2 and
   dissolved into the page by 58%, so the region had no bottom edge and no
   identity: the tint just ran out somewhere above the fold. Optima's hero is a
   BOUNDED FULL BLEED REGION, and that boundary is what makes the space inside it
   read as composition rather than as emptiness. So the tint is now constant
   across the whole band. Its top edge is the nav's own hairline, which the hero
   begins flush against, and its bottom edge is the navy proof band immediately
   below: two hard boundaries, nothing dissolving.

   The second was 96px of top padding on desktop, which is dead zone, not
   composition. It is now 32px, a two thirds cut, and the space above the h1
   reads as band interior. THE PHONE IS DELIBERATELY UNTOUCHED at 48px top: it
   was already compact, the band is the whole viewport width there, and cutting
   it further would crowd the headline against the sticky nav.

   The radial highlight moved with the band: it was aimed at -10% vertically,
   which put its centre above the old taller region, so on the shorter band most
   of it was cropped away. */
.hero {
  padding: var(--s7) 0 var(--s8);
  background:
    radial-gradient(680px 320px at 92% 4%, rgba(23,83,158,.07), transparent 64%),
    var(--paper-2);
  border-bottom: 1px solid var(--line);
}
/* 3c trims the wide-layout band from 32/48 to 24/32. The left stack is centred
   against a taller drawn scene, so its bottom edge sits at
   (top padding) + (row height + stack height) / 2 below the nav; every pixel off
   the top padding comes straight off that, and half of every pixel off the stack
   does too. See the arithmetic beside .hero-line. */
@media (min-width: 1000px) { .hero { padding: var(--s5) 0 var(--s6); } }

/* THE TWO COLUMNS, AND THE HISTORY OF THIS ONE LINE.

   WO-TPR-REDESIGN-2c set align-items: start at >=1000px. The reason was sound at
   the time: the text column was much the taller of the two (headline, sub, three
   fact rows and the action row), so centring pushed the drawn scene visibly
   below the headline and the owner called it out.

   WO-TPR-REDESIGN-3 removed the three fact rows and the supporting paragraph
   from this column, and 3b removed nothing further but restated the type, so the
   premise for that ruling no longer holds: the text stack is now headline, gap,
   sub, button, micro-line, which is SHORTER than the document beside it.
   Starting them together would now hang the text off the top of a taller scene.

   WO-TPR-REDESIGN-3b RULING 5 SUPERSEDES 2c: the left stack is vertically
   centred against the scene. Recorded rather than quietly flipped, because the
   2c comment argued the opposite case and the next person deserves to know the
   inputs changed, not the taste. */
.hero-grid { display: grid; gap: var(--s7); align-items: center; }
@media (min-width: 1000px) {
  .hero-grid { grid-template-columns: 1fr .88fr; gap: var(--s8); align-items: center; }
}

/* The headline block reads dense the way both references set theirs: Optima runs
   its h1 hard against a one line sub with no floating label between them.

   WO-TPR-REDESIGN-3 removed the eyebrow from this hero entirely, which is what
   2b's .hero .eyebrow override existed to tighten, so that rule is deleted
   rather than left to rot. The base .kicker, .eyebrow rule stays: the eyebrow is
   still used in the page-head on the intake form and the status page. */
@media (min-width: 1000px) { .hero h1 { letter-spacing: -.026em; } }

/* The one word the whole page turns on. Pass 1 coloured it and stopped there; it
   now sits over a drawn swash, which is the "annotate the important thing" move
   Lemonade makes with its arrows. A background image rather than a
   pseudo-element, so it survives a line break correctly. */
/* WO-TPR-REDESIGN-3. The green emphasis moved off the headline and onto the
   sub-line, so this selector is no longer scoped to h1. It was .hero h1 .removed
   and is now .hero .removed: the treatment belongs to the WORD, wherever in the
   hero the word lives, and scoping it to a tag is exactly the kind of coupling
   that breaks silently the next time the copy moves. Deliberately NOT global:
   nothing outside the hero should be able to pick it up by accident. */
/* 3d: COLOUR ONLY. The swash is gone.

   Pass 2 drew a --relief-line bar under this word with a background-image, as
   the "annotate the important thing" move Lemonade makes with its arrows. That
   was defensible when the word sat inside a running headline and needed help
   being noticed. It stopped being defensible once 3b made the answer its own
   line at display scale: at that size the word is already the loudest thing in
   the band, and a bar under it read as an underline, which on the web means a
   link. Decoration that impersonates an affordance is worse than no decoration.

   3d also narrows the green to the verb alone. "Remove" is the thing the reader
   wants; "It." is grammar, and colouring grammar dilutes the one word that is
   answering the red "Penalty?" above it. The span moved in the markup rather
   than being faked with a pseudo-element, so what is emphasised is what is
   marked up as emphasised.

   white-space: nowrap went with the rest: it existed so "Remove It." could not
   break across two lines, and the span now wraps a single word that cannot
   break at all. */
.hero .removed { color: var(--relief); }
.hero-accent { color: var(--alarm); }

/* THE SUB IS THE ANSWER, SET AS THE EQUAL OF THE QUESTION (3b rulings 2 to 4).

   The hero is now a question and its answer, and the owner ruled they carry the
   same weight: same face, same scale, same tracking as the h1, so neither one
   subordinates the other. The red Penalty in the question is answered by the
   green Remove It. underneath it, which is why the emphasis colours are on those
   two phrases specifically and on nothing else in this band.

   THE BREAK IS HARD, NOT LUCK. "You May Qualify To / Remove It." is broken with
   a <br> in the markup, so the answer always lands on its own line. Relying on
   wrap would put the break wherever the viewport happened to fall and would
   split the green phrase at some widths. For the same reason there is no
   text-wrap: balance here: balancing would fight the explicit break.

   3c: THE SIZE AND THE GAP WERE BOTH MEASURED, NOT GUESSED.

   3b set this line at the full --t-display so the question and the answer
   carried equal weight. On a real desktop that wrapped to THREE lines with "To"
   orphaned on the second, and the pause below the headline read as a void. Both
   were arithmetic errors on my part, and here is the arithmetic that fixes them.

   THE COLUMN. .wrap caps at 1140px with 48px of padding each side, so its
   content is 1044px at any viewport from 1236px up, including 1280 and 1680. The
   grid is 1fr .88fr with a 64px gap, so the text column is
   (1044 - 64) / 1.88 = 521.28px. That is the number the line has to fit, and it
   does not change between 1280 and 1680 because the wrap is already at its cap.

   THE STRING. Measured off the shipped woff2 at the instance actually rendered
   (wght 600, optical size matched to the pixel size), "You May Qualify To" is
   9.572em at opsz 64 and 9.303em at opsz 48. At the old full display size of
   64px that is 612.6px, less 18 characters of -.026em tracking (30.0px), giving
   582.6px against a 521.28px column: it overflowed by 61px, which is exactly why
   "To" fell to its own line and pushed "Remove It." to a third.

   At 0.75 of display, 48px, it is 446.5px less 22.5px of tracking = 424.0px,
   which clears the column by 97px. Even if a browser applies no optical sizing
   and uses the widest instance, it is 443px and still clears. "Remove It." is
   223.5px, less than half the column, so the hard break holds everywhere.

   THE SAME ORPHAN HAPPENED ON THE PHONE, so the reduction is proportional rather
   than gated behind a media query: at a 390px viewport the column is 358px and
   the old line measured 370px, overflowing by 12px. --t-hero-sub is three
   quarters of --t-display in all three clamp terms, so a 41.6px headline there
   now carries a 31.2px answer measuring 278px, inside a 358px column.

   THE GAP. 1em at this size is 48px, exactly half the 96px that 1.5em at the old
   64px produced, which is the halving the owner ruled. */
.hero-line {
  margin: 1em 0 0;
  font-family: var(--display);
  font-size: var(--t-hero-sub);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -.022em;
  color: var(--ink);
}
@media (min-width: 1000px) { .hero-line { letter-spacing: -.026em; } }
/* 3c: 48px here put the action row below the fold on a 900px-tall viewport once
   the nav and the centred offset were counted. 32px, with the hero band padding
   trimmed alongside it, buys back the room without collapsing the separation
   between the answer and the thing you do about it. */
.hero .cta-row { margin-top: var(--s6); }

.cta-row { display: flex; gap: var(--s3); flex-wrap: wrap; align-items: center; }
.cta-note { width: 100%; font-size: var(--t-micro); color: var(--ink-3); margin-top: var(--s2); }
.cta-row .btn { flex: 1 1 auto; }
@media (min-width: 640px) { .cta-row .btn { flex: 0 0 auto; min-width: 200px; } }

/* --- The premise section (WO-TPR-REDESIGN-3) -----------------------------
   The paragraph and the three facts that used to sit in the middle of the hero.
   Their strings are byte-identical to what they were there; only the setting
   changed, because what works in a narrow column beside a drawing does not work
   across a full measure.

   The paragraph leads at sub scale and holds a readable measure. The three facts
   were a stack on hairline rules in the hero, which is the right shape for a
   narrow column and the wrong one here; across the full width they become a
   three-up on the same grid the proof band and the four steps use, each on its
   own top rule, so they read as three pieces of supporting evidence rather than
   as a list to work through. */
.premise { padding: var(--s7) 0; border-bottom: 1px solid var(--line); }
@media (min-width: 1000px) { .premise { padding: var(--s8) 0; } }
.premise-lead {
  font-size: var(--t-sub);
  color: var(--ink-2);
  max-width: 68ch;
  margin-bottom: var(--s6);
}
.premise-lead strong { color: var(--ink); font-weight: 600; }

.premise-facts { list-style: none; display: grid; gap: var(--s4); }
@media (min-width: 1000px) { .premise-facts { grid-template-columns: repeat(3, 1fr); gap: var(--s6); } }
.premise-facts li {
  display: flex;
  align-items: flex-start;
  gap: var(--s3);
  padding: var(--s4) 0 0;
  border-top: 2px solid var(--line-2);
  font-size: var(--t-small);
  color: var(--ink);
}
.premise-facts .ic { margin-top: 1px; }

/* --- The drawn notice scene ----------------------------------------------
   THE SINGLE BIGGEST GAP PASS 1 LEFT OPEN. All three references anchor the first
   screen on a subject; pass 1's right column was a tinted table. There is no
   photography for this product and none may be hotlinked, so the subject is
   drawn: a windowed envelope and our prepared reply behind, the notice itself in
   front as a real document, and a drawn annotation arrow running from the struck
   through total down to the granted result. Lemonade does exactly this with its
   app sketch and its two hand drawn arrows, and Lemonade has no photographs on
   that page either.

   The frozen notice copy is REAL TEXT inside the drawn sheet, not part of the
   drawing, so it stays selectable, translatable and readable by assistive
   technology.

   WO-TPR-REDESIGN-2b, AND THIS IS A DEFECT REPORT AS MUCH AS A COMMENT. Pass 2
   shipped this block styling a class called .scene-back that DOES NOT EXIST in
   the markup, while the two drawings that do exist, .scene-sheet and .scene-env,
   had no rules at all. Unpositioned inline SVG with a viewBox and no width or
   height resolves to the full width of its container at its own aspect ratio, so
   instead of layering behind and in front of the notice the two drawings laid
   out in normal flow as full width blocks stacked ABOVE and BELOW it: roughly
   450px of unintended column height on desktop, and a large part of the empty
   vertical space this pass was asked to remove. The rules below are what pass 2
   meant to ship.

   THE LAYERING IS THE ILLUSTRATION. The reply sheet sits behind and above at
   z-index 0, the notice sits at 1, and the envelope sits at 2, IN FRONT of the
   notice's lower edge, so the document reads as going into the mail rather than
   as three pictures in a column. The wrap's asymmetric padding is what gives the
   sheet room to show above and the envelope room to sit below; both are sized in
   percentages with a pixel ceiling so the composition holds at 640, at 1000 and
   at full width without a third breakpoint.

   WO-TPR-REDESIGN-2c, TWO RULINGS FROM THE LIVE DESKTOP REVIEW.

   THE ENVELOPE IS GONE. It was drawn in FRONT of the notice's lower edge to make
   the document read as going into the mail, and on a real screen it did not read
   that way: it superimposed over the caption under the figures, which is real
   copy a reader needs, and so it read as an artifact rather than as an idea. A
   decoration that covers text has already lost the argument, so it is removed
   rather than nudged. This is done in CSS, which fully removes it with no
   leftover gap because the element was absolutely positioned and therefore
   contributed no height to begin with. The markup is still in index.html,
   aria-hidden and now display:none; any later pass that opens that file should
   delete the <svg class="scene-env"> block outright.

   THE SCENE STARTS AT THE TOP. The wrap carried 26 to 30px of top padding to let
   the reply sheet peek ABOVE the notice. Combined with the grid centring that
   put the document visibly below the headline, so the padding is gone and the
   notice's top edge is now the column's top edge. The sheet keeps its job by
   peeking BELOW and to the left instead, out of the 34px the envelope's reserved
   bottom padding just freed up: same "there is another document here" reading,
   from underneath, where nothing it overlaps is text. Percentage widths with a
   pixel ceiling, so it holds on the phone, at 640, at 1000 and at full width
   with no extra breakpoint. */
.notice-wrap { position: relative; padding: 0 0 34px; }

.scene-sheet {
  position: absolute;
  left: 0;
  bottom: 0;
  width: min(62%, 250px);
  height: auto;
  z-index: 0;
  pointer-events: none;
}
.scene-env { display: none; }

.notice {
  position: relative;
  z-index: 1;
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: 3px solid var(--navy);
  border-radius: 0 0 var(--r) var(--r);
  box-shadow: var(--shadow-4);
  padding: var(--s5);
  max-width: 440px;
  margin: 0 auto;
}
@media (min-width: 640px) { .notice { padding: var(--s6) var(--s6) var(--s5); } }

.illus {
  display: inline-block;
  font-size: var(--t-nano);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 4px 9px;
  margin-bottom: var(--s4);
}
.notice-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  border-bottom: 1.5px solid var(--ink);
  padding-bottom: var(--s2);
  margin-bottom: var(--s1);
  gap: var(--s3);
}
.notice-head .agency { font-weight: 700; font-size: var(--t-micro); letter-spacing: .01em; }
.notice-head .form { font-family: var(--mono); font-size: var(--t-nano); color: var(--ink-3); }
.notice-sub { font-size: var(--t-nano); color: var(--ink-3); margin-bottom: var(--s3); }

.n-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 2px;
  font-size: var(--t-small);
  gap: var(--s3);
}
.n-row + .n-row { border-top: 1px solid var(--line); }
.n-row .lbl { color: var(--ink-2); }
.n-row .val { font-family: var(--mono); font-size: .88rem; font-variant-numeric: tabular-nums; }
.n-row.penalty {
  background: var(--alarm-bg);
  border: 1px solid var(--alarm-line);
  margin: var(--s1) -10px;
  padding: 10px;
  border-radius: var(--r-sm);
}
.n-row.penalty + .n-row { border-top: none; }
.n-row.penalty .lbl, .n-row.penalty .val { color: var(--alarm); font-weight: 700; }
.n-strike {
  text-decoration: line-through;
  text-decoration-thickness: 2px;
  text-decoration-color: var(--alarm);
  color: var(--ink-3);
  font-weight: 400;
  margin-right: var(--s2);
}
/* The drawn annotation arrow, in flow between the struck total and the granted
   result so it cannot drift out of alignment with either. */
.n-arrow {
  display: block;
  width: 62px;
  height: 32px;
  margin: var(--s2) 30px 0 auto;
  fill: none;
  stroke: var(--relief);
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.n-result {
  background: var(--relief-bg);
  border: 1px solid var(--relief-line);
  border-radius: var(--r-sm);
  padding: var(--s3) var(--s4);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s3);
}
.n-result .t { font-weight: 600; color: var(--relief); font-size: var(--t-small); }
.n-result .v { font-family: var(--mono); font-weight: 700; color: var(--relief); }
.n-cite { margin-top: var(--s3); font-size: var(--t-nano); color: var(--ink-3); line-height: 1.5; }

/* --- The proof band ------------------------------------------------------
   Pass 1 set our three strongest one line claims as a row of small grey text on
   navy. Optima gives the equivalent three claims a whole coloured band with an
   icon and a two line statistic each, and it is the most legitimising thing on
   that page. This is that band: the frozen <b> lead-in becomes the statement,
   and the rest of the sentence becomes its caption underneath. */
.strip {
  background: var(--navy);
  color: var(--on-navy);
  padding: var(--s6) 0;
  font-size: var(--t-small);
}
.strip .wrap { display: grid; gap: var(--s5); }
@media (min-width: 640px)  { .strip .wrap { grid-template-columns: repeat(3, 1fr); gap: var(--s6); } }
@media (min-width: 1000px) { .strip { padding: var(--s7) 0; } }
.strip span {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: var(--s2) var(--s4);
  line-height: 1.5;
}
.strip .ic { color: var(--gold); grid-row: span 2; margin-top: 2px; }
.strip b {
  display: block;
  color: var(--on-navy-hi);
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.3rem;
  letter-spacing: -.014em;
  line-height: 1.2;
}

/* --- Sections ------------------------------------------------------------ */
section { padding: var(--s8) 0; }
@media (min-width: 1000px) { section { padding: var(--s9) 0; } }
.sect-alt { background: var(--paper-2); border-block: 1px solid var(--line); }

/* A centred section head. A container class rather than three inline text-align
   declarations on the children. The kicker needs justify-content because it is a
   flex row, not a text block. */
.center { text-align: center; }
.center h2, .center .lead { margin-left: auto; margin-right: auto; }
.center .kicker { justify-content: center; }

/* --- Candor --------------------------------------------------------------
   THE TWO PANELS ARE NO LONGER THE SAME OBJECT. Pass 1 gave "Doing it alone" and
   "With Tax Penalty Reply on your side" identical cards and asked a border
   colour to carry the whole argument. The reference move is to make the
   preferred thing a different KIND of thing: Optima's own column is raised off a
   flat comparison, TurboTax's chosen plan is a bordered card among plain rows.
   So the first panel is now flat on the page behind a muted drawn motif, and the
   second is a raised white card with the action border. */
.candor { display: grid; gap: var(--s5); }
@media (min-width: 1000px) { .candor { grid-template-columns: 1fr 1fr; gap: var(--s6); align-items: start; } }

.candor-card {
  position: relative;
  border-radius: var(--r-lg);
  padding: var(--s5);
  background: transparent;
  border: 1px solid var(--line);
}
@media (min-width: 640px) { .candor-card { padding: var(--s6); } }
.candor-card h3 { font-size: var(--t-h3); margin-bottom: var(--s3); padding-right: 64px; }
.candor-card p { color: var(--ink-2); font-size: var(--t-small); }
.candor-card p + p { margin-top: var(--s3); }

/* The card that should be read earns it with elevation and a real border weight,
   not with a coloured bar down its edge. */
.candor-card.us {
  background: var(--surface);
  border: 2px solid var(--action-line);
  box-shadow: var(--shadow-3);
}
.candor-card.us h3 { color: var(--action); }
.candor + .candor-card { margin-top: var(--s5); }

/* The drawn motif in the corner of a panel. Low contrast on purpose: it is
   texture, and the copy beside it is the content. */
.card-motif {
  position: absolute;
  right: var(--s4);
  top: var(--s4);
  width: 54px;
  height: 54px;
  fill: none;
  stroke: var(--line-2);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}
.candor-card.us .card-motif { stroke: var(--action-line); }

/* --- The eligibility checker ---------------------------------------------
   MOVED UP THE PAGE IN THIS PASS. TurboTax puts a working entry point beside its
   headline; ours was two screens down behind an anchor. It now sits directly
   under the proof band, which makes it the first thing after the hero. */
.checker-shell {
  max-width: 720px;
  margin: 0 auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-4);
  overflow: hidden;
  text-align: left;
}
.checker-top, .shell-top {
  background: var(--navy);
  color: var(--on-navy-hi);
  padding: var(--s4);
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  flex-direction: column;
  gap: var(--s1);
}
@media (min-width: 640px) {
  .checker-top, .shell-top {
    padding: var(--s5) var(--s6);
    flex-direction: row;
    align-items: center;
    gap: var(--s4);
  }
}
.checker-top h3, .shell-top h2 {
  font-size: var(--t-h4);
  font-weight: 600;
  color: var(--on-navy-hi);
  margin: 0;
  max-width: none;
}
.checker-top .safe, .shell-top .safe {
  font-size: var(--t-micro);
  color: var(--on-navy);
  font-family: var(--sans);
}

.progress { height: 4px; background: var(--paper-2); }
.progress i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--action);
  transition: width var(--t-enter) var(--ease-out);
}
.checker-body { padding: var(--s5) var(--s4); }
@media (min-width: 640px) { .checker-body { padding: var(--s7) var(--s6) var(--s6); } }

.q-count {
  font-size: var(--t-nano);
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: var(--s2);
}
.q-text {
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -.014em;
  line-height: 1.2;
  margin-bottom: var(--s2);
}
.q-help { font-size: var(--t-small); color: var(--ink-3); margin-bottom: var(--s5); }

/* --- Options -------------------------------------------------------------
   Crisp 4px rows. On the landing page an option is a <button>; on the intake
   form it is a <label> wrapping a real radio, so the label form draws its own
   control and the button form does not need the room. */
.opts { display: grid; gap: var(--s2); }
.opt {
  display: block;
  width: 100%;
  text-align: left;
  background: var(--surface);
  border: 1.5px solid var(--line-2);
  border-radius: var(--r-sm);
  padding: 14px 16px;
  font-family: var(--sans);
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  transition: border-color var(--t) var(--ease-out), background var(--t) var(--ease-out),
              box-shadow var(--t) var(--ease-out);
}
.opt small { display: block; font-weight: 400; color: var(--ink-3); font-size: var(--t-micro); margin-top: 2px; }
@media (hover: hover) and (pointer: fine) {
  .opt:hover { border-color: var(--action); background: var(--action-bg); }
}

/* THE RADIO IS DRAWN, NOT THEMED. accent-color paints the browser's own control,
   which on this page meant a 17px native dot sitting beside a 22px drawn icon
   set at a different stroke weight: the one control the customer actually
   touches was the one thing on the page not on the system. The native input
   stays in the DOM at full size and zero opacity, so it is still focusable,
   still clickable, still announced, and still what the form reads. */
label.opt { position: relative; padding-left: 48px; }
label.opt input {
  position: absolute;
  left: 16px;
  top: 16px;
  margin: 0;
  width: 20px;
  height: 20px;
  opacity: 0;
  cursor: pointer;
}
label.opt > span { display: block; }
label.opt > span::before {
  content: "";
  position: absolute;
  left: 16px;
  top: 17px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1.5px solid var(--line-2);
  background: var(--surface);
  transition: border-color var(--t) var(--ease-out);
}
label.opt > span::after {
  content: "";
  position: absolute;
  left: 22px;
  top: 23px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--action);
  transform: scale(0);
  transition: transform var(--t) var(--ease-out);
}
label.opt input:checked ~ span::before { border: 2px solid var(--action); }
label.opt input:checked ~ span::after { transform: scale(1); }
label.opt:has(input:checked) {
  border-color: var(--action);
  background: var(--action-bg);
  box-shadow: inset 0 0 0 1px var(--action);
}
label.opt input:focus-visible ~ span::before {
  outline: 2.5px solid var(--action-hi);
  outline-offset: 2px;
}
.opt input:checked ~ span { color: var(--action); }

.back-link, .restart {
  margin-top: var(--s5);
  background: none;
  border: none;
  color: var(--ink-3);
  font-family: var(--sans);
  font-size: var(--t-micro);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
  padding: 0;
}

/* --- The verdict: the one authored moment on the site --------------------
   This is where the person finds out where they stand. It is rare, it is the
   emotional centre of the product, and it is the only thing here that gets a
   real entrance: a short settle out of a slight blur and lift, ease-out from an
   already visible default. Everything else on these pages is feedback measured
   in a tenth of a second. */
@keyframes tpr-settle {
  from { opacity: 0; transform: translateY(10px); filter: blur(6px); }
  to   { opacity: 1; transform: none;             filter: blur(0); }
}
.verdict, .result { display: none; }
.verdict.show, .result.show {
  display: block;
  animation: tpr-settle var(--t-enter) var(--ease-out) both;
}

.v-badge {
  display: inline-block;
  font-family: var(--sans);
  font-size: var(--t-nano);
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  border-radius: var(--r-sm);
  padding: 6px 11px;
  margin-bottom: var(--s4);
}
.v-badge.good { background: var(--relief-bg); color: var(--relief); border: 1px solid var(--relief-line); }
.v-badge.mid  { background: var(--caution-bg); color: var(--caution); border: 1px solid var(--caution-line); }
.v-badge.stop { background: var(--alarm-bg); color: var(--alarm); border: 1px solid var(--alarm-line); }

.verdict h4, .result h3 {
  font-size: clamp(1.5rem, 4vw, 1.85rem);
  font-weight: 600;
  letter-spacing: -.016em;
  margin-bottom: var(--s3);
  max-width: none;
}
.verdict p, .result p { color: var(--ink-2); font-size: var(--t-small); margin-bottom: var(--s3); }

/* The verdict price is set on the same numeral treatment as the package cards,
   one step down, so the number a person is quoted looks like the number they saw
   on the way in. */
.v-price {
  font-family: var(--display);
  font-size: var(--fig-sm);
  font-weight: 600;
  letter-spacing: -.026em;
  line-height: 1;
  color: var(--ink);
  margin: var(--s5) 0 2px;
  font-variant-numeric: tabular-nums;
}
.v-price small {
  display: block;
  font-family: var(--sans);
  font-size: var(--t-micro);
  font-weight: 500;
  letter-spacing: 0;
  color: var(--ink-3);
  margin-top: var(--s2);
}
.v-pending { font-size: var(--t-small); color: var(--ink-3); margin: var(--s5) 0 2px; }
.v-cta { margin-top: var(--s5); display: flex; gap: var(--s3); flex-wrap: wrap; align-items: center; }
.v-note {
  background: var(--caution-bg);
  border: 1px solid var(--caution-line);
  color: var(--caution);
  border-radius: var(--r);
  padding: var(--s3) var(--s4);
  font-size: var(--t-small);
  margin-top: var(--s4);
}
.v-ref {
  margin-top: var(--s5);
  padding-top: var(--s4);
  border-top: 1px solid var(--line);
  font-size: var(--t-micro);
  color: var(--ink-3);
}
.v-ref b { font-family: var(--mono); color: var(--ink); font-weight: 600; letter-spacing: .04em; }

/* --- Packages: RETIRED (WO-TPR-REDESIGN-3b) ------------------------------
   The packages/pricing section was DELETED from the landing page by owner ruling
   on 2026-08-04, which overrode D-6. Its rules (.packs, .pack, .pack.feature,
   .pack-motif, .pack .p-tag, .pack .p-price and the list styling) went with it
   rather than being left to rot: none of those class names appears in any of the
   three pages any more, and dead selectors are how a stylesheet stops being
   readable. The intake form and the verdict screen still quote a price; that is
   .v-price, which is a different rule and is untouched.
   ------------------------------------------------------------------------- */

/* --- The three way comparison --------------------------------------------
   A shared rule grid rather than three identical floating cards. Two of the
   three columns are plain: they are context, and context should not look like an
   offer. Only ours is raised. */
.compare { display: grid; gap: var(--s4); }
@media (min-width: 640px)  { .compare { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .compare { grid-template-columns: repeat(3, 1fr); gap: var(--s5); align-items: start; } }

.compare .col {
  background: transparent;
  border-top: 3px solid var(--line-2);
  border-radius: 0;
  padding: var(--s5) 0 0;
}
.compare .col h3 { font-size: var(--t-h4); margin-bottom: 2px; }
.compare .tag { display: block; font-size: var(--t-micro); color: var(--ink-3); margin-bottom: var(--s4); }
.compare .col ul { list-style: none; }
.compare .col li {
  display: flex;
  align-items: flex-start;
  gap: var(--s3);
  padding: 10px 0;
  font-size: var(--t-small);
  color: var(--ink-2);
  border-top: 1px solid var(--line);
}
.compare .col li .ic { margin-top: 2px; }
/* Ours is the one that is raised, tinted and given a real border, because it is
   the one being offered. Everything else here is the honest landscape. */
.compare .col.us {
  background: var(--surface);
  border: 2px solid var(--relief-line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3);
  padding: var(--s5);
}
@media (min-width: 640px)  { .compare .col.us { grid-column: span 2; } }
@media (min-width: 1000px) { .compare .col.us { grid-column: auto; margin-top: -20px; padding: var(--s6) var(--s5); } }
.compare .col.us h3 { color: var(--relief); }
.compare .col.us li { color: var(--ink); }

/* --- The four steps ------------------------------------------------------
   Optima's blurb pattern: a drawn icon above the label, numbered because the
   ORDER is the information here (the reader needs to know the free check comes
   before the payment), and joined by a drawn rule on the wide layout. */
.steps { display: grid; gap: var(--s5); position: relative; }
@media (min-width: 640px)  { .steps { grid-template-columns: 1fr 1fr; gap: var(--s6) var(--s5); } }
@media (min-width: 1000px) { .steps { grid-template-columns: repeat(4, 1fr); gap: var(--s5); } }

.step { position: relative; background: transparent; padding: 0; }
.step-head { display: flex; align-items: center; gap: var(--s3); margin-bottom: var(--s3); }
.step .s-n {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--navy);
  color: var(--on-navy-hi);
  font-family: var(--sans);
  font-weight: 700;
  font-size: var(--t-micro);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  position: relative;
  z-index: 1;
}
.step h3 { font-size: var(--t-h4); }
.step p { font-size: var(--t-small); color: var(--ink-2); }
.step-mark {
  display: block;
  width: 30px;
  height: 30px;
  margin-bottom: var(--s4);
  fill: none;
  stroke: var(--action);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* The connecting rule, drawn only where there is room for it to mean anything. */
@media (min-width: 1000px) {
  .step::after {
    content: "";
    position: absolute;
    left: 34px;
    top: 63px;
    right: calc(var(--s5) * -1);
    height: 1px;
    background: var(--line-2);
  }
  .step:last-child::after { display: none; }
}

/* --- What we refuse ------------------------------------------------------
   THE THIRD FULL BLEED REGION, AND THE MOST IMPORTANT ONE. A document service
   that takes every case is a red flag, and saying so in public is the single
   most differentiating thing on this site. Pass 1 set it as body copy in a
   tinted section. Lemonade gives its three institutional facts a strip of their
   own; this gets the same treatment, on the deep navy, with the four refusals as
   bordered rows a reader can count. */
.refuse-band {
  background: var(--navy);
  color: var(--on-navy);
  border-block: none;
}
.refuse-band .kicker { color: var(--gold); }
.refuse-band .kicker::before { background: var(--gold); }
.refuse-band h2 { color: var(--on-navy-hi); }
.refuse-band .lead { color: var(--on-navy); }

.refuse { display: grid; gap: var(--s6); align-items: start; }
@media (min-width: 1000px) { .refuse { grid-template-columns: 1fr 1fr; gap: var(--s8); } }
.refuse .lead { margin-bottom: 0; }

.refuse-list { list-style: none; display: grid; gap: var(--s3); }
.refuse-list li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s1) var(--s3);
  align-items: start;
  padding: var(--s4);
  font-size: var(--t-body);
  font-weight: 600;
  color: var(--on-navy-hi);
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(185,203,224,.22);
  border-radius: var(--r);
}
.refuse-list .ic { color: var(--gold); grid-row: span 2; margin-top: 2px; }
.refuse-list small {
  display: block;
  grid-column: 2;
  color: var(--on-navy);
  font-size: var(--t-micro);
  font-weight: 400;
  line-height: 1.5;
}

/* --- FAQ -----------------------------------------------------------------
   A bare accordion on rules, which is what both Optima and TurboTax use. No
   card: an answer the reader opens should not arrive inside a container that
   implies it is an offer. */
.faq details { border-top: 1px solid var(--line); padding: var(--s5) 0; }
.faq details:last-of-type { border-bottom: 1px solid var(--line); }
.faq summary {
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--t-h4);
  line-height: 1.35;
  cursor: pointer;
  list-style: none;
  position: relative;
  padding-right: 40px;
}
.faq summary::-webkit-details-marker { display: none; }
/* A drawn plus that rotates into a minus, rather than a glyph swap. */
.faq summary::before, .faq summary::after {
  content: "";
  position: absolute;
  right: 8px;
  top: .68em;
  width: 15px;
  height: 2px;
  border-radius: 1px;
  background: var(--action);
  transition: transform var(--t) var(--ease-out);
}
.faq summary::after { transform: rotate(90deg); }
.faq details[open] summary::after { transform: rotate(0deg); }
.faq p { margin-top: var(--s3); color: var(--ink-2); font-size: var(--t-small); max-width: 70ch; }

/* --- Page head (form and status pages) ----------------------------------- */
.page-head {
  position: relative;
  padding: var(--s7) 0 var(--s6);
  background: linear-gradient(180deg, var(--paper-2) 0%, var(--paper) 70%);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
@media (min-width: 1000px) { .page-head { padding: var(--s8) 0 var(--s7); } }
.page-head h1 { font-size: clamp(2rem, 5vw, 2.9rem); max-width: 24ch; }
.page-head .sub { margin: var(--s5) 0 0; font-size: var(--t-sub); color: var(--ink-2); max-width: 56ch; }
.page-head .wrap { position: relative; z-index: 1; }
/* The document motif, at the small end of the drawn system, so the form page and
   the status page belong visibly to the same world as the landing hero. */
.head-motif {
  display: none;
  position: absolute;
  right: 6%;
  top: 50%;
  transform: translateY(-50%);
  width: 190px;
  height: 190px;
  fill: none;
  stroke: var(--line-2);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
  z-index: 0;
}
@media (min-width: 1000px) { .head-motif { display: block; } }
.safe-note {
  margin-top: var(--s5);
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  font-size: var(--t-micro);
  color: var(--relief);
  background: var(--relief-bg);
  border: 1px solid var(--relief-line);
  border-radius: var(--r-pill);
  padding: 8px 16px 8px 12px;
}

main { padding: var(--s6) 0 var(--s8); }

/* --- The form shell ------------------------------------------------------ */
.shell {
  max-width: 780px;
  margin: 0 auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-4);
  overflow: hidden;
}
.shell-body { padding: var(--s5) var(--s4); }
@media (min-width: 640px) { .shell-body { padding: var(--s7) var(--s6) var(--s6); } }

/* Each fieldset is a section on a left rule, which is TurboTax's form register:
   the group is visibly a group without needing a card around it. */
fieldset {
  border: 0;
  margin: 0 0 var(--s7);
  padding-left: var(--s4);
  border-left: 2px solid var(--line);
}
fieldset:last-of-type { margin-bottom: var(--s3); }
legend {
  font-family: var(--sans);
  font-size: var(--t-nano);
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--action);
  margin-bottom: var(--s1);
}
.fs-help { font-size: var(--t-small); color: var(--ink-3); margin-bottom: var(--s5); }

.q { margin-bottom: var(--s6); }
.q .q-text {
  font-family: var(--sans);
  font-size: 1.06rem;
  font-weight: 700;
  letter-spacing: -.006em;
  line-height: 1.4;
  margin-bottom: var(--s1);
}
.q .q-help { margin-bottom: var(--s3); font-size: var(--t-micro); }

.grid2, .grid3 { display: grid; grid-template-columns: 1fr; gap: var(--s4); }
@media (min-width: 640px) {
  .grid2 { grid-template-columns: 1fr 1fr; }
  .grid3 { grid-template-columns: 1.6fr .7fr .7fr; }
}

.field { display: flex; flex-direction: column; gap: var(--s1); margin-bottom: var(--s4); }
.field label { font-size: var(--t-micro); font-weight: 700; }
.field .hint { font-size: var(--t-nano); color: var(--ink-3); font-weight: 400; }
.req { color: var(--alarm); font-weight: 700; }

input[type=text], input[type=email], input[type=date],
input[type=number], select, textarea {
  font-family: inherit;
  font-size: 1rem;
  color: var(--ink);
  background: var(--surface);
  border: 1.5px solid var(--line-2);
  border-radius: var(--r-sm);
  padding: 12px 13px;
  width: 100%;
  transition: border-color var(--t) var(--ease-out), box-shadow var(--t) var(--ease-out);
}
textarea { min-height: 130px; resize: vertical; line-height: 1.6; }
input:focus, select:focus, textarea:focus {
  border-color: var(--action);
  outline: none;
  box-shadow: 0 0 0 3px rgba(23,83,158,.16);
}
::placeholder { color: var(--ink-3); opacity: 1; }

/* The checkbox is drawn on the same system as the radio, and for the same
   reason: the controls a customer touches should not be the only things on the
   page rendered by somebody else's stylesheet. */
.checks { display: grid; gap: var(--s1); }
.check {
  position: relative;
  display: block;
  padding: 7px 0 7px 32px;
  font-size: var(--t-small);
  color: var(--ink);
  cursor: pointer;
}
.check input {
  position: absolute;
  left: 0;
  top: 9px;
  margin: 0;
  width: 20px;
  height: 20px;
  opacity: 0;
  cursor: pointer;
}
.check > span::before {
  content: "";
  position: absolute;
  left: 0;
  top: 9px;
  width: 20px;
  height: 20px;
  border-radius: var(--r-sm);
  border: 1.5px solid var(--line-2);
  background: var(--surface);
  transition: border-color var(--t) var(--ease-out), background var(--t) var(--ease-out);
}
/* The tick itself, drawn at the same weight as the SVG icon set so the two never
   read as different systems. */
.check > span::after {
  content: "";
  position: absolute;
  left: 6px;
  top: 14px;
  width: 8px;
  height: 4px;
  border-left: 2px solid #FFFFFF;
  border-bottom: 2px solid #FFFFFF;
  transform: rotate(-45deg) scale(0);
  transition: transform var(--t) var(--ease-out);
}
.check input:checked ~ span::before { border-color: var(--action); background: var(--action); }
.check input:checked ~ span::after { transform: rotate(-45deg) scale(1); }
.check input:focus-visible ~ span::before { outline: 2.5px solid var(--action-hi); outline-offset: 2px; }

.submit-row {
  border-top: 1px solid var(--line);
  padding-top: var(--s5);
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  align-items: flex-start;
}
.submit-row .btn { width: 100%; }
@media (min-width: 640px) { .submit-row .btn { width: auto; } }
.submit-note { font-size: var(--t-micro); color: var(--ink-3); }

.form-error, .form-ok {
  display: none;
  border-radius: var(--r);
  padding: var(--s3) var(--s4);
  font-size: var(--t-small);
  font-weight: 600;
  margin-bottom: var(--s4);
}
.form-error { background: var(--alarm-bg); border: 1px solid var(--alarm-line); color: var(--alarm); }
.form-ok    { background: var(--relief-bg); border: 1px solid var(--relief-line); color: var(--relief); }
.form-error.show, .form-ok.show { display: block; }

/* --- Path shaped blocks and the honest step indicator -------------------- */
.block { display: none; }
.block.show { display: block; }
.step-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  font-family: var(--sans);
  font-size: var(--t-nano);
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--action);
  margin-bottom: var(--s4);
}
.step-tag::before { content: ""; width: 20px; height: 2px; background: var(--action); flex-shrink: 0; }
.step2 { border-top: 1px solid var(--line); margin-top: var(--s2); padding-top: var(--s6); }

.preview {
  background: var(--caution-bg);
  border: 1px solid var(--caution-line);
  border-radius: var(--r);
  padding: var(--s4) var(--s5);
  margin-bottom: var(--s5);
}
.preview.stop { background: var(--alarm-bg); border-color: var(--alarm-line); }
.preview .p-badge {
  display: inline-block;
  font-family: var(--sans);
  font-size: var(--t-nano);
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--caution);
  margin-bottom: var(--s1);
}
.preview.stop .p-badge { color: var(--alarm); }
.preview h3 { font-size: var(--t-h4); margin-bottom: var(--s2); }
.preview p { font-size: var(--t-small); color: var(--ink-2); }
.await-note {
  font-size: var(--t-small);
  color: var(--ink-3);
  border-top: 1px solid var(--line);
  margin-top: var(--s2);
  padding-top: var(--s5);
}

/* --- Status page --------------------------------------------------------- */
.ref-line { font-size: var(--t-small); color: var(--ink-3); margin-bottom: var(--s5); }
.ref-line b { font-family: var(--mono); color: var(--ink); font-weight: 600; font-size: 1rem; letter-spacing: .04em; }
.sent {
  background: var(--relief-bg);
  border: 1px solid var(--relief-line);
  border-radius: var(--r);
  padding: var(--s4) var(--s5);
  margin-bottom: var(--s5);
}
.sent h3 { font-size: var(--t-h4); color: var(--relief); margin-bottom: var(--s1); }
.sent p { font-size: var(--t-small); color: var(--ink-2); }
.next {
  border-top: 1px solid var(--line);
  margin-top: var(--s6);
  padding-top: var(--s5);
  font-size: var(--t-small);
  color: var(--ink-2);
}
.next h3 { font-size: var(--t-h4); margin-bottom: var(--s2); }
.next p + p { margin-top: var(--s2); }

/* --- The Commitment statement --------------------------------------------
   PROMOTED IN THIS PASS, AND STILL CSS ONLY. This is the strongest legitimacy
   asset we own: a published statement of exactly what we are, what we are not,
   and what we will never promise. Pass 1 set it at .78rem grey uppercase at the
   very bottom of the page, which is how you style something you want skipped.
   Lemonade gives the equivalent material (Public Benefit Corporation, B-Corp,
   the reinsurance) a strip of its own with real weight; TurboTax's guarantee
   wall is the same idea at ten times the length. So this is now a sealed
   statement: a panel under a heavy navy rule, with a readable heading, the
   paragraph at full body size on a real measure, and the domain line set as a
   signature under a rule of its own.

   BOTTOM JUSTIFIED ON EVERY PAGE. body is a full height flex column (see the
   body rule at the top) and this section takes the slack, so the statement and
   the footer beneath it sit on the bottom edge however short the page is, and
   nothing moves on a page that is already long. That matters on the form page,
   where the form collapses to an email field on the no-sale paths, and on the
   status page, which is two fields long.

   The markup between the COMMITMENT:BEGIN/END markers is generated by
   scripts/gen_commitment_block.py and compared byte for byte by
   tests/acceptance/test_tpr_commitment.py, so it is styled from out here and
   never edited. */
.commitment {
  background: var(--paper-2);
  border-top: 1px solid var(--line);
  padding: var(--s7) 0;
  margin-top: auto;
}
@media (min-width: 1000px) { .commitment { padding: var(--s8) 0; } }
.commitment-in {
  max-width: 820px;
  position: relative;
  border-top: 3px solid var(--navy);
  padding-top: var(--s5);
}
.commitment h2 {
  font-family: var(--sans);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: .18em;
  color: var(--navy);
  margin: 0 0 var(--s4);
  max-width: none;
}
.commitment p { color: var(--ink-2); font-size: var(--t-body); line-height: 1.68; max-width: 72ch; }
.commitment p + p { margin-top: var(--s3); }
.commitment .commitment-domain {
  font-family: var(--display);
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--navy);
  margin-top: var(--s5);
  padding-top: var(--s4);
  border-top: 1px solid var(--line-2);
  max-width: 20ch;
}

/* --- Footer -------------------------------------------------------------- */
footer {
  background: var(--navy);
  color: var(--on-navy);
  padding: var(--s7) 0;
  font-size: var(--t-micro);
  line-height: 1.7;
}
footer .biz {
  color: var(--on-navy-hi);
  font-weight: 600;
  font-size: 1.02rem;
  font-family: var(--display);
  margin-bottom: var(--s2);
}
footer p + p { margin-top: var(--s2); }
footer a { color: #DCE6F5; }
.foot-grid { display: grid; gap: var(--s6); }
@media (min-width: 1000px) { .foot-grid { grid-template-columns: 1.6fr 1fr 1fr 1.2fr; gap: var(--s8); } }
/* WO-FOOTER-RESOURCES-1: Topics + Resources nav columns + signature line (shared footer skeleton) */
.foot-col h4 { font-family: var(--sans); font-size: var(--t-nano); letter-spacing: .14em; text-transform: uppercase; color: var(--on-navy); margin: 0 0 var(--s3); }
.foot-col a { display: block; color: #DCE6F5; margin-top: var(--s2); font-weight: 600; }
.foot-col a:first-of-type { margin-top: 0; }
.foot-col a:hover { text-decoration: underline; }
.foot-col .new { color: #6f9bff; font-size: 11px; font-weight: 700; margin-left: 6px; letter-spacing: .05em; }
.foot-sig { font-family: ui-monospace, monospace; letter-spacing: .14em; text-transform: uppercase; color: var(--on-navy); margin-top: var(--s3); }
.foot-contact { font-size: var(--t-small); }
.foot-contact .biz {
  font-size: var(--t-nano);
  font-family: var(--sans);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--on-navy);
}

/* WO-TPR-FOOTER-1. The copyright line, on its own rule under the two columns.

   It is set QUIETER than the disclaimer above it on purpose. The disclaimer is
   the part a reader may actually need (what we are, what we are not, and who
   decides their penalty); the copyright is boilerplate, and boilerplate that
   competes with a disclaimer for attention makes both easier to skip. Same move
   TurboTax makes with the fine print under its guarantee wall. */
.foot-legal {
  margin-top: var(--s6);
  padding-top: var(--s5);
  border-top: 1px solid rgba(185,203,224,.22);
  font-size: var(--t-nano);
  color: var(--on-navy);
}

/* --- Reduced motion ------------------------------------------------------
   Fewer and gentler, NOT zero. A blanket
   *{transition:none!important;animation:none!important} also kills the opacity
   and colour transitions that tell somebody a state actually changed, which
   makes an interface read as broken rather than as calm. So: remove movement and
   blur, keep the fade. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  /* Movement goes. The verdict still fades in, because an answer that appears
     with no transition at all reads as a glitch rather than as a result. */
  .verdict.show, .result.show { animation: tpr-fade var(--t) ease both; }

  /* No transforms that carry motion. The two drawn controls are exempt from
     REMOVAL and instead have their transition dropped: their transform IS the
     checked state, not an animation of it, so taking it away would leave a radio
     that never fills in. */
  .btn, .btn:active, .opt, .faq summary::before, .faq summary::after {
    transform: none;
  }
  .faq summary::after { transform: rotate(90deg); }
  .faq details[open] summary::after { transform: rotate(0deg); }
  label.opt > span::after, .check > span::after { transition: none; }

  /* Colour and opacity transitions are kept on purpose: they are what tell
     somebody a control responded. Only the motion-carrying ones are dropped. */
  .progress i { transition: none; }
}
@keyframes tpr-fade { from { opacity: 0; } to { opacity: 1; } }
