/* tokens.css */
/* tokens.css
   The ONLY file in this project allowed to contain a hex value. The build fails
   if a color appears anywhere else.

   Every ratio below was MEASURED against WCAG 2.2 AA on the real pairing, not
   assumed and not inherited. Structure is deliberately identical to AIOSeniors:
   these are sibling System Two properties and a family moving between them
   should not have to relearn the interface. Only the hue differs.

   WHY NAVY AND NOT AIOSENIORS MARINE. AIOSeniors is the front door and reads
   warm, because a family arriving there is frightened. This is the entitlement
   layer: statutory, checkable, institutional. Navy is the register of the
   agencies whose rules we are quoting, and it keeps the two properties visually
   separable when a plan links from one to the other. */

:root {
  /* Color ------------------------------------------------------------- */
  --ink:         #102A3A;  /* headings + body.        14.02:1 on ground */
  --brand:       #234E7A;  /* navy. links, fills.      8.12:1 on ground */
  --brand-lift:  #2F6299;  /* hover, active.           5.96:1 on ground */
  --accent:      #D98C3A;  /* CTA FILL ONLY. never type: 2.55:1, fails by design.
                              Ink on this fill measures 5.05:1, which is the pair
                              that actually has to pass. Shared with AIOSeniors
                              on purpose: one System Two "this is the button". */
  --accent-lift: #E9A254;  /* CTA hover. LIGHTER, so the ink label GAINS contrast: 6.35:1 */
  --ground:      #FBF8F3;  /* warm off-white. never pure white, never gray */
  --surface:     #FFFFFF;  /* cards only */
  --line:        #E3DDD3;  /* warm hairline, never cool gray */
  --ok:          #2E6E62;  /* confirmed states only.   5.63:1 on ground */

  /* Outcome colors. These carry MEANING, so none is decorative and none may be
     reused for anything else. `ruled-out` is deliberately NOT red: being ruled
     out of one program is information, not an error, and a family that sees
     red stops reading the four programs underneath it. */
  --likely:      #2E6E62;  /* same value as ok.       5.63:1 on ground */
  --possible:    #234E7A;  /* same value as brand.    8.12:1 on ground */
  --ruled-out:   #5C5147;  /* warm slate, quiet.      7.02:1 on ground */

  --ink-70:      color-mix(in srgb, var(--ink) 70%, var(--ground));
  --ink-55:      color-mix(in srgb, var(--ink) 55%, var(--ground));
  --brand-wash:  color-mix(in srgb, var(--brand) 7%, var(--ground));
  --accent-wash: color-mix(in srgb, var(--accent) 14%, var(--ground));
  --ok-wash:     color-mix(in srgb, var(--ok) 10%, var(--ground));
  --ruled-wash:  color-mix(in srgb, var(--ruled-out) 6%, var(--ground));

  /* Type --------------------------------------------------------------- */
  --display: 'Fraunces', Georgia, 'Times New Roman', serif;
  --sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

  /* Body base is 18px. Some readers are 80. This is a floor, not a default. */
  --t-body:   1.125rem;   /* 18 */
  --t-lead:   1.375rem;   /* 22 */
  --t-small:  1rem;       /* 16 */
  --t-micro:  0.875rem;   /* 14, labels and meta only, never prose */
  --t-h3:     1.5rem;     /* 24 */
  --t-h2:     2rem;       /* 32 */
  --t-h1:     2.75rem;    /* 44 */
  --t-hero:   clamp(2.25rem, 4.4vw, 3.375rem);

  /* Space -------------------------------------------------------------- */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.5rem;
  --s-6: 2rem;
  --s-7: 3rem;
  --s-8: 4rem;
  --s-9: 6rem;

  /* Shape -------------------------------------------------------------- */
  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 22px;
  --wrap: 1160px;
  --measure: 62ch;

  /* Targets. 48px minimum, 64px for anything primary. */
  --tap: 48px;
  --tap-primary: 64px;

  --shadow-card: 0 1px 2px rgba(16, 42, 58, .05), 0 8px 24px rgba(16, 42, 58, .06);
  --shadow-lift: 0 2px 4px rgba(16, 42, 58, .07), 0 16px 40px rgba(16, 42, 58, .10);
  --ease: cubic-bezier(.22, .61, .36, 1);
}

/* base.css */
/* base.css: reset, type scale, buttons, links. No color literals: tokens only. */

@font-face {
  font-family: 'Fraunces';
  src: url('/assets/fonts/fraunces-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-display: swap;
  font-style: normal;
  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;
}

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

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

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--t-body);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

img, svg { max-width: 100%; }
img { height: auto; } /* an img height attribute beats aspect-ratio. this wins it back */

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 600;
  line-height: 1.14;
  letter-spacing: -0.015em;
  margin: 0 0 var(--s-4);
  font-variation-settings: 'SOFT' 0, 'WONK' 0;
}

h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); line-height: 1.24; }

p { margin: 0 0 var(--s-4); max-width: var(--measure); }
.lead { font-size: var(--t-lead); line-height: 1.5; color: var(--ink-70); }

a { color: var(--brand); text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover { color: var(--brand-lift); }

:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 3px;
  border-radius: 3px;
}

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--s-5); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: var(--s-4); top: -100px; z-index: 100;
  background: var(--ink); color: var(--ground);
  padding: var(--s-3) var(--s-5); border-radius: var(--r-sm); text-decoration: none;
  transition: top .15s var(--ease);
}
.skip:focus { top: var(--s-4); color: var(--ground); }

/* Buttons -------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: var(--tap-primary);
  padding: 0 var(--s-6);
  border: 2px solid transparent; border-radius: 999px;
  font-family: var(--sans); font-size: var(--t-body); font-weight: 650;
  line-height: 1; text-decoration: none; cursor: pointer;
  transition: background-color .18s var(--ease), transform .18s var(--ease), box-shadow .18s var(--ease);
}

/* Amber fill, ink label. White on amber measures 2.71:1 and fails AA;
   ink on amber measures 5.05:1 and passes. This pairing is not decorative. */
.btn-primary { background: var(--accent); color: var(--ink); box-shadow: var(--shadow-card); }
.btn-primary:hover { background: var(--accent-lift); color: var(--ink); transform: translateY(-1px); box-shadow: var(--shadow-lift); }
.btn-primary:active { transform: translateY(0); }

.btn-quiet {
  background: transparent; color: var(--brand); border-color: var(--line);
  min-height: var(--tap);
}
.btn-quiet:hover { border-color: var(--brand); color: var(--brand-lift); background: var(--surface); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* Shared blocks -------------------------------------------------------- */

section { padding-block: var(--s-9); }
.section-head { max-width: var(--measure); margin-bottom: var(--s-7); }
.eyebrow {
  font-size: var(--t-micro); font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--brand); margin: 0 0 var(--s-3);
}

.beta {
  display: inline-block; vertical-align: 1px;
  font-family: var(--sans); font-size: 0.6875rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 999px;
  background: var(--brand-wash); color: var(--brand); border: 1px solid var(--line);
}

.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: var(--s-6);
  box-shadow: var(--shadow-card);
}

.rule { border: 0; border-top: 1px solid var(--line); margin: 0; }

.src {
  font-size: var(--t-small); color: var(--ink-55);
  border-top: 1px solid var(--line); padding-top: var(--s-3); margin-top: var(--s-5);
}
.src a { color: var(--brand); }
.checked { white-space: nowrap; }

.reviewed {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-size: var(--t-small); color: var(--ink-55);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 999px; padding: var(--s-2) var(--s-4);
}

/* chrome.css */
/* chrome.css: header, megamenu, footer. */

.site-header {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--ground) 92%, transparent);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--line);
}

.header-in {
  display: flex; align-items: center; gap: var(--s-5);
  min-height: 76px;
}

.brand {
  display: inline-flex; align-items: center; gap: var(--s-3);
  min-height: var(--tap);
  color: var(--ink); text-decoration: none; flex: 0 0 auto;
}
.brand-mark { display: block; width: 34px; height: 34px; color: var(--brand); }
.brand-mark svg { display: block; width: 100%; height: 100%; }
.brand-name {
  font-family: var(--display); font-weight: 600; font-size: 1.375rem; letter-spacing: -0.02em;
}

.sitenav { margin-left: auto; }
.navlist { display: flex; align-items: center; gap: var(--s-2); list-style: none; margin: 0; padding: 0; }
.navgroup { position: relative; }

.navtop {
  display: inline-flex; align-items: center; gap: var(--s-2);
  min-height: var(--tap); padding: 0 var(--s-4);
  background: transparent; border: 0; border-radius: var(--r-sm);
  font-family: var(--sans); font-size: var(--t-body); font-weight: 550; color: var(--ink);
  cursor: pointer;
}
.navtop:hover { background: var(--brand-wash); color: var(--brand); }
.chev { width: 11px; height: 7px; transition: transform .18s var(--ease); }
.navtop[aria-expanded="true"] .chev { transform: rotate(180deg); }
.navtop[aria-expanded="true"] { background: var(--brand-wash); color: var(--brand); }

/* PLACEMENT CONTRACT, fixed 2026-07-30. left:0 is the anchor the whole fleet was
   moved off in July, and this site inherited it because it was never listed in
   ecosystem-site-engine/modules/megamenu/config/sites.json and so was never once
   graded. Measured before the fix: the panels sat 262-317px off centre under their
   triggers, and one hung 97.55px off the right edge of a 1280px window.
   Centre, then let the placement script's clamp slide a panel whose trigger sits
   too near the window edge. The clamp is why the right-anchored :last-child
   override below is deleted rather than kept: two anchoring rules cannot both be
   the answer, and only one of them keeps the panel under its own trigger. */
.navpanel {
  position: absolute; top: calc(100% + 10px); left: 50%; right: auto; z-index: 60;
  margin-left: var(--mm-shift, 0px);
  transform: translateX(-50%);
  min-width: 264px; list-style: none; margin-block: 0; padding: var(--s-3);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); box-shadow: var(--shadow-lift);
  display: none;
  /* The fold guard reads these; the script writes them. */
  max-height: var(--mm-maxh, none); overflow-y: auto; overscroll-behavior: contain;
}
.navpanel[data-open] { display: block; }
.navpanel a {
  display: flex; align-items: center; gap: var(--s-2);
  min-height: var(--tap); padding: 0 var(--s-4);
  border-radius: var(--r-sm); text-decoration: none; color: var(--ink); font-weight: 500;
}
.navpanel a:hover { background: var(--brand-wash); color: var(--brand); }
.navpanel a[aria-current="page"] { background: var(--brand-wash); color: var(--brand); font-weight: 650; }

.btn-header { flex: 0 0 auto; min-height: var(--tap); padding: 0 var(--s-5); }

.navtoggle { display: none; }

/* Mobile --------------------------------------------------------------- */
/* Every header child gets an explicit order under 980px. A child without one
   defaults to 0 and jumps above the H1. This has cost real time on Digilu. */

@media (max-width: 980px) {
  .header-in { flex-wrap: wrap; gap: var(--s-3); padding-block: var(--s-3); }

  .brand      { order: 1; margin-right: auto; }
  .navtoggle  { order: 2; }
  .btn-header { order: 3; display: none; }
  .sitenav    { order: 4; flex-basis: 100%; margin-left: 0; }

  .navtoggle {
    display: inline-flex; align-items: center; gap: var(--s-2);
    min-height: var(--tap); padding: 0 var(--s-4);
    background: transparent; color: var(--ink);
    border: 1px solid var(--line); border-radius: 999px;
    font-family: var(--sans); font-size: var(--t-small); font-weight: 650; cursor: pointer;
  }
  .navtoggle-bars { display: grid; gap: 4px; }
  .navtoggle-bars i { display: block; width: 18px; height: 2px; background: currentColor; border-radius: 2px; }

  .sitenav { display: none; }
  .sitenav[data-open] { display: block; }

  .navlist { flex-direction: column; align-items: stretch; gap: 0; padding-bottom: var(--s-4); }
  .navgroup { border-top: 1px solid var(--line); }

  .navtop { width: 100%; justify-content: space-between; min-height: var(--tap-primary); border-radius: 0; }

  /* Accordion, never an unlabelled hamburger drawer. */
  .navpanel {
    position: static; display: none; min-width: 0;
    border: 0; box-shadow: none; background: transparent;
    padding: 0 0 var(--s-3) var(--s-3);
  }
  .navpanel[data-open] { display: block; }
  .navpanel a { min-height: var(--tap-primary); }
}

/* NARROW PHONES: stop the header wrapping onto two rows.
 *
 * Measured 2026-07-29. At 375px and below the brand (222px) and the menu toggle
 * (103px) stopped fitting on one line, `.header-in` wrapped, and the header grew
 * from 77px to 133px with the toggle orphaned under the logo. That is 56px of
 * vertical space gone on EVERY page before any content renders, on the iPhone SE
 * and iPhone 8, which are over-represented among the readers this site is for. It
 * also cost the homepage hero its submit button at those sizes.
 *
 * The cause is one word. "AIOGovernment" is 13 characters where the sibling
 * site's "AIONonprofit" is 12, which puts its brand at 192px and its header at a
 * correct 77px all the way down to 360px. So this is a type-size step and not a
 * layout change: the target is a brand no wider than about 190px, the width
 * already proven to sit next to a 103px toggle at 360px.
 *
 * THESE TIERS GO AFTER THE 980px BLOCK, NOT INSIDE IT. The first attempt spliced
 * them in mid-block, which silently pushed the whole mobile nav accordion
 * (`.sitenav`, `.navlist`, `.navtop`, `.navpanel`) into a 380px-only query. Every
 * gate passed, 360 and 375 measured correctly, and 390 quietly broke to a 135px
 * header. Caught by measuring a viewport that was already passing. */
@media (max-width: 400px) {
  .brand-name { font-size: 1.1875rem; }   /* 19px, from 22px. Brand: 222 -> 199 */
}

/* 360px needs one more step, and the margin is genuinely this tight: at 199px the
   brand plus the 103px toggle plus a 12px gap came to 314 against 312 of
   available width, and wrapped by TWO pixels. */
@media (max-width: 380px) {
  .brand-name { font-size: 1.0625rem; }   /* 17px. Brand: 199 -> 179 */
  .brand-mark { width: 30px; height: 30px; }
}

/* Footer --------------------------------------------------------------- */

.site-footer {
  background: var(--surface);
  border-top: 1px solid var(--line);
  padding-block: var(--s-8) var(--s-6);
  margin-top: var(--s-9);
}

.foot-top { display: grid; grid-template-columns: 1.1fr 2fr; gap: var(--s-8); }
.foot-brand .brand-mark { width: 40px; height: 40px; margin-bottom: var(--s-3); }
.foot-brand .brand-name { display: block; font-size: 1.5rem; margin-bottom: var(--s-3); }
.foot-promise { color: var(--ink-70); margin-bottom: var(--s-5); }

.foot-nav { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-6); }
.foot-nav h2 {
  font-family: var(--sans); font-size: var(--t-micro); font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-55); margin-bottom: var(--s-3);
}
.foot-nav ul { list-style: none; margin: 0; padding: 0; }
.foot-nav li { margin-bottom: var(--s-1); }
.foot-nav a {
  display: inline-flex; align-items: center; gap: var(--s-2);
  min-height: var(--tap); color: var(--ink); text-decoration: none;
}
.foot-nav a:hover { color: var(--brand-lift); text-decoration: underline; }

.foot-legal {
  border-top: 1px solid var(--line); margin-top: var(--s-7); padding-top: var(--s-5);
  font-size: var(--t-small); color: var(--ink-70);
}
.foot-legal p { max-width: 78ch; }
.foot-meta { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-5); align-items: center; color: var(--ink-55); }
/* Navigation, not links inside a sentence, so the inline target-size exception
   does not apply to these. */
.foot-meta a { display: inline-flex; align-items: center; min-height: var(--tap); }

@media (max-width: 860px) {
  .foot-top { grid-template-columns: 1fr; gap: var(--s-7); }
  .foot-nav { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 520px) {
  .foot-nav { grid-template-columns: 1fr; }
}

/* ============================================================== */
/* MEGA-MENU, floating card, opens on HOVER on desktop.           */
/* ============================================================== */
/*
 * The nav shipped as a click-to-open list of plain text links. Three things were
 * wrong with it: it did not open on hover, so it felt broken to anybody who
 * expected a menu; it carried no line art, against the standing directive that
 * every block on every Digilu property carries it; and it gave a row of
 * destinations with no indication of which one to pick.
 *
 * Desktop opens on :hover AND on :focus-within, so it works by keyboard without
 * any JavaScript. The click handler stays for touch and for the mobile
 * accordion, which is why aria-expanded is still driven in script.
 */

@media (min-width: 981px) {
  /* The bridge. Without it the pointer crosses a 10px gap on the way down and
     the panel closes under the cursor, which reads as a flickering menu. */
  .navgroup::after {
    content: ''; position: absolute; left: 0; right: 0; top: 100%;
    height: 14px;
  }

  .navpanel {
    display: block;
    opacity: 0; visibility: hidden; transform: translateX(-50%) translateY(-6px);
    transition: opacity .16s var(--ease), transform .16s var(--ease), visibility .16s;
    /* WIDTH IS LOAD BEARING. At 30rem the two columns squeezed the row blurbs to
       three words a line and the feature heading to one word a line, which looks
       broken and is slower to read than the plain list it replaced. A mega-menu
       that is not wide enough to breathe is worse than no mega-menu. */
    width: 46rem; max-width: calc(100vw - var(--s-6) * 2);
    padding: var(--s-5);
  }

  /* Keep the panel inside the viewport. The rightmost menu sits close to the
     CTA, so a left anchored 46rem panel would run off the edge. */
  /* The right-anchored :last-child override is GONE. It was here because a
     left:0 panel 46rem wide ran off the edge, which the clamp now handles
     without giving up centring. Keeping both would reintroduce the 317px
     offset this fix exists to remove. */

  .navgroup:hover > .navpanel,
  .navgroup:focus-within > .navpanel,
  .navpanel[data-open] {
    opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0);
  }

  /* SPECIFICITY TRAP, found by rendering rather than by reading.
     The base stylesheet carries `.navpanel[data-open] { display: block }`, which
     is (0,2,0) and therefore beats the `.navpanel { display: grid }` below at
     (0,1,0). Hover worked, because hover never sets data-open. The CLICK and
     TOUCH path sets it, so on a touch device the mega-menu silently collapsed
     into a stacked column with a full width feature card. Matching the
     specificity here is the fix. */
  .navpanel[data-open] { display: grid; }

  /* A feature card plus a list of rows. The card answers "which one do I want",
     which a flat list of links never does. */
  .navpanel {
    display: grid; grid-template-columns: 16rem minmax(0, 1fr); gap: var(--s-6);
  }

  .mm-feature {
    background: var(--brand-wash); border: 1px solid var(--line);
    border-radius: var(--r-md); padding: var(--s-5);
    text-decoration: none; color: var(--ink);
    display: flex; flex-direction: column;
  }
  .mm-feature:hover { border-color: var(--brand); }
  .mm-feature .mm-kicker {
    font-size: var(--t-micro); font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--brand); margin-bottom: var(--s-2);
  }
  .mm-feature h3 { font-size: var(--t-h3); margin-bottom: var(--s-2); }
  .mm-feature p { font-size: var(--t-small); color: var(--ink-70); margin: 0; }
  .mm-feature .mm-go {
    margin-top: auto; padding-top: var(--s-4);
    font-size: var(--t-small); font-weight: 650; color: var(--brand);
  }

  /* ROW RHYTHM, measured 2026-07-30 (Mike: "some of the new ones are way too
     spaced out"). At 12px of row padding plus an 8px gap these rows measured
     81.5px of pitch on 49.5px of text: 39% air, against 25-35% across the menus
     already approved on digilu, aioinsights, fortclips and marketinghelix.
     8px of padding and a 4px gap bring it to roughly 29% and take ~48px out of a
     four row panel, which is height this site could not afford: one of its panels
     was hanging off the right edge and the whole set sat past the hero.
     min-height stays var(--tap): these rows carry a title AND a blurb, so the
     content is already taller than the tap target and the token is not what was
     padding them out. Measured by the DENSITY rule in
     ecosystem-site-engine/modules/megamenu/core/contract.mjs. */
  .mm-rows { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-1); align-content: start; }
  .mm-rows a {
    display: grid; grid-template-columns: 22px 1fr; gap: var(--s-4);
    align-items: start; padding: var(--s-2) var(--s-4); min-height: var(--tap);
    border-radius: var(--r-sm); text-decoration: none; color: var(--ink);
  }
  .mm-rows a:hover { background: var(--brand-wash); }
  .mm-rows a[aria-current="page"] { background: var(--brand-wash); }
  .mm-rows .mm-text { display: block; min-width: 0; }
  .mm-rows b { display: block; font-weight: 650; font-size: var(--t-small); }
  .mm-rows .mm-text span { display: block; font-size: var(--t-micro); color: var(--ink-55); }
  .mm-rows .la--ico { margin-top: 2px; }
}

/* Mobile: the accordion keeps the icons but drops the feature card, which would
   be a 15rem block above every list on a 390px screen. */
@media (max-width: 980px) {
  .mm-feature { display: none; }
  .mm-rows { list-style: none; margin: 0; padding: 0; }
  .mm-rows a {
    display: grid; grid-template-columns: 22px 1fr; gap: var(--s-4); align-items: center;
    min-height: var(--tap); padding: var(--s-3) var(--s-5); text-decoration: none; color: var(--ink);
  }
  .mm-rows b { font-weight: 600; font-size: var(--t-body); }
  .mm-rows .mm-text span { display: none; }
}

/* ============================================================== */
/* WORDMARK: AIO reads first, then the noun.                      */
/* ============================================================== */
/*
 * "AIOGovernment" set in one weight and one color is 13 characters of
 * undifferentiated text, and the eye has to parse the whole string before the
 * brand lands. AIO is the family mark and has to arrive first.
 *
 * The separation is WEIGHT plus COLOUR, not color alone, so it survives a
 * grayscale print and a color-blind reader. The accent is not used: it is the
 * CTA fill and measures 2.55:1 on the ground, which fails as type by design.
 * Brand navy measures 8.12:1 and the noun stays at ink's 14.02:1, so both halves
 * pass AA comfortably.
 */
/* Two-tone, and the tones are far enough apart to actually separate. The first
   attempt put brand navy next to ink navy, which are close in value, so at
   header size it still read as one 13 character word. AIO now carries the
   heavier weight AND the saturated hue; the noun steps back in weight and
   lightness so the eye lands on AIO first and reads the noun second. */
.brand-name {
  letter-spacing: -0.005em;
  font-weight: 500;
  color: var(--ink-70);
}
.brand-name b {
  font-weight: 800;
  color: var(--brand);
  letter-spacing: .015em;
  margin-right: 0.08em;   /* a hair of air, not a visible gap */
}

/* On the dark trust-bar side of the footer the same relationship has to hold,
   so the noun lightens rather than the mark darkening. */
.foot-brand .brand-name { color: var(--ink-70); }

/* ============================================================== */
/* FOOTER: ecosystem cross links + the mandated Digilu trust bar. */
/* ============================================================== */

.foot-eco {
  border-top: 1px solid var(--line);
  padding-top: var(--s-6); margin-top: var(--s-7);
}
.foot-eco h2 {
  font-size: var(--t-micro); font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-55); margin-bottom: var(--s-4);
}
.foot-eco ul {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--s-4);
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}
.foot-eco a {
  display: block; text-decoration: none; color: var(--ink);
  font-weight: 650; min-height: var(--tap); padding: var(--s-2) 0;
}
.foot-eco a span {
  display: block; font-weight: 400; font-size: var(--t-small); color: var(--ink-70);
}
.foot-eco a:hover { color: var(--brand); }

/* The trust bar is the LAST row of the footer, always. Centerd strip, its own
   rule above it, three chips of equal height. */
.digilu-trust-bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: var(--s-4);
  padding: var(--s-6) var(--s-4);
  border-top: 1px solid var(--line);
  margin-top: var(--s-7);
}
.dtb-chip, .dtb-badge {
  display: inline-flex; align-items: center; height: 52px;
  box-sizing: border-box; text-decoration: none; border-radius: 11px;
}
.dtb-built {
  gap: var(--s-3); padding: 0 var(--s-5);
  background: var(--ink); border: 1px solid var(--line);
}
.dtb-built span {
  font-size: 9px; font-weight: 600; line-height: 1.1; letter-spacing: .13em;
  text-transform: uppercase; color: var(--line); white-space: nowrap;
}
.dtb-built img { height: 22px; width: auto; display: block; }
.dtb-badge img {
  height: 52px; width: 217px; display: block;
  border: 1px solid var(--line); border-radius: 11px; box-sizing: border-box;
}
.dtb-chip:hover, .dtb-badge:hover { border-color: var(--brand); }

@media (max-width: 560px) {
  .digilu-trust-bar { gap: var(--s-3); padding: var(--s-5) var(--s-3); }
  .dtb-badge img { width: 100%; max-width: 217px; }
}

/* lineart.css */
/* lineart.css: the .la system, ported from the Digilu web line-art standard.
 *
 * Eight house rules, three of which are enforced here:
 *   - navy HAIRLINE ink, never a fill
 *   - the accent used exactly once per piece, on the stroke carrying the meaning
 *   - a ghost pass used as TOOTH, not as a drop shadow
 *
 * Everything is DRAWN in order rather than faded in. Every stroke carries
 * pathLength="1", so the draw-on is a single dashoffset transition and nothing
 * has to be measured in script.
 *
 * No hex values here. tokens.css owns color.
 */

.la { display: block; width: 100%; height: auto; overflow: visible; }

.la-ink   { stroke: var(--ink); }
.la-det   { stroke: var(--ink-55); }
.la-acc   { stroke: var(--accent); }
.la-ghost { stroke: var(--line); }

/* On a dark field the ink inverts, and the accent stays the accent: it is the
   one stroke whose color is load bearing. */
.la--dark .la-ink   { stroke: var(--ground); }
.la--dark .la-det   { stroke: var(--line); }
.la--dark .la-ghost { stroke: rgba(255, 255, 255, .14); }


/* WHY A TAG LIST AND NOT [pathLength], 2026-07-29.
 *
 * These rules used to select `[pathLength]`, and they selected NOTHING in the
 * cascade, so every mark on the site rendered as a blank rectangle. The whole
 * line-art system was installed, deployed and invisible on both this site and
 * AIOGovernment.
 *
 * The cause is that a CSS attribute selector written in an HTML document is
 * lowercased to `[pathlength]`, while the attribute on an SVG element really is
 * `pathLength`, and attribute names on foreign elements match case SENSITIVELY.
 * So the selector could never match. It is a particularly quiet failure because
 * `querySelectorAll('[pathLength]')` DOES return the elements, which makes the
 * selector look correct from the console while the stylesheet ignores it.
 *
 * The tag list has no case to get wrong. `pathLength="1"` stays on every stroke,
 * because that is what normalises the dash to one path length; it is simply no
 * longer what the CSS keys off.
 */

/* Draw-on ---------------------------------------------------------------- */
/* One transition, driven by a class the observer adds. Strokes draw in document
   order, so the subject assembles the way somebody would draw it.
   
   THE DRAWN STATE IS THE DEFAULT, AND THE HIDING IS OPT IN.
   
   The hiding is scoped to `.la-anim`, which nav.js puts on <html> only once it
   has an IntersectionObserver and is about to drive the animation. This
   ordering matters: the first version hid every stroke by default and revealed
   them on observe, so the hero mark rendered as a large blank rectangle when the
   observer did not fire. Art that depends on script to be VISIBLE is art that is
   sometimes missing. Now the failure mode is a mark that does not animate,
   which nobody notices, instead of a mark that is not there, which is the whole
   right column of the homepage. */

.la-anim .la :is(path,circle,rect,line,polyline,polygon) {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1.1s var(--ease);
}
.la-anim .la.is-drawn :is(path,circle,rect,line,polyline,polygon) { stroke-dashoffset: 0; }

/* Stagger by position so it reads as drawing rather than as everything at once.
   Ten steps is enough for the busiest mark here. */
.la-anim .la :is(path,circle,rect,line,polyline,polygon):nth-child(1)  { transition-delay: .00s; }
.la-anim .la :is(path,circle,rect,line,polyline,polygon):nth-child(2)  { transition-delay: .06s; }
.la-anim .la :is(path,circle,rect,line,polyline,polygon):nth-child(3)  { transition-delay: .12s; }
.la-anim .la :is(path,circle,rect,line,polyline,polygon):nth-child(4)  { transition-delay: .18s; }
.la-anim .la :is(path,circle,rect,line,polyline,polygon):nth-child(5)  { transition-delay: .24s; }
.la-anim .la :is(path,circle,rect,line,polyline,polygon):nth-child(6)  { transition-delay: .30s; }
.la-anim .la :is(path,circle,rect,line,polyline,polygon):nth-child(7)  { transition-delay: .36s; }
.la-anim .la :is(path,circle,rect,line,polyline,polygon):nth-child(8)  { transition-delay: .42s; }
.la-anim .la :is(path,circle,rect,line,polyline,polygon):nth-child(9)  { transition-delay: .48s; }
.la-anim .la :is(path,circle,rect,line,polyline,polygon):nth-child(10) { transition-delay: .54s; }

/* A reader who has asked for less motion gets the finished drawing, immediately
   and in full. Never a half-drawn mark. */
@media (prefers-reduced-motion: reduce) {
  .la-anim .la :is(path,circle,rect,line,polyline,polygon) { transition: none; stroke-dashoffset: 0; }
}

/* Sizes ------------------------------------------------------------------ */

.la--ico  { width: 22px; height: 22px; flex: 0 0 auto; }
.la--feat { width: 100%; max-width: 15rem; margin-bottom: var(--s-4); }
.la--hero { width: 100%; max-width: 26rem; }

/* Under 900px the pen wobble and the stagger both cost more than they add. */
@media (max-width: 900px) {
  .la-anim .la :is(path,circle,rect,line,polyline,polygon) { transition-duration: .6s; transition-delay: 0s !important; }
}

/* home.css */
/* home.css: hero and page sections. */

/* Hero ----------------------------------------------------------------- */
/* Not dark. Not a bare photo rectangle. The right panel is a composed preview
   of the actual output, which is a stronger promise than a stock photograph
   and avoids every photo trap in the brief at the same time. */

.hero {
  position: relative; overflow: hidden;
  padding-block: var(--s-7) var(--s-8);
  background:
    radial-gradient(1100px 520px at 78% -10%, var(--brand-wash), transparent 62%),
    radial-gradient(760px 420px at 4% 108%, var(--accent-wash), transparent 66%),
    var(--ground);
}

.hero-in {
  display: grid; grid-template-columns: 1.06fr .94fr;
  gap: var(--s-8); align-items: center;
}

.hero h1 {
  font-size: var(--t-hero);
  letter-spacing: -0.025em;
  margin-bottom: var(--s-5);
  max-width: 15ch;
}

.hero-sub {
  font-size: var(--t-lead); line-height: 1.5; color: var(--ink-70);
  max-width: 46ch; margin-bottom: var(--s-6);
}

.hero-eyebrow {
  display: inline-flex; align-items: center; gap: var(--s-3);
  font-size: var(--t-micro); font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--brand);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 999px; padding: var(--s-2) var(--s-4);
  margin-bottom: var(--s-5);
}
.hero-eyebrow .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); }

/* Field art: the aperture motif, drawn not photographed. */
.hero-field {
  position: absolute; inset: 0; pointer-events: none;
  color: var(--brand); opacity: .09;
}
.hero-field svg { position: absolute; right: -14%; top: -34%; width: 76%; height: auto; }

/* Plan preview --------------------------------------------------------- */

.plan {
  position: relative;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-lift);
  padding: var(--s-6);
}
.plan-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-4);
  border-bottom: 1px solid var(--line); padding-bottom: var(--s-4); margin-bottom: var(--s-4);
}
.plan-head h2 {
  font-size: 1.25rem; margin: 0;
}
.plan-tag { font-size: var(--t-micro); color: var(--ink-55); text-transform: uppercase; letter-spacing: .1em; font-weight: 700; }

.plan-row { display: flex; gap: var(--s-4); padding-block: var(--s-4); border-bottom: 1px solid var(--line); }
.plan-row:last-of-type { border-bottom: 0; }
.plan-row b { display: block; font-size: var(--t-body); font-weight: 650; margin-bottom: 2px; }
.plan-row p { font-size: var(--t-small); color: var(--ink-70); margin: 0; }

.tag {
  flex: 0 0 auto; align-self: flex-start;
  font-size: 0.75rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: var(--s-1) var(--s-3); border-radius: 999px; border: 1px solid var(--line);
  white-space: nowrap;
}
.tag-likely { background: var(--ok-wash); color: var(--ok); }
.tag-check  { background: var(--brand-wash); color: var(--brand); }
.tag-out    { background: var(--ground); color: var(--ink-55); }

.plan-foot { border-top: 1px solid var(--line); margin-top: var(--s-4); padding-top: var(--s-4); }
/* Prose, not a label, so it does not use --t-micro. */
.plan-foot p { font-size: var(--t-small); color: var(--ink-70); margin: 0; }

@media (max-width: 980px) {
  .hero { padding-block: var(--s-7) var(--s-8); }
  .hero-in { grid-template-columns: 1fr; gap: var(--s-7); }
  .hero h1 { max-width: 100%; }
  /* Explicit order: the plan preview never climbs above the hook or the form. */
  .hero-copy { order: 1; }
  .plan       { order: 2; }
}

/* The problem ---------------------------------------------------------- */

.problem { background: var(--surface); border-block: 1px solid var(--line); }
.problem-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-8); align-items: start; }
.problem h2 { font-size: var(--t-h2); max-width: 20ch; }
.problem-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-4); }
.problem-list li {
  display: flex; gap: var(--s-4); align-items: flex-start;
  padding-bottom: var(--s-4); border-bottom: 1px solid var(--line);
}
.problem-list li:last-child { border-bottom: 0; padding-bottom: 0; }
.problem-list .n {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--brand-wash); color: var(--brand);
  font-size: var(--t-small); font-weight: 700;
}
.problem-list p { margin: 0; }

@media (max-width: 860px) { .problem-grid { grid-template-columns: 1fr; gap: var(--s-6); } }

/* Programs, the proof -------------------------------------------------- */

.progs { display: grid; gap: var(--s-6); }
.prog {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: var(--s-7);
  box-shadow: var(--shadow-card);
}
.prog-head { margin-bottom: var(--s-5); }
.prog h3 { font-size: 1.75rem; margin-bottom: var(--s-3); max-width: 26ch; }
.prog-name { font-size: var(--t-small); font-weight: 650; color: var(--brand); margin: 0; }
.prog-level {
  font-weight: 500; color: var(--ink-55);
  border-left: 1px solid var(--line); margin-left: var(--s-3); padding-left: var(--s-3);
}

.pull {
  margin: var(--s-5) 0; padding: var(--s-5) var(--s-6);
  background: var(--brand-wash); border-left: 3px solid var(--brand);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
}
.pull p { font-family: var(--display); font-size: 1.3125rem; line-height: 1.4; margin: 0 0 var(--s-2); }
.pull cite { font-style: normal; font-size: var(--t-small); color: var(--ink-55); }

.figure {
  font-family: var(--display); font-size: 1.5rem; font-weight: 600;
  color: var(--ink); background: var(--accent-wash);
  display: inline-block; padding: var(--s-3) var(--s-5); border-radius: var(--r-sm);
}

.catch { background: var(--ground); border: 1px solid var(--line); border-radius: var(--r-sm); padding: var(--s-4) var(--s-5); }
.apply { font-weight: 600; }

/* Steps ---------------------------------------------------------------- */

.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-6); counter-reset: step; }
.step { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); padding: var(--s-6); }
.step .num {
  display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%;
  background: var(--brand); color: var(--surface);
  font-family: var(--display); font-size: 1.25rem; font-weight: 600; margin-bottom: var(--s-4);
}
.step h3 { font-size: var(--t-h3); }
.step p { color: var(--ink-70); margin-bottom: 0; }

@media (max-width: 860px) { .steps { grid-template-columns: 1fr; } }

/* Mid CTA + friction removers ----------------------------------------- */
/* Friction removers live HERE, after the sell, never in the hero. At the top of
   the page nobody has decided anything yet, so these lines plant doubts instead
   of killing them. */

.cta-band {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: var(--s-8);
  box-shadow: var(--shadow-card); text-align: center;
}
.cta-band h2 { font-size: var(--t-h2); max-width: 22ch; margin-inline: auto; }
.cta-band > p { margin-inline: auto; }

.friction {
  list-style: none; margin: 0 0 var(--s-6); padding: 0;
  display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s-3) var(--s-5);
}
.friction li {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-size: var(--t-small); font-weight: 600; color: var(--ink-70);
}
.friction svg { width: 19px; height: 19px; color: var(--ok); flex: 0 0 auto; }

/* Situations ----------------------------------------------------------- */

.sits { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s-5); }
.sit { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); padding: var(--s-6); }
.sit h3 { font-size: 1.3125rem; }
.sit p { color: var(--ink-70); margin-bottom: 0; font-size: var(--t-small); }
@media (max-width: 760px) { .sits { grid-template-columns: 1fr; } }

/* Engines -------------------------------------------------------------- */

.engines { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-5); }
.engine {
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: var(--s-6);
}
.engine-top { display: flex; align-items: center; gap: var(--s-3); margin-bottom: var(--s-4); }
.engine-mark { width: 30px; height: 30px; color: var(--brand); }
.engine h3 { font-size: var(--t-h3); margin: 0; }
.engine p { color: var(--ink-70); font-size: var(--t-small); }
.engine .btn { margin-top: auto; align-self: flex-start; }
@media (max-width: 900px) { .engines { grid-template-columns: 1fr; } }

/* FAQ ------------------------------------------------------------------ */

.faq { display: grid; gap: var(--s-3); max-width: 78ch; }
.qa { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }
.qa summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-4);
  min-height: var(--tap-primary); padding: var(--s-4) var(--s-6);
  font-family: var(--display); font-size: 1.1875rem; font-weight: 600;
  cursor: pointer; list-style: none;
}
.qa summary::-webkit-details-marker { display: none; }
.qa summary::after {
  content: ''; flex: 0 0 auto; width: 12px; height: 12px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-3px, -3px); transition: transform .18s var(--ease);
}
.qa[open] summary::after { transform: rotate(-135deg) translate(-3px, -3px); }
.qa summary:hover { background: var(--brand-wash); }
.qa-body { padding: 0 var(--s-6) var(--s-5); }
.qa-body p:last-child { margin-bottom: 0; }

/* Page headers for inner routes --------------------------------------- */

.pagehead {
  padding-block: var(--s-8) var(--s-7);
  background: radial-gradient(900px 420px at 12% -30%, var(--brand-wash), transparent 64%), var(--ground);
  border-bottom: 1px solid var(--line);
}
.pagehead h1 { max-width: 20ch; }
.pagehead .lead { max-width: 56ch; margin-bottom: 0; }

.prose { max-width: var(--measure); }
.prose h2 { margin-top: var(--s-7); }
.prose h3 { margin-top: var(--s-6); font-size: 1.3125rem; }
.prose ul, .prose ol { padding-left: var(--s-5); }
.prose li { margin-bottom: var(--s-2); max-width: var(--measure); }

.callout {
  background: var(--surface); border: 1px solid var(--line); border-left: 3px solid var(--brand);
  border-radius: 0 var(--r-sm) var(--r-sm) 0; padding: var(--s-5) var(--s-6); margin-block: var(--s-6);
}
.callout p:last-child { margin-bottom: 0; }

.notify { background: var(--brand-wash); border: 1px solid var(--line); border-radius: var(--r-lg); padding: var(--s-7); }

/* ============================================================== */
/* AIOGovernment additions. No hex values: tokens.css owns color. */
/* ============================================================== */

/* Bands. The alternating rhythm that carries every content page. */
.band { padding: var(--s-8) 0; border-top: 1px solid var(--line); }
.band--alt { background: var(--brand-wash); }
.band > .wrap > h2 { font-size: var(--t-h2); margin-bottom: var(--s-4); max-width: 24ch; }
.band > .wrap > p { max-width: var(--measure); margin-bottom: var(--s-4); }

.pagehead { padding: var(--s-8) 0 var(--s-7); background: var(--brand-wash); border-bottom: 1px solid var(--line); }
.pagehead--tight { padding-bottom: var(--s-6); }
.pagehead h1 { margin-bottom: var(--s-4); }

.hero-copy { max-width: 44rem; }
.hero-note { font-size: var(--t-small); color: var(--ink-70); margin-top: var(--s-4); max-width: var(--measure); }

/* Numbered explanation steps. */
.steps { list-style: none; counter-reset: s; padding: 0; margin: 0; display: grid; gap: var(--s-6); }
.steps > li { counter-increment: s; position: relative; padding-left: var(--s-8); }
.steps > li::before {
  content: counter(s); position: absolute; left: 0; top: 0;
  width: var(--s-7); height: var(--s-7); border-radius: 999px;
  background: var(--brand); color: var(--surface);
  display: grid; place-items: center; font-family: var(--display); font-size: var(--t-h3);
}
.steps h3 { font-size: var(--t-h3); margin-bottom: var(--s-2); }
.steps p { max-width: var(--measure); }

/* Plain prose lists that still need breathing room. */
.plain { list-style: none; padding: 0; margin: 0 0 var(--s-5); display: grid; gap: var(--s-4); max-width: var(--measure); }
.plain > li { padding-left: var(--s-5); border-left: 3px solid var(--line); }

/* The five outcomes, explained. */
.outcomes { list-style: none; padding: 0; margin: 0 0 var(--s-5); display: grid; gap: var(--s-5); }
.outcomes > li { display: grid; gap: var(--s-2); max-width: var(--measure); }
.outcomes .pill { justify-self: start; margin: 0; }

/* The asymmetry: two cards, deliberately equal width so neither reads louder. */
.asym { display: grid; gap: var(--s-5); grid-template-columns: 1fr 1fr; margin-bottom: var(--s-5); }
.asym > div { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: var(--s-6); }
.asym h3 { font-size: var(--t-h3); margin-bottom: var(--s-2); }
@media (max-width: 700px) { .asym { grid-template-columns: 1fr; } }

/* Coverage counts. Numbers we publish so they can be checked. */
.statgrid { list-style: none; padding: 0; margin: 0 0 var(--s-5); display: grid; gap: var(--s-4);
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
.statgrid > li { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); padding: var(--s-5); }
.statgrid b { display: block; font-family: var(--display); font-size: var(--t-h1); line-height: 1; color: var(--brand); margin-bottom: var(--s-2); }
.statgrid span { font-size: var(--t-small); color: var(--ink-70); }

/* Questions. */
.faqs { display: grid; gap: var(--s-6); max-width: 52rem; }
.faqs .faq h2 { font-size: var(--t-h3); margin-bottom: var(--s-2); }
.faqs .faq p { max-width: var(--measure); }

/* The county table. Scrolls inside itself so the page body never does. */
.tablewrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); }
.ctable { width: 100%; border-collapse: collapse; font-size: var(--t-small); min-width: 44rem; }
.ctable caption { text-align: left; padding: var(--s-5); color: var(--ink-70); border-bottom: 1px solid var(--line); }
.ctable th, .ctable td { text-align: left; padding: var(--s-4); border-bottom: 1px solid var(--line); vertical-align: top; }
.ctable thead th { background: var(--ground); font-size: var(--t-micro); text-transform: uppercase; letter-spacing: .06em; color: var(--ink-55); }
.ctable tbody th { font-weight: 650; white-space: nowrap; }
.ctable tr:last-child th, .ctable tr:last-child td { border-bottom: 0; }

/* The catalog list. */
.proglist { list-style: none; padding: 0; margin: 0 0 var(--s-6); display: grid; gap: var(--s-5); }
.proglist > li { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); padding: var(--s-5); }
.proglist > li > b { font-size: var(--t-h3); font-family: var(--display); display: block; }
.proglist-org { font-size: var(--t-small); color: var(--ink-55); display: block; margin-bottom: var(--s-3); }
.proglist p { max-width: var(--measure); }

/* An honest absence. Never an empty cell. */
.none { color: var(--ink-55); font-style: italic; }

/* Form bits the intake needs. */
.hint { color: var(--ink-70); font-size: var(--t-small); max-width: var(--measure); margin-bottom: var(--s-5); }
.found { color: var(--ok); font-weight: 650; font-size: var(--t-small); margin-top: var(--s-2); min-height: 1.4em; }

.radios, .checks { display: grid; gap: var(--s-3); }
.checks { grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.radios label, .checks label {
  display: flex; align-items: center; gap: var(--s-3);
  min-height: var(--tap); padding: var(--s-3) var(--s-4);
  background: var(--surface); border: 2px solid var(--line); border-radius: var(--r-md);
  cursor: pointer; font-weight: 500;
}
.radios label:hover, .checks label:hover { border-color: var(--brand); }
.radios input, .checks input { width: 1.35rem; height: 1.35rem; flex: 0 0 auto; accent-color: var(--brand); }
.radios label:focus-within, .checks label:focus-within { border-color: var(--brand); outline: 2px solid var(--brand); outline-offset: 2px; }

/* Honeypot. Off screen rather than display:none, which some bots skip. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.stepnav { display: flex; gap: var(--s-3); flex-wrap: wrap; margin-top: var(--s-6); }
@media (max-width: 560px) { .stepnav .btn { width: 100%; } }

/* ============================================================== */
/* THE HERO. Form above the fold, and the right column answers    */
/* "why would I fill this in".                                    */
/* ============================================================== */
/*
 * The hero shipped with the form BELOW the fold and an empty right column, which
 * broke the pattern every property in this ecosystem uses: the form is the hero,
 * and the thing next to it says what you get for filling it in.
 *
 * The H1 does the hooking. The right column does the answering. A ZIP field with
 * no stated payoff is a toll gate, and people do not pay a toll before they know
 * what is on the other side.
 */

.hero { padding: var(--s-8) 0 var(--s-9); border-bottom: 1px solid var(--line); }

.hero-in {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: var(--s-8);
  align-items: start;   /* top align: centring a short column against a tall one
                           is what pushes a CTA below the fold */
}

/* THE TYPE SCALE IS THE FOLD FIX. Read this before enlarging anything here.
 *
 * Measured on the live page 2026-07-29: the ZIP input sat at 637px and the button
 * at 637-701, against roughly 648px of usable height on a 1366x768 laptop and
 * roughly 700px on an iPhone 14 in Safari. The button was cut off on both. On the
 * two devices this audience actually uses, the reader could not see the thing
 * they were supposed to do.
 *
 * The cause was 566px of preamble above the field, almost entirely two things: an
 * H1 wrapping to THREE lines at 54px under a `max-width: 15ch` cap, and a 250
 * character lead running to five lines. Both are fixed here, at the base.
 *
 * WHEN THE FORM IS THE HERO, THE H1 IS THE CAPTION, NOT THE MONUMENT. A 54px
 * headline above an invisible field is worth less than a 40px headline above a
 * visible one. Do not put --t-hero back without re-measuring the button position
 * at 1366x768 and 390x745. */
.hero-copy { max-width: 38rem; }
.hero-copy h1 {
  font-size: clamp(2rem, 3.1vw, 2.5rem);   /* 40px desktop, 32px phone */
  line-height: 1.12;
  max-width: 24ch;                          /* was 15ch, which forced the 3rd line */
  margin-bottom: var(--s-4);
}
.hero-copy .lead {
  font-size: 1.3125rem;                     /* 21px, from 22px */
  line-height: 1.52;
  max-width: 38rem;                         /* from 32rem: the cheapest line saved */
  margin-bottom: var(--s-5);
}

/* The one line of copy that answers the only question a reader actually has at
 * the field: what happens the moment I type this. It sits directly under the
 * button, above the slower reassurance, because it is the only reassurance that
 * changes a decision rather than confirming one already made. It also sets an
 * honest expectation of the flow, which is exactly six fieldsets. */
.hero-next {
  margin-top: var(--s-3);
  font-size: var(--t-small);
  line-height: 1.45;
  color: var(--ink-70);
  max-width: 34rem;
}

/* The payoff card. This is the "what do I get" answer, and it sits at the same
   height as the form so the two are read together. */
.hero-get {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: var(--s-6);
  box-shadow: var(--shadow-card);
}
.hero-get .la--hero { margin: 0 auto var(--s-5); }
.hero-get h2 {
  font-size: var(--t-h3); margin-bottom: var(--s-4);
  padding-bottom: var(--s-3); border-bottom: 1px solid var(--line);
}
.hero-get ol { list-style: none; margin: 0 0 var(--s-5); padding: 0; counter-reset: g; display: grid; gap: var(--s-4); }
.hero-get li { counter-increment: g; display: grid; grid-template-columns: 26px 1fr; gap: var(--s-4); align-items: start; }
.hero-get li::before {
  content: counter(g); grid-row: span 2;
  width: 26px; height: 26px; border-radius: 999px;
  background: var(--brand); color: var(--surface);
  display: grid; place-items: center;
  font-family: var(--display); font-size: var(--t-small);
}
.hero-get b { display: block; font-weight: 650; }
.hero-get span { display: block; font-size: var(--t-small); color: var(--ink-70); }

.hero-get .hero-cost {
  border-top: 1px solid var(--line); padding-top: var(--s-4);
  font-size: var(--t-small); color: var(--ink-70);
}
.hero-get .hero-cost b { display: inline; color: var(--ink); }

.hero-copy .zipform { max-width: none; }

/* `.hero-why` (a row of three ticked reassurances) was removed from the hero on
 * 2026-07-29 and its rules deleted with it. All three of its facts now live in
 * `.hero-next` above, in one line, directly under the button. They were three
 * separate claims in a row 61px tall, and the reader had to have already decided
 * to care before any of them helped. Folded into the sentence that answers "what
 * happens next", they do the same work in a third of the space and at the moment
 * the answer changes something. */

@media (max-width: 980px) {
  .hero { padding: var(--s-7) 0 var(--s-8); }
  .hero-in { grid-template-columns: 1fr; gap: var(--s-6); }
  /* On a phone the form comes FIRST, then the payoff card. Explicit order,
     because a child with no order defaults to 0 and jumps above the H1. */
  .hero-copy { order: 1; max-width: none; }
  .hero-get  { order: 2; }
  .hero-get .la--hero { max-width: 18rem; }
}

/* ===================================================================== */
/* PHONES: the form must be reachable without scrolling.                 */
/* ===================================================================== */
/*
 * NOTHING IN THIS FILE MAY STYLE `.zipform`. The bundle order in build.mjs is
 * tokens, base, chrome, lineart, home.css, forms.css, results.css, so forms.css
 * loads after this file. A `.zipform` rule in each place has identical
 * specificity (a media query adds none), so forms.css wins on source order and
 * anything written here is silently dead. On the sibling site that killed four
 * such rules, including one that visually hid the ZIP label: it never applied,
 * the label was never actually hidden in production, and the comment described
 * behavior that did not exist. Form compaction lives in forms.css.
 *
 * KEYED ON WIDTH, NOT HEIGHT, and that ordering matters. Compaction keyed on
 * `max-height` gave the sibling site a BETTER hero on an iPhone SE than on an
 * iPhone 14: the tier fired on the short screen and tightened everything, while
 * the roomier phone kept a 3-line headline and pushed its own button 140px
 * lower. The most common phone got the loosest layout. `max-height` is also
 * unstable on a phone, because mobile Safari reports a taller viewport before
 * the URL bar collapses and a shorter one after, so a height-keyed tier can
 * reflow the hero mid-scroll. Tolerable for padding and a font step. Never for
 * hiding or reordering anything.
 */
@media (max-width: 560px) {
  .hero-copy h1 {
    font-size: 1.75rem;    /* 28px: still comfortably the largest thing on screen */
    line-height: 1.14;
    max-width: 100%;
  }
  .hero-copy .lead { font-size: var(--t-body); line-height: 1.45; }
}

@media (max-width: 700px) and (max-height: 740px) {
  .hero { padding-block: var(--s-5) var(--s-6); }
  .hero-copy .eyebrow { margin-bottom: var(--s-3); }
  .hero-copy h1 { margin-bottom: var(--s-3); }
  .hero-copy .lead { margin-bottom: var(--s-4); }
  .hero-next, .hero-note { margin-top: var(--s-3); }
}

/* iPhone SE and iPhone 8 at 667px, still in service and over-represented among
   exactly the readers this site is built for. */
@media (max-width: 700px) and (max-height: 700px) {
  .hero { padding-block: var(--s-3) var(--s-5); }
  .hero-copy h1 { font-size: 1.625rem; margin-bottom: var(--s-2); }
  .hero-copy .lead { line-height: 1.42; margin-bottom: var(--s-3); }
}

/* 360x640 and smaller, a large population of older Android handsets and
   over-represented here for the same reason.
 *
 * This tier works harder than the sibling site's equivalent, and the reason is
 * a defect OUTSIDE the hero: at 375px and below the site header wraps, because
 * the brand (222px) and the menu toggle (103px) stop fitting on one line. The
 * header goes from 77px to 133px and the toggle lands orphaned under the logo.
 * That is 56px of fold gone before the hero renders a single pixel, on the
 * iPhone SE and iPhone 8 this audience actually holds.
 *
 * It is chrome.css and it affects all 98 pages, so it is not fixed here. The
 * hero instead clears the fold GIVEN a 133px header, which is why the eyebrow
 * gets its tracking reduced: at full tracking it wraps to two lines at 360px and
 * costs another 23px. Reducing letter-spacing on a decorative uppercase micro
 * label costs nothing legible and buys the line back.
 *
 * If the header wrap is ever fixed, this tier can be relaxed, not deleted. */
@media (max-width: 380px) and (max-height: 700px) {
  .hero { padding-block: 0 var(--s-5); }
  .hero-copy .eyebrow {
    margin-bottom: var(--s-2);
    letter-spacing: .07em;   /* keeps it to ONE line at 360px */
  }
  .hero-copy h1 { font-size: 1.5rem; }
  .hero-copy .lead { margin-bottom: var(--s-2); }
}

/* Three-up comparison, used where a distinction has three sides rather than two.
   Equal widths on purpose: the point is that these are peers, not a ranking. */
.asym--3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) { .asym--3 { grid-template-columns: 1fr; } }

/* forms.css */
/* forms.css: the inline ZIP entry and the full intake. */

/* Question one, inline in the hero. The button and the first field are the same
   element, so this is still ONE call to action: it starts the form instead of
   promising to. */

.zipform {
  display: flex; align-items: flex-end; gap: var(--s-3); flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: var(--s-4);
  box-shadow: var(--shadow-card);
  max-width: 33rem;
}
.zipwrap { flex: 1 1 12rem; min-width: 0; }
.zipform label {
  display: block; font-size: var(--t-micro); font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--ink-55);
  margin-bottom: var(--s-2); padding-left: var(--s-3);
}
.zipform input {
  width: 100%; min-height: var(--tap-primary);
  padding: 0 var(--s-4);
  font-family: var(--sans); font-size: 1.25rem; font-weight: 600; color: var(--ink);
  background: var(--ground); border: 2px solid var(--line); border-radius: var(--r-md);
}
.zipform input::placeholder { color: var(--ink-55); font-weight: 500; }
.zipform input:focus-visible { border-color: var(--brand); outline-offset: 1px; }
.zipform input[aria-invalid="true"] { border-color: var(--brand); background: var(--surface); }
.zipform .btn { flex: 0 0 auto; }

.err { font-size: var(--t-small); color: var(--brand); margin: var(--s-2) 0 0; padding-left: var(--s-3); font-weight: 600; }

@media (max-width: 560px) {
  .zipform { flex-direction: column; align-items: stretch; }
  .zipform .btn { width: 100%; }
  /* `.zipwrap` carries `flex: 1 1 12rem`, which is correct in the desktop ROW
     layout where 12rem is a width. Once the container flips to a column, that
     same basis becomes a HEIGHT and opened a dead gap of roughly 190px between
     the ZIP field and the button, on the primary call to action, on the device
     most of these families are holding. Reset it. */
  .zipwrap { flex: 0 0 auto; }
}

/* SMALL VIEWPORT FORM COMPACTION LIVES HERE, NOT IN home.css.
 *
 * The bundle order in build.mjs is tokens, base, chrome, lineart, home.css,
 * forms.css, results.css. This file loads later, so a `.zipform` rule here beats
 * an identical-specificity one in home.css on source order. The reverse is not
 * true, which is why four such rules in the sibling site's home.css were dead for
 * as long as they existed. Nothing errored and nothing applied.
 *
 * Tap targets are never reduced below 52px. The readers this site is for are
 * frequently in their eighties, often on a phone they find hard to hit
 * accurately, and buying fold space by shrinking the one thing they have to touch
 * is the wrong trade every time. The label also stays visible: a placeholder is
 * not a label, it vanishes the moment they start typing, and this audience is the
 * least able to afford that. */
@media (max-width: 700px) and (max-height: 740px) {
  .zipform { padding: var(--s-3); }
  .zipform label { margin-bottom: var(--s-1); }
  .zipform input, .zipform .btn { min-height: 56px; }
}

@media (max-width: 700px) and (max-height: 700px) {
  .zipform { padding: var(--s-3); gap: var(--s-2); }
  .zipform input, .zipform .btn { min-height: 52px; }
}

/* The last few pixels on an older small Android with browser chrome. Taken from
   the form's padding and the label gap, never from the input or the button. */
@media (max-width: 380px) and (max-height: 700px) {
  .zipform { padding: var(--s-2); }
  .zipform label { margin-bottom: 2px; }
}

/* Full intake ---------------------------------------------------------- */

.check { max-width: 46rem; }

.progress { margin-bottom: var(--s-6); }
.progress-bar { height: 8px; background: var(--line); border-radius: 999px; overflow: hidden; }
.progress-fill { height: 100%; width: 0%; background: var(--brand); border-radius: 999px; transition: width .3s var(--ease); }
.progress-meta {
  display: flex; justify-content: space-between; gap: var(--s-4);
  font-size: var(--t-small); color: var(--ink-55); margin-top: var(--s-3); font-weight: 600;
}

.stepcard {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: var(--s-7); box-shadow: var(--shadow-card);
}
.stepcard[hidden] { display: none; }
.stepcard h2 { font-size: 1.75rem; max-width: 24ch; }
.stepcard .hint { color: var(--ink-70); font-size: var(--t-small); }

.field { margin-bottom: var(--s-6); }
.field > label, .fieldset > legend {
  display: block; font-size: var(--t-body); font-weight: 650; margin-bottom: var(--s-2); padding: 0;
}
.field .hint { display: block; margin-bottom: var(--s-3); }

.field input[type="text"], .field input[type="email"], .field input[type="tel"], .field select {
  width: 100%; min-height: var(--tap-primary); padding: 0 var(--s-4);
  font-family: var(--sans); font-size: var(--t-body); color: var(--ink);
  background: var(--ground); border: 2px solid var(--line); border-radius: var(--r-md);
}
.field select { appearance: none; padding-right: var(--s-7); }
.field input:focus-visible, .field select:focus-visible { border-color: var(--brand); }

.fieldset { border: 0; margin: 0 0 var(--s-6); padding: 0; }
.opts { display: grid; gap: var(--s-3); }
.opts-2 { grid-template-columns: 1fr 1fr; }
@media (max-width: 640px) { .opts-2 { grid-template-columns: 1fr; } }

.opt {
  display: flex; align-items: center; gap: var(--s-3);
  min-height: var(--tap-primary); padding: var(--s-3) var(--s-5);
  background: var(--ground); border: 2px solid var(--line); border-radius: var(--r-md);
  cursor: pointer; font-weight: 550;
}
.opt:hover { border-color: var(--brand); background: var(--surface); }
.opt input { width: 22px; height: 22px; flex: 0 0 auto; accent-color: var(--brand); margin: 0; }
.opt:has(input:checked) { border-color: var(--brand); background: var(--brand-wash); }
.opt:has(input:focus-visible) { outline: 3px solid var(--ink); outline-offset: 3px; }

/* Consent wraps to two lines on a phone, so it cannot be a single-line row. */
.opt-consent { align-items: flex-start; padding-block: var(--s-4); line-height: 1.5; }
.opt-consent input { margin-top: 3px; }

.stepnav { display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap; margin-top: var(--s-6); }
.stepnav .btn-primary { min-width: 12rem; }
.saved { font-size: var(--t-small); color: var(--ok); font-weight: 650; display: none; align-items: center; gap: var(--s-2); }
.saved[data-on] { display: inline-flex; }

.asterisk { font-size: var(--t-small); color: var(--ink-55); margin-top: var(--s-5); max-width: 68ch; }

.done { text-align: center; }
.done .tick {
  width: 64px; height: 64px; margin: 0 auto var(--s-5);
  display: grid; place-items: center; border-radius: 50%;
  background: var(--ok-wash); color: var(--ok);
}
.done .tick svg { width: 30px; height: 30px; }
.done h2 { margin-inline: auto; }
.done p { margin-inline: auto; }

.noscript-note { background: var(--accent-wash); border-radius: var(--r-md); padding: var(--s-5); }

/* The step heading receives focus programmatically when a question advances, so
   a screen reader announces the new question. It is not interactive and the
   reader did not navigate to it by keyboard, so the visible ring is noise: on
   first paint it read as an error box around an untouched form. Focus, and the
   announcement, are preserved. */
.stepcard h2:focus { outline: none; }
.stepcard h2:focus-visible { outline: 2px solid var(--brand); outline-offset: 4px; }

/* results.css */
/* results.css: the answer, the action plan, and the live-check badges.
   No hex values here. tokens.css owns color. */

/* --------------------------------------------------------------- summary */

.res-head { background: var(--brand-wash); border-bottom: 1px solid var(--line); padding: var(--s-7) 0 var(--s-6); }
.res-head h1 { margin-bottom: var(--s-3); }
.res-where { font-size: var(--t-lead); color: var(--ink-70); margin-bottom: var(--s-5); }
.res-where b { color: var(--ink); }

/* The count row. `ruled_out` is present and never hidden: telling a family what
   to skip returns time they do not have. */
.res-counts { display: flex; flex-wrap: wrap; gap: var(--s-3); list-style: none; padding: 0; margin: 0; }
.res-counts li {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: var(--s-3) var(--s-4); font-size: var(--t-small); font-weight: 650; color: var(--ink-70);
}
.res-counts b { font-size: var(--t-h3); display: block; font-family: var(--display); color: var(--ink); }

/* ----------------------------------------------------------------- group */

.res-group { padding: var(--s-7) 0 0; }
.res-group > .wrap > h2 { font-size: var(--t-h2); margin-bottom: var(--s-2); }
.res-group-note { color: var(--ink-70); max-width: var(--measure); margin-bottom: var(--s-5); }

.res-list { display: grid; gap: var(--s-5); list-style: none; padding: 0; margin: 0; }

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

.res {
  background: var(--surface); border: 1px solid var(--line); border-left: 6px solid var(--line);
  border-radius: var(--r-lg); padding: var(--s-6); box-shadow: var(--shadow-card);
}
.res--likely    { border-left-color: var(--likely); }
.res--possible  { border-left-color: var(--possible); }
.res--general   { border-left-color: var(--possible); }
.res--unknown   { border-left-color: var(--line); }
.res--ruled_out { border-left-color: var(--ruled-out); background: var(--ruled-wash); }

.res h3 { font-size: var(--t-h3); margin-bottom: var(--s-2); }
.res-org { font-size: var(--t-small); color: var(--ink-55); font-weight: 650; margin-bottom: var(--s-4); }
.res-summary { margin-bottom: var(--s-4); max-width: var(--measure); }

/* Outcome pill. Text ALWAYS states the outcome in words: color is a second
   signal, never the only one. */
.pill {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-size: var(--t-micro); font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: var(--s-2) var(--s-3); border-radius: 999px; border: 1px solid currentColor;
  margin-bottom: var(--s-3);
}
.pill--likely    { color: var(--likely); background: var(--ok-wash); }
.pill--possible  { color: var(--possible); background: var(--brand-wash); }
.pill--general   { color: var(--possible); background: var(--brand-wash); }
.pill--unknown   { color: var(--ink-70); background: var(--ground); }
.pill--ruled_out { color: var(--ruled-out); background: var(--ground); }

/* The reason. This is the product: never a score without the sentence that
   produced it. */
.res-why {
  border-left: 3px solid var(--line); padding-left: var(--s-4);
  color: var(--ink-70); margin-bottom: var(--s-4); max-width: var(--measure);
}
.res-why b { color: var(--ink); }

.res-missing {
  background: var(--ground); border: 1px dashed var(--line); border-radius: var(--r-md);
  padding: var(--s-4); margin-bottom: var(--s-4); font-size: var(--t-small);
}

/* ------------------------------------------------------------ next steps */

.res-steps { margin: 0 0 var(--s-5); padding-left: var(--s-5); }
.res-steps li { margin-bottom: var(--s-3); }

.res-actions { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-bottom: var(--s-4); }
.res-actions .btn { min-height: var(--tap); }

.res-phone {
  font-family: var(--display); font-size: var(--t-h3); color: var(--brand);
  text-decoration: none; font-weight: 600;
}
.res-phone:hover { color: var(--brand-lift); }

/* --------------------------------------------------------------- sourcing */

.res-meta {
  border-top: 1px solid var(--line); padding-top: var(--s-4); margin-top: var(--s-4);
  font-size: var(--t-small); color: var(--ink-55); display: grid; gap: var(--s-2);
}
.res-meta a { color: var(--brand); }

/* Live check badge. Three states, three different sentences, never one icon
   doing the work of all three. */
.live { display: inline-flex; align-items: center; gap: var(--s-2); font-weight: 650; }
.live-dot { width: 10px; height: 10px; border-radius: 999px; background: currentColor; flex: 0 0 auto; }
.live--ok      { color: var(--ok); }
.live--moved   { color: var(--possible); }
.live--down    { color: var(--ruled-out); }
.live--unknown { color: var(--ink-55); }

/* ------------------------------------------------------------- veterans */

.vet {
  background: var(--brand-wash); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: var(--s-6); margin-bottom: var(--s-6);
}
.vet h2 { font-size: var(--t-h3); margin-bottom: var(--s-3); }
.vet-note { font-size: var(--t-small); color: var(--ink-70); max-width: var(--measure); }
.vet-office { background: var(--surface); border-radius: var(--r-md); padding: var(--s-5); margin-top: var(--s-4); }
.vet-office address { font-style: normal; margin-bottom: var(--s-3); }

/* An honest absence. Alpine County has no CVSO in the state directory and the
   engine records that as a VERIFIED FINDING rather than showing nothing. */
.vet-absent { background: var(--ground); border: 1px dashed var(--line); }

/* ------------------------------------------------------------------ plan */

.plan-save {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: var(--s-7); box-shadow: var(--shadow-card); max-width: 40rem;
}
.plan-save h2 { font-size: var(--t-h3); }
.plan-privacy { font-size: var(--t-small); color: var(--ink-70); margin-top: var(--s-4); }

.plan-link {
  display: block; word-break: break-all; background: var(--ground);
  border: 1px solid var(--line); border-radius: var(--r-md);
  padding: var(--s-4); font-family: var(--sans); font-size: var(--t-small); margin: var(--s-4) 0;
}

/* ------------------------------------------------- the one referral out */
/* Family Observatory. The ONLY commercial destination on this site, and it
   carries no price: the results page states the need and hands over. */

.handoff {
  background: var(--ink); color: var(--ground);
  border-radius: var(--r-lg); padding: var(--s-8) var(--s-7); margin: var(--s-8) 0;
}
.handoff h2 { color: var(--ground); font-size: var(--t-h2); margin-bottom: var(--s-4); max-width: 20ch; }
.handoff p { color: var(--ground); opacity: .88; max-width: var(--measure); margin-bottom: var(--s-5); }
.handoff .btn-primary { background: var(--accent); color: var(--ink); }
.handoff .btn-primary:hover { background: var(--accent-lift); }

/* --------------------------------------------------------------- report */

.report-toggle {
  background: none; border: 0; color: var(--ink-55); font-size: var(--t-small);
  text-decoration: underline; cursor: pointer; padding: var(--s-2) 0; min-height: var(--tap);
}
.report-toggle:hover { color: var(--brand); }

/* ------------------------------------------------------------- printing */
/* A printable plan is a real requirement here: a lot of these families take
   paper to an office appointment. */

@media print {
  .site-header, .site-footer, .handoff, .plan-save, .report-toggle, .skip { display: none !important; }
  .res { break-inside: avoid; box-shadow: none; border: 1px solid var(--line); }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.8em; word-break: break-all; }
  body { background: var(--surface); }
}

@media (max-width: 560px) {
  .res { padding: var(--s-5); }
  .res-actions .btn { width: 100%; }
}
