/**
 * site.css — the public marketing site's only stylesheet.
 *
 * ── WHAT THIS FILE MAY AND MAY NOT DO ───────────────────────────────────────
 *
 * MAY: own marketing layout — the nav, the hero, section bands, card grids,
 * the logo marquee, the footer. None of that exists in the SDK and none of it
 * should: the SDK is the vocabulary of the authenticated application, and a
 * mega-menu is not part of that vocabulary.
 *
 * MAY: read any design token. That is the integration point, and the reason the
 * Brand Switcher repaints this site and the application together from one
 * source.
 *
 * MAY NOT: redefine a design token at :root. Brands are owned by
 * branding/tokens.css and nothing else. If this file set --accent it would
 * silently defeat the switcher for whichever pages loaded it.
 *
 * MAY NOT: reference an SDK internal class name. Same contract every other
 * consumer is held to — it is what keeps SDK internals free to change.
 *
 * ── THE MARKETING TYPE SCALE IS LOCAL, ON PURPOSE ───────────────────────────
 *
 * A marketing headline is 5rem. The largest token in the SDK's scale, --fs-5xl,
 * is sized for an application heading and is nowhere near that. The temptation
 * is to redefine --fs-* here so the numbers come out bigger.
 *
 * That would be wrong twice: tokens.css's own header forbids touching the type
 * scale without SDK-owner sign-off (it is component-internal and there is no
 * visual-regression tooling to catch a mistake — ND-46/47), and this stylesheet
 * shares a document with sdk.css, so a bigger --fs-lg would resize anything the
 * SDK rendered on the same page.
 *
 * So the marketing scale lives in its own --site-* namespace below. It borrows
 * the brand's --font and --fw-* weights, which is the part that must match, and
 * keeps its own sizes, which is the part that must not.
 *
 * ── STRUCTURAL DEBT WORTH NAMING ────────────────────────────────────────────
 *
 * Everything here is scoped under `body.site`. sdk.css styles `body` directly,
 * and this document loads both. Scoping means this file always wins on
 * specificity without either stylesheet needing to know about the other, but it
 * is a guard, not a boundary — if the SDK ever adds a `body.site` rule these
 * will collide. Unlikely enough to accept, worth writing down.
 */

/* ══════════════════════════════════════════════════════════════════════════
   1. Marketing type + rhythm scale (local namespace — see header)
   ══════════════════════════════════════════════════════════════════════════ */
body.site {
  /* Sizes mirror OneShield's own scale, which is where the visual match comes
     from: display 7rem, h1 5rem, h3 3rem, h4 2rem, h2 2.25rem. Their h2/h3
     ordering is inverted relative to what you would expect — that is a quirk of
     their Webflow setup and is NOT reproduced here, because inheriting someone
     else's tooling artefact is not the same as matching their design. */
  --site-display: clamp(2.75rem, 8vw, 7rem);
  --site-h1: clamp(2.25rem, 6vw, 5rem);
  --site-h2: clamp(1.75rem, 3.5vw, 3rem);
  --site-h3: clamp(1.375rem, 2.4vw, 2rem);
  --site-h4: clamp(1.125rem, 1.6vw, 1.375rem);
  --site-lead: clamp(1.0625rem, 1.4vw, 1.3125rem);
  --site-body: 1.0625rem;
  --site-small: 0.9375rem;
  --site-micro: 0.8125rem;

  /* Headings are 800 and line-height 1.1 — the single most recognisable part of
     the OneShield look after the accent colour. */
  --site-heading-weight: 800;
  --site-heading-lh: 1.06;
  --site-heading-tracking: -0.022em;

  /* Vertical rhythm. Marketing bands are far taller than application panels, so
     these are independent of --spacing-*. */
  --site-band-y: clamp(3.5rem, 8vw, 7.5rem);
  --site-gap: clamp(1.25rem, 2.5vw, 2rem);
  --site-max: 1240px;
  --site-max-narrow: 760px;

  /* Marketing surfaces derive from brand tokens so every brand gets them free.
     color-mix rather than a hardcoded rgba(): a fixed alpha over an unknown
     brand background is how a "subtle" tint becomes invisible on one brand and
     muddy on another. */
  --site-hairline: color-mix(in srgb, var(--border) 70%, transparent);
  --site-glass: color-mix(in srgb, var(--bg) 82%, transparent);
  --site-tile-veil: color-mix(in srgb, var(--bg) 55%, transparent);
}

/* ══════════════════════════════════════════════════════════════════════════
   2. Base
   ══════════════════════════════════════════════════════════════════════════ */
body.site {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--site-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

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

body.site h1, body.site h2, body.site h3, body.site h4 {
  margin: 0;
  font-weight: var(--site-heading-weight);
  line-height: var(--site-heading-lh);
  letter-spacing: var(--site-heading-tracking);
  text-wrap: balance;
}
body.site h1 { font-size: var(--site-h1); }
body.site h2 { font-size: var(--site-h2); }
body.site h3 { font-size: var(--site-h3); }
body.site h4 { font-size: var(--site-h4); letter-spacing: -0.01em; }

body.site p { margin: 0; text-wrap: pretty; }
body.site img, body.site svg { max-width: 100%; }
body.site ul, body.site ol { margin: 0; padding: 0 0 0 1.15em; }
body.site li + li { margin-top: 0.4em; }

/* ── THE LINK RESET, AND THE BUG IT CAUSED THREE TIMES ──────────────────────
   This was `body.site a { color: inherit; text-decoration: none; }`, and that
   one declaration silently broke every component that is an <a>:

       body.site a      (0,1,2)   ← two type selectors + one class
       .btn-primary     (0,1,0)

   (0,1,2) beats (0,1,0), so `.btn-primary { color: var(--text-on-accent) }` never
   applied to a CTA rendered as a link. The hero and header "Get a quote" buttons
   are anchors; the quote-bar "Start" is a <button>. Only the <button> got its
   colour, which is exactly why the bug looked brand-specific and intermittent
   rather than universal. Measured at **1.05:1 on trident** — invisible — on all
   five brands. The token values were correct the whole time.

   This was the THIRD instance of the same root cause. The alert bar's CTA and
   accent-band links were the first two, and both were "fixed" by escalating
   specificity at the call site. That is an arms race and it loses: every new
   component that happens to be an <a> starts out broken.

   So the reset is fixed instead. Two rules, and the split is the whole point:

   1. An UNCLASSED <a> is prose — it should look like a link, and nothing else
      competes for it, so ordinary specificity is fine.
   2. A CLASSED <a> is a component. It must take its colour from its component
      rule. `:where()` contributes ZERO specificity, so `:where(body.site a)` is
      (0,0,0) — enough to beat the user-agent's default link blue, and beaten by
      every single class. Which is precisely the contract we want.

   Do not "tidy" the :where() away. Without it, components that are links lose
   their colour and the failure is invisible until someone photographs it. */
:where(body.site a) { color: inherit; }
body.site a { text-decoration: none; }
body.site a:not([class]) {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}
body.site a:not([class]):hover { text-decoration-thickness: 2px; }

/* One visible focus treatment for everything. Two-colour so it survives every
   brand, including the monochrome phosphor ones where a single ring can vanish
   against its own background. */
body.site :focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--radius-xs, 4px);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: 0.75rem 1.25rem;
  background: var(--accent);
  color: var(--text-on-accent);
  font-weight: 700;
}
.skip-link:focus { left: 0.5rem; top: 0.5rem; }

.wrap {
  width: 100%;
  max-width: var(--site-max);
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2.5rem);
}
.wrap-narrow { max-width: var(--site-max-narrow); }

.eyebrow {
  display: block;
  font-size: var(--site-micro);
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.lead { font-size: var(--site-lead); color: var(--text-muted); line-height: 1.55; }
.muted { color: var(--text-muted); }
.dim { color: var(--text-dim); }
.small { font-size: var(--site-small); }
.micro { font-size: var(--site-micro); }
.center { text-align: center; }
.center .lead, .center p { margin-inline: auto; }
.mt-1 { margin-top: 0.5rem; }
.mt-2 { margin-top: 1rem; }
.mt-3 { margin-top: 1.75rem; }
.mt-4 { margin-top: 2.5rem; }
.stack > * + * { margin-top: 1rem; }
.stack-sm > * + * { margin-top: 0.5rem; }
.stack-lg > * + * { margin-top: 1.75rem; }

/* ══════════════════════════════════════════════════════════════════════════
   3. Buttons
   OneShield's primary button is a near-black fill that INVERTS on hover. That
   inversion is reproduced with tokens rather than literal colours, so it works
   on every brand instead of only the dark ones.
   ══════════════════════════════════════════════════════════════════════════ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.85rem 1.6rem;
  border: 1px solid transparent;
  border-radius: 999px;
  font: inherit;
  font-size: var(--site-small);
  font-weight: 700;
  letter-spacing: -0.005em;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease,
              border-color 0.18s ease, transform 0.18s ease;
}
.btn:active { transform: translateY(1px); }
.btn-lg { padding: 1.05rem 2rem; font-size: var(--site-body); }
.btn-sm { padding: 0.55rem 1.1rem; font-size: var(--site-micro); }
.btn-block { width: 100%; }

/* The signature: accent fill, brand-correct text colour on it. --text-on-accent
   is not assumed to be white — on the trident brand's lime it is near-black,
   and hardcoding white here would have made every primary button illegible. */
.btn-primary {
  background: var(--accent);
  color: var(--text-on-accent);
  border-color: var(--accent);
}
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }

.btn-solid {
  background: var(--text);
  color: var(--bg);
  border-color: var(--text);
}
.btn-solid:hover { background: var(--accent); border-color: var(--accent); color: var(--text-on-accent); }

.btn-outline {
  background: transparent;
  color: var(--text);
  border-color: var(--border);
}
.btn-outline:hover { background: var(--text); color: var(--bg); border-color: var(--text); }

.btn-ghost { background: transparent; color: var(--text-muted); }
.btn-ghost:hover { color: var(--text); }

.btn-row { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; }
.center .btn-row { justify-content: center; }

/* An arrow that leans into the hover, used on text links that act as CTAs. */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: var(--site-small);
  font-weight: 700;
  color: var(--accent);
}
.arrow-link svg { transition: transform 0.18s ease; }
.arrow-link:hover svg { transform: translateX(3px); }

.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.8rem;
  border: 1px solid var(--site-hairline);
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  font-size: var(--site-micro);
  font-weight: 700;
  letter-spacing: 0.01em;
}
.badge-dot::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

/* ══════════════════════════════════════════════════════════════════════════
   4. Alert bar + utility bar + navigation
   ══════════════════════════════════════════════════════════════════════════ */
.alertbar {
  background: var(--accent);
  color: var(--text-on-accent);
  font-size: var(--site-micro);
  font-weight: 600;
}
.alertbar .wrap {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding-block: 0.5rem;
}
/* ── ACCENT-ON-ACCENT: the bug this guards, and why it is written this way ──
   The bar's background is var(--accent). The global link rule is
   `body.site a:not([class]) { color: var(--accent) }`, so an unclassed link in
   here came out accent-on-accent — measured at 1:1, completely invisible, on all
   four brands. It was the catastrophe banner's only call to action.

   THE FIRST FIX FAILED, AND THE FAILURE IS THE INSTRUCTIVE PART. It was
   `.alertbar a { color: inherit }` — correct intent, wrong specificity:

       body.site a:not([class])   (0,2,2)   ← still won
       .alertbar a               (0,1,1)

   So the real fix is structural: the link now CARRIES a class
   (`.alertbar-cta`, see _nav.html), which removes it from the `:not([class])`
   match altogether instead of trying to outrank it. The descendant selector
   below is kept as a safety net for any future unclassed link dropped in here,
   and is deliberately scoped with `body.site` to reach (0,3,2).

   Only browser verification could find either the original bug or the failed
   fix: the CSS is valid in both cases, every token resolves, and no gate in this
   workspace compares a colour against the colour behind it. */
.alertbar-cta,
body.site .alertbar a:not([class]) {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.15em;
  font-weight: 800;
}
.alertbar-close {
  margin-left: auto;
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.15rem 0.35rem;
}

.utilitybar {
  border-bottom: 1px solid var(--site-hairline);
  font-size: var(--site-micro);
  color: var(--text-muted);
}
.utilitybar .wrap {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  padding-block: 0.5rem;
}
.utilitybar nav { display: flex; gap: 1.25rem; margin-left: auto; align-items: center; }
.utilitybar a { font-weight: 600; }
.utilitybar a:hover { color: var(--text); }
.utilitybar .phone { font-weight: 700; color: var(--text); }

.siteheader {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--site-glass);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--site-hairline);
}
.siteheader > .wrap {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2.5rem);
  padding-block: 0.9rem;
}

/* The mark is --brand-logo, so it repaints per brand for free. The wordmark is
   real text beside it rather than part of the image: if the token is unset (an
   unbranded deployment) the mark is simply absent and the site still has a
   legible identity, instead of an empty box where a logo should be. */
.brandmark { display: inline-flex; align-items: center; gap: 0.6rem; flex: none; }
.brandmark-glyph {
  width: 30px;
  height: 30px;
  flex: none;
  background-image: var(--brand-logo);
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}
.brandmark-word {
  font-size: 1.2rem;
  font-weight: 800;
  letter-spacing: -0.03em;
}

.mainnav { margin-left: auto; }
.mainnav > ul {
  display: flex;
  align-items: center;
  gap: clamp(0.35rem, 1.4vw, 1.35rem);
  list-style: none;
  margin: 0;
  padding: 0;
}
.mainnav > ul > li { position: relative; }
.mainnav > ul > li > a,
.navtrigger {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.55rem 0.6rem;
  background: none;
  border: 0;
  border-radius: var(--radius-sm, 6px);
  font: inherit;
  font-size: var(--site-small);
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
}
.navtrigger svg { transition: transform 0.2s ease; }
.navtrigger[aria-expanded='true'] svg { transform: rotate(180deg); }
.mainnav > ul > li > a:hover,
.navtrigger:hover { color: var(--accent); }

/* ── Mega-menu panel ────────────────────────────────────────────────────────
   Hidden with [hidden] + display:none rather than opacity, so it is genuinely
   out of the accessibility tree when closed. site.js toggles aria-expanded and
   the hidden attribute together.

   THE DEAD ZONE BUG. This was `top: calc(100% + 0.7rem)` — a 0.7rem visual gap
   between the trigger and the panel. That gap is not part of either element, so
   moving the mouse from the trigger down to the panel fired `pointerleave` on
   the trigger's <li> and the menu shut before it could be reached. The panel was
   effectively unclickable by mouse.

   Fixed structurally, in two independent ways so neither alone is load-bearing:

   1. The panel now starts at `top: 100%` — flush against the trigger, no gap to
      cross — and the visual separation comes from `padding-top` INSIDE the
      panel's own box. The gap is now transparent hoverable area belonging to the
      panel, so the pointer never leaves.
   2. Because the panel is the hit area, the surface styling (background, border,
      radius, shadow) had to move off it and onto the inner .megagrid, or the
      background would extend up and visually fuse with the header.

   site.js additionally applies a short close delay, which covers diagonal
   pointer paths that exit the <li> sideways. Belt and braces on purpose: this is
   the single most-used control on the site. */
.megapanel {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  min-width: max-content;
  /* The transparent bridge. Hoverable, and part of the panel. */
  padding-top: 0.7rem;
  z-index: 110;
}
.megapanel[hidden] { display: none; }
.megagrid {
  display: flex;
  gap: 2.25rem;
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 14px);
  box-shadow: var(--elev-dropdown, 0 18px 50px rgb(0 0 0 / 0.35));
}
.megacol { min-width: 190px; }
.megacol > .eyebrow { margin-bottom: 0.7rem; }
.megacol ul { list-style: none; margin: 0; padding: 0; }
.megacol li + li { margin-top: 0.1rem; }
.megacol a {
  display: block;
  padding: 0.42rem 0.55rem;
  margin-inline: -0.55rem;
  border-radius: var(--radius-sm, 6px);
  font-size: var(--site-small);
  font-weight: 600;
}
.megacol a:hover { background: var(--surface-2); color: var(--accent); }
.megacol a .micro { display: block; font-weight: 500; color: var(--text-dim); }

.navactions { display: flex; align-items: center; gap: 0.6rem; flex: none; }

.navtoggle {
  display: none;
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 6px);
  padding: 0.5rem 0.6rem;
  color: var(--text);
  cursor: pointer;
}

/* ══════════════════════════════════════════════════════════════════════════
   5. Bands — the alternating section rhythm
   ══════════════════════════════════════════════════════════════════════════ */
.band { padding-block: var(--site-band-y); }
.band-tight { padding-block: clamp(2.25rem, 4vw, 3.5rem); }
.band-alt { background: var(--surface); }
.band-sunken { background: color-mix(in srgb, var(--surface) 60%, var(--bg)); }

/* Accent band. Text colour is --text-on-accent throughout, because on the
   trident brand the accent is a light lime and inheriting --text would put a
   near-white heading on it. */
.band-accent { background: var(--accent); color: var(--text-on-accent); }
.band-accent .eyebrow,
.band-accent .lead,
.band-accent .muted { color: color-mix(in srgb, var(--text-on-accent) 75%, transparent); }
/* Same accent-on-accent trap the alert bar hit — see the long note there. Any
   band whose background IS --accent must reclaim the link colour, or an unclassed
   <a> inherits var(--accent) and vanishes.
   Scoped with `body.site` for specificity (0,3,2), which is what it takes to beat
   `body.site a:not([class])` at (0,2,2). Without the prefix this rule is (0,2,1)
   and loses silently — exactly how the alert bar's first fix failed. */
body.site .band-accent a:not([class]) { color: inherit; text-decoration-thickness: 2px; }
.band-accent .arrow-link { color: var(--text-on-accent); }
.band-accent .badge {
  background: color-mix(in srgb, var(--text-on-accent) 12%, transparent);
  border-color: color-mix(in srgb, var(--text-on-accent) 30%, transparent);
}
.band-accent .badge-dot::before { background: var(--text-on-accent); }
.band-accent .btn-solid { background: var(--text-on-accent); color: var(--accent); border-color: var(--text-on-accent); }
.band-accent .btn-outline { border-color: color-mix(in srgb, var(--text-on-accent) 40%, transparent); color: var(--text-on-accent); }
.band-accent .btn-outline:hover { background: var(--text-on-accent); color: var(--accent); }

.bandhead { max-width: 780px; margin-bottom: clamp(2rem, 4vw, 3.25rem); }
.bandhead.center { margin-inline: auto; }
.bandhead > * + * { margin-top: 0.85rem; }

/* ══════════════════════════════════════════════════════════════════════════
   6. Hero
   ══════════════════════════════════════════════════════════════════════════ */
.hero { position: relative; padding-block: clamp(3rem, 7vw, 6.5rem) var(--site-band-y); overflow: hidden; }
.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.hero-copy > * + * { margin-top: 1.25rem; }
.hero h1 { font-size: var(--site-h1); }
.hero-meta { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; }

/* Abstract brand art. Built from tokens and CSS gradients rather than a
   supplied image: no photography or illustration assets exist for this carrier,
   and generated art that repaints per brand demonstrates the switcher better
   than a flat PNG that cannot. */
.hero-art {
  position: relative;
  aspect-ratio: 1 / 1;
  display: grid;
  place-items: center;
}
.hero-art::before {
  content: '';
  position: absolute;
  inset: 4%;
  border-radius: 50%;
  background: radial-gradient(circle at 32% 28%,
              color-mix(in srgb, var(--accent) 42%, transparent) 0%,
              transparent 62%);
  filter: blur(6px);
}
.hero-rings { position: absolute; inset: 0; }
.hero-rings span {
  position: absolute;
  inset: 0;
  margin: auto;
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  border-radius: 50%;
}
.hero-rings span:nth-child(1) { width: 96%; height: 96%; }
.hero-rings span:nth-child(2) { width: 74%; height: 74%; border-style: dashed; }
.hero-rings span:nth-child(3) { width: 52%; height: 52%; }
.hero-art svg { position: relative; width: 44%; height: auto; }

@media (prefers-reduced-motion: no-preference) {
  .hero-rings span:nth-child(2) { animation: site-spin 44s linear infinite; }
  .hero-art > svg { animation: site-float 7s ease-in-out infinite; }
}
@keyframes site-spin { to { transform: rotate(360deg); } }
@keyframes site-float { 50% { transform: translateY(-9px); } }

/* ── Quote starter strip ── */
.quotebar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: flex-end;
  padding: 1.1rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 14px);
  box-shadow: var(--elev-card, 0 2px 10px rgb(0 0 0 / 0.18));
}
.quotebar .field { flex: 1 1 11rem; min-width: 0; }

/* ══════════════════════════════════════════════════════════════════════════
   7. Forms
   ══════════════════════════════════════════════════════════════════════════ */
.field { display: block; }
.field > .label {
  display: block;
  margin-bottom: 0.35rem;
  font-size: var(--site-micro);
  font-weight: 700;
  color: var(--text-muted);
}
body.site input[type='text'],
body.site input[type='email'],
body.site input[type='tel'],
body.site input[type='date'],
body.site input[type='number'],
body.site input[type='password'],
body.site input[type='search'],
body.site select,
body.site textarea {
  width: 100%;
  padding: 0.75rem 0.9rem;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 8px);
  font: inherit;
  font-size: var(--site-small);
}
body.site textarea { min-height: 8rem; resize: vertical; }
body.site input:focus, body.site select:focus, body.site textarea:focus {
  border-color: var(--accent);
  outline: 2px solid color-mix(in srgb, var(--accent) 35%, transparent);
  outline-offset: 0;
}
body.site input::placeholder, body.site textarea::placeholder { color: var(--text-dim); }
body.site fieldset { border: 0; margin: 0; padding: 0; }
body.site legend { padding: 0; font-weight: 700; }
.formgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
.formgrid .span-2 { grid-column: 1 / -1; }
.checkline { display: flex; gap: 0.6rem; align-items: flex-start; font-size: var(--site-small); }
.checkline input { width: auto; margin-top: 0.2rem; }

/* A form that submits nowhere says so, rather than pretending. */
.demo-note {
  display: flex;
  gap: 0.6rem;
  padding: 0.8rem 1rem;
  border-left: 3px solid var(--warning);
  background: var(--warning-bg);
  border-radius: var(--radius-sm, 8px);
  font-size: var(--site-small);
}

/* ══════════════════════════════════════════════════════════════════════════
   8. Grids, cards, features, tiles
   ══════════════════════════════════════════════════════════════════════════ */
.grid { display: grid; gap: var(--site-gap); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; gap: clamp(2rem, 5vw, 4rem); }

.card {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: clamp(1.35rem, 2.2vw, 2rem);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 14px);
  transition: border-color 0.2s ease, transform 0.2s ease;
}
.card > .arrow-link { margin-top: auto; }
a.card:hover, .card-hover:hover { border-color: var(--accent); transform: translateY(-3px); }
.card-flush { background: transparent; border: 0; padding: 0; }

.card-kicker {
  font-size: var(--site-micro);
  font-weight: 800;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--accent);
}

.iconbox {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  flex: none;
  border-radius: var(--radius-md, 10px);
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
}
.iconbox svg { width: 22px; height: 22px; }

.feature { display: flex; flex-direction: column; gap: 0.9rem; }

/* Image tiles. No photography exists, so a tile is a token-derived gradient
   plate with a glyph — consistent across brands and honest about being
   generated, rather than stock imagery that would date the demo. */
.tile {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 0.3rem;
  min-height: 190px;
  padding: 1.25rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 14px);
  overflow: hidden;
  background:
    linear-gradient(180deg, transparent 35%, var(--site-tile-veil) 100%),
    linear-gradient(142deg,
      color-mix(in srgb, var(--accent) 26%, var(--surface)) 0%,
      var(--surface) 58%);
  transition: transform 0.22s ease, border-color 0.22s ease;
}
.tile:hover { transform: translateY(-4px); border-color: var(--accent); }
.tile svg { position: absolute; top: 1.1rem; left: 1.15rem; width: 26px; height: 26px; color: var(--accent); }
.tile .tile-name { font-size: var(--site-h4); font-weight: 800; letter-spacing: -0.02em; }

/* ── Stat band ── */
.stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--site-gap); }
.stat > .stat-n {
  display: block;
  font-size: clamp(2.1rem, 4.2vw, 3.4rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.035em;
}
.stat > .stat-l { display: block; margin-top: 0.5rem; font-size: var(--site-small); }

/* ── Story / case-study card ── */
.story { display: flex; flex-direction: column; overflow: hidden; padding: 0; }
.story-plate {
  min-height: 150px;
  background: linear-gradient(142deg,
    color-mix(in srgb, var(--accent) 30%, var(--surface-2)) 0%,
    var(--surface-2) 70%);
  display: grid;
  place-items: center;
  font-size: 1.15rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: var(--text);
}
.story-body { display: flex; flex-direction: column; gap: 0.7rem; padding: 1.35rem; }

/* ── Logo marquee ──
   Duplicated track, translated by exactly -50%, so the seam is invisible. The
   duplicate must be aria-hidden or a screen reader announces every name twice.
   Paused entirely under prefers-reduced-motion — a permanently scrolling strip
   is a vestibular trigger, not decoration. */
.marquee { position: relative; overflow: hidden; mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.marquee-track { display: flex; width: max-content; gap: clamp(2rem, 5vw, 4rem); align-items: center; }
@media (prefers-reduced-motion: no-preference) {
  .marquee-track { animation: site-marquee 42s linear infinite; }
  .marquee:hover .marquee-track { animation-play-state: paused; }
}
@keyframes site-marquee { to { transform: translateX(-50%); } }
.marquee-item {
  font-size: var(--site-small);
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  white-space: nowrap;
}

/* ══════════════════════════════════════════════════════════════════════════
   9. Accordion — native <details>, no JavaScript
   A disclosure widget is already a browser primitive with correct keyboard
   behaviour and correct semantics. Re-implementing it in JS would be strictly
   worse and would stop working if site.js failed to load.
   ══════════════════════════════════════════════════════════════════════════ */
.faq { border-top: 1px solid var(--site-hairline); }
.faq details { border-bottom: 1px solid var(--site-hairline); }
.faq summary {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1.35rem 0;
  font-size: var(--site-h4);
  font-weight: 700;
  letter-spacing: -0.012em;
  cursor: pointer;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '';
  margin-left: auto;
  flex: none;
  width: 12px;
  height: 12px;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(45deg);
  transition: transform 0.2s ease;
}
.faq details[open] summary::after { transform: rotate(-135deg); }
.faq summary:hover { color: var(--accent); }
.faq .faq-a { padding: 0 3rem 1.5rem 0; color: var(--text-muted); max-width: 74ch; }

/* ══════════════════════════════════════════════════════════════════════════
   10. Login doors — the audience chooser
   ══════════════════════════════════════════════════════════════════════════ */
.doors { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--site-gap); }
.door {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  padding: clamp(1.5rem, 2.5vw, 2.25rem);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 14px);
  transition: border-color 0.2s ease, transform 0.2s ease, box-shadow 0.2s ease;
}
.door:hover { border-color: var(--accent); transform: translateY(-4px); box-shadow: var(--elev-raised, 0 14px 34px rgb(0 0 0 / 0.25)); }
.door .iconbox { width: 52px; height: 52px; }
.door h3 { font-size: var(--site-h4); }
.door .door-links { margin-top: auto; padding-top: 0.5rem; display: flex; flex-wrap: wrap; gap: 0.35rem 1rem; }
.door .door-links a { font-size: var(--site-micro); font-weight: 600; color: var(--text-muted); text-decoration: underline; text-underline-offset: 0.15em; }
.door .door-links a:hover { color: var(--accent); }

/* The door card is a <div> and its HEADING carries the destination, with a
   transparent ::after stretched over the card. That is what lets a whole card
   be one click target while still containing a real, focusable sub-link —
   nested <a> is invalid HTML, so the sub-link cannot live inside a card-wide
   anchor. It also gives the card link an accessible name of just its heading
   rather than the card's entire text. See the ND-42 structure contract
   (login-door-forgot-password). */
.door { position: relative; }
.door h3 .door-target { color: inherit; }
.door .door-target::after { content: ''; position: absolute; inset: 0; z-index: 1; border-radius: inherit; }

/* z-index goes on the ANCHORS, never on the .door-links row. Lifting the whole
   row above the stretched layer turns the row's EMPTY space into a dead zone:
   a click there hits neither the sub-link nor the card. Measured with
   elementFromPoint in the sketch — do not "simplify" this onto the row. */
.door .door-links a { position: relative; z-index: 2; display: inline-flex; align-items: center; min-height: 24px; }
.door .door-links { row-gap: 0.5rem; }

/* Hover must say WHICH of the two nested targets the pointer is on, so the card
   does not lift while the sub-link is the thing under the cursor. */
.door:has(.door-links a:hover) { transform: none; border-color: var(--border); box-shadow: none; }

/* A keyboard user must see the CARD, not four words of heading text. */
.door:has(.door-target:focus-visible) { outline: 2px solid var(--accent); outline-offset: 3px; }
.door .door-target:focus-visible { outline: none; }
.door .door-links a:focus-visible { color: var(--accent); }

/* The employee door is deliberately the quietest of the three: it is the only
   one that currently authenticates, but it is also the one the public has no
   business using. Carrier sites treat it the same way. */
.door-quiet { background: transparent; }

/* Auth card, used by the two portal pages that do not sign anyone in yet. */
.authcard {
  max-width: 420px;
  margin-inline: auto;
  padding: clamp(1.75rem, 3vw, 2.5rem);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 14px);
}

/* ══════════════════════════════════════════════════════════════════════════
   11. Data tables (availability, appetite, class codes)
   ══════════════════════════════════════════════════════════════════════════ */
.tablewrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-lg, 14px); }
body.site table.data { width: 100%; border-collapse: collapse; font-size: var(--site-small); }
body.site table.data th,
body.site table.data td { padding: 0.8rem 1rem; text-align: left; border-bottom: 1px solid var(--site-hairline); }
body.site table.data thead th {
  background: var(--surface-2);
  font-size: var(--site-micro);
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
}
body.site table.data tbody tr:last-child td { border-bottom: 0; }
body.site table.data tbody tr:hover { background: var(--surface); }
.pill {
  display: inline-block;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  font-size: var(--site-micro);
  font-weight: 700;
}
.pill-yes { background: var(--success-bg); color: var(--success); }
.pill-no { background: var(--danger-bg); color: var(--danger); }
.pill-soon { background: var(--info-bg); color: var(--info); }

/* ══════════════════════════════════════════════════════════════════════════
   12. Steps / timeline
   ══════════════════════════════════════════════════════════════════════════ */
.steps { list-style: none; padding: 0; counter-reset: step; }
.steps > li {
  position: relative;
  padding: 0 0 1.6rem 3.25rem;
  margin: 0;
  counter-increment: step;
}
.steps > li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--text-on-accent);
  font-size: var(--site-small);
  font-weight: 800;
}
.steps > li::after {
  content: '';
  position: absolute;
  left: 17px;
  top: 40px;
  bottom: 0;
  width: 1px;
  background: var(--border);
}
.steps > li:last-child { padding-bottom: 0; }
.steps > li:last-child::after { display: none; }
.steps h4 { margin-bottom: 0.3rem; }

/* ══════════════════════════════════════════════════════════════════════════
   13. Brand switcher — the demo control
   ══════════════════════════════════════════════════════════════════════════ */
/* Lives in the site HEADER (see _nav.html), so the menu drops DOWN. It was in
   the footer and opened upward; both the anchor and the shadow direction had to
   flip with it. z-index sits above .megapanel (110) so the two cannot fight. */
.brandswitch { position: relative; flex: none; }
.brandswitch-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 0.6rem);
  min-width: 210px;
  padding: 0.45rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md, 10px);
  box-shadow: var(--elev-dropdown, 0 18px 50px rgb(0 0 0 / 0.35));
  z-index: 130;
}
.brandswitch-menu[hidden] { display: none; }
.brandswitch-menu button {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0.55rem 0.65rem;
  background: none;
  border: 0;
  border-radius: var(--radius-sm, 6px);
  font: inherit;
  font-size: var(--site-small);
  font-weight: 600;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}
.brandswitch-menu button:hover { background: var(--surface-2); }
.brandswitch-menu button[aria-current='true'] { color: var(--accent); }
.brandswitch-menu button[aria-current='true']::after { content: '✓'; margin-left: auto; font-weight: 800; }
.swatch { width: 14px; height: 14px; flex: none; border-radius: 4px; border: 1px solid var(--site-hairline); }
/* THE PER-BRAND `.swatch-<key>` RULES ARE GONE (ND-766).
   The colour is now an inline `style="background:…"` on the generated chip,
   taken from `swatch` in that brand's ui/brands/<key>/brand.json. That was the
   last reason site.css had to know a carrier's name, and adding a brand no
   longer touches this file.

   The colours still have to be LITERAL rather than `var(--accent)`, and that
   reason is unchanged: each swatch shows what you are about to switch TO, so it
   cannot read the tokens of the brand currently applied. brand.json is where
   that literal lives now. */

/* ══════════════════════════════════════════════════════════════════════════
   14. Footer
   ══════════════════════════════════════════════════════════════════════════ */
.sitefooter {
  border-top: 1px solid var(--site-hairline);
  background: var(--surface);
  padding-block: clamp(2.5rem, 5vw, 4rem) 1.75rem;
  font-size: var(--site-small);
}
.footer-top { display: grid; grid-template-columns: minmax(0, 1.4fr) repeat(4, minmax(0, 1fr)); gap: 2rem; }
.footer-col > .eyebrow { margin-bottom: 0.9rem; }
.footer-col ul { list-style: none; margin: 0; padding: 0; }
.footer-col li + li { margin-top: 0.5rem; }
.footer-col a { color: var(--text-muted); font-weight: 500; }
.footer-col a:hover { color: var(--accent); }
.footer-about > * + * { margin-top: 1rem; }
.footer-ratings { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.rating-chip {
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 8px);
  font-size: var(--site-micro);
  line-height: 1.35;
}
.rating-chip b { display: block; font-size: var(--site-small); }

.footer-disclaimer {
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: 1.5rem;
  border-top: 1px solid var(--site-hairline);
  color: var(--text-dim);
  font-size: var(--site-micro);
  max-width: 95ch;
}
.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.35rem;
  align-items: center;
  margin-top: 1.25rem;
  font-size: var(--site-micro);
  color: var(--text-dim);
}
.footer-bottom nav { display: flex; flex-wrap: wrap; gap: 0.75rem 1.35rem; }
.footer-bottom a { color: var(--text-dim); }
.footer-bottom a:hover { color: var(--accent); }
.footer-bottom .spacer { margin-left: auto; }

/* ══════════════════════════════════════════════════════════════════════════
   15. Responsive
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 1080px) {
  .footer-top { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .footer-about { grid-column: 1 / -1; }
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 960px) {
  .hero-grid { grid-template-columns: 1fr; }
  .hero-art { order: -1; max-width: 340px; margin-inline: auto; }
  .grid-3, .doors { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-split { grid-template-columns: 1fr; }
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .utilitybar nav a[data-optional] { display: none; }

  /* Mobile navigation. The mega-panels stop being absolutely positioned and
     become inline disclosure content inside a stacked drawer, which is why they
     use [hidden] rather than opacity — the same toggle works in both layouts
     with no second implementation. */
  .navtoggle { display: inline-flex; margin-left: auto; }
  .mainnav {
    display: none;
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    max-height: 78vh;
    overflow-y: auto;
    margin: 0;
    padding: 1rem clamp(1rem, 4vw, 2.5rem) 2rem;
    background: var(--bg);
    border-bottom: 1px solid var(--border);
    box-shadow: var(--elev-dropdown, 0 18px 50px rgb(0 0 0 / 0.35));
  }
  .siteheader[data-open='true'] .mainnav { display: block; }
  .mainnav > ul { flex-direction: column; align-items: stretch; gap: 0.15rem; }
  .mainnav > ul > li > a, .navtrigger { width: 100%; justify-content: space-between; padding: 0.8rem 0; font-size: var(--site-body); }
  /* In the drawer the panel is inline disclosure content, not a dropdown. The
     surface styling now lives on .megagrid (see the dead-zone note above), so it
     is .megagrid that has to be flattened here — resetting .megapanel alone would
     leave a floating card inside the drawer. */
  .megapanel {
    position: static;
    transform: none;
    min-width: 0;
    padding: 0.25rem 0 0.75rem 0;
  }
  .megagrid {
    flex-direction: column;
    gap: 1.25rem;
    padding: 0.25rem 0 0.25rem 0.9rem;
    background: transparent;
    border: 0;
    border-left: 2px solid var(--border);
    border-radius: 0;
    box-shadow: none;
  }
  .navactions .btn-hide-mobile { display: none; }
  /* The switcher stays on mobile — it is the demo control — but drops to
     icon-only so the header still fits a phone. */
  #brandswitch-label { display: none; }
  .brandswitch-menu { min-width: 190px; }
}

@media (max-width: 640px) {
  .grid-2, .grid-3, .grid-4, .doors { grid-template-columns: 1fr; }
  .formgrid { grid-template-columns: 1fr; }
  .stats { grid-template-columns: 1fr 1fr; }
  .footer-top { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .faq .faq-a { padding-right: 0; }
  .utilitybar .wrap { gap: 0.75rem; }
  .utilitybar nav { gap: 0.9rem; }
}

/* ══════════════════════════════════════════════════════════════════════════
   16. Print — a policyholder printing a claims or billing page
   ══════════════════════════════════════════════════════════════════════════ */
@media print {
  .alertbar, .utilitybar, .siteheader, .sitefooter, .brandswitch, .skip-link { display: none !important; }
  body.site { background: #fff; color: #000; }
  .band { padding-block: 1rem; }
}
