/* ============================================================================
   COMPONENTS — site chrome. V2, Aug 2026 (spec §2).
   Utility nav top-right; six-item primary nav. Version B, Oct 2026: the
   ASC / CheckFirst family bar is back as the header's first row.
   Tokens only — no literal colours or sizes below this line.
   ========================================================================== */

/* --- 0. family bar (ASC / CheckFirst) -------------------------------------
   Version B, Oct 2026 — FEEDBACK.md "Return to the original tab design". The
   tabs from the first scaffold (2d06f2d), on current tokens: the footer navy
   for the bar, the raised current tab in the page's own white, and the
   CheckFirst check tile in orange where it used to be teal.

   It is the one part of the header with a fill of its own. The hero is pulled
   up behind the WHOLE header, bar included (--header-h is measured), so the
   bar simply sits over the top of the band.

   The bar is a dark surface, so it is the inheritance root for its own text
   and focus colour — see the note on .mobile-nav. */
.family-bar {
  --color-focus: var(--color-focus-on-dark);
  background: var(--color-surface-sunken);
  color: var(--color-text-inverse);
  font-size: var(--text-sm);
}
.family-bar__inner { display: flex; align-items: stretch; gap: var(--space-1); height: var(--family-bar-h); }
.family-bar__tab {
  display: flex; align-items: center; gap: var(--space-2);
  padding-inline: var(--space-5);
  color: var(--color-text-inverse);
  text-decoration: none;
  font-weight: var(--weight-medium);
  transition: background var(--duration-fast) var(--ease);
}
.family-bar__tab:hover { background: var(--color-surface-on-dark-hover); }
/* The current tab takes the colour of the band behind the header, so it reads
   as the top of the page it opens onto (Celeste, Oct 2026): the navy band's
   head on Home, the orange band on every other page, the page colour where
   there is no hero. Its text and focus ring read --color-text and
   --color-focus, which the on-dark header already remaps to white, so the
   label is white on both bands (9.99:1 navy, 4.90:1 orange) and ink on the
   page. Keyed to the attributes chrome.js and each page already set on <html>. */
.family-bar__tab[aria-current="page"] {
  background: var(--color-page);
  color: var(--color-text);
}
[data-hero-header="on-dark"] .family-bar__tab[aria-current="page"] { background: var(--color-surface-hero); }
[data-hero-header="on-dark"][data-section="Home"] .family-bar__tab[aria-current="page"] { background: var(--color-band-feature-head); }
.family-bar__sub { font-weight: var(--weight-regular); color: var(--color-text-muted); }
/* The one place the teal survives in Version B: CheckFirst's own mark.
   White on --color-checkfirst is 5.36:1. */
.family-bar__mark {
  width: 1.25em; height: 1.25em; flex: none;
  display: grid; place-items: center;
  border-radius: var(--radius-sm);
  background: var(--color-checkfirst);
  color: var(--color-checkfirst-ink);
  font-size: var(--text-xs);
}

/* --- 1. utility bar ------------------------------------------------------- */
/* Sep 2026: the site search moved up here from the old brand row, and the
   brand row itself is gone — the logo now sits in the nav row. That takes a
   three-row header down to two and reclaims most of its vertical space. */
/* No fill (Figma 153:2568). The header carries no background of its own; the
   hero is pulled up underneath it so the page's own band runs behind the
   header, and the two read as one surface instead of a bar sitting on a hero
   sitting on a page. On a page with no hero — records/case.html — nothing is
   behind it and it falls through to --color-page, which is what it was.

   The header is positioned with a z-index so the hero, which arrives later in
   the DOM with a negative top margin, paints under it rather than over it. */
[data-site-header] { background: none; position: relative; z-index: 50; }
.utility-bar { font-size: var(--text-sm); }
/* Everything right-aligned as one group: links then the search control. */
.utility-bar__inner { display: flex; align-items: center; justify-content: flex-end; gap: var(--space-5); padding-block: var(--space-1); }
.utility-bar__list { list-style: none; margin: 0; padding: 0; display: flex; gap: var(--space-5); }
.utility-bar a { text-decoration: none; color: var(--color-text-muted); }
.utility-bar a:hover { text-decoration: underline; color: var(--color-text); }

/* Reduced to an icon and a label (Figma 153:2568). The field it used to hold
   is gone: the homepage's Get Started band now owns the only real search box,
   so two of them are never on screen at once. The height clears --tap-min-aa
   with room, and the hover fill is what tells a pointer user it is a control
   rather than a third utility link. */
.util-search {
  display: inline-flex; align-items: center; gap: var(--space-2);
  min-height: var(--tap-min-aa);
  padding: var(--space-1) var(--space-3);
  background: none;
  border: 0;
  border-radius: var(--radius-pill);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  transition: background var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease);
}
.util-search:hover { background: var(--color-surface-muted); color: var(--color-text); }
.util-search__icon { flex: none; }

/* ON-DARK HEADER. chrome.js sets data-hero-header="on-dark" on <html> when the
   page defines a hero, because that is the only case where a band is pulled up
   behind the header. Both hero colourways carry white above 4.5:1 — the navy
   homepage band at 9.99:1 and the orange --color-surface-hero at 4.90:1 — so
   one on-dark treatment serves every page that has a hero, and a page without
   one (records/case.html) keeps the light header unchanged.

   It stays on when the mobile header condenses. The condensed bar takes a solid
   navy fill (767 block below) rather than reverting to the light colourway,
   because the logo is a raster in two inks and swapping its src on every scroll
   is a worse trade than keeping one treatment. */
[data-hero-header="on-dark"] [data-site-header] {
  --color-text: var(--color-text-inverse);
  /* White, not --color-text-inverse-muted. The muted tier is 5.98:1 on the navy
     band but only 2.93:1 on the orange one every interior page uses, and the
     header has to be correct on both without branching. The same goes for the
     border: --color-border-on-dark is 1.28:1 on orange. Losing the muted step
     inside the header costs a little hierarchy and buys AA everywhere. */
  --color-text-muted: var(--color-text-inverse);
  --color-border: var(--color-text-inverse);
  --color-surface-muted: var(--color-surface-on-dark-hover);
  --color-focus: var(--color-focus-on-dark);
  /* See the note on .mobile-nav: a token override alone does not reach an
     element that inherits its colour rather than declaring it. Nothing in the
     header does today, but the next thing added to it might. */
  color: var(--color-text);
}
/* The rules above recolour by overriding tokens, which reaches every label,
   link and control in the header at once. Two things do not follow from a
   token and are set directly: the nav's bottom hairline, which would otherwise
   cut the band in half, and the active-item underline, which is orange at
   3.12:1 on the band — under the 3:1 a non-text indicator needs once the band
   darkens toward its foot. */
[data-hero-header="on-dark"] [data-site-header] .primary-nav { border-bottom-color: transparent; }
[data-hero-header="on-dark"] [data-site-header] .primary-nav__trigger[aria-expanded="true"],
[data-hero-header="on-dark"] [data-site-header] .primary-nav__trigger[aria-current="true"] { text-decoration-color: var(--color-text-inverse); }
/* Mega panels are a light surface hanging off a dark header, so they opt back
   out of the inherited overrides — reading the canonical values rather than
   restating them, which is why --color-ink and friends exist. */
[data-hero-header="on-dark"] .mega {
  --color-text: var(--color-ink);
  --color-text-muted: var(--color-ink-muted);
  --color-border: var(--color-line);
  --color-surface-muted: var(--color-fill-muted);
  color: var(--color-text);
}

/* --- 2. brand + nav row --------------------------------------------------- */
.brand { display: flex; align-items: center; text-decoration: none; color: var(--color-text); }
/* The alt text carries the link's accessible name, so the anchor needs none. */
.brand__logo { display: block; height: var(--logo-h); width: auto; }

/* --- 3. primary nav + mega menu ------------------------------------------- */
.primary-nav { position: relative; border-bottom: var(--border-width) solid var(--color-border-subtle); }
/* Logo and nav share one row. `align-items: stretch` lets each trigger fill the
   row height, so its mega panel still opens flush against the row's bottom
   edge rather than floating mid-air. */
.primary-nav__inner { display: flex; align-items: stretch; gap: var(--space-6); }
.brand { flex: none; padding-block: var(--space-3); }
/* The list grows into whatever the logo leaves and pushes its items to the end,
   so the nav's right edge lands on the content container's — Figma 153:2568,
   where the ul's box is flush with the column. The last trigger keeps its own
   --space-4 padding, so the label itself sits a little inside that edge; the
   frame does the same, and removing it would drag the mega panels' left anchor
   with it. */
.primary-nav__list { list-style: none; margin: 0; padding: 0; display: flex; align-items: stretch; justify-content: flex-end; gap: var(--space-1); flex-wrap: wrap; flex: 1 1 auto; }
.primary-nav__trigger { display: inline-flex; align-items: center; height: 100%; gap: var(--space-2); padding-inline: var(--space-4); background: none; border: 0; color: var(--color-text); font-size: var(--text-md); }
.primary-nav__trigger[aria-expanded="true"],
.primary-nav__trigger[aria-current="true"] { font-weight: var(--weight-bold); text-decoration: underline; text-underline-offset: 6px; text-decoration-thickness: 2px; text-decoration-color: var(--color-accent); }
.primary-nav__chevron { transition: transform var(--duration-fast) var(--ease); }
.primary-nav__trigger[aria-expanded="true"] .primary-nav__chevron { transform: rotate(180deg); }

/* Sep 2026 feedback c7 — the panel lives inside its trigger's <li>, so the
   <li> is the positioning context and `left: 0` lands on the trigger's own
   left edge. The panel had no business spanning the viewport. */
.primary-nav__list > li { position: relative; }

/* c7 — no `.shell` inside the panel any more: `.shell` is exactly what forced
   full width plus gutters. Inline padding was 16px, matching the trigger's own
   padding so the first column heading sat directly under the trigger's label;
   Celeste, Sep 2026: too tight, doubled to 32px. The panel's LEFT EDGE still
   aligns to the trigger (left: 0) — that was the actual c7 requirement; only
   the heading-to-label optical alignment is given up.
   c5 — the open state is a class, not the `hidden` attribute, because
   `display: none` cannot be transitioned. `visibility: hidden` keeps a closed
   panel out of the accessibility tree and out of tab order, which `hidden`
   was doing. --duration-* are already zeroed under prefers-reduced-motion, so
   this transition needs no query of its own. */
.mega {
  position: absolute; left: 0; top: 100%; z-index: 40;
  width: max-content; max-width: var(--width-mega-max);
  padding: var(--space-6);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translateY(calc(-1 * var(--space-1)));
  transition: opacity var(--duration-base) var(--ease),
              transform var(--duration-base) var(--ease),
              visibility var(--duration-base);
}
.mega--open { opacity: 1; visibility: visible; pointer-events: auto; transform: none; }

/* c8 — flex, not grid. The old --cols-N modifiers declared one track more
   than there were columns, so every panel carried a phantom empty track and
   read as over-wide. Flex items do not grow, so columns stay left-aligned at
   their content width with a --width-mega-col floor. */
.mega__inner { display: flex; align-items: flex-start; gap: var(--space-5); }
.mega__col { min-width: var(--width-mega-col); }
.mega__col h3 { font-size: var(--text-md); margin-bottom: var(--space-4); }
/* c6 — now that EVERY heading is a link, `font-size: inherit` matters: the
   generic `.mega__col a` rule below would otherwise drop all nine headings to
   --text-sm and flatten the panel's hierarchy. */
.mega__col h3 a { text-decoration: none; color: var(--color-text); font-size: inherit; }
.mega__col h3 a:hover { text-decoration: underline; }
.mega__col ul { list-style: none; margin: 0; padding: 0; }
.mega__col li + li { margin-top: var(--space-3); }
.mega__col a { text-decoration: none; color: var(--color-text-muted); font-size: var(--text-sm); }
.mega__col a:hover { color: var(--color-accent); text-decoration: underline; }

/* --- 4. CTA card (mega menu + mobile) ------------------------------------- */
/* The page body's standout treatment (.callout-card in blocks.css): the amber
   tint with an --color-accent-bright edge. It used to be --color-surface-muted,
   which the push nav remaps to the translucent white hover fill — so on mobile
   the card was a barely-there wash rather than a card.

   It carries its own colours rather than inheriting, because the same card
   appears on two opposite surfaces: a white mega panel and the navy push nav.
   --color-ink and friends are the canonical values the dark surfaces' token
   overrides cannot reach. Body text on the tint is 12.9:1. */
.cta-card {
  background: var(--color-surface-accent);
  border: var(--border-width) solid var(--color-line-callout);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  /* Left-aligned like every other callout (Celeste, Oct 2026); it was
     centred. */
  text-align: left;
  max-width: var(--width-cta-card);
  color: var(--color-ink);
}
.cta-card h3 { font-size: var(--text-md); color: var(--color-ink); }
/* --text-sm, not --text-xs: 12px is under the floor for a sentence of real
   copy, and this one is read on a phone. */
.cta-card p { font-size: var(--text-sm); color: var(--color-ink-secondary); margin-bottom: var(--space-4); }
/* The CTA gap equals the card's padding (--space-5, 24px): see .callout-card
   in blocks.css. */
.cta-card > .button { margin-top: var(--space-2); }

/* --- button system, Sep 2026 ----------------------------------------------
   Three tiers. Colour is a MODIFIER, not baked into the tier, so a dark band
   swaps one class and inherits everything else.

     .button                    primary    filled orange, white label
     .button--secondary         secondary  transparent, orange border and label
     .button--brand             colourway  navy secondary, for the light-navy tint
     .button--tertiary          tertiary   bare label + arrow, no chrome
     .button--on-dark           for a dark band: white border and label

   Secondary takes no arrow; tertiary always does.                          */
.button {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-3) var(--space-5);
  background: var(--color-accent);
  color: var(--color-accent-ink);
  border: var(--border-width) solid var(--color-accent);
  /* Pill, every tier, every size (Figma 153:2568). The shape is the constant;
     fill, border and label stay the tier's own. Tertiary opts out below — it
     has no box to round. */
  border-radius: var(--radius-pill);
  text-decoration: none; font-weight: var(--weight-medium); font-size: var(--text-sm);
}
.button:hover { background: var(--color-accent-hover); border-color: var(--color-accent-hover); }

/* Small size, for dense chrome like the utility bar. Sized so its box clears
   --tap-min-aa (WCAG 2.2 AA, 24x24) with room to spare. The 44px AAA figure
   is reserved for primary touch targets such as the hamburger. This alters
   the box only — the fill and label colours, and so the contrast, are the
   tier's and unchanged. */
.button--sm {
  padding: var(--space-2) var(--space-4);
  font-size: var(--text-sm);
  line-height: var(--leading-tight);
  min-height: var(--tap-min-aa);
}

.button--secondary { background: transparent; color: var(--color-accent); border-color: var(--color-accent); }
/* Orange outline at rest, orange fill on hover (Celeste, Oct 2026; it was
   navy). --color-accent is 4.90:1 on white both ways. The hover border is
   white, matching the label, as before. ON A DARK BAND use
   .button--on-dark, which keeps the white outline: orange on the navies is
   2.04:1. And never place it straight on --color-surface-brand, where the
   orange label is 4.37:1 — on Home it lives inside white cards. */
.button--secondary:hover { background: var(--color-accent); color: var(--color-accent-ink); border-color: var(--color-text-inverse); }

.button--tertiary { background: none; border-color: transparent; border-radius: 0; padding: 0; color: var(--color-accent); font-weight: var(--weight-bold); }
.button--tertiary:hover { background: none; color: var(--color-accent-hover); text-decoration: underline; }

/* On a dark band the border and label go white; hover fills white. */
/* Navy colourway for a secondary button on the light-navy tint (Oct 2026).
   Orange is 4.37:1 on --color-surface-brand, under AA for 14px; this navy,
   the band's head and the tint's own parent hue, is 8.9:1 there, and white
   on it is 9.99:1 on hover. */
.button--secondary.button--brand { color: var(--color-band-feature-head); border-color: var(--color-band-feature-head); }
.button--secondary.button--brand:hover { background: var(--color-band-feature-head); color: var(--color-text-inverse); border-color: var(--color-text-inverse); }
.button--on-dark.button--secondary { background: transparent; color: var(--color-text-inverse); border-color: var(--color-text-inverse); }
.button--on-dark.button--secondary:hover { background: var(--color-surface); color: var(--color-text); }

/* --- 5. mobile push nav --------------------------------------------------- */
.nav-toggle { display: none; }
/* The panel is the footer's surface, Sep 2026: the menu is site-wide chrome and
   now looks like the other piece of site-wide chrome. Recoloured by overriding
   tokens rather than by restating each rule, which reaches the close button,
   the rows, the dividers, the back link, the search control and the CTA card in
   one place — the same technique as the on-dark header.

   --color-border-on-dark is 2.15:1 here. That is fine for a row divider, which
   is decoration between rows already separated by their own text, but do not
   reach for it to outline a control. */
.mobile-nav {
  position: fixed; inset: 0 0 0 auto; z-index: 60;
  width: min(88vw, var(--width-mobile-nav));
  background: var(--color-surface-sunken);
  box-shadow: var(--shadow-lg);
  padding: var(--space-5);
  overflow-y: auto;

  --color-text: var(--color-text-inverse);
  --color-text-muted: var(--color-text-inverse-muted);
  --color-border: var(--color-border-on-dark);
  --color-border-subtle: var(--color-border-on-dark);
  --color-surface-muted: var(--color-surface-on-dark-hover);
  --color-focus: var(--color-focus-on-dark);
  /* Load-bearing, and not obvious. Redefining --color-text only reaches
     elements that DECLARE color: var(--color-text) themselves. Anything that
     just inherits — a heading, a bare <p> — inherited body's already-resolved
     rgb(25,48,71) and stayed dark navy on a dark panel. Setting color here
     makes the panel the inheritance root. Substitution uses the custom
     property's computed value on this element, so the redefinition above
     applies even though it sits in the same rule. */
  color: var(--color-text);
}
.mobile-nav[hidden] { display: none; }
.mobile-nav__scrim { position: fixed; inset: 0; z-index: 50; background: var(--color-scrim); }
.mobile-nav__scrim[hidden] { display: none; }
.mobile-nav__head { display: flex; justify-content: flex-end; }
/* --tap-min, not the old bare glyph: a close button is a primary touch target
   and this one sits in the corner a thumb reaches for. */
.mobile-nav__close { display: inline-flex; align-items: center; justify-content: center; width: var(--tap-min); height: var(--tap-min); background: none; border: 0; border-radius: var(--radius-pill); font-size: var(--text-lg); padding: 0; color: var(--color-text); }
.mobile-nav__close:hover { background: var(--color-surface-muted); }

/* The same control as the utility bar's, scaled for touch: the desktop one is
   --text-sm on a 24px box, which is the AA floor and no more. Full width here
   because it is the panel's only control of its kind and a left-aligned label
   reads as a row, matching the nav items beneath it. */
.mobile-nav .util-search {
  width: 100%;
  justify-content: flex-start;
  min-height: var(--tap-min);
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  margin-block: var(--space-4) var(--space-5);
  font-size: var(--text-base);
  border: var(--border-width) solid var(--color-border);
}

.mobile-nav__back { display: inline-flex; align-items: center; gap: var(--space-2); background: none; border: 0; font-style: italic; color: var(--color-text-muted); padding: var(--space-3) 0; }
.mobile-nav__list { list-style: none; margin: 0 0 var(--space-5); padding: 0; }
.mobile-nav__list li { border-bottom: var(--border-width) solid var(--color-border-subtle); }
.mobile-nav__item { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); padding: var(--space-4) var(--space-2); background: none; border: 0; text-align: left; text-decoration: none; color: var(--color-text); font-size: var(--text-base); }
.mobile-nav__item:hover { background: var(--color-surface-muted); }

/* Utility links, root level only. Smaller and muted so they read as a second
   tier under the primary items rather than as six more of them, but still on a
   --tap-min row: secondary in the hierarchy is not secondary to a thumb. */
.mobile-nav__utility { list-style: none; margin: 0 0 var(--space-5); padding: 0; }
.mobile-nav__utility a {
  display: flex; align-items: center;
  min-height: var(--tap-min);
  padding: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  text-decoration: none;
}
.mobile-nav__utility a:hover { color: var(--color-text); text-decoration: underline; }

.mobile-nav .cta-card { max-width: none; }
.mobile-nav .cta-card .button { min-height: var(--tap-min); }

/* --- 6. footer ------------------------------------------------------------ */
/* THE FOOTER OWNS THE GAP ABOVE IT, and it is the only thing that does (Sep
   2026). It carried --space-10 of margin AND every page shell carried
   --space-10 of bottom padding, so the page paid twice and content sat 192px
   clear of the footer. One --space-9 is a block break, which is what the
   footer is: the next block after the content.

   Keeping it on the footer rather than on the shells means it applies no
   matter which shell precedes it, so a new page cannot land flush against
   the dark band by forgetting to pad itself. */
.site-footer { background: var(--color-surface-sunken); margin-top: var(--space-9); padding-block: var(--space-8); }
/* The footer is a dark surface like the header, family bar and push nav, but
   never took their focus remap: the standard blue ring is about 2:1 on this
   navy, under the 3:1 a focus indicator needs. White is 13.5:1. */
.site-footer { --color-focus: var(--color-focus-on-dark); }
.footer-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: var(--space-6); }
.footer-grid h3 { font-size: var(--text-md); margin-bottom: var(--space-4); color: var(--color-text-inverse); }
.footer-grid ul { list-style: none; margin: 0; padding: 0; }
.footer-grid li + li { margin-top: var(--space-2); }
.footer-grid a { text-decoration: none; color: var(--color-text-inverse-muted); font-size: var(--text-sm); }
.footer-grid a:hover { text-decoration: underline; color: var(--color-text-inverse); }
.footer-base { margin-top: var(--space-7); padding-top: var(--space-5); border-top: var(--border-width) solid var(--color-border-on-dark); display: flex; justify-content: space-between; gap: var(--space-6); flex-wrap: wrap; font-size: var(--text-sm); color: var(--color-text-inverse-muted); }
.footer-base__logo { height: var(--logo-h-footer); width: auto; margin-bottom: var(--space-3); }
.footer-base__legal { text-align: right; }
/* The footer is a dark surface now, so links go light rather than orange —
   --color-accent is only 2.04:1 on it and --color-accent-on-dark 3.12:1, both
   under the 4.5 body text needs. They keep their underline. */
.footer-base a { color: var(--color-text-inverse-muted); text-decoration: underline; }
.footer-base a:hover { color: var(--color-text-inverse); }
.footer-base__legal ul { list-style: none; margin: 0 0 var(--space-3); padding: 0; display: flex; gap: var(--space-5); justify-content: flex-end; }

/* --- 7. breadcrumb -------------------------------------------------------- */
.breadcrumb { font-size: var(--text-sm); }
.breadcrumb ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-2); }
.breadcrumb li + li::before { content: "›"; margin-right: var(--space-2); color: var(--color-text-muted); }
.breadcrumb a { color: var(--color-text-muted); }

/* --- 8. toast for unbuilt links ------------------------------------------- */
/* --- back to top ---------------------------------------------------------
   Floating, bottom right, shown from 75% down (chrome.js). A light control
   floating OVER the page, so --shadow-lg. 44px (--tap-min), the AAA target,
   since it is a primary touch control on a phone. Navy on white is 13.5:1;
   on hover it fills navy. Below the mobile push nav and its scrim (50/60),
   so an open menu covers it, and bottom-right so it clears the toast, which
   is centred. */
.to-top {
  position: fixed; right: var(--space-5); bottom: var(--space-5); z-index: 45;
  display: grid; place-items: center;
  width: var(--tap-min); height: var(--tap-min);
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  color: var(--color-ink);
  border: var(--border-width) solid var(--color-line);
  box-shadow: var(--shadow-lg);
  opacity: 0; visibility: hidden; transform: translateY(var(--space-2));
  transition: opacity var(--duration-base) var(--ease),
              transform var(--duration-base) var(--ease),
              visibility 0s linear var(--duration-base),
              background var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease);
}
.to-top.is-shown {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity var(--duration-base) var(--ease),
              transform var(--duration-base) var(--ease),
              visibility 0s,
              background var(--duration-fast) var(--ease),
              color var(--duration-fast) var(--ease);
}
.to-top:hover { background: var(--color-surface-inverse); color: var(--color-text-inverse); }

#stub-toast { position: fixed; left: 50%; bottom: var(--space-6); transform: translateX(-50%); z-index: 200; background: var(--color-surface-inverse); color: var(--color-text-inverse); padding: var(--space-3) var(--space-5); border-radius: var(--radius-md); font-size: var(--text-sm); box-shadow: var(--shadow-lg); }

/* --- 9. responsive -------------------------------------------------------- */
@media (max-width: 1024px) {
  .footer-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* c8 — the panel is capped by --width-mega-max, so columns wrap instead of
     being forced into a fixed 2-up grid. The .cta-card max-width override
     that used to live here is gone: with flex, `max-width: none` would let
     the card expand to its max-content width. */
  .mega__inner { flex-wrap: wrap; }
}
@media (max-width: 767px) {
  /* Sticky, condensing header. The menu has to be reachable from anywhere on
     a long Guide page, so the header pins and shrinks rather than scrolling
     away. Transitions are on padding and the wordmark's height; --duration-*
     are already zeroed under prefers-reduced-motion. */
  /* The negative top is the family bar's height: the header sticks only once
     the bar has scrolled out of view, so on a phone the tabs are there on
     arrival and at the top of the page, and the pinned header is the logo row
     alone. --header-condensed-h stays the height of what is pinned. */
  [data-site-header] {
    position: sticky; top: calc(var(--family-bar-h) * -1); z-index: 50;
    transition: box-shadow var(--duration-base) var(--ease);
  }
  /* Condensed, the bar is no longer over the hero — it is over page content, so
     it needs a fill of its own. On a page with a hero that fill is navy, which
     keeps the white logo and the white labels correct; elsewhere it is the page
     colour. --shadow-sm is the resting step: the bar belongs to the page, it is
     not floating above it. */
  [data-site-header].is-condensed { background: var(--color-page); box-shadow: var(--shadow-sm); }
  [data-hero-header="on-dark"] [data-site-header].is-condensed { background: var(--color-surface-inverse); }
  .primary-nav__inner { align-items: center; }
  .brand { transition: padding-block var(--duration-base) var(--ease); }
  /* One lockup now, so condensing scales the whole logo rather than dropping
     the wordmark. The 44px hamburger still sets the condensed header height,
     so shrinking the logo costs no height — it just stops it dominating. */
  .brand__logo { height: var(--logo-h-mobile); transition: height var(--duration-base) var(--ease); }
  .is-condensed .brand { padding-block: var(--space-1); }
  .is-condensed .brand__logo { height: var(--logo-h-condensed); }

  .utility-bar { display: none; }
  /* Two tabs, half the width each, labels only. They stay out of the push nav
     on purpose: which site you are on should be visible on arrival, not one
     tap away. */
  .family-bar__inner { padding-inline: 0; gap: 0; }
  .family-bar__tab { flex: 1 1 50%; justify-content: center; }
  .family-bar__sub { display: none; }
  /* The utility bar is hidden on mobile, so its search pill goes with it —
     the push nav carries its own search field instead. */
  .primary-nav__inner { gap: var(--space-3); justify-content: space-between; }
  .brand { gap: var(--space-3); }
  .primary-nav__list, .mega { display: none !important; }
  /* Icon only; the accessible name comes from the visually-hidden label.
     44px square is the minimum comfortable touch target and is kept at both
     header sizes, so condensing never shrinks the tap area. */
  .nav-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: var(--tap-min); height: var(--tap-min); padding: 0;
    background: none; border: 0;
    border-radius: var(--radius-pill); color: var(--color-text);
  }
  /* No stroke, so hover fills instead of recolouring a border. The 44px box is
     still there and is still the tap target — the ring was never what carried
     it. --color-surface-muted is remapped to a translucent white by the on-dark
     header block, so this works on the band and off it. */
  .nav-toggle:hover { background: var(--color-surface-muted); }
  .footer-grid { grid-template-columns: 1fr; }
  .footer-base { flex-direction: column; }
  .footer-base__legal { text-align: left; }
  .footer-base__legal ul { justify-content: flex-start; }
}
