/* ============================================================================
   chrome.css — THE SITE'S NAVIGATION BAR AND FOOTER, AND NOTHING ELSE.

   WHY THIS FILE EXISTS (mc-g629, 2026-09-05)
   The old pages — the giveaway, the giveaway rules, the client portal, the
   services agreement, vendor-partnership and the ten blog posts — now show the
   same nav and footer as the nineteen v2 pages. Those rules used to live in
   assets/tokens.css, which those pages cannot load: tokens.css and
   assets/css/base.css both define body, h1, h2, h3, p, .btn, .eyebrow, .prose,
   .container and .nav with DIFFERENT declarations, so whichever loads second
   wins outright. Loading both would either render the bar as a v1/v2 hybrid or
   re-skin every one of those pages' bodies — on a giveaway that is live and
   taking entries. There is no scoping mechanism for an external stylesheet
   short of rewriting its selectors, which is what this file is.

   WHO LOADS IT
     · the 19 v2 pages  — includes/head.php: chrome.css, then tokens.css
     · the old pages    — includes/layout-start.php: base.css, then chrome.css
     · vendor-partnership.php, which writes its own <head>: base.css, then this
   Loading it FIRST on the v2 pages and LAST on the old ones is deliberate: on
   v2 nothing here needs to beat tokens.css (the declarations are the same
   values), and on the old pages several rules here exist precisely to beat
   base.css. Where that mattered the selector is specific enough to win in
   either order; the load order is belt and braces, not the mechanism.

   WHAT IS DELIBERATELY NOT HERE
   --forest, --gold, --radius, --radius-lg, --container and --shadow-* are NOT
   redefined below. The first five hold identical values in both stylesheets and
   the shadows do not — redefining them would shift the shadow on every blog
   figure, every services-agreement clause and vendor-partnership's form card,
   which is a re-skin of a page body and not this file's business.
   --font-display is also absent, and that one is load-bearing: base.css never
   defined it, so client-portal.php's headings currently fall back to the
   browser's serif. Defining it here would silently restyle that page. Nothing
   in the nav or footer uses it.
   ========================================================================== */

:root {
  /* Only the names assets/css/base.css does not already define, and only the
     ones the rules in THIS file reference. Every value is copied verbatim from
     assets/tokens.css — this is a second home for those tokens, not a second
     opinion about them. base.css's equivalents (--warm-white, --blush, --ink,
     --ink-soft, --muted, --border, --terracotta, --terracotta-text) hold the
     same hexes under different names and are left exactly as they are. */
  --surface-1:     #FFFFFF;
  --surface-2:     #EBDDC5;
  --surface-dark:  #1F2540;
  --text-primary:  #1F2540;
  --text-secondary:#3D4D60;
  --text-muted:    #65737C;   /* darkened to 4.5:1 — do NOT lighten */
  --hairline:      #D4C5A8;
  --accent:        #E89A7A;   /* PRIMARY ACTION ONLY */
  --accent-text:   #7A4E3C;   /* small text on light grounds — 7.04:1 on white */

  /* Text on DARK grounds — the footer's ink and its hairlines. */
  --on-dark-muted: rgba(255,255,255,.82);
  --on-dark-line:  rgba(255,255,255,.55);   /* borders only, never text */

  --font-body: 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* Spacing — the 8px steps this file uses. tokens.css carries the full scale. */
  --s2: 8px; --s3: 16px; --s4: 24px; --s5: 32px; --s6: 48px;
  --gutter: var(--s4);

  --nav-h: 76px;
}

/* --- Nav: transparent over a dark hero, solid otherwise -------------------- */
/* The two nav appearances are ONE set of local custom properties, redefined once per state,
   rather than a parallel `.nav.is-solid <child>` rule for every child. That is not tidiness.
   The old shape ranked `.nav-links a` (0,1,1) and then `.nav.is-solid .nav-links a` (0,3,1)
   above the button classes, so the nav CTA lost its own colour TWICE — the same defect
   rediscovered one cascade layer deeper, each time needing its own guard. A variable never
   outranks a button's own `color`, so that whole failure mode is gone with the rules below.

   WHICH STATE A PAGE STARTS IN is derived from the page's own markup instead of a per-page
   flag, so the declaration and the reality cannot drift apart. Measured 2026-08-25 across all
   19 v2 pages x 2 languages: the 15 pages that open <main> with .hero / .carousel-wrap paint
   rgb(31,37,64) behind the nav — white text at 15.03:1 — while the four legal pages open with
   a plain .section and paint cream rgb(250,246,238), where the white nav measured 1.07:1 and
   was, confirmed by screenshot, invisible. A new page needs no flag: give it a hero and the nav
   goes transparent, omit one and it stays solid. The undeclared direction is the safe one.
   NONE of the old pages opens with a hero (.gw-hero, .gwr-wrap, .portal-soon-hero, .page-hero
   and .vp-hero are all something else), so the bar is solid white on every one of them —
   including over vendor-partnership's dark gradient, where a transparent bar would have been
   white-on-white the moment it scrolled. */
.nav {
  position: fixed; inset-block-start: 0; inset-inline: 0; z-index: 50;
  height: var(--nav-h);
  display: flex; align-items: center;

  --nav-fg:          var(--text-secondary);   /* links, event-group toggle */
  --nav-fg-strong:   var(--text-primary);     /* logo, mobile toggle glyph */
  --nav-current:     var(--accent-text);      /* current page, open group */
  --nav-muted:       var(--text-muted);       /* quiet nav text */
  --nav-line:        var(--hairline);         /* language pill outline */
  --nav-lang-hover:  var(--accent-text);      /* language pill, hovered — 7.04:1 on white */
  --nav-toggle-line: var(--hairline);         /* mobile toggle border */

  /* THE BAR STATES ITS OWN FONT (mc-g629), and it is not belt-and-braces. Nothing inside the bar
     except the Events toggle and the two buttons declares a family, so the plain links and the
     language pill inherit it from `body` — and the two stylesheets spell `body` differently.
     tokens.css uses --font-body ('Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI',
     sans-serif); base.css's own body rule drops the 'Segoe UI' step. Measured on Windows, the two
     bars resolved to the SAME face — Plus Jakarta Sans loads on both — but to different fallback
     chains, so the moment that webfont fails to load the old pages' bar would fall to a different
     typeface from every other page's. Declaring it here settles it in one place. No-op on the v2
     pages, where body already carries this exact value. */
  font-family: var(--font-body);

  background: var(--surface-1);
  border-bottom: 1px solid var(--hairline);
  box-shadow: var(--shadow-sm);
  transition: background .25s ease, border-color .25s ease, box-shadow .25s ease;
}
/* Over a dark hero, until the page scrolls past it (site.js adds .is-solid at 24px). */
body:has(main > .hero:first-child, main > .carousel-wrap:first-child) .nav:not(.is-solid) {
  --nav-fg:          var(--surface-1);
  --nav-fg-strong:   var(--surface-1);
  --nav-current:     var(--surface-1);
  --nav-muted:       var(--on-dark-muted);
  --nav-line:        var(--on-dark-line);
  /* --accent-text is 2.14:1 on this navy — a light-ground brown, invisible here. --surface-2 is
     12.28:1 and is the same warm cream the hero's own eyebrow already uses. */
  --nav-lang-hover:  var(--surface-2);
  --nav-toggle-line: rgba(255,255,255,.45);

  background: transparent;
  border-bottom-color: transparent;
  box-shadow: none;
}
.nav .container { display: flex; align-items: center; gap: var(--s4); width: 100%; }
.nav-logo { display: flex; align-items: center; gap: var(--s2); font-weight: 600; letter-spacing: .04em; text-decoration: none; color: var(--nav-fg-strong); }
.nav-logo img { height: 38px; width: auto; display: block; }
.nav-links { display: flex; gap: var(--s3); margin-inline-start: auto; align-items: center; list-style: none; margin-block: 0; padding: 0; }
.nav-links a {
  font-size: .9rem; font-weight: 500; letter-spacing: .04em;
  color: var(--nav-fg); text-decoration: none; padding-block: var(--s2);
  border-bottom: 1px solid transparent;
}
/* CASCADE COLLISION GUARD (measured regression, 2026-08-19): `.nav-links a` is (0,1,1) and
   beat `.btn-primary` (0,1,0), so the nav CTA lost its ink and took the nav's link colour —
   2.25:1 over the transparent nav, 3.84:1 once solid, against the 6.7:1 the audit had
   deliberately remediated it to. A button inside the nav keeps its own button colour.
   Do not remove. */
.nav-links a.btn-primary { color: var(--text-primary); }
.nav-links a.btn-portal { color: var(--surface-1); }
.nav-links a.btn-secondary { color: var(--forest); }

/* Language toggle — mc-3csi, review pin 13: "It should look more like a toggle, very much like
   version 1. Here's a screenshot."
   The screenshot is v1's pill, and this is that pill rebuilt in v2's tokens: a rounded outline
   around "ES · Español", quiet at rest, warm on hover.
   THE SELECTOR CARRIES `.nav-links a` ON PURPOSE. `.nav-links a` (0,1,1) sets
   `border-bottom: 1px solid transparent` on every link in the bar and it appears earlier in this
   file; a bare `.lang-toggle` (0,1,0) loses to it, and the pill would have rendered with three
   sides drawn and the bottom one invisible. It has to out-rank the rule it is undoing — and on
   the old pages it also has to out-rank base.css's own `.lang-toggle:hover` (0,2,0), which
   paints the v1 terracotta. (0,3,1) does both. */
.nav-links a.lang-toggle {
  display: inline-flex; align-items: center;
  font-size: .8rem; font-weight: 500; letter-spacing: .04em;
  white-space: nowrap;
  padding: 5px 12px;
  border: 1px solid var(--nav-line);
  border-radius: 999px;
  color: var(--nav-fg);
}
/* THE HOVER COLOUR IS A PER-STATE VARIABLE, not one value, and the numbers are why: --accent-text
   is 7.04:1 on the white nav and 2.14:1 on the navy hero — a warm brown tuned for light grounds,
   which disappears on a dark one. --surface-2 over the hero measures 12.28:1. */
.nav-links a.lang-toggle:hover,
.nav-links a.lang-toggle:focus-visible {
  color: var(--nav-lang-hover);
  border-color: var(--nav-lang-hover);
}
/* mc-dkxu, operator verbatim: "The portal login on hover has a white line at the bottom of the
   button and it's not appealing."
   ROOT CAUSE, and it was one rule: `.nav-links a` gives EVERY anchor in the nav a transparent
   bottom border, and this hover rule paints it currentColor. The two nav BUTTONS are anchors too,
   so the rule drew a line inside the button — white under the green Portal Login (its text is
   --surface-1), navy under the terracotta CTA. An underline is the affordance for a link; a button
   already looks like a button. `:not(.btn)` says exactly that. */
.nav-links a:not(.btn):hover, .nav-links a:not(.btn):focus-visible { border-bottom-color: currentColor; }
/* THE BASE.CSS HOVER LEAK, CANCELLED (mc-g629). assets/css/base.css:101 says
   `.nav-links a:hover, .nav-links a.active { color: var(--terracotta) }` at (0,2,1). On the old
   pages that sheet is loaded, so without this line every link in the v2 bar turned bright
   terracotta on hover — 2.25:1 on the white bar, a colour the v2 palette reserves for FILLS and
   never for text. Restating --nav-fg wins it back.
   THE SELECTOR IS NARROW ON PURPOSE, and each exclusion is a rule this would otherwise break:
     · `> li >`      keeps it out of the Events dropdown, whose items are `.sub a` and want
                     --text-primary on the pale hover ground below;
     · `:not(.btn)`  leaves the two buttons their own colours (see the guard above);
     · `:not(.lang-toggle)` leaves the language pill its --nav-lang-hover, which is the whole
                     point of that variable existing per nav state.
   On the 19 v2 pages every one of these links already computes to --nav-fg on hover, so this
   rule changes nothing there. It exists to neutralise v1, not to restyle v2. */
.nav-links > li > a:not(.btn):not(.lang-toggle):hover,
.nav-links > li > a:not(.btn):not(.lang-toggle):focus-visible { color: var(--nav-fg); }
/* CONTRAST: --accent-text is a warm brown tuned for LIGHT grounds; on the dark hero it is far
   too close to the ground to read. Over a transparent nav the active state therefore stays
   white and is signalled by the underline alone — which is exactly what --nav-current carries
   per state, so this rule states the intent once instead of twice. */
.nav-links a[aria-current="page"] { color: var(--nav-current); border-bottom-color: var(--accent); }

/* --- Nav disclosure group ("Events") -------------------------------------- */
/* "Milestones" inside this group is an IA LABEL ONLY — it groups five event types
   so people can find them. It is never a priced package; the legal stack prices
   eight types independently (Milestone was retired as a type 2026-08-18). */
.has-sub { position: relative; }
.sub-toggle {
  font-family: var(--font-body); font-size: .9rem; font-weight: 500; letter-spacing: .04em;
  color: var(--nav-fg); background: none; border: 0; cursor: pointer;
  padding: var(--s2) 0; border-bottom: 1px solid transparent;
  display: inline-flex; align-items: center; gap: 6px;
}
.sub-toggle::after {
  content: ''; width: 6px; height: 6px; border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor; transform: rotate(45deg) translate(-2px,-2px);
  transition: transform .18s ease;
}
.sub-toggle[aria-expanded="true"]::after { transform: rotate(-135deg) translate(-3px,-3px); }
.sub-toggle:hover, .sub-toggle:focus-visible { border-bottom-color: currentColor; }
/* Same contrast rule as the active nav link, and now literally the same variable: white over
   a dark hero, warm brown on a light ground. */
.sub-toggle[data-in-group="true"] { color: var(--nav-current); border-bottom-color: var(--accent); }

.sub {
  display: none; list-style: none; margin: 0; padding: var(--s2) 0;
  position: absolute; inset-block-start: calc(100% + 10px); inset-inline-start: -14px;
  min-width: 210px; background: var(--surface-1);
  border: 1px solid var(--hairline); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md); z-index: 60;
}
.sub.is-open { display: block; }
.sub a {
  display: block; padding: 10px 18px; font-size: .9rem;
  color: var(--text-secondary); border-bottom: 0;
}
.sub a:hover, .sub a:focus-visible { background: var(--surface-2); color: var(--text-primary); }
.sub a[aria-current="page"] { color: var(--accent-text); font-weight: 600; }

/* --- The two buttons that live in the bar --------------------------------- */
/* SCOPED TO `.nav` DELIBERATELY. tokens.css's `.btn` and base.css's `.btn` disagree — 12px/24px
   with a 1px transparent border and a flex gap, against 14px/28px with no border and no gap —
   and the nav buttons need the v2 shape: the border is what --accent / --forest paint on hover,
   and the gap is what separates the account glyph from "Portal Login". Restating those few
   properties at (0,2,0) gets the bar right on BOTH stylesheets without touching a single
   in-page button on any page. */
.nav .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  font-family: var(--font-body); font-size: .95rem; font-weight: 500; letter-spacing: .02em;
  padding: 12px 24px; border-radius: var(--radius);
  text-decoration: none; cursor: pointer; border: 1px solid transparent;
  transition: background .18s ease, border-color .18s ease, color .18s ease;
}
.nav .btn-primary { background: var(--accent); color: var(--text-primary); }  /* 6.7:1 */
/* Nav buttons carry short labels ("Book a call", "Portal Login"), so the 24px side padding
   tuned for a full sentence left them looking mostly empty. Tighter here only — in-page
   buttons keep the generous padding, where they are the primary action on the screen.
   Vertical padding is untouched: it is what keeps the target above the 24px 2.5.8 minimum. */
.nav-links .btn { padding-inline: 16px; }
/* mc-dkxu, operator verbatim: "Same thing with the Book a Call: there's not enough contrast
   between the on hover and the base colors."
   MEASURED: --accent (#E89A7A) → --accent-hover (#C97A5C) is 1.45:1 background-to-background.
   That is the complaint, literally: two warm oranges a shade apart.
   IT STAYS IN THE TERRACOTTA FAMILY and inverts inside it: --accent → --accent-text is 3.13:1,
   and the label flips to --surface-1 at 7.04:1 on it (up from 4.60:1 on the old hover).
   SCOPED TO THE NAV. `.btn-primary` is the in-page primary action on every page of the site; the
   mark was on the nav CTA, so only the nav CTA changes.
   THE BORDER IS MEASURED, NOT DECORATION. --accent-text is a deep brown and the nav is transparent
   over a navy hero: fill-to-ground is 2.14:1 there. Holding the border at --accent keeps that edge
   at 6.68:1 over the hero, and at 2.25:1 over the solid white nav — the same figure the RESTING
   button already ships with on that ground, so nothing is worse anywhere.
   transform AND box-shadow ARE PINNED TO none (mc-g629): base.css:73 lifts and shadows every
   hovered .btn-primary, which on the old pages made the bar's CTA jump a pixel while the same
   button on every v2 page sat still. No v2 page sets either, so this is a no-op there. */
.nav-links .btn-primary:hover,
.nav-links .btn-primary:focus-visible {
  background: var(--accent-text);
  color: var(--surface-1);
  border-color: var(--accent);
  transform: none;
  box-shadow: none;
}
/* Portal Login (operator walk, mark 1). Sits to the RIGHT of the terracotta CTA and has to
   read as a different KIND of action — a returning client, not a new enquiry — so it takes the
   forest tone. Deliberately NOT a third accent colour at REST: the palette spends its boldness
   on one thing, and that thing is the booking CTA. --forest holds the same #2A5560 in both
   stylesheets, which is why it is not redefined at the top of this file. */
.btn-portal { background: var(--forest); color: var(--surface-1); border-color: var(--forest); }
/* mc-dkxu, operator verbatim: "Can we also make it so that it inverts to orange or something that
   contrasts more with the green?"
   IT INVERTS TO ORANGE, LITERALLY. --forest → --forest-bright measured 1.55:1
   background-to-background, which is why the hover read as nothing happening. The green now flips
   to --accent, the terracotta the operator named: 3.64:1 between the resting button and the
   hovered one, and the label flips to --text-primary at 6.68:1 on it.
   THE SELECTOR IS NOT OVER-QUALIFIED. `.nav-links a.btn-portal { color: var(--surface-1) }` is the
   cascade-collision guard above, and it is (0,2,1) — a plain `.btn-portal:hover` is (0,2,0) and
   LOSES the colour half, so the hovered button would have kept white text on a terracotta ground
   at 2.25:1. The guard has to be out-specified where it applies: inside the nav. */
.btn-portal:hover,
.nav-links a.btn-portal:hover,
.nav-links a.btn-portal:focus-visible {
  background: var(--accent);
  color: var(--text-primary);
  border-color: var(--accent);
}

/* --- Footer --------------------------------------------------------------- */
/* font-family for the same reason the bar declares one — see the note on `.nav` above. */
.footer { background: var(--surface-dark); color: var(--on-dark-muted); font-family: var(--font-body); padding-block: 80px var(--s5); }
/* WCAG 2.5.8 (Target Size, Minimum, AA): every target is at least 24x24 CSS px, unless the
   spacing or inline exception applies. The footer link columns are stacked with <br> at an
   18px box on a 21px line — too small, and too tightly packed for the spacing exception. They
   are a link LIST, not links inside a sentence, so the inline exception does not rescue them
   either. inline-block + padding makes each target 26px tall without changing the look. */
.footer a {
  color: var(--on-dark-muted); text-decoration: none;
  display: inline-block; padding-block: 4px;
}
/* (0,2,1), which is the same weight as base.css:274's `.footer-bottom a:hover { color: gold }`.
   A tie goes to whichever sheet loads later, and on the old pages that is this one — which is
   why includes/layout-start.php loads base.css first and this second. */
.footer a:hover { color: var(--surface-1); text-decoration: underline; }
.footer-bottom { border-top: 1px solid rgba(255,255,255,.14); margin-top: var(--s6); padding-top: var(--s4); font-size: .875rem; display: flex; gap: var(--s4); flex-wrap: wrap; }

/* THE FOOTER'S GENERIC CLASSES, SCOPED TO THE FOOTER (mc-g629).
   .grid, .grid-3, .eyebrow and .small are tokens.css component classes, and the footer markup
   uses all four. base.css defines only .eyebrow — with a 16px bottom margin and inline-block —
   and has no .grid, .grid-3 or .small at all, so on the old pages the footer would have laid
   out as three stacked blocks of body-size text. Restating them at (0,2,0) inside .footer gives
   the same footer on both stylesheets and cannot reach a .grid, an .eyebrow or a .small
   anywhere else on any page. */
.footer .grid { display: grid; gap: var(--s4); }
.footer .grid-3 { grid-template-columns: repeat(3, 1fr); }
.footer .small { font-size: .875rem; line-height: 1.5; }
.footer p { margin: 0 0 var(--s3); }
.footer .eyebrow {
  font-family: var(--font-body);
  font-size: .75rem; font-weight: 600; line-height: 1.2;
  letter-spacing: .15em; text-transform: uppercase;
  margin: 0 0 var(--s2);
  display: block;
  color: var(--gold);   /* gold is legal here: dark ground */
}

/* --- Mobile nav ----------------------------------------------------------- */
.nav-toggle {
  display: none; align-items: center; justify-content: center;
  margin-inline-start: auto;
  width: 44px; height: 44px;             /* 44px minimum touch target */
  background: transparent; border: 1px solid var(--nav-toggle-line);
  border-radius: var(--radius); cursor: pointer; color: var(--nav-fg-strong);
}
.nav-toggle span { display: block; width: 18px; height: 2px; background: currentColor; position: relative; }
.nav-toggle span::before, .nav-toggle span::after {
  content: ''; position: absolute; left: 0; width: 18px; height: 2px; background: currentColor;
}
.nav-toggle span::before { top: -6px; }
.nav-toggle span::after  { top: 6px; }

@media (max-width: 1150px) {
  .nav-toggle { display: inline-flex; }
  .nav .container { gap: var(--s3); }

  /* The menu itself: a real panel, not a hidden list. */
  .nav-links {
    position: fixed; inset-block-start: var(--nav-h); inset-inline: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--surface-1);
    border-bottom: 1px solid var(--hairline);
    box-shadow: var(--shadow-md);
    padding: var(--s2) var(--gutter) var(--s4);
    max-height: calc(100dvh - var(--nav-h)); overflow-y: auto;
    display: none;
  }
  .nav-links.is-open { display: flex; }
  .nav-links a {
    color: var(--text-primary);
    padding-block: 14px;                 /* generous touch targets */
    border-bottom: 1px solid var(--hairline);
  }
  /* THIRD instance of the same cascade bug, and the worst one: the mobile panel ground is
     --surface-1 (white), but `.nav-links a[aria-current="page"]` (0,2,1) sets colour to
     --surface-1 for the transparent DESKTOP nav and out-specifies `.nav-links a` (0,1,1)
     here. The current page's own link rendered white on white — invisible. The desktop rule
     is scoped to a ground that does not exist inside this panel, so it must be overridden
     for every nav-link variant the panel contains, not just the plain ones. */
  .nav-links a[aria-current="page"] { color: var(--accent-text); }
  /* And the same for the drawer's plain links, which the base.css leak-canceller above pins to
     --nav-fg at (0,4,2) — correct on the desktop bar, but this panel has its own white ground
     and its own --text-primary. It has to out-rank that, hence the extra `.nav-links`. */
  .nav .nav-links > li > a:not(.btn):not(.lang-toggle):hover,
  .nav .nav-links > li > a:not(.btn):not(.lang-toggle):focus-visible { color: var(--text-primary); }
  /* mc-3csi, and it is the SAME bug as the three lines below it: the language pill takes its
     colours from --nav-fg / --nav-line / --nav-lang-hover, which over a hero are white, a
     translucent white and a cream — correct on navy, invisible inside this white panel. The panel
     has its own ground, so it pins its own values. */
  .nav-links a.lang-toggle { color: var(--text-primary); border-color: var(--hairline); }
  .nav-links a.lang-toggle:hover,
  .nav-links a.lang-toggle:focus-visible { color: var(--accent-text); border-color: var(--accent-text); }
  .nav-links a.btn-primary { color: var(--text-primary); }
  .nav-links a.btn-portal { color: var(--surface-1); }
  .nav-links a.btn-secondary { color: var(--forest); }
  .nav-links li:last-child a { border-bottom: 0; }
  /* mc-dkxu at 375. The drawer's row separator is `.nav-links a`, which is every anchor in the
     panel — so both BUTTONS carried a hairline across their bottom edge at rest, and the hover
     rule then painted it white inside the green one. `:not(.btn)` fixed the hover half; this
     fixes the resting half. A button is not a row in a list. */
  .nav-links a.btn { border-bottom: 0; }
  .nav-links .btn { margin-top: var(--s3); justify-content: center; }

  /* The Events group must NOT become a desktop-only affordance (375px gate).
     On mobile it is a flat, always-visible section rather than a hover popover —
     a popover anchored to a full-width row has nowhere sensible to go. */
  .sub-toggle {
    display: none;                       /* no toggle needed; the list is already open */
  }
  .has-sub { position: static; }
  .sub {
    display: block; position: static; min-width: 0;
    border: 0; border-radius: 0; box-shadow: none; background: transparent;
    padding: 0;
  }
  .sub::before {
    /* i18n: the label comes from the HTML (data-label-events) so a Spanish page does not
       render an English "Events" heading under 900px. A hard-coded content string was a
       real leak — the HTML and JS were localized while the CSS was not. */
    content: attr(data-label-events);
    display: block; padding: 14px 0 6px;
    font-size: .75rem; font-weight: 600; letter-spacing: .15em; text-transform: uppercase;
    color: var(--text-muted);
  }
  .sub a {
    padding: 14px 0 14px var(--s3);
    border-bottom: 1px solid var(--hairline);
    color: var(--text-primary);
  }

  /* The footer's three columns become one. This HAS to be here rather than relying on
     tokens.css's `.grid-3 { grid-template-columns: 1fr }`: the rule above is `.footer .grid-3`
     at (0,2,0) and would out-rank a bare `.grid-3` (0,1,0) even inside this media query, so
     without this line the v2 footer would have stayed three columns wide on a phone. */
  .footer .grid-3 { grid-template-columns: 1fr; }
}
