/* ==========================================================================
   Components
   ========================================================================== */

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */
.c-btn {
  --btn-bg: var(--accent);
  --btn-ink: var(--accent-ink);
  --btn-edge: transparent;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  /* 48px minimum on both axes at the base scale. Touch target, not a hint. */
  min-height: 3rem;
  padding: var(--space-2xs) var(--space-m);
  background: var(--btn-bg);
  color: var(--btn-ink);
  border: 2px solid var(--btn-edge);
  border-radius: var(--radius-s);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--step-0);
  letter-spacing: 0.01em;
  text-decoration: none;
  cursor: pointer;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}

/* The leaning wipe. A skewed pseudo-element sweeps across on hover, echoing
   the wordmark's slant rather than fading a flat colour.
 *
 * It runs on the outlined variants only, where it is a real transformation
 * from transparent to a solid fill. On the solid primary button it was
 * sweeping a much darker blue across an already-blue surface, which read as
 * the button dimming rather than responding. A solid button lifts instead. */
.c-btn--ghost::before,
.c-btn--onDark::before {
  content: "";
  position: absolute;
  inset: -2px -30% -2px -30%;
  transform: skewX(var(--lean)) translateX(-115%);
  transition: transform var(--dur-base) var(--ease-out);
  z-index: -1;
}
.c-btn--ghost:hover::before, .c-btn--ghost:focus-visible::before,
.c-btn--onDark:hover::before, .c-btn--onDark:focus-visible::before {
  transform: skewX(var(--lean)) translateX(0);
}

/* Solid primary hover.
 *
 * Scoped away from the outlined variants. `.c-btn:hover` also matched them,
 * so a ghost button was getting a blue background from here AND the navy
 * sweep from its own rule at the same time, which is what made the rollover
 * look broken.
 *
 * The colour shift is deliberately small: white text needs 4.5:1, and
 * anything brighter than #0A72D0 (4.85:1) drops below it. So the feedback is
 * carried by a physical lift instead of by colour, which costs no contrast. */
/* Restore the button's own ink at every interactive state.
 *
 * base.css carries a global `a:hover { color: var(--accent-hover) }` for body
 * links. Its specificity is (0,1,1); `.c-btn`'s own `color: var(--btn-ink)` is
 * (0,1,0), so the link rule wins and any anchor styled as a button turns its
 * label dark blue on hover, on a blue background. The header call to action did
 * exactly that.
 *
 * `.c-btn:hover` is (0,2,0) and beats (0,1,1), so this puts the token back in
 * charge without touching the global rule that body links rely on. It covers
 * focus and active too, which fail the same way for the same reason. */
.c-btn:hover,
.c-btn:focus-visible,
.c-btn:active { color: var(--btn-ink); }

.c-btn:not(.c-btn--ghost):not(.c-btn--onDark):hover,
.c-btn:not(.c-btn--ghost):not(.c-btn--onDark):focus-visible {
  --btn-bg: #0A72D0;
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgb(10 110 203 / 0.34);
}
.c-btn:active {
  transform: translateY(1px);
  box-shadow: none;
}
.c-btn:not(.c-btn--ghost):not(.c-btn--onDark):active { --btn-bg: var(--accent-hover); }

@media (prefers-reduced-motion: reduce) {
  .c-btn:hover, .c-btn:active { transform: none; }
}

.c-btn--ghost {
  --btn-bg: transparent;
  --btn-ink: var(--ink-strong);
  --btn-edge: var(--rule-strong);
}
.c-btn--ghost::before { background: var(--navy-800); }
.c-btn--ghost:hover { --btn-ink: #FFFFFF; --btn-edge: var(--navy-800); }

.c-btn--onDark {
  --btn-bg: transparent;
  --btn-ink: #FFFFFF;
  --btn-edge: rgb(255 255 255 / 0.45);
}
.c-btn--onDark::before { background: #FFFFFF; }
.c-btn--onDark:hover { --btn-ink: var(--navy-900); --btn-edge: #FFFFFF; }

.c-btn--wide { width: 100%; }

/* --------------------------------------------------------------------------
   Kickers and eyebrow labels
   -------------------------------------------------------------------------- */
.c-kicker {
  display: inline-flex;
  align-items: center;
  /* An inline-flex row will not wrap by default, so a long label plus the
     leading rule can exceed a narrow viewport once the text scale is raised.
     Wrapping and a width cap keep it inside the column. */
  flex-wrap: wrap;
  max-width: 100%;
  gap: var(--space-2xs);
  font-family: var(--font-display);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: var(--tracking-kicker);
  text-transform: uppercase;
  color: var(--ink-muted);
}
.c-kicker::before {
  content: "";
  width: 1.75rem;
  height: 2px;
  background: var(--brand-azure);
  transform: skewX(var(--lean));
  flex: none;
}
/* The kicker's default muted grey is tuned for the light page. On any dark
   surface it drops to about 3.4:1, so every dark context has to restate it.
   The hero and the mega menu feature panel are dark but are not
   .l-section--inverse, which is exactly how this was missed by eye. */
:is(.l-section--inverse, .c-hero, .c-megamenu__feature, .c-footer) .c-kicker {
  color: var(--ink-invert-muted);
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */
.c-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: color-mix(in oklab, var(--paper) 88%, transparent);
  backdrop-filter: saturate(1.6) blur(14px);
  border-bottom: 1px solid var(--rule);
  /* A soft drop shadow the bar carries at rest, so the white header reads as a
     layer lifted above the page instead of a flat band. It deepens on scroll
     (below) once there is content sliding under it. */
  box-shadow: 0 4px 16px -8px rgb(3 22 59 / 0.14);
  transition: box-shadow var(--dur-base) var(--ease-out),
              background var(--dur-base) var(--ease-out);
}
.c-header[data-scrolled="true"] { box-shadow: 0 8px 24px -8px rgb(3 22 59 / 0.20); }

@supports not (backdrop-filter: blur(1px)) {
  .c-header { background: var(--paper); }
}

.c-header__bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-m);
  padding-inline: var(--gutter);
  padding-block: var(--space-2xs);
  /* A fixed rem base, NOT var(--header-h). app.js publishes --header-h from this
     bar's own measured height, so feeding it back into the bar's min-height made
     a loop: each resize added the bar's padding on top of the last value and the
     header ratcheted taller until it swallowed the page. rem still scales with
     the text-size preference, which was the reason the variable was used here. */
  min-height: 4.75rem;
}

.c-header__logo { flex: 0 1 auto; display: block; min-width: 0; }

/* Sized against the viewport, not the root font.
 *
 * A rem-based logo width scales with the text-size preference, and at 200% a
 * 9rem minimum becomes 288px, which alone overflows a 320px viewport and
 * breaks WCAG 1.4.10 reflow. The logo is a graphic, not text: it should track
 * the viewport and honour the text preference only through the surrounding
 * layout. The vw term wins on narrow screens, the px term caps it on wide ones. */
.c-header__logo img { width: min(216px, 42vw); height: auto; }

.c-header__actions {
  margin-inline-start: auto;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  min-width: 0;
}

/* --------------------------------------------------------------------------
   Mega menu

   Behaviour lives in megamenu.js: open on hover after a delay, open
   immediately on click or Enter, close on Escape, and trap nothing (a menu
   that traps focus is a menu that strands keyboard users).
   -------------------------------------------------------------------------- */
/* The nav claims the whole space between the logo and the header actions and
   centres itself in it, rather than sitting flush against the logo. flex: 1
   makes it take the remaining room; min-width: 0 keeps it from refusing to
   shrink below its content and pushing the actions off the bar. */
.c-nav {
  display: flex;
  align-items: stretch;
  justify-content: center;
  flex: 1 1 auto;
  min-width: 0;
  gap: var(--space-3xs);
}

/* Panels are positioned against the header, not against their own trigger.
 *
 * Centring each panel on its trigger means the rightmost one hangs past the
 * viewport, and because a closed panel is only visibility:hidden it still
 * widens the document. That produced horizontal overflow on pages where no
 * menu was ever opened. A JS nudge could pull each one back, but it has to run
 * on every resize and it fails silently if it does not. Anchoring to the
 * header and capping the width makes the overflow structurally impossible
 * instead of merely corrected. */
.c-nav__item { position: static; display: flex; }

.c-nav__trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0 var(--space-s);
  /* Fixed rem, not var(--header-h): same feedback loop as .c-header__bar. The
     trigger sits inside the bar whose height feeds --header-h, so sizing it from
     --header-h compounded the header taller on every resize. */
  min-height: 4.75rem;
  background: none;
  border: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--step-0);
  color: var(--ink-strong);
  cursor: pointer;
  text-decoration: none;
  position: relative;
}

/* The active underline leans, and it grows from the left rather than fading. */
.c-nav__trigger::after {
  content: "";
  position: absolute;
  inset-inline: var(--space-s);
  bottom: 1.1rem;
  height: 2px;
  background: var(--accent);
  transform: skewX(var(--lean)) scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-base) var(--ease-out);
}
.c-nav__trigger:hover::after,
.c-nav__trigger[aria-expanded="true"]::after,
.c-nav__item[data-current="true"] .c-nav__trigger::after {
  transform: skewX(var(--lean)) scaleX(1);
}

.c-nav__chevron {
  width: 0.6rem; height: 0.6rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
  transition: transform var(--dur-base) var(--ease-out);
}
.c-nav__trigger[aria-expanded="true"] .c-nav__chevron { transform: rotate(225deg) translateY(-2px); }

/* A full-width drawer, flush under the header.
 *
 * The panel used to be a 64rem box centred on the page and floated half a rem
 * below the bar. It lined up with neither the trigger you hovered nor the header
 * above it, so it read as a card that had come loose. A full-width drawer
 * anchored to the header's bottom edge is the professional pattern: whichever
 * item is opened, the surface is the same and it plainly belongs to the header.
 * The content inside is constrained and aligned to the site container, so the
 * columns sit under the nav rather than drifting. */
.c-megamenu {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: var(--z-megamenu);
  /* Dark, so it pops off the white header instead of blending into it. A tinted
     navy with a faint azure top hairline reads as a deliberate surface rather
     than a dropped white box. */
  background:
    linear-gradient(180deg, color-mix(in oklab, var(--azure-500) 10%, var(--navy-900)) 0%, var(--navy-900) 34%);
  color: var(--ink-invert);
  border-bottom: 1px solid var(--navy-700);
  box-shadow: 0 24px 48px rgb(0 8 31 / 0.45);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(-0.5rem);
  transition:
    opacity var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out),
    visibility 0s linear var(--dur-base);
}

.c-nav__item.is-open .c-megamenu {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0);
  transition-delay: 0s;
}

/* The content: constrained to the site container, aligned to it, no card
   styling of its own because the drawer above is now the surface. */
.c-megamenu__panel {
  max-width: 78rem;
  margin-inline: auto;
  padding: var(--space-l) var(--gutter);
  display: grid;
  gap: var(--space-l);
}

@media (min-width: 64em) {
  /* The feature sits in its own track on the right, so the panel is a
     composition rather than a list of links in a box. */
  .c-megamenu__panel { grid-template-columns: minmax(0, 1.9fr) minmax(0, 1fr); gap: var(--space-2xl); }
}

/* A panel with no feature keeps its content tight and left-aligned rather than
   stretched the full width of the bar. */
.c-megamenu--simple .c-megamenu__panel { grid-template-columns: minmax(0, 1fr); max-width: 60rem; }

.c-megamenu__body { padding: 0; }

.c-megamenu__intro {
  font-size: var(--step--1);
  color: var(--ink-muted);
  max-width: 52ch;
  margin-bottom: var(--space-m);
}

.c-megamenu__columns {
  display: grid;
  gap: var(--space-m) var(--space-l);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
}

/* One row, always, however many columns the panel happens to hold.

   auto-fit sized the tracks from an 11rem floor, and the body column is not
   wide enough for three of those, so a third column wrapped onto a second row
   on its own and left a third of the row empty. The panel's column count is
   whatever the config declares minus any dynamic column with no data, so it
   varies between two and four and no fixed track count is right for all of
   them. Flowing by column makes the row divide by the number actually
   rendered, which cannot be ragged. */
@media (min-width: 48em) {
  .c-megamenu__columns {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
  }
}

/* Sponsored slot in the mega menu. */
.c-mmsponsor__tag {
  display: inline-block;
  margin-inline-start: 0.4em;
  padding: 0.05rem 0.35rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  /* The heading is uppercased; this must not inherit that and shout. */
  text-transform: none;
}

.c-mmsponsor__offer {
  display: block;
  margin-top: var(--space-2xs);
  border: 1px dashed var(--rule-strong);
  border-radius: var(--radius-m);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: border-color var(--dur-fast) var(--ease-out);
}
.c-mmsponsor__offer:hover,
.c-mmsponsor__offer:focus-visible { border-color: var(--accent); border-style: solid; }

.c-mmsponsor__offer img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.c-mmsponsor__offerbody {
  display: block;
  padding: var(--space-2xs) var(--space-xs) var(--space-xs);
  font-size: var(--step--1);
  line-height: 1.35;
}
.c-mmsponsor__offerbody strong { display: block; color: var(--ink-strong); }
.c-mmsponsor__offerbody span { color: var(--ink-muted); font-size: 0.78rem; }

/* Column heading, anchored by a filled icon circle in the deck's key style. The
   circle turns a list header into a thing with weight, which is the difference
   between a tidy menu and one that looks designed. */
.c-megamenu__heading {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  min-height: 2rem;
  font-size: var(--step--1);
  letter-spacing: var(--tracking-kicker);
  text-transform: uppercase;
  color: var(--azure-300);
  margin-bottom: var(--space-s);
}

/* Smaller icon, and now it glows against the dark surface rather than sitting
   as a heavy blue disc on white. */
.c-megamenu__ico {
  flex: 0 0 auto;
  width: 2rem;
  height: 2rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: color-mix(in oklab, var(--azure-500) 22%, transparent);
  border: 1px solid color-mix(in oklab, var(--azure-400) 55%, transparent);
  color: var(--azure-300);
}
.c-megamenu__ico svg { width: 1.05rem; height: 1.05rem; }

/* The heading text can still wrap without pushing its list out of line, because
   the row height is fixed to the icon. */
.c-megamenu__htext { line-height: 1.15; }

.c-megamenu__list { list-style: none; margin: 0; padding: 0; }

.c-megamenu__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2xs);
  padding-block: 0.4rem;
  /* Near-white on the dark surface, at a real weight, so a column of price
     bands is comfortably legible rather than faint grey on grey. */
  color: var(--ink-invert);
  font-weight: 500;
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-out);
}
/* Hover brightens the row to azure and slides the chevron in. */
.c-megamenu__link:hover { color: var(--azure-300); }
/* A chevron that arrives on hover, so the resting state stays calm and the
   hovered row clearly says "go". */
.c-megamenu__link > span:first-child { position: relative; }
.c-megamenu__link > span:first-child::after {
  content: "\2192";
  margin-inline-start: 0.4rem;
  opacity: 0;
  transform: translateX(-0.2rem);
  display: inline-block;
  transition: opacity var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.c-megamenu__link:hover > span:first-child::after {
  opacity: 1;
  transform: translateX(0);
}
.c-megamenu__count {
  font-family: var(--font-mono);
  font-size: 0.75em;
  color: var(--azure-300);
  font-variant-numeric: tabular-nums;
}

/* High contrast: the menu hardcodes navy, so force a solid black surface with
   pure-white text and outlines, which clears 7:1 everywhere and does not depend
   on the tinted tokens the dark theme uses. */
html[data-contrast="high"] .c-megamenu {
  background: #000000;
  border-bottom: 2px solid #FFFFFF;
}
html[data-contrast="high"] :is(.c-megamenu__link, .c-megamenu__heading, .c-megamenu__count) { color: #FFFFFF; }
html[data-contrast="high"] .c-megamenu__ico {
  background: transparent;
  border-color: #FFFFFF;
  color: #FFFFFF;
}
html[data-contrast="high"] .c-megamenu__feature {
  background: #000000;
  border: 2px solid #FFFFFF;
}
html[data-contrast="high"] .c-megamenu__link:hover { color: var(--azure-300); text-decoration: underline; }

/* Rich media panel. */
.c-megamenu__feature {
  padding: var(--space-m);
  /* An azure-lit card so the promo pops off the dark menu instead of blending
     into it: a diagonal glow and a bright hairline border make it the one thing
     in the panel that reads as a surface with light on it. */
  background:
    radial-gradient(120% 90% at 100% 0%, color-mix(in oklab, var(--azure-500) 34%, transparent) 0%, transparent 55%),
    var(--navy-700);
  color: var(--ink-invert);
  border: 1px solid color-mix(in oklab, var(--azure-400) 45%, transparent);
  border-radius: var(--radius-l);
  box-shadow: 0 14px 34px rgb(0 8 31 / 0.5);
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  position: relative;
  overflow: hidden;
}
/* Rotor-arc motif, drawn in CSS so it costs no request. */
.c-megamenu__feature::after {
  content: "";
  position: absolute;
  width: 22rem; height: 22rem;
  right: -9rem; bottom: -12rem;
  border: 1px solid rgb(255 255 255 / 0.14);
  border-top-color: var(--azure-500);
  border-radius: 50%;
  transform: rotate(-24deg);
  pointer-events: none;
}
.c-megamenu__feature h3 { color: #FFFFFF; font-size: var(--step-1); }
.c-megamenu__feature p { color: var(--ink-invert-muted); font-size: var(--step--1); }
.c-megamenu__feature > a { color: #FFFFFF; font-weight: 700; text-decoration: none; margin-top: auto; }
.c-megamenu__feature > a::after { content: " \2192"; }
.c-megamenu__feature > a:hover { text-decoration: underline; }

/* --------------------------------------------------------------------------
   Sponsored placement, in the feature panel.

   The paid slot lives in the prominent dark panel now, not a card under the
   nav. Live sponsors render as brand rows; the slots nobody has bought render
   as an invitation. Everything sits above the rotor-arc motif on the navy.
   -------------------------------------------------------------------------- */
.c-mmfeat--sponsor { gap: var(--space-xs); }

.c-mmfeat--sponsor h3 {
  font-size: var(--step-1);
  line-height: var(--leading-snug);
  max-width: 22ch;
}

/* The Sponsored label. Quiet by design: it is a disclosure, not a shout, but it
   is always present because the promise is that paid position is always marked. */
.c-mmfeat__tag {
  display: inline-block;
  margin-inline-start: 0.5em;
  padding: 0.05rem 0.4rem;
  border: 1px solid rgb(255 255 255 / 0.28);
  border-radius: 999px;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: none;
  color: var(--ink-invert-muted);
}

.c-mmfeat__slots {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}

/* A sponsor row: logo tile plus name, as a card that lifts on hover. The
   translucent surface keeps it legible over the navy and the arc behind it. */
.c-mmfeat__brand,
.c-mmfeat__open {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-2xs);
  border-radius: var(--radius-s);
  text-decoration: none;
  color: var(--ink-invert);
  background: rgb(255 255 255 / 0.06);
  border: 1px solid rgb(255 255 255 / 0.10);
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.c-mmfeat__brand:hover,
.c-mmfeat__brand:focus-visible,
.c-mmfeat__open:hover,
.c-mmfeat__open:focus-visible {
  background: rgb(255 255 255 / 0.12);
  border-color: var(--azure-400);
  transform: translateX(2px);
}

.c-mmfeat__logo {
  flex: 0 0 auto;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-xs);
  object-fit: contain;
  background: #FFFFFF;
}

/* No-logo fallback: the brand's initial on an azure tile, so a sponsor without
   artwork still reads as a brand rather than a blank square. */
.c-mmfeat__logo--mark {
  display: inline-grid;
  place-items: center;
  background: var(--azure-500);
  color: #FFFFFF;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--step-0);
}

.c-mmfeat__brandname { font-weight: 600; }

/* The open-slot invitation. Dashed, so it reads as a placeholder rather than a
   live sponsor, and carries a + to say the slot is fillable. */
.c-mmfeat__open {
  background: transparent;
  border-style: dashed;
  border-color: rgb(255 255 255 / 0.28);
}
.c-mmfeat__openmark {
  flex: 0 0 auto;
  width: 2.25rem;
  height: 2.25rem;
  display: inline-grid;
  place-items: center;
  border-radius: var(--radius-xs);
  border: 1px dashed rgb(255 255 255 / 0.4);
  font-size: var(--step-1);
  line-height: 1;
  color: var(--azure-300);
}
.c-mmfeat__open strong { display: block; color: #FFFFFF; font-size: var(--step--1); }
.c-mmfeat__open span span,
.c-mmfeat__open > span > span { color: var(--ink-invert-muted); font-size: 0.78rem; }

.c-mmfeat__cta {
  margin-top: auto;
  color: #FFFFFF;
  font-weight: 700;
  text-decoration: none;
}
.c-mmfeat__cta::after { content: " \2192"; }
.c-mmfeat__cta:hover { text-decoration: underline; }

/* --------------------------------------------------------------------------
   Language switch (Google Translate)

   The stock widget renders an unstyled select and a banner frame. We hide the
   vendor UI entirely and drive it from our own accessible listbox, reading and
   writing the googtrans cookie. See docs/TRANSLATION.md for the caveats.
   -------------------------------------------------------------------------- */
.c-lang { position: relative; }

.c-lang__toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 2.75rem;
  padding: 0 var(--space-xs);
  background: transparent;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  font-size: var(--step--1);
  font-weight: 700;
  color: var(--ink-strong);
  cursor: pointer;
  transition: border-color var(--dur-fast), background var(--dur-fast);
}
.c-lang__toggle:hover { border-color: var(--accent); background: color-mix(in oklab, var(--accent) 8%, transparent); }
.c-lang__code { font-family: var(--font-mono); text-transform: uppercase; letter-spacing: 0.06em; }

.c-lang__menu {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  min-width: 13rem;
  max-height: 20rem;
  overflow-y: auto;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-mid);
  padding: var(--space-3xs);
  margin: 0;
  list-style: none;
  z-index: var(--z-megamenu);
}
.c-lang__menu[hidden] { display: none; }

.c-lang__option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
  width: 100%;
  min-height: 2.75rem;
  padding: 0 var(--space-xs);
  background: none;
  border: 0;
  border-radius: var(--radius-s);
  text-align: left;
  cursor: pointer;
  color: var(--ink-body);
}
.c-lang__option:hover { background: var(--bg-sunken); }
.c-lang__option[aria-selected="true"] { color: var(--accent); font-weight: 700; }
.c-lang__option[aria-selected="true"]::after { content: "\2713"; }

/* Suppress every part of the vendor chrome. The toolbar iframe shifts the
   whole document down by 40px if left alone. */
.skiptranslate iframe,
.goog-te-banner-frame,
.goog-te-gadget { display: none !important; }
body { top: 0 !important; position: static !important; }
.goog-text-highlight { background: none !important; box-shadow: none !important; }

/* --------------------------------------------------------------------------
   Mobile drawer
   -------------------------------------------------------------------------- */
/* The menu control is a sibling of the EN language pill and now matches it: a
   round, transparent button with the same border, so the two read as one set
   of controls rather than a pill next to a heavy box.
   Its visibility comes from bold bars, not from its own fill. The bars are
   navy-900 at 2.5px, the weight of the "EN" glyph beside them, so they carry on
   the white header the way that text does. The earlier failure was thin 2px
   bars in a medium-grey outline: the control was there but read as empty. */
.c-burger {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 2.75rem; height: 2.75rem;
  padding: 0;
  background: transparent;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  cursor: pointer;
  transition: border-color var(--dur-fast), background var(--dur-fast);
}
.c-burger span {
  display: block;
  width: 1.15rem;
  height: 2.5px;
  border-radius: 2px;
  background: var(--ink-strong);
  transform-origin: center;
  transition: transform var(--dur-base) var(--ease-out), opacity var(--dur-fast);
}
.c-burger:hover, .c-burger:focus-visible {
  border-color: var(--ink-strong);
  background: color-mix(in oklab, var(--navy-900) 6%, transparent);
}
/* In forced-colors the author colours are discarded, so the bars have to be
   told to follow the system text colour or the button renders empty. */
@media (forced-colors: active) {
  .c-burger span { background: ButtonText; }
}
.c-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7.5px) rotate(45deg); }
.c-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.c-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg); }

.c-drawer {
  position: fixed;
  inset: var(--header-h, 76px) 0 0 0;
  z-index: var(--z-drawer);
  background: var(--paper);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--space-m) var(--gutter) calc(var(--dock-h, 68px) + env(safe-area-inset-bottom, 0px) + var(--space-xl));
  transform: translateX(100%);
  visibility: hidden;
  transition: transform var(--dur-base) var(--ease-out), visibility 0s linear var(--dur-base);
}
.c-drawer.is-open { transform: none; visibility: visible; transition-delay: 0s; }

.c-drawer__section + .c-drawer__section { margin-top: var(--space-s); border-top: 1px solid var(--rule); padding-top: var(--space-s); }

.c-drawer__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 3.25rem;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 800;
  color: var(--ink-strong);
  cursor: pointer;
  list-style: none;
}
.c-drawer__summary::-webkit-details-marker { display: none; }
.c-drawer__summary::after {
  content: "";
  width: 0.6rem; height: 0.6rem;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(45deg);
  transition: transform var(--dur-base) var(--ease-out);
}
details[open] > .c-drawer__summary::after { transform: rotate(225deg); }

.c-drawer__link {
  display: block;
  min-height: 3rem;
  padding: 0.7rem 0;
  color: var(--ink-body);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
}

/* --------------------------------------------------------------------------
   Mobile dock

   Fixed to the bottom of the viewport, sitting above the home indicator via
   the safe-area inset. This is the primary action surface on a handset.
   -------------------------------------------------------------------------- */
.c-dock {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: var(--z-dock);
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  align-items: stretch;
  background: color-mix(in oklab, var(--paper) 92%, transparent);
  backdrop-filter: saturate(1.8) blur(18px);
  border-top: 1px solid var(--rule);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  padding-inline: max(env(safe-area-inset-left, 0px), 0px) max(env(safe-area-inset-right, 0px), 0px);
  /* Slides away on downward scroll to return reading space, returns on any
     upward scroll. Handled in app.js. */
  transform: translateY(0);
  transition: transform var(--dur-base) var(--ease-out);
}
.c-dock[data-hidden="true"] { transform: translateY(calc(100% + env(safe-area-inset-bottom, 0px))); }

@supports not (backdrop-filter: blur(1px)) {
  .c-dock { background: var(--paper); }
}

@media (min-width: 64em) { .c-dock { display: none; } }

.c-dock__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-height: var(--dock-h, 68px);
  padding: 0.4rem 0.25rem;
  color: var(--ink-muted);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-decoration: none;
  position: relative;
  -webkit-tap-highlight-color: transparent;
}
.c-dock__item svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 1.7; }
.c-dock__item[aria-current="page"] { color: var(--accent); }
.c-dock__item[aria-current="page"]::before {
  content: "";
  position: absolute;
  top: 0;
  width: 30%;
  height: 3px;
  background: var(--accent);
  transform: skewX(var(--lean));
}
.c-dock__item:active { background: color-mix(in oklab, var(--accent) 10%, transparent); }

/* The primary action is raised out of the bar. */
.c-dock__item--primary { color: var(--accent); }
.c-dock__item--primary svg { stroke-width: 2.1; }

/* --------------------------------------------------------------------------
   Accessibility panel
   -------------------------------------------------------------------------- */
.c-a11y__launch {
  position: fixed;
  right: var(--space-s);
  bottom: calc(var(--dock-h, 68px) + env(safe-area-inset-bottom, 0px) + var(--space-s));
  z-index: var(--z-a11y);
  width: 3.25rem; height: 3.25rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 2px solid var(--paper);
  background: var(--navy-800);
  color: #FFFFFF;
  box-shadow: var(--shadow-mid);
  cursor: pointer;
}
@media (min-width: 64em) {
  .c-a11y__launch { bottom: var(--space-l); }
}
.c-a11y__launch:hover { background: var(--azure-600); }
.c-a11y__launch svg { width: 26px; height: 26px; }

.c-a11y__panel {
  position: fixed;
  right: var(--space-s);
  bottom: calc(var(--dock-h, 68px) + env(safe-area-inset-bottom, 0px) + var(--space-s) + 4rem);
  z-index: var(--z-a11y);
  width: min(22rem, calc(100vw - var(--space-s) * 2));
  max-height: min(34rem, calc(100dvh - 10rem));
  overflow-y: auto;
  background: var(--paper);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-m);
  box-shadow: var(--shadow-high);
  padding: var(--space-s);
}
@media (min-width: 64em) {
  .c-a11y__panel { bottom: calc(var(--space-l) + 4rem); }
}
.c-a11y__panel[hidden] { display: none; }

.c-a11y__group + .c-a11y__group { margin-top: var(--space-s); padding-top: var(--space-s); border-top: 1px solid var(--rule); }
.c-a11y__legend {
  font-family: var(--font-display);
  font-size: var(--step--1);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: var(--tracking-kicker);
  color: var(--ink-muted);
  margin-bottom: var(--space-2xs);
  padding: 0;
}

.c-a11y__options { display: flex; flex-wrap: wrap; gap: var(--space-3xs); }

.c-a11y__opt {
  flex: 1 1 auto;
  min-height: 2.75rem;
  padding: 0.4rem var(--space-2xs);
  background: var(--bg-sunken);
  border: 2px solid transparent;
  border-radius: var(--radius-s);
  font-size: var(--step--1);
  font-weight: 600;
  cursor: pointer;
  color: var(--ink-body);
}
.c-a11y__opt:hover { border-color: var(--rule-strong); }
.c-a11y__opt[aria-pressed="true"],
.c-a11y__opt[aria-checked="true"] {
  background: var(--navy-800);
  border-color: var(--navy-800);
  color: #FFFFFF;
}

.c-a11y__reset {
  margin-top: var(--space-s);
  width: 100%;
  min-height: 2.75rem;
  background: none;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-s);
  cursor: pointer;
  font-weight: 700;
}

.c-a11y__note {
  margin-top: var(--space-2xs);
  font-size: 0.78rem;
  color: var(--ink-muted);
  line-height: 1.45;
}

/* --------------------------------------------------------------------------
   Cards
   -------------------------------------------------------------------------- */
/* Equal height across a row, with the meta line pinned to the bottom, so two
   cards with different amounts of text still end level. */
.c-card {
  height: 100%;
  display: flex;
  flex-direction: column;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius-m);
  overflow: hidden;
  position: relative;
  transition: transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}
.c-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-mid); border-color: var(--silver-400); }

.c-card__media {
  aspect-ratio: 16 / 10;
  background: var(--bg-sunken);
  overflow: hidden;
  position: relative;
}
.c-card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur-slow) var(--ease-out); }
.c-card:hover .c-card__media img { transform: scale(1.04); }

.c-card__body { padding: var(--space-s); display: flex; flex-direction: column; gap: var(--space-2xs); flex: 1; }

.c-card__title { font-size: var(--step-1); line-height: 1.2; }
/* The whole card is clickable, but only the title is a link, so the
   accessible name stays meaningful and the DOM has one link per card. */
.c-card__title a { color: inherit; text-decoration: none; }
.c-card__title a::after { content: ""; position: absolute; inset: 0; }
.c-card__title a:hover { color: var(--accent); }

.c-card__meta {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.75rem;
}

.c-card__price {
  margin-top: auto;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 800;
  color: var(--ink-strong);
  font-variant-numeric: tabular-nums;
}
.c-card__price small { display: block; font-size: 0.7rem; font-weight: 500; color: var(--ink-muted); letter-spacing: 0.02em; }

/* Status flags. Colour is never the only signal; each carries a word. */
.c-flag {
  position: absolute;
  top: var(--space-2xs);
  left: var(--space-2xs);
  z-index: 2;
  padding: 0.25rem 0.6rem;
  font-family: var(--font-display);
  font-size: 0.7rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #FFFFFF;
  background: var(--navy-800);
  transform: skewX(var(--lean));
  border-radius: var(--radius-xs);
}
.c-flag > span { display: block; transform: skewX(calc(var(--lean) * -1)); }
.c-flag--sold { background: var(--state-sold); }
.c-flag--new  { background: var(--state-live); }

.c-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.15rem 0.55rem;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--ink-muted);
}
.c-badge--verified { border-color: var(--state-live); color: var(--state-live); }

/* --------------------------------------------------------------------------
   Specification list

   The label/value row used on brand, listing and school pages. It wraps rather
   than forcing a minimum width, because at a large text scale a long label and
   a long value cannot share one line on a narrow screen, and refusing to wrap
   there is what pushes the page into horizontal scrolling.
   -------------------------------------------------------------------------- */
.c-specs { margin: 0; border-top: 1px solid var(--rule); }

.c-specs__row {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0 var(--space-s);
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--rule);
}
.c-specs__row dt { color: var(--ink-muted); font-size: var(--step--1); min-width: 0; }
.c-specs__row dd {
  margin: 0;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  min-width: 0;
  overflow-wrap: break-word;
}

.c-note { font-size: 0.78rem; color: var(--ink-muted); line-height: 1.5; }

/* --------------------------------------------------------------------------
   Brand list (inverse surface)
   -------------------------------------------------------------------------- */
.c-brandlist { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; background: var(--rule-invert); }
.c-brandlist > li { background: var(--navy-800); }

.c-brandlist__link {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3xs) var(--space-s);
  padding: var(--space-s);
  text-decoration: none;
  color: #FFFFFF;
  min-width: 0;
}
.c-brandlist__name {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--step-1);
  color: #FFFFFF;
  min-width: 0;
  overflow-wrap: break-word;
}
.c-brandlist__place { display: block; font-size: var(--step--1); color: var(--ink-invert-muted); }
.c-brandlist__count { font-family: var(--font-mono); font-size: var(--step--1); color: var(--azure-300); }
.c-brandlist__link:hover .c-brandlist__name { text-decoration: underline; }

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */
.c-hero {
  position: relative;
  background: var(--navy-900);
  color: var(--ink-invert);
  overflow: hidden;
  padding-block: var(--space-2xl) var(--space-xl);
}

/* --------------------------------------------------------------------------
   Photographic hero

   The scrim is not a decorative wash, it is what makes the headline legible.
   Measured from the source photograph: the band where the h1 and lede sit has
   a 95th-percentile luminance of 0.993, effectively white sky. White text over
   that unmodified is about 1:1, which is invisible.

   Solving the contrast equation for white text over a navy (#001235) scrim
   gives a minimum alpha of 0.60 to reach 4.5:1 against a pure white pixel.
   The gradient below holds 0.90 to 0.72 across the whole text column, so
   there is real margin rather than a value that only just passes.

   The brand blue deliberately does no darkening. Azure at 0.70 over white
   composites to roughly 1.9:1, so using it as the scrim would look on-brand
   and be unreadable. Navy carries contrast on the left where the text is;
   blue carries hue on the right where the aircraft is and no text sits.
   -------------------------------------------------------------------------- */
.c-hero--photo {
  /* Equal padding top and bottom, and the grid rows centred inside a stated
     minimum height, so the content block sits on the vertical midline rather
     than riding high with a deep gap beneath it. The min-height is what gives
     the centring something to centre within; without it the section is only as
     tall as its content and padding, and align-content has nothing to do. */
  /* A tall, cinematic video hero that fills the screen down to the fold. The
     content is vertically centred in the frame, so it stays in the first screen
     while the photograph and video have real presence around it. */
  padding-block: var(--space-2xl);
  align-content: center;
  min-height: clamp(34rem, 82vh, 54rem);

  /* Secondary text is lifted over a photograph.
   *
   * The flat-navy hero used #A9B7CB for the kicker, lede and stat labels, and
   * it clears 9:1 there. Over the scrimmed photograph it measures 3.1:1, and
   * deepening the scrim does not fix it: that grey sits close to the mid-tone
   * of the scrimmed image, so darkening the background drags it toward 1:1
   * before it improves. Contrast is a distance, not a direction. The colour is
   * what has to move. #E6EBF2 measures 5.05:1 at the worst sampled point, a
   * 12% margin over the 4.5 minimum, and still reads as secondary against the
   * white headline. */
  --ink-invert-muted: #E6EBF2;
}

/* Section landing heroes are shorter than the homepage: they introduce a page
   rather than carrying it, and a full-height photo above a directory listing
   pushes the actual content off the fold. */
.c-hero--section {
  /* Taller and cinematic, to match the homepage hero and the deck. The old
     20–27rem band read as a thin banner; every secondary page now opens on a
     photograph with real presence. Content is centred in the taller frame. */
  min-height: clamp(26rem, 58vh, 40rem);
  padding-block: var(--space-2xl);
  align-content: center;
}

.c-hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  /* An absolutely positioned child of a grid container is contained by its
     grid area, not by the padding box. Because .l-canvas assigns every child
     grid-column: main, inset:0 would resolve to the centre column and leave
     the gutters bare. Claiming the full track restores true full bleed. */
  grid-column: full;
}

/* <picture> is a plain inline-ish wrapper and the global reset gives it
   height:auto. A percentage height on the img inside it therefore has no
   definite parent to resolve against and silently falls back to the intrinsic
   aspect ratio, which is why the photograph rendered at its own proportions
   instead of filling the hero. The wrapper has to carry the box. */
.c-hero__media picture {
  display: block;
  width: 100%;
  height: 100%;
}

.c-hero__media img {
  width: 100%;
  height: 100%;
  /* The global reset caps every image at max-width:100%, which clamps the
     deliberate over-size below back to the container width. */
  max-width: none;
  object-fit: cover;
  object-position: 58% 56%;
}

/* Background hero video, layered over the still photo. Covers the same box as
   the image. Hidden on small screens (mobile data) and for reduced-motion, where
   the photograph beneath shows through unchanged. */
.c-hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 56% 52%;
}
@media (max-width: 47.99em) {
  .c-hero__video { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .c-hero__video { display: none; }
}

/* Moving the subject out from behind the headline.
 *
 * The hero is wider in aspect than the source photograph, so cover crops top
 * and bottom only and object-position's horizontal value does nothing at
 * desktop width. The aircraft sits at about 53% of the frame, directly under
 * the second line of the h1.
 *
 * Over-sizing the image and anchoring it left shifts the subject right without
 * throwing away resolution or re-cropping the file: at 128% width the visible
 * window is the left 78% of the photograph, which puts the aircraft near 68%
 * of the viewport, clear of a headline that ends around 57%. The overflow is
 * clipped by the hero. */
@media (min-width: 64em) {
  .c-hero__media img {
    width: 128%;
    /* 62% rather than centre: the uncropped source is a taller frame than the
       pre-cropped file it replaced, so a centred crop sits in empty upper sky
       and loses the sun and horizon entirely. Dropping the window brings the
       warm band back and, measured, also improves the contrast margin on the
       figures row from x1.29 to x1.43. */
    object-position: 50% 62%;
  }
}

.c-hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  grid-column: full;
  background:
    /* Horizontal scrim. Navy and heavy across the text column, thinning into
       a blue tint over the aircraft. */
    linear-gradient(
      100deg,
      rgb(0 18 53 / 0.94) 0%,
      rgb(0 18 53 / 0.88) 28%,
      rgb(0 18 53 / 0.78) 46%,
      /* The right-hand stops carry the live-figures row, which sits over the
         brightest sky in the frame. They are deeper than pure composition
         would want, because that row is where the measured margin was
         thinnest. */
      rgb(0 18 53 / 0.64) 60%,
      rgb(4 71 140 / 0.52) 78%,
      rgb(9 124 228 / 0.46) 100%
    ),
    /* Anchors the photograph to the section edges so it does not end in a hard
       line against the page below. Kept deliberately light: the horizon and
       treeline are the warmest part of the frame, and an aggressive bottom
       gradient flattens them into a blue band. */
    linear-gradient(to top, rgb(0 8 31 / 0.60) 0%, rgb(0 8 31 / 0) 26%),
    linear-gradient(to bottom, rgb(0 8 31 / 0.45) 0%, rgb(0 8 31 / 0) 22%);
}

/* Below the desktop breakpoint the text spans the full width, so the
   left-weighted gradient no longer covers it. The scrim becomes vertical and
   uniformly heavier: there is no longer a text-free side to protect. */
@media (max-width: 63.99em) {
  .c-hero__scrim {
    /* Uniform rather than left-weighted, because the text now spans the full
       width and there is no protected side left to trade against. Held around
       0.74, which clears the 4.5 minimum against the brightest sky in the
       frame while leaving the aircraft and the sunset actually visible. Pushed
       to 0.9 the type is no more readable and the photograph is gone. */
    background:
      linear-gradient(
        180deg,
        rgb(0 18 53 / 0.70) 0%,
        rgb(0 18 53 / 0.74) 40%,
        rgb(0 18 53 / 0.82) 100%
      ),
      linear-gradient(90deg, rgb(9 124 228 / 0.20) 0%, rgb(9 124 228 / 0.08) 100%);
  }
  /* Keeps the aircraft near the middle of a portrait crop instead of letting
     it drift behind the headline or off the frame entirely. */
  .c-hero__media img { object-position: 56% 48%; }
}

.c-hero--photo .c-hero__inner { position: relative; z-index: 2; }

/* The photograph already contains a rotor. Overlaying the CSS arcs on top of
   it reads as clutter rather than as a motif, so they are suppressed when a
   photograph is present. */
.c-hero--photo .c-hero__arcs { display: none; }

/* Layered rotor arcs. Pure CSS, no image request, and they scale with the
   viewport rather than pixelating. */
.c-hero__arcs { position: absolute; inset: 0; pointer-events: none; opacity: 0.5; }
.c-hero__arcs span {
  position: absolute;
  border-radius: 50%;
  border: 1px solid rgb(186 195 205 / 0.16);
  top: 50%; left: 62%;
  translate: -50% -50%;
}
.c-hero__arcs span:nth-child(1) { width: 44rem; height: 44rem; border-top-color: var(--brand-azure); }
.c-hero__arcs span:nth-child(2) { width: 62rem; height: 62rem; border-left-color: rgb(186 195 205 / 0.5); }
.c-hero__arcs span:nth-child(3) { width: 80rem; height: 80rem; }

@media (prefers-reduced-motion: no-preference) {
  .c-hero__arcs span { animation: gyro-spin 90s linear infinite; }
  .c-hero__arcs span:nth-child(2) { animation-duration: 140s; animation-direction: reverse; }
  .c-hero__arcs span:nth-child(3) { animation-duration: 220s; }
}
@keyframes gyro-spin {
  from { rotate: 0deg; }
  to   { rotate: 360deg; }
}

.c-hero__inner { position: relative; z-index: 1; }
.c-hero h1 { color: #FFFFFF; }
.c-hero__lede { font-size: var(--step-1); color: var(--ink-invert-muted); }

/* Live figures strip under the hero. */
.c-stats { display: flex; flex-wrap: wrap; gap: var(--space-l) var(--space-l); }
/* Each figure sits behind a brand accent rule, so the row reads as a set of
   distinct stats rather than three loose numbers. The first item drops the
   rule so the block does not open on a divider. */
.c-stats > div {
  padding-left: var(--space-m);
  border-left: 3px solid color-mix(in oklab, var(--azure-400) 65%, transparent);
}
.c-stats > div:first-child { padding-left: 0; border-left: 0; }
.c-stat__n {
  font-family: var(--font-display);
  font-size: var(--step-4);
  font-weight: 800;
  color: #FFFFFF;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  letter-spacing: -0.015em;
}
.c-stat__label {
  margin-top: var(--space-3xs);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.09em;
  font-weight: 600;
  color: var(--azure-300);
}

/* A counter that has not started yet. Same size as a real figure so the row
   stays level, azure so it reads as "coming", not as a hollow zero. */
.c-stat__n--soon { color: var(--azure-300); }

/* --------------------------------------------------------------------------
   Editorial
   -------------------------------------------------------------------------- */
.c-prose { font-size: var(--step-0); }
/* Body rhythm is space-m, not space-s: at space-s the paragraph gap was
   smaller than a single line of text, so breaks read as cramped and uneven.
   space-m sits clearly above the line box, giving one consistent gap between
   every block across every page and article layout. Headings keep their own
   larger top margins below. */
.c-prose > * + * { margin-top: var(--space-m); }
.c-prose h2 { font-size: var(--step-3); margin-top: var(--space-xl); }
.c-prose h3 { font-size: var(--step-2); margin-top: var(--space-l); }
.c-prose h4 { font-size: var(--step-1); margin-top: var(--space-m); }
.c-prose ul, .c-prose ol { padding-left: 1.35em; }
.c-prose li + li { margin-top: 0.4em; }

/* Structural disruption: the expert call-out. */
.c-callout {
  border-left: 4px solid var(--accent);
  padding: var(--space-s) var(--space-m);
  background: var(--bg-sunken);
  border-radius: 0 var(--radius-m) var(--radius-m) 0;
  font-size: var(--step-1);
  line-height: 1.4;
  color: var(--ink-strong);
}
.c-callout cite { display: block; margin-top: var(--space-2xs); font-size: var(--step--1); font-style: normal; color: var(--ink-muted); }

/* Structural disruption: the comparison table. Scrolls inside its own box so
   the page body never scrolls sideways. */
.c-tablewrap {
  overflow-x: auto;
  border: 1px solid var(--rule);
  border-radius: var(--radius-m);
}
.c-table { min-width: 34rem; font-size: var(--step--1); }
.c-table caption {
  caption-side: top;
  text-align: left;
  padding: var(--space-2xs) var(--space-s);
  font-weight: 700;
  color: var(--ink-muted);
  font-size: var(--step--1);
  border-bottom: 1px solid var(--rule);
}
.c-table th, .c-table td { padding: 0.7rem var(--space-s); text-align: left; border-bottom: 1px solid var(--rule); vertical-align: top; }
.c-table thead th { background: var(--bg-sunken); font-family: var(--font-display); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-muted); }
/* th as well as td. A row header is a th, so clearing only td left a rule
   under the first column of the last row and nothing under the rest of it,
   which read as a stray underline hanging off the bottom-left of the table. */
.c-table tbody tr:last-child :is(td, th) { border-bottom: 0; }
.c-table td[data-num] { font-variant-numeric: tabular-nums; font-family: var(--font-mono); }

/* Converted figure. Ours, not the manufacturer's, so it is visually
   subordinate to the published value and never confusable with it. Sits on its
   own line rather than inline: the published column is monospaced and tabular,
   and a second figure on the same line breaks the column of numbers the
   monospace exists to create. */
.c-table__conv {
  display: block;
  margin-top: 0.15rem;
  font-family: var(--font-body);
  font-size: 0.78rem;
  color: var(--ink-muted);
}
.c-table__conv::before { content: "\2248 "; }

/* External links in body content carry a small outbound mark.

   Opening a new tab without saying so is a documented accessibility problem:
   the reader's back button stops working and there is nothing to explain why.
   WCAG lists warning about it under 3.2.5, and while that is a AAA criterion
   and this site targets AA, the mark costs nothing and removes the surprise.

   Scoped to <main>, which excludes the header, mega menu, mobile drawer and
   footer without having to name them. The first attempt listed content
   containers instead and missed the FAA link on the instructor form, because
   it sits in a field note nobody thought to add to the list. Naming the region
   to include beats maintaining a list of every wrapper that might hold prose.

   Buttons are excluded within main as well: they are deliberate destinations
   where a glyph after the label reads as clutter, and the manufacturer-site
   button already states "(opens in a new tab)" in its own text.

   The glyph is decorative and is not announced by assistive technology, which
   ignores generated content. It is a visual affordance, not a substitute for
   the text some links carry. */
main a[target="_blank"]:not(.c-btn):not(.c-megamenu__link):not(.c-drawer__link)::after {
  content: "\2197";               /* north east arrow */
  display: inline-block;
  margin-inline-start: 0.15em;
  font-size: 0.85em;
  line-height: 1;
  text-decoration: none;
  vertical-align: baseline;
}

/* Spec tables carry two columns now that the repeated source column is gone,
   and the browser split the width evenly: a 1323px table gave the label column
   762px, so "Empty mass" sat a foot away from its own figure. The label column
   is sized to the longest label instead and the value column takes the rest. */
/* The width must be declared on the header cell, not on the row headers in
   the body: under table-layout: fixed the browser takes column widths from
   the first row and ignores every row after it. Setting it on th[scope=row]
   silently did nothing and the columns stayed at an even 50/50 split. */
.c-table--specs { table-layout: fixed; width: 100%; }
.c-table--specs thead th:first-child { width: 22rem; }

/* Below the breakpoint the spec table stops being a table and becomes a list
   of label-and-value pairs.

   .c-table carries min-width: 34rem, which is wider than a phone, so the
   wrapper scrolled sideways and half of every figure was off screen until you
   dragged it. Sideways scrolling inside a page is the thing people miss
   entirely, and a specification nobody scrolls to is a specification that is
   not published.

   Two columns is the case where stacking works without help: the row header is
   the label and the only cell is its value, so the pair still reads correctly
   with no data-label duplication in the markup. The table keeps its semantics
   for assistive technology, which uses the element roles rather than the
   display property. The header row is hidden because "Specification / As
   published" over a stacked list says nothing the layout is not already
   saying. */
@media (max-width: 47.99em) {
  .c-table--specs,
  .c-table--stack { min-width: 0; table-layout: auto; }

  .c-table--specs thead,
  .c-table--stack thead {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%);
  }

  .c-table--specs tr,
  .c-table--stack tr {
    display: block;
    border-bottom: 1px solid var(--rule);
    padding-block: var(--space-2xs);
  }
  .c-table--specs tbody tr:last-child,
  .c-table--stack tbody tr:last-child { border-bottom: 0; }

  .c-table--specs :is(th, td),
  .c-table--stack :is(th, td) { display: block; border-bottom: 0; padding-block: 0.25rem; }

  .c-table--specs th[scope="row"],
  .c-table--stack th[scope="row"] { width: auto; font-weight: 700; }

  /* Two columns need no per-cell label: the row header is the label and the
     single cell is its value. The row header is set quiet so the figure reads
     as the content. */
  .c-table--specs th[scope="row"] { color: var(--ink-muted); font-size: 0.78rem; }

  /* Three and four column tables lose their meaning when stacked, because the
     column a cell belonged to is what told you what it was. data-label carries
     that word down with the cell. It is written in the template rather than
     read from thead because CSS cannot reach across the table to fetch it. */
  .c-table--stack td[data-label]::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 0.1rem;
    font-family: var(--font-display);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ink-muted);
  }
}

/* Source line under a spec table. Carries the attribution the per-row Source
   column used to carry, so it sits closer to the tables than the general
   caveat that follows it. */
.c-specsource {
  margin: calc(var(--space-s) * -1) 0 var(--space-m);
  font-size: var(--step--1);
  color: var(--ink-muted);
}

/* Author block. */
.c-author {
  display: grid;
  /* minmax(0, 1fr), not 1fr: the text column's min-content would otherwise set
     the floor and push the block wider than a narrow viewport at large text
     scales. The portrait is sized in px so it does not grow with the text
     preference either. */
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-s);
  align-items: start;
  padding: var(--space-m);
  border: 1px solid var(--rule);
  border-radius: var(--radius-m);
  background: var(--bg-sunken);
}
.c-author > div { min-width: 0; overflow-wrap: break-word; }
.c-author__photo { width: 72px; height: 72px; border-radius: 50%; object-fit: cover; background: var(--silver-300); flex: none; }

/* Below the breakpoint the portrait stacks above the text rather than stealing
   horizontal room from it. */
@media (max-width: 30em) {
  .c-author { grid-template-columns: minmax(0, 1fr); }
}
.c-author__name { font-size: var(--step-1); }
.c-author__role { font-size: var(--step--1); color: var(--ink-muted); }
.c-author__proof { margin-top: var(--space-2xs); font-size: var(--step--1); }

.c-sources { font-size: var(--step--1); }
.c-sources ol { padding-left: 1.25em; }
.c-sources li { margin-bottom: 0.4em; word-break: break-word; }

/* --------------------------------------------------------------------------
   Filter rail
   -------------------------------------------------------------------------- */
.c-filters { display: grid; gap: var(--space-s); }
/* min-width: 0 is the load-bearing declaration here, not the reset.
   The UA stylesheet gives every fieldset min-width: min-content, and unlike a
   div it will not shrink below the widest thing inside it. In the filter rail
   that made the fieldset 30px wider than its own parent, so the controls
   pushed out past the rail's padding and sat hard against the listings. It
   reads as the filters overlapping the results, and it is invisible to a
   reflow check because the page itself never scrolls. */
.c-filters__group { border: 0; margin: 0; padding: 0; min-width: 0; }
.c-filters__legend {
  font-family: var(--font-display);
  font-size: var(--step--1);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: var(--tracking-kicker);
  color: var(--ink-muted);
  margin-bottom: var(--space-2xs);
  padding: 0;
}
.c-filters select,
.c-filters input[type="number"] {
  width: 100%;
  min-height: 3rem;
  padding: 0 var(--space-2xs);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-s);
  background: var(--paper);
}

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */
.c-form { display: grid; gap: var(--space-m); }

.c-fieldset { border: 0; margin: 0; padding: 0; }
.c-fieldset > legend {
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 800;
  color: var(--ink-strong);
  padding: 0;
  margin-bottom: var(--space-2xs);
}
.c-fieldset__hint {
  font-size: var(--step--1);
  color: var(--ink-muted);
  margin: 0 0 var(--space-s);
}

.c-grid2 {
  display: grid;
  gap: var(--space-s);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
}

.c-field { display: grid; gap: 0.35rem; min-width: 0; }

.c-field > label {
  font-weight: 700;
  font-size: var(--step--1);
  color: var(--ink-strong);
}
.c-field__optional { font-weight: 400; color: var(--ink-muted); }

.c-field :is(input, select, textarea) {
  width: 100%;
  min-height: 3rem;
  padding: 0.6rem var(--space-2xs);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-s);
  background: var(--paper);
  color: var(--ink-body);
}
.c-field textarea { min-height: 9rem; resize: vertical; line-height: 1.55; }

.c-field :is(input, select, textarea):focus-visible { border-color: var(--accent); }

/* Invalid state is carried by a border, an icon-free message, and
   aria-invalid. Colour alone never marks a field as wrong. */
.c-field[data-invalid] :is(input, select, textarea) {
  border-color: var(--state-sold);
  border-width: 2px;
}
.c-field__error {
  font-size: var(--step--1);
  font-weight: 700;
  color: var(--state-sold);
}
.c-field__error::before { content: "Problem: "; }

.c-field__note { font-size: 0.78rem; color: var(--ink-muted); }

.c-check {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-2xs);
  align-items: start;
  padding: var(--space-2xs) 0;
}
.c-check input { width: 1.35rem; height: 1.35rem; min-height: 0; margin-top: 0.15rem; accent-color: var(--accent); }
.c-check label { font-weight: 400; font-size: var(--step--1); }

/* The honeypot. Off-screen rather than display:none, because some bots skip
   hidden fields; hidden from assistive technology so nobody is asked to fill
   in a field that must stay empty. */
.c-trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.c-alert {
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-m);
  border-left: 4px solid;
  background: var(--bg-sunken);
}
.c-alert--ok    { border-color: var(--state-live); }
.c-alert--error { border-color: var(--state-sold); }
.c-alert h2, .c-alert h3 { font-size: var(--step-1); margin-bottom: 0.3rem; }
.c-alert p:last-child { margin-bottom: 0; }
.c-alert code {
  font-family: var(--font-mono);
  background: var(--paper);
  padding: 0.15rem 0.4rem;
  border-radius: var(--radius-xs);
  border: 1px solid var(--rule);
}

/* Search box on the marketplace filter rail. */
.c-search { display: flex; gap: var(--space-3xs); }
.c-search input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 3rem;
  padding: 0 var(--space-2xs);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-s);
}
.c-search button { flex: none; min-height: 3rem; padding-inline: var(--space-s); }

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

   Native <details>/<summary>: keyboard operable and screen-reader announced
   without a line of JavaScript, and findable by browser in-page search even
   while collapsed. A div-and-click reimplementation of this gets all three
   wrong by default.
   -------------------------------------------------------------------------- */
.c-faq { border-top: 1px solid var(--rule); }

.c-faq__item { border-bottom: 1px solid var(--rule); }

.c-faq__q {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-s);
  padding: var(--space-s) 0;
  min-height: 3rem;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 700;
  color: var(--ink-strong);
  cursor: pointer;
  list-style: none;
}
.c-faq__q::-webkit-details-marker { display: none; }

.c-faq__q::after {
  content: "";
  flex: none;
  width: 0.7rem;
  height: 0.7rem;
  margin-top: 0.45em;
  border-right: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(45deg);
  transition: transform var(--dur-base) var(--ease-out);
}
.c-faq__item[open] > .c-faq__q::after { transform: rotate(225deg); }

.c-faq__q:hover { color: var(--accent); }

.c-faq__a {
  padding-bottom: var(--space-m);
  font-size: var(--step-0);
}

/* --------------------------------------------------------------------------
   Contributor cards
   -------------------------------------------------------------------------- */
.c-people {
  display: grid;
  gap: var(--space-m);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
  list-style: none;
  margin: 0;
  padding: 0;
}
.c-person {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-s);
  align-items: start;
  padding: var(--space-s);
  border: 1px solid var(--rule);
  border-radius: var(--radius-m);
  position: relative;
}
.c-person__photo {
  width: 60px; height: 60px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--silver-300);
  flex: none;
}
.c-person__name { font-size: var(--step-1); }
.c-person__name a { color: inherit; text-decoration: none; }
.c-person__name a::after { content: ""; position: absolute; inset: 0; }
.c-person__name a:hover { color: var(--accent); }
.c-person__meta { font-size: var(--step--1); color: var(--ink-muted); }

@media (max-width: 30em) {
  .c-person { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */
.c-footer {
  background: var(--navy-900);
  color: var(--ink-invert-muted);
  padding-block: var(--space-2xl) var(--space-l);
}
.c-footer h2, .c-footer h3 { color: #FFFFFF; }
.c-footer a { color: var(--ink-invert-muted); text-decoration: none; }
.c-footer a:hover { color: #FFFFFF; text-decoration: underline; }
.c-footer__grid {
  display: grid;
  gap: var(--space-l);
  /* min() guards the track floor against the text-scale preference. A bare
     minmax(12rem, 1fr) becomes a 384px minimum at 200%, which overflows a
     320px viewport no matter how few columns auto-fit produces. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
}
.c-footer__legal {
  margin-top: var(--space-xl);
  padding-top: var(--space-s);
  border-top: 1px solid var(--rule-invert);
  font-size: var(--step--1);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-m);
  align-items: center;
}
.c-footer__list { list-style: none; margin: 0; padding: 0; }
.c-footer__list li + li { margin-top: 0.4rem; }

/* --------------------------------------------------------------------------
   Breadcrumbs, pagination, empty states
   -------------------------------------------------------------------------- */
.c-crumbs { font-size: var(--step--1); color: var(--ink-muted); }
.c-crumbs ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.3rem 0.5rem; }
.c-crumbs li:not(:last-child)::after { content: "/"; margin-left: 0.5rem; color: var(--rule-strong); }
.c-crumbs a { color: inherit; }

.c-pager { display: flex; flex-wrap: wrap; gap: var(--space-2xs); align-items: center; justify-content: center; }
.c-pager a, .c-pager span {
  min-width: 2.75rem; min-height: 2.75rem;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0 var(--space-2xs);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-s);
  text-decoration: none;
  color: var(--ink-body);
}
.c-pager [aria-current="page"] { background: var(--navy-800); border-color: var(--navy-800); color: #FFFFFF; font-weight: 700; }

.c-empty {
  padding: var(--space-xl);
  text-align: center;
  border: 1px dashed var(--rule-strong);
  border-radius: var(--radius-m);
  color: var(--ink-muted);
}

/* --------------------------------------------------------------------------
   Table of contents
   -------------------------------------------------------------------------- */
.c-toc__title {
  font-family: var(--font-display);
  font-size: var(--step--1);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: var(--tracking-kicker);
  color: var(--ink-muted);
  margin: 0 0 var(--space-2xs);
  padding-bottom: var(--space-3xs);
  border-bottom: 1px solid var(--rule);
}
.c-toc__list { list-style: none; margin: 0; padding: 0; counter-reset: toc; }
.c-toc__list li { counter-increment: toc; }
.c-toc__list a {
  display: flex;
  gap: var(--space-2xs);
  padding: 0.45rem 0;
  font-size: var(--step--1);
  line-height: 1.35;
  color: var(--ink-muted);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
}
.c-toc__list a::before {
  content: counter(toc, decimal-leading-zero);
  font-family: var(--font-mono);
  font-size: 0.78em;
  color: var(--silver-500);
  flex: none;
}
.c-toc__list a:hover { color: var(--accent); }
.c-toc__list a[aria-current="true"] { color: var(--ink-strong); font-weight: 700; }
.c-toc__list a[aria-current="true"]::before { color: var(--accent); }

/* --------------------------------------------------------------------------
   Policy prose

   Fitted section headings need room to breathe and a rule to sit on, or a
   90px heading reads as an accident rather than a decision.
   -------------------------------------------------------------------------- */
.c-prose--policy > h2 {
  margin-top: var(--space-2xl);
  margin-bottom: var(--space-s);
  padding-top: var(--space-s);
  border-top: 1px solid var(--rule);
  line-height: 1.06;
}
.c-prose--policy > h2:first-child { margin-top: 0; }
.c-prose--policy > h3 {
  margin-top: var(--space-l);
  color: var(--ink-strong);
}
/* Body copy fills its column. No measure cap.
   The typographic default is to cap a paragraph around 68ch for readability,
   and that is what left every policy and reference page with an empty right
   third. The site rule is that content spans 100% of its container unless an
   image is wrapped beside it, so the cap comes off and the column itself is
   what sets the line length. Where a narrower measure is genuinely wanted,
   put the text in a narrower container rather than capping it here. */
.c-prose--policy > p { font-size: var(--step-0); }

/* The opening paragraph of a policy section carries a little more weight. */
.c-prose--policy > h2 + p { font-size: var(--step-1); color: var(--ink-strong); }

/* Currency switch. Shares the language switch's shell; the distinction that
   matters is that they are two separate controls, not one. */
.c-currency .c-lang__toggle { min-width: 4.2rem; justify-content: center; }
.c-currency .c-lang__menu { min-width: 15rem; }

/* Approximate converted prices. Always visually subordinate to the seller's
   own figure, because that figure is the price and this one is an estimate. */
.c-card__approx {
  display: block;
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--ink-muted);
  letter-spacing: 0.01em;
}
.c-approx {
  margin-top: calc(var(--space-2xs) * -1);
  font-size: var(--step--1);
  color: var(--ink-muted);
}
.c-approx__note { display: block; font-size: 0.75rem; margin-top: 0.15rem; }

/* A fitted heading measures its parent, so that parent needs a width of its
   own from the layout rather than one inherited from the heading's content. */
.c-prose--policy { min-width: 0; }
.c-prose--policy > h2 { max-width: 100%; overflow: clip; }


/* --------------------------------------------------------------------------
   Intake form layout

   The submission form was running four inputs across a full-width canvas,
   which reads as a data-entry screen rather than something a private owner
   fills in once. Capping the grid at two columns and holding the form to a
   readable column makes the sequence obvious.
   -------------------------------------------------------------------------- */
.c-form { width: 100%; }
.c-grid2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); }

.c-fieldset + .c-fieldset {
  margin-top: var(--space-l);
  padding-top: var(--space-l);
  border-top: 1px solid var(--rule);
}
.c-fieldset > legend {
  display: flex;
  align-items: baseline;
  gap: var(--space-2xs);
}
/* Numbered steps, so a long form reads as a sequence with an end. */
.c-form { counter-reset: step; }
.c-fieldset { counter-increment: step; }
.c-fieldset > legend::before {
  content: counter(step);
  font-family: var(--font-mono);
  font-size: 0.75em;
  color: var(--accent);
  border: 2px solid var(--accent);
  border-radius: 50%;
  width: 1.9em; height: 1.9em;
  display: grid; place-items: center;
  flex: none;
}

/* Supporting rail beside the form on wide screens. */
.l-intake { display: grid; gap: var(--space-l); grid-column: main; }
@media (min-width: 64em) {
  .l-intake {
    grid-template-columns: minmax(0, 1fr) minmax(0, 20rem);
    gap: var(--space-2xl);
    align-items: start;
  }
  .l-intake__aside { position: sticky; top: calc(var(--header-h, 76px) + var(--space-m)); }
}

/* --------------------------------------------------------------------------
   Article hero banner

   The photograph carries the title. A dark scrim keeps white text legible over
   any image, and the height is capped so a wide hero cannot swallow the fold.
   Used by journal/show.php only when an article has a hero_path.
   -------------------------------------------------------------------------- */
.c-articlehero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: clamp(280px, 38vw, 440px);
  border-radius: var(--radius-m);
  overflow: hidden;
  isolation: isolate;
  background: var(--bg-inverse);
}
.c-articlehero__img {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%;
  object-fit: cover;
}
.c-articlehero__scrim {
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(to top,
    rgb(0 8 31 / 0.86) 0%,
    rgb(0 8 31 / 0.58) 40%,
    rgb(0 8 31 / 0.18) 74%,
    rgb(0 8 31 / 0.02) 100%);
}
.c-articlehero__inner {
  width: 100%;
  padding: clamp(var(--space-l), 4vw, var(--space-2xl));
  color: #FFFFFF;
}
.c-articlehero__kicker { color: var(--azure-300); }
.c-articlehero__title { color: #FFFFFF; margin: 0; }
.c-articlehero__dek {
  max-width: 52ch;
  margin-top: var(--space-2xs);
  font-size: var(--step-1);
  color: rgb(255 255 255 / 0.86);
}
.c-articlehero__meta {
  display: flex; flex-wrap: wrap; gap: 0.15rem 1.1rem;
  margin-top: var(--space-s);
  font-size: var(--step--1);
  color: rgb(255 255 255 / 0.82);
}
.c-articlehero__meta a { color: #FFFFFF; }

/* High-contrast preference: drop the gradient for a solid backing. */
html[data-contrast="high"] .c-articlehero__scrim { background: rgb(0 8 31 / 0.92); }

/* Forced colours: the image cannot be relied on for contrast, so cover it with
   a system-coloured backing and let the text use system colours. */
@media (forced-colors: active) {
  .c-articlehero__scrim { background: Canvas; }
  .c-articlehero__inner,
  .c-articlehero__title,
  .c-articlehero__kicker,
  .c-articlehero__dek,
  .c-articlehero__meta,
  .c-articlehero__meta a { color: CanvasText; }
}

/* --------------------------------------------------------------------------
   Content figure
   -------------------------------------------------------------------------- */
.c-figure { margin: 0; }
/* In-article content photo: capped so it reads as an inline illustration rather
   than a full-measure slab. Centred within the prose column. */
.c-figure--inset { max-width: 40rem; margin-inline: auto; }
/* The caption fills the figure width, not a narrower measure. */
.c-figure--inset figcaption { max-width: 100%; }
.c-figure img {
  width: 100%;
  border-radius: var(--radius-m);
  aspect-ratio: 16 / 10;
  object-fit: cover;
  background: var(--bg-sunken);
}
.c-figure figcaption {
  margin-top: var(--space-2xs);
  font-size: var(--step--1);
  color: var(--ink-muted);
  max-width: 44ch;
}

/* --------------------------------------------------------------------------
   Listing gallery and lightbox
   -------------------------------------------------------------------------- */
.c-gallery__main { display: block; position: relative; border-radius: var(--radius-m); overflow: hidden; }
.c-gallery__main img { width: 100%; aspect-ratio: 3/2; object-fit: cover; background: var(--bg-sunken);
  transition: transform var(--dur-slow) var(--ease-out); }
.c-gallery__main:hover img { transform: scale(1.03); }
.c-gallery__zoom {
  position: absolute; right: var(--space-2xs); bottom: var(--space-2xs);
  padding: 0.35rem 0.7rem; border-radius: 999px;
  background: rgb(0 8 31 / 0.78); color: #fff;
  font-size: 0.78rem; font-weight: 700; letter-spacing: 0.02em;
  backdrop-filter: blur(6px);
}
.c-gallery__thumbs {
  list-style: none; margin: var(--space-2xs) 0 0; padding: 0;
  display: grid; gap: var(--space-3xs);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 7rem), 1fr));
}
.c-gallery__thumbs img {
  width: 100%; aspect-ratio: 3/2; object-fit: cover;
  border-radius: var(--radius-s); background: var(--bg-sunken);
  transition: opacity var(--dur-fast) var(--ease-out);
}
.c-gallery__thumbs a:hover img { opacity: 0.82; }

.c-lightbox {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center;
  background: rgb(0 8 31 / 0.94);
  padding: var(--space-l) var(--space-m);
}
.c-lightbox__stage {
  /* The drift is applied here, so the figure and its caption move together
     and the caption never separates from the photograph it describes. */
  transform: translate3d(var(--lb-x, 0px), var(--lb-y, 0px), 0);
  transition: transform 380ms var(--ease-out);
  max-width: min(72rem, 100%);
  max-height: 100%;
}
.c-lightbox__figure { margin: 0; display: grid; gap: var(--space-2xs); justify-items: center; }
.c-lightbox__img {
  max-width: 100%; max-height: 76dvh; width: auto;
  border-radius: var(--radius-m);
  box-shadow: 0 30px 80px rgb(0 0 0 / 0.5);
}
.c-lightbox.is-shifted .c-lightbox__img { animation: lb-in 460ms var(--ease-out) both; }
@keyframes lb-in {
  from { opacity: 0; transform: scale(0.985) translateY(10px); }
  to   { opacity: 1; transform: none; }
}
.c-lightbox__cap { color: var(--ink-invert-muted); font-size: var(--step--1); max-width: 62ch; text-align: center; }
.c-lightbox__count {
  position: absolute; top: var(--space-m); left: 50%; transform: translateX(-50%);
  margin: 0; color: #E6EBF2; font-family: var(--font-mono); font-size: var(--step--1);
}
.c-lightbox__close, .c-lightbox__nav {
  position: absolute; display: grid; place-items: center;
  width: 3rem; height: 3rem; border-radius: 50%;
  background: rgb(255 255 255 / 0.12); color: #fff;
  border: 1px solid rgb(255 255 255 / 0.3);
  font-size: 1.6rem; line-height: 1; cursor: pointer;
}
.c-lightbox__close:hover, .c-lightbox__nav:hover { background: rgb(255 255 255 / 0.24); }
.c-lightbox__close { top: var(--space-m); right: var(--space-m); }
.c-lightbox__nav--prev { left: var(--space-m); top: 50%; transform: translateY(-50%); }
.c-lightbox__nav--next { right: var(--space-m); top: 50%; transform: translateY(-50%); }

@media (prefers-reduced-motion: reduce) {
  .c-lightbox__stage { transition: none; }
  .c-lightbox.is-shifted .c-lightbox__img { animation: none; }
}

/* --------------------------------------------------------------------------
   Header at mid widths

   Logo, four nav items, two switchers and a call to action stop fitting on one
   line somewhere around 1200px, and flex-wrap then drops the actions onto a
   second row. Rather than let it wrap, the bar sheds what is redundant: the
   Browse aircraft button duplicates the Marketplace nav item, so it goes
   first, and the nav tightens before anything else has to give.
   -------------------------------------------------------------------------- */
@media (min-width: 64em) and (max-width: 89.99em) {
  .c-header__bar { gap: var(--space-2xs) var(--space-s); }
  .c-nav__trigger { padding-inline: var(--space-2xs); font-size: var(--step--1); }
  .c-nav__trigger::after { inset-inline: var(--space-2xs); }
  .c-header__actions > .c-btn { display: none; }
}

/* The bar never wraps at any width. Wrapping was the escape valve that let it
   silently become a two-row header at exactly one viewport size; shedding the
   redundant button above is the intended relief instead. */
.c-header__bar { flex-wrap: nowrap; }

/* Mobile bar layout.
   Logo left, language switch and burger hard right, one row, burger last.
   Three controls next to the wordmark wrapped the bar onto two rows on a
   handset and left the burger stranded under the switches. The currency
   switch moves into the drawer at this width rather than competing for the
   space; language stays because switching it is the reason a non-English
   visitor is looking at the header at all. */
@media (max-width: 63.99em) {
  .c-header__bar { flex-wrap: nowrap; gap: var(--space-2xs); }
  .c-header__actions {
    flex-wrap: nowrap;
    margin-inline-start: auto;
    gap: var(--space-2xs);
  }
  .c-burger { order: 99; margin-inline-start: var(--space-2xs); }
}

/* Questions and answers both span the full container. */
.c-faq,
.c-faq__intro {
  width: 100%;
}
.c-faq__q { width: 100%; }
.c-faq__a { max-width: 100%; }

/* --------------------------------------------------------------------------
   Glossary
   -------------------------------------------------------------------------- */
.c-glossary { margin: 0 0 var(--space-l); }
.c-glossary__row {
  display: grid;
  gap: 0.15rem var(--space-m);
  padding: var(--space-s) 0;
  border-bottom: 1px solid var(--rule);
}
@media (min-width: 48em) {
  .c-glossary__row { grid-template-columns: minmax(0, 15rem) minmax(0, 1fr); gap: var(--space-m); }
}
.c-glossary__term {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--step-0);
  color: var(--ink-strong);
}
.c-glossary__aka {
  display: block;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--step--1);
  color: var(--ink-muted);
}
.c-glossary__def { margin: 0; }

/* -----------------------------------------------------------------------------
   Diagram
   -----------------------------------------------------------------------------
   Inline SVG explainer inside prose. The figure is allowed to break out of the
   prose measure, because a diagram constrained to a reading measure is a
   diagram nobody can read, but it stops at the container so it cannot start a
   horizontal scroll on the page. The caption stays at the measure.
   -------------------------------------------------------------------------- */
.c-diagram {
  margin: var(--space-l) 0;
  padding: var(--space-m);
  background: var(--bg-sunken);
  border: 1px solid var(--rule);
  border-radius: var(--radius-m);
}

.c-diagram svg {
  display: block;
  width: 100%;
  max-width: 40rem;
  height: auto;
  margin-inline: auto;
}

.c-diagram figcaption {
  max-width: 100%;
  margin: var(--space-s) auto 0;
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--ink-muted);
}

/* Forced-colours mode drops the tint fills entirely, so the regions have to be
   distinguishable by stroke and label alone. They are: both region outlines are
   stroked, and both carry a text label. */
@media (forced-colors: active) {
  .c-diagram svg ellipse[opacity] { opacity: 1; fill: none; }
  .c-diagram svg ellipse,
  .c-diagram svg line,
  .c-diagram svg path { stroke: CanvasText; }
  .c-diagram svg text { fill: CanvasText; }
}

/* -- Drawer: currency chips ------------------------------------------------
   The currency switch is a popup menu in the desktop bar and a flat row of
   chips here. Same choice, different affordance: a menu inside an already-open
   drawer is a second layer to dismiss, and there are only eight options. */
.c-drawer__label {
  margin: 0 0 var(--space-2xs);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.c-drawer__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
}

.c-drawer__chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 3.4rem;
  min-height: 44px;            /* pointer target, WCAG 2.5.8 */
  padding: 0 var(--space-xs);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-m);
  font-size: var(--step--1);
  font-weight: 700;
  text-decoration: none;
  color: var(--ink-strong);
}

.c-drawer__chip[aria-current="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: #FFFFFF;
}

.c-drawer__note {
  margin: var(--space-xs) 0 0;
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--ink-muted);
}

/* -- Fitted heading clamp bands --------------------------------------------
   fit-heading.js reads --fit-min and --fit-max off the computed style and
   clamps the solved size into that band.

   Why these exist. A fitted heading's size is set by how long the string is:
   fill the same column with four words or with nine and the four-word version
   comes out more than twice as large. Left unbounded on a handset that put a
   short h2 at 42px and a long one at 19px, below the 19px body text underneath
   it. Both filled 100%. Neither read as a heading of the same rank.

   So the band is narrow on small screens, where there is little room for the
   swing, and opens up as the viewport grows. A heading whose natural fitted
   size lands outside the band clamps and stops short of 100%: that is the
   deliberate trade, and it is the only lever that keeps rank legible. If a
   heading is clamping short, the fix is a longer heading, not a wider band.
   -------------------------------------------------------------------------- */

/* Base band for every fitted heading.
   This exists so nothing can fall through to the script's 190px default. Three
   headings did exactly that (the marketplace and sell h1s, and the financing
   form band) and rendered at 118px, because the bands below only named heroes
   and prose. A base on [data-fit] means a new fitted heading is merely
   mis-sized until someone tunes it, never enormous. */
[data-fit] {
  --fit-min: 24px;
  --fit-max: 38px;
}

/* Section headings inside prose. */
.c-prose h2,
[data-fit-sections] h2 {
  --fit-min: 22px;
  --fit-max: 30px;
}

/* Page h1 in a hero. Larger band: it is the only heading in its container and
   it has the full canvas width to work with. */
.c-hero h1 {
  --fit-min: 26px;
  --fit-max: 40px;
}

@media (min-width: 48em) {
  [data-fit]             { --fit-min: 28px; --fit-max: 54px; }
  .c-prose h2,
  [data-fit-sections] h2 { --fit-min: 26px; --fit-max: 44px; }
  .c-hero h1             { --fit-min: 32px; --fit-max: 72px; }
}

@media (min-width: 64em) {
  [data-fit]             { --fit-min: 30px; --fit-max: 66px; }
  .c-prose h2,
  [data-fit-sections] h2 { --fit-min: 28px; --fit-max: 54px; }
  .c-hero h1             { --fit-min: 36px; --fit-max: 104px; }
}

@media (min-width: 90em) {
  [data-fit]             { --fit-min: 32px; --fit-max: 76px; }
  .c-prose h2,
  [data-fit-sections] h2 { --fit-min: 30px; --fit-max: 60px; }
  .c-hero h1             { --fit-min: 40px; --fit-max: 124px; }
}

/* --------------------------------------------------------------------------
   Payment calculator
   -------------------------------------------------------------------------- */
.c-calc {
  margin: var(--space-l) 0;
  padding: var(--space-m);
  background: var(--bg-sunken);
  border: 1px solid var(--rule);
  border-radius: var(--radius-m);
}

.c-calc__title {
  margin: 0 0 var(--space-s);
  font-size: var(--step-1);
  color: var(--ink-strong);
}

/* Four controls made of three different things: two inputs behind a currency
   prefix, one behind a percent suffix, and a bare select. Left to themselves
   they measured 57, 50 and 56 pixels tall and started at three different
   heights, because the min-height sits on the input while the border is drawn
   by the wrapper around it. The notes underneath run one to three lines each,
   so the row ended ragged too. Four controls that happened to be near each
   other rather than one instrument.

   Subgrid puts label, control and note on three shared rows, so every field
   lines up whatever the length of its own label or note. Row gap is set here
   rather than on .c-field because subgrid takes its gaps from the parent.
   Browsers without subgrid keep the previous stacked behaviour. */
.c-calc__grid {
  display: grid;
  gap: 0.35rem var(--space-m);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
  grid-template-rows: auto auto auto;
  align-items: start;
}

.c-calc__grid > .c-field {
  grid-row: span 3;
  grid-template-rows: subgrid;
  align-content: start;
  /* Separates wrapped rows on narrow screens, where the 0.35rem row gap above
     would otherwise run one field straight into the next. */
  padding-bottom: var(--space-s);
}

/* One height for every control, set on whatever draws the border. */
.c-calc__grid :is(.c-field__prefixed, select) { min-height: 3.25rem; }
.c-calc__grid .c-field__prefixed > input { min-height: 0; }

/* The note sits on the last row and pins to its top, so a three-line note and
   a one-line note begin on the same line. */
.c-calc__grid .c-field__note { align-self: start; margin: 0; }

/* Currency and percent affixes sit inside the field's border so the pair reads
   as one control. The input keeps its own focus ring rather than the wrapper
   taking it, because a ring drawn on the wrapper is not what a screen
   magnifier follows. */
.c-field__prefixed {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-m);
  background: var(--bg-page);
  overflow: hidden;
}
.c-field__prefixed > input {
  border: 0;
  border-radius: 0;
  flex: 1 1 auto;
  min-width: 0;
  background: transparent;
}
.c-field__prefix {
  display: flex;
  align-items: center;
  padding-inline: var(--space-xs);
  background: var(--bg-sunken);
  font-size: var(--step--1);
  font-weight: 700;
  color: var(--ink-muted);
  white-space: nowrap;
}
.c-field__prefixed--suffix .c-field__prefix { order: 2; }

.c-calc__out {
  margin-top: var(--space-m);
  padding-top: var(--space-m);
  border-top: 1px solid var(--rule);
}

.c-calc__figure {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-xs);
  margin-bottom: var(--space-s);
}
.c-calc__label {
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.c-calc__value {
  font-size: clamp(1.9rem, 6vw, 2.9rem);
  line-height: 1.05;
  color: var(--ink-strong);
  font-variant-numeric: tabular-nums;
}

.c-calc__rows {
  display: grid;
  gap: var(--space-2xs);
  margin: 0;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
}
.c-calc__rows > div {
  display: flex;
  justify-content: space-between;
  gap: var(--space-xs);
  padding-block: var(--space-2xs);
  border-bottom: 1px solid var(--rule);
}
.c-calc__rows dt { font-size: var(--step--1); color: var(--ink-muted); }
.c-calc__rows dd {
  margin: 0;
  font-weight: 700;
  color: var(--ink-strong);
  font-variant-numeric: tabular-nums;
}

.c-calc__nojs,
.c-calc__warn { margin: 0; font-size: var(--step--1); color: var(--ink-muted); }
.c-calc__warn { color: var(--state-warn, #8A4B00); font-weight: 700; }

.c-calc__note {
  margin: var(--space-m) 0 0;
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--ink-muted);
}

/* --------------------------------------------------------------------------
   Form band: a full-width form section closing an editorial page
   Reuses the established form vocabulary (c-fieldset, c-grid2, c-field,
   c-alert, c-check). Only the band itself is new.
   -------------------------------------------------------------------------- */
.c-formband {
  background: var(--bg-sunken);
  border-top: 1px solid var(--rule);
}

.c-formband__lede {
  font-size: var(--step-1);
  color: var(--ink-strong);
}

.c-form__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-m);
  margin-top: var(--space-l);
}

.c-form__actions .c-note { margin: 0; flex: 1 1 18rem; }


/* Postal address blocks. <address> is italic by default in every UA. */
.c-address {
  font-style: normal;
  margin: var(--space-xs) 0 var(--space-m);
  line-height: 1.6;
}
.c-address span { display: block; }

/* --------------------------------------------------------------------------
   Glossary term page
   --------------------------------------------------------------------------
   The problem this solves: six identical full-width heading blocks stacked
   down a page reads as a template regardless of the words in it. Scale was
   making it worse, not better, because a short heading fitted to the full
   canvas comes out enormous.

   So the section heading moves into a narrow left rail and the prose runs
   beside it. The heading still fills its container; the container is now
   14rem, so it settles around 20px. Asymmetry carries the hierarchy that size
   was failing to carry.
   -------------------------------------------------------------------------- */

/* -- The definition, leading the page -------------------------------------- */
.c-termdef {
  padding-block: var(--space-m) var(--space-l);
  border-bottom: 1px solid var(--rule);
}

.c-termdef__text {
  margin: 0;
  font-size: var(--step-2);
  line-height: 1.35;
  color: var(--ink-strong);
  text-wrap: pretty;
}

.c-termdef__aka {
  margin: var(--space-s) 0 0;
  font-size: var(--step--1);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* -- Sections -------------------------------------------------------------- */
.c-entry {
  padding-block: var(--space-l);
  border-bottom: 1px solid var(--rule);
}

.c-entry__head { margin-bottom: var(--space-s); }

.c-entry__num {
  display: block;
  margin-bottom: var(--space-3xs);
  font-size: var(--step--1);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.1em;
  color: var(--accent);
}

.c-entry__title {
  margin: 0;
  font-size: var(--step-1);
  line-height: 1.2;
  color: var(--ink-strong);
  text-wrap: balance;
}

.c-entry__body > :first-child { margin-top: 0; }
.c-entry__body > :last-child  { margin-bottom: 0; }

/* The title is an h2 inside .c-prose, which gave it a large top margin and left
   the number stranded above it. Cancel that, and on narrow screens run the
   number inline as a prefix so it sits on the title's first line, not above it. */
.c-entry__head .c-entry__title { margin-top: 0; }
@media (max-width: 59.99em) {
  .c-entry__num   { display: inline; margin: 0 0.4em 0 0; }
  .c-entry__title { display: inline; }
}

/* Diagrams and other break-outs sit outside the two-column rhythm. */
.c-entry__break { padding-block: var(--space-l); border-bottom: 1px solid var(--rule); }
.c-entry__break .c-diagram { margin: 0; }

@media (min-width: 60em) {
  .c-entry {
    display: grid;
    grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
    gap: var(--space-2xl);
    align-items: start;
  }

  /* Sticky so the section title stays with the prose on a long section, which
     is the whole benefit of putting it in a rail rather than above. */
  .c-entry__head {
    position: sticky;
    top: calc(var(--header-h, 76px) + var(--space-m));
    margin-bottom: 0;
  }

  .c-entry__title { font-size: var(--step-0); }
}

/* -- Onward links: related terms -------------------------------------------
   Rows, not cards.

   A card grid must divide evenly by the column count or it leaves a short
   final row, and the number of related terms is whatever the group holds:
   four here, six there. Every arrangement that looked acceptable at one count
   broke at another.

   Rows remove the problem rather than tuning around it. Each spans the full
   width, so any number of them reads as deliberate, and the columns line up
   with .c-entry above so the page runs on a single grid from the first section
   to the last link instead of ending in a floating component.
   -------------------------------------------------------------------------- */
.c-onward {
  padding-block: var(--space-l);
  border-bottom: 1px solid var(--rule);
}

.c-onward__title {
  margin: 0 0 var(--space-xs);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.c-onward__list { list-style: none; margin: 0; padding: 0; }

.c-onward__row + .c-onward__row { border-top: 1px solid var(--rule); }

.c-onward__link {
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-areas:
    "num  term def"
    "num  def  def";
  align-items: baseline;
  gap: var(--space-2xs) var(--space-s);
  padding-block: var(--space-s);
  text-decoration: none;
  color: inherit;
}

/* The row tints on hover without a card border. The inline padding is negative
   space borrowed back on hover so the tint reads as a band rather than a box
   that appeared out of nowhere. */
.c-onward__link:hover,
.c-onward__link:focus-visible {
  background: var(--bg-sunken);
  box-shadow: 0 0 0 var(--space-xs) var(--bg-sunken);
}

.c-onward__num {
  grid-area: num;
  align-self: start;
  padding-top: 0.15em;
  font-size: var(--step--1);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.1em;
  color: var(--rule-strong);
}
.c-onward__link:hover .c-onward__num { color: var(--accent); }

.c-onward__term {
  grid-area: term;
  font-weight: 700;
  font-size: var(--step-0);
  color: var(--ink-strong);
}
.c-onward__link:hover .c-onward__term { color: var(--accent); }

.c-onward__def {
  grid-area: def;
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--ink-muted);
}

.c-onward__go {
  grid-area: go;
  align-self: center;
  display: none;
  color: var(--accent);
  transition: transform var(--dur-base) var(--ease-out);
}
.c-onward__link:hover .c-onward__go { transform: translateX(4px); }

@media (min-width: 48em) {
  /* Term and definition sit side by side, on the same 14rem rail the section
     headings use. The arrow only appears here: on a handset the whole row is
     the target and the arrow is decoration competing for narrow space. */
  .c-onward__link {
    grid-template-columns: 2.5rem minmax(0, 14rem) minmax(0, 1fr) auto;
    grid-template-areas: "num term def go";
    align-items: center;
    gap: var(--space-m);
    padding-block: var(--space-m);
  }
  .c-onward__num { align-self: center; padding-top: 0; }
  .c-onward__go  { display: block; }
}

@media (prefers-reduced-motion: reduce) {
  .c-onward__go { transition: none; }
  .c-onward__link:hover .c-onward__go { transform: none; }
}

/* -- Stub note and footer link --------------------------------------------- */
.c-termnote {
  padding-block: var(--space-l);
  margin: 0;
  font-size: var(--step-0);
  color: var(--ink-muted);
  border-bottom: 1px solid var(--rule);
}

.c-termback {
  padding-block: var(--space-m);
  margin: 0;
  font-size: var(--step--1);
}

@media (prefers-reduced-motion: reduce) {
  .c-entry__head { position: static; }
}

/* --------------------------------------------------------------------------
   Quiz
   -------------------------------------------------------------------------- */

/* -- Start panel ----------------------------------------------------------- */
.c-quizstart {
  display: grid;
  gap: var(--space-l);
  padding-block: var(--space-l);
  border-bottom: 1px solid var(--rule);
}

.c-quizstart__facts {
  display: grid;
  gap: var(--space-m);
  grid-template-columns: 1fr;
}

.c-quizstart__fact { display: flex; flex-direction: column; gap: var(--space-3xs); }

.c-quizstart__n {
  font-size: clamp(2.2rem, 6vw, 3.4rem);
  font-weight: 800;
  line-height: 1;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.c-quizstart__l { font-size: var(--step--1); color: var(--ink-muted); line-height: 1.4; }

.c-quizstart__go { display: flex; flex-direction: column; gap: var(--space-xs); align-items: flex-start; }
.c-quizstart__go .c-note { margin: 0; }

.c-btn--lg { padding: 0.9em 1.6em; font-size: var(--step-0); }

@media (min-width: 48em) {
  .c-quizstart { grid-template-columns: minmax(0, 1fr) auto; align-items: end; }
  .c-quizstart__facts { grid-template-columns: repeat(3, auto); gap: var(--space-xl); }
}

/* -- Topic tags ------------------------------------------------------------ */
.c-taglist {
  display: flex; flex-wrap: wrap; gap: var(--space-2xs);
  list-style: none; margin: var(--space-s) 0 0; padding: 0;
}
.c-tag {
  display: inline-flex; align-items: center; gap: var(--space-2xs);
  padding: 0.3em 0.7em;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  font-size: var(--step--1);
}
.c-tag__n { font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }

/* -- Progress -------------------------------------------------------------- */
.c-quizbar { position: sticky; top: var(--header-h, 76px); z-index: 3;
  padding-block: var(--space-s); background: var(--bg-page); }
.c-quizbar__track { height: 4px; border-radius: 999px; background: var(--rule); overflow: hidden; }
.c-quizbar__fill  { display: block; height: 100%; width: 0; background: var(--accent);
  transition: width var(--dur-base) var(--ease-out); }
.c-quizbar__text  { margin: var(--space-2xs) 0 0; font-size: var(--step--1); color: var(--ink-muted); }

/* -- Questions ------------------------------------------------------------- */
.c-quizlist { list-style: none; margin: 0; padding: 0; }

.c-quizq { padding-block: var(--space-l); border-bottom: 1px solid var(--rule); }
.c-quizq fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }

.c-quizq__legend { display: block; width: 100%; padding: 0; margin-bottom: var(--space-m); }
.c-quizq__legend:focus-visible { outline: 3px solid var(--focus-outer); outline-offset: 4px; }

.c-quizq__num {
  display: block; margin-bottom: var(--space-2xs);
  font-size: var(--step--1); font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--accent);
}
.c-quizq__prompt {
  display: block; font-size: var(--step-1); line-height: 1.3;
  font-weight: 700; color: var(--ink-strong); text-wrap: pretty;
}

.c-quizq__options { display: grid; gap: var(--space-2xs); }

/* The whole row is the target, not just the dot. */
.c-choice {
  display: flex; align-items: flex-start; gap: var(--space-s);
  padding: var(--space-s);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-m);
  cursor: pointer;
  transition: border-color var(--dur-base) var(--ease-out),
              background var(--dur-base) var(--ease-out);
}
.c-choice:hover { border-color: var(--accent); background: var(--bg-sunken); }
.c-choice input { margin-top: 0.25em; flex: none; width: 1.15rem; height: 1.15rem; accent-color: var(--accent); }
.c-choice__body { line-height: 1.5; }
.c-choice:has(input:checked) { border-color: var(--accent); background: var(--bg-sunken); }
.c-choice:has(input:focus-visible) { outline: 3px solid var(--focus-outer); outline-offset: 2px; }

.c-quizactions {
  display: flex; flex-wrap: wrap; gap: var(--space-s);
  padding-block: var(--space-l);
}

/* -- Score ----------------------------------------------------------------- */
.c-score {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-m);
  padding-block: var(--space-m) var(--space-l);
  border-bottom: 1px solid var(--rule);
}
.c-score__figure { margin: 0; line-height: 1; }
.c-score__n {
  font-size: clamp(3.4rem, 13vw, 6.5rem); font-weight: 800;
  color: var(--ink-strong); font-variant-numeric: tabular-nums;
}
.c-score__of { font-size: clamp(1.6rem, 5vw, 2.4rem); font-weight: 700; color: var(--ink-muted); }
.c-score__meta { flex: 1 1 14rem; }
.c-score__pct { margin: 0; font-size: var(--step-1); font-weight: 700; color: var(--accent); }
.c-score__note { margin: var(--space-2xs) 0 0; color: var(--ink-muted); }
.c-score__caveat {
  padding-block: var(--space-m);
  font-size: var(--step--1); line-height: 1.6; color: var(--ink-muted);
}

/* -- Review ---------------------------------------------------------------- */
.c-review__title {
  margin: 0 0 var(--space-xs);
  font-size: var(--step--1); font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-muted);
}

.c-review { list-style: none; margin: 0; padding: 0; }

.c-review__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-s);
  padding-block: var(--space-m);
  border-top: 1px solid var(--rule);
}

.c-review__mark {
  display: flex; align-items: center; justify-content: center;
  width: 1.75rem; height: 1.75rem; border-radius: 999px; flex: none;
}
.is-right .c-review__mark { background: var(--state-live); color: #FFFFFF; }
.is-wrong .c-review__mark { background: var(--state-alert, #A8321E); color: #FFFFFF; }

.c-review__q { margin: 0 0 var(--space-2xs); font-weight: 700; color: var(--ink-strong); }
.c-review__yours { margin: 0 0 var(--space-2xs); font-size: var(--step--1); color: var(--ink-muted); }
.c-review__answer { margin: 0 0 var(--space-2xs); }
.c-review__label {
  display: inline-block; margin-right: var(--space-2xs);
  font-size: var(--step--1); font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--state-live);
}
.c-review__why { margin: 0 0 var(--space-2xs); font-size: var(--step--1); line-height: 1.55; color: var(--ink-muted); }
.c-review__source { margin: 0; font-size: var(--step--1); }

.c-quizagain { padding-block: var(--space-l); display: flex; flex-direction: column;
  align-items: flex-start; gap: var(--space-xs); }
.c-quizagain .c-note { margin: 0; }

.c-quizpaper__lede { font-size: var(--step-1); color: var(--ink-muted); }

@media (prefers-reduced-motion: reduce) {
  .c-quizbar__fill, .c-choice { transition: none; }
}

/* --------------------------------------------------------------------------
   Account and dashboard
   -------------------------------------------------------------------------- */
.c-authcol { max-width: 46rem; }

.c-roles { display: grid; gap: var(--space-2xs); }
.c-choice__hint { display: block; font-size: var(--step--1); color: var(--ink-muted); margin-top: 0.15em; }
.c-choice__body strong { display: block; color: var(--ink-strong); }

.c-dash__sub { margin: var(--space-2xs) 0 0; color: var(--ink-muted); }
.c-dash__signout { padding-block: var(--space-l); }

.c-dashpanel { padding-block: var(--space-l); border-top: 1px solid var(--rule); }
.c-dashpanel:first-of-type { border-top: 1px solid var(--rule); }

.c-dashpanel__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-s); margin-bottom: var(--space-s);
}
.c-dashpanel__title {
  margin: 0; font-size: var(--step--1); font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-muted);
}
.c-dashpanel__count { font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }
.c-dashpanel__more { font-size: var(--step--1); }
.c-dashpanel__empty { margin: 0; color: var(--ink-muted); }

/* Stat strip */
.c-statrow { display: flex; flex-wrap: wrap; gap: var(--space-xl); margin-bottom: var(--space-m); }
.c-stat { display: flex; flex-direction: column; }
.c-stat__n {
  font-size: clamp(1.8rem, 5vw, 2.6rem); font-weight: 800; line-height: 1;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
.c-stat__l { font-size: var(--step--1); color: var(--ink-muted); }

/* Generic full-width row list. Rows, never a card grid: the count is whatever
   the query returned and rows cannot leave an orphan. */
.c-rows { list-style: none; margin: 0; padding: 0; }
.c-rows__row + .c-rows__row { border-top: 1px solid var(--rule); }
.c-rows__link {
  display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: var(--space-xs);
  padding-block: var(--space-s); text-decoration: none; color: inherit;
}
a.c-rows__link:hover { background: var(--bg-sunken); box-shadow: 0 0 0 var(--space-xs) var(--bg-sunken); }
.c-rows__main { font-weight: 700; color: var(--ink-strong); }
a.c-rows__link:hover .c-rows__main { color: var(--accent); }
.c-rows__meta { font-size: var(--step--1); color: var(--ink-muted); display: flex; gap: var(--space-2xs); align-items: center; }

.c-pill {
  display: inline-block; padding: 0.15em 0.6em; border-radius: 999px;
  border: 1px solid var(--rule-strong); font-size: var(--step--1);
  text-transform: capitalize;
}

/* --------------------------------------------------------------------------
   Manufacturer directory
   --------------------------------------------------------------------------
   Rows grouped by country. Not a card grid: a country holds however many
   marques it holds, and every column count that made one country's row full
   left another with an orphan. Rows cannot be uneven.
   -------------------------------------------------------------------------- */
.c-mfrtools {
  display: grid;
  gap: var(--space-m);
  padding-block: var(--space-m) var(--space-l);
  border-bottom: 1px solid var(--rule);
}

.c-mfrtools__search label {
  display: block;
  font-weight: 700;
  margin-bottom: var(--space-2xs);
}
.c-mfrtools__search input { width: 100%; }

.c-mfrtools__jump { display: flex; flex-wrap: wrap; gap: var(--space-2xs); }

.c-chip {
  display: inline-flex; align-items: center; gap: var(--space-2xs);
  min-height: 40px; padding: 0 var(--space-s);
  border: 1px solid var(--rule-strong); border-radius: 999px;
  font-size: var(--step--1); text-decoration: none; color: var(--ink-strong);
}
.c-chip:hover { border-color: var(--accent); color: var(--accent); background: var(--bg-sunken); }
.c-chip__n { font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }

.c-mfrgroup { padding-block: var(--space-l) 0; scroll-margin-top: calc(var(--header-h, 76px) + var(--space-m)); }

.c-mfrgroup__title {
  display: flex; align-items: baseline; gap: var(--space-xs);
  margin: 0 0 var(--space-xs);
  font-size: var(--step-1);
  padding-bottom: var(--space-2xs);
  border-bottom: 1px solid var(--rule);
}
.c-mfrgroup__n {
  font-size: var(--step--1); font-weight: 400; color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.c-mfrlist { list-style: none; margin: 0; padding: 0; }
.c-mfrlist__row + .c-mfrlist__row { border-top: 1px solid var(--rule); }

.c-mfrlist__link {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "name  count" "desc  desc" "kind  kind";
  gap: var(--space-2xs) var(--space-s);
  align-items: baseline;
  padding-block: var(--space-s);
  text-decoration: none; color: inherit;
}
.c-mfrlist__link:hover,
.c-mfrlist__link:focus-visible {
  background: var(--bg-sunken);
  box-shadow: 0 0 0 var(--space-xs) var(--bg-sunken);
}

.c-mfrlist__name { grid-area: name; font-weight: 700; font-size: var(--step-0); color: var(--ink-strong); }
.c-mfrlist__link:hover .c-mfrlist__name { color: var(--accent); }
.c-mfrlist__desc { grid-area: desc; font-size: var(--step--1); line-height: 1.5; color: var(--ink-muted); }
.c-mfrlist__kind { grid-area: kind; white-space: nowrap; }
.c-mfrlist__count { grid-area: count; font-size: var(--step--1); color: var(--ink-muted); white-space: nowrap; }
.c-mfrlist__count strong { color: var(--accent); font-variant-numeric: tabular-nums; }
.c-mfrlist__none { color: var(--ink-muted); }
.c-mfrlist__go { grid-area: go; display: none; align-self: center; color: var(--accent); }

@media (min-width: 48em) {
  .c-mfrtools { grid-template-columns: minmax(0, 22rem) minmax(0, 1fr); align-items: start; }
  .c-mfrlist__link {
    grid-template-columns: minmax(0, 15rem) minmax(0, 1fr) auto auto auto;
    grid-template-areas: "name desc kind count go";
    align-items: center;
    gap: var(--space-m);
    padding-block: var(--space-m);
  }
  .c-mfrlist__go { display: block; }
}

.c-linkbtn {
  background: none; border: 0; padding: 0;
  font: inherit; color: var(--accent); text-decoration: underline; cursor: pointer;
}

/* Quoted material inside a question. Set apart from the instruction above it:
   run together on one line the two read as a single run-on sentence and the
   reader has to hunt for where the question ends. */
.c-quizq__quote {
  display: block;
  margin-top: var(--space-s);
  padding-left: var(--space-s);
  border-left: 3px solid var(--accent);
  font-weight: 400;
  font-size: var(--step-0);
  line-height: 1.55;
  color: var(--ink-strong);
}

.c-review__quote {
  margin: 0 0 var(--space-2xs);
  padding-left: var(--space-s);
  border-left: 3px solid var(--rule-strong);
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--ink-muted);
}

/* Strong notice. Used where the disclaimer is load-bearing rather than
   decorative: a page headed "ground school" is read as instruction whatever
   the footer says, so this sits above the content and looks like it means it. */
.c-notice-strong {
  padding: var(--space-m);
  margin-block: var(--space-m) var(--space-l);
  background: var(--bg-sunken);
  border-left: 4px solid var(--accent);
  border-radius: 0 var(--radius-m) var(--radius-m) 0;
}
.c-notice-strong--tight { margin-block: var(--space-s) var(--space-m); }
.c-notice-strong__title {
  margin: 0 0 var(--space-2xs);
  font-size: var(--step-1);
  color: var(--ink-strong);
}
.c-notice-strong p { margin: 0 0 var(--space-xs); line-height: 1.6; }
.c-notice-strong p:last-child { margin-bottom: 0; }

.c-sources { padding-block: var(--space-l) 0; }

/* --------------------------------------------------------------------------
   Ground school module list
   --------------------------------------------------------------------------
   This started as a reuse of .c-onward, which is sized for a related-terms
   list in a narrow column. On a full-width page at 1900px it came apart: the
   14rem title track forced every title onto two lines, the status pills wrapped
   into the middle of them, and a one-sentence description sat stranded in an
   800px track with the arrow a hand-span away.

   The fix is proportional tracks rather than one fixed and one 1fr. Title and
   description both scale with the viewport, so neither is starved at 1200px
   nor marooned at 1900px, and the status column gives the extra width
   something to do instead of turning it into a gap.
   -------------------------------------------------------------------------- */
.c-modules__heading {
  margin: var(--space-xl) 0 0;
  padding-bottom: var(--space-2xs);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-muted);
  border-bottom: 1px solid var(--rule);
}

.c-modules { list-style: none; margin: 0; padding: 0; }
.c-modules__row + .c-modules__row { border-top: 1px solid var(--rule); }

/* Mobile: title, then description, then meta. The number and arrow are
   suppressed rather than squeezed. */
.c-modules__link {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas:
    "num  title"
    "num  desc"
    "num  meta";
  gap: var(--space-2xs) var(--space-s);
  padding-block: var(--space-m);
  text-decoration: none;
  color: inherit;
}
.c-modules__link:hover,
.c-modules__link:focus-visible {
  background: var(--bg-sunken);
  box-shadow: 0 0 0 var(--space-xs) var(--bg-sunken);
}

.c-modules__num {
  grid-area: num;
  align-self: start;
  padding-top: 0.2em;
  font-size: var(--step--1);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.1em;
  color: var(--rule-strong);
}
.c-modules__link:hover .c-modules__num { color: var(--accent); }

.c-modules__title {
  grid-area: title;
  font-weight: 700;
  font-size: var(--step-0);
  line-height: 1.25;
  color: var(--ink-strong);
  text-wrap: balance;
}
.c-modules__link:hover .c-modules__title { color: var(--accent); }

.c-modules__desc {
  grid-area: desc;
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--ink-muted);
}

.c-modules__meta {
  grid-area: meta;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  align-items: center;
}

.c-modules__time { font-size: var(--step--1); color: var(--ink-muted); white-space: nowrap; }
.c-modules__go   { grid-area: go; display: none; align-self: center; color: var(--accent); }

.c-pill--quiet {
  border-style: dashed;
  color: var(--ink-muted);
}

@media (min-width: 62em) {
  .c-modules__link {
    /* Proportional, not fixed-plus-1fr. Both text tracks grow together, so a
       short description never floats alone in a track sized for prose. */
    grid-template-columns: auto minmax(0, 1.35fr) minmax(0, 1.65fr) auto auto;
    grid-template-areas: "num title desc meta go";
    /* Top-align, not centre. Rows have different description lengths, and
       centring floated each title and description to the vertical middle of
       its own row, so no two lines started at the same height and the column
       read as ragged. Starting them at the top lines every title and every
       description up across the whole list. num and go opt back to centre. */
    align-items: start;
    gap: var(--space-l);
    padding-block: var(--space-m);
  }
  .c-modules__num { align-self: center; padding-top: 0; }
  .c-modules__meta { align-self: center; }
  .c-modules__meta { justify-content: flex-end; flex-wrap: nowrap; }
  .c-modules__go { display: block; }
}

/* The larger title waits for room to hold it on one line. Applied at the grid's
   own breakpoint it wrapped titles at 1024 and 1280, which are widths where the
   columns exist but are not yet generous. Measured, not guessed: the longest
   module title needs about 1400px of viewport before step-1 fits on one line. */
@media (min-width: 88em) {
  .c-modules__title { font-size: var(--step-1); }
}

/* -- CFI directory --------------------------------------------------------- */
.c-cfisearch {
  display: grid;
  gap: var(--space-s);
  padding-block: var(--space-m) var(--space-l);
  border-bottom: 1px solid var(--rule);
}
.c-cfisearch input, .c-cfisearch select { width: 100%; }
.c-cfisearch__go { display: flex; gap: var(--space-xs); align-items: end; }
.c-cfisearch__jump { display: flex; flex-wrap: wrap; gap: var(--space-2xs); padding-block: var(--space-m); }

@media (min-width: 56em) {
  .c-cfisearch {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr) auto;
    align-items: end;
  }
}

.c-cfimeta {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-s); padding-block: var(--space-m);
}
.c-cfimeta p { margin: 0; color: var(--ink-muted); }

.c-pill--ok { border-color: var(--state-live); color: var(--state-live); font-weight: 700; }

/* Founding-rate flag on the membership tiers. Filled accent, so it reads as a
   claim worth acting on rather than a neutral tag. */
.c-pill--founding {
  display: inline-block;
  margin-bottom: var(--space-3xs);
  padding: 0.12em 0.6em;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: none;
}

/* Verification statement. Deliberately not a bare green tick: the wording is
   the claim, and the claim is narrow. */
.c-verify {
  padding: var(--space-m);
  margin-block: var(--space-m) var(--space-l);
  background: var(--bg-sunken);
  border-left: 4px solid var(--rule-strong);
  border-radius: 0 var(--radius-m) var(--radius-m) 0;
}
.c-verify--ok { border-left-color: var(--state-live); }
.c-verify__head {
  margin: 0 0 var(--space-2xs);
  font-weight: 700; font-size: var(--step-0); color: var(--ink-strong);
}
.c-verify p { margin: 0 0 var(--space-xs); line-height: 1.6; }
.c-verify p:last-child { margin-bottom: 0; }
.c-verify__limit { font-size: var(--step--1); color: var(--ink-muted); }

/* Fact list. Rows, full width, label left. */
.c-factlist { margin: 0; padding: 0; }
.c-factlist__row {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-3xs);
  padding-block: var(--space-s); border-bottom: 1px solid var(--rule);
}
.c-factlist dt {
  font-size: var(--step--1); font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-muted);
}
.c-factlist dd { margin: 0; color: var(--ink-strong); }
.c-factlist__note { display: block; font-size: var(--step--1); color: var(--ink-muted); }

@media (min-width: 48em) {
  .c-factlist__row { grid-template-columns: minmax(0, 14rem) minmax(0, 1fr); gap: var(--space-m); align-items: baseline; }
}

/* --------------------------------------------------------------------------
   Membership tiers
   --------------------------------------------------------------------------
   Rows, not pricing cards. Four tiers divides evenly into a four-column grid,
   which is the trap: it looks correct until a fifth is added or one retires,
   and then it orphans. Rows are stable at any count, and they give the benefit
   list room to be read rather than truncated into a card.
   -------------------------------------------------------------------------- */
.c-tiers { list-style: none; margin: 0; padding: 0; }
.c-tiers__row {
  display: grid;
  gap: var(--space-s);
  padding-block: var(--space-l);
  border-top: 1px solid var(--rule);
}
.c-tiers__row:first-child { border-top: 1px solid var(--rule); }

.c-tiers__name { margin: 0; font-size: var(--step-1); color: var(--ink-strong); }
.c-tiers__audience { margin: var(--space-3xs) 0 0; font-size: var(--step--1); color: var(--ink-muted); }

.c-tiers__price { display: flex; align-items: baseline; gap: var(--space-2xs); }
.c-tiers__amount {
  font-size: clamp(1.9rem, 5vw, 2.6rem); font-weight: 800; line-height: 1;
  color: var(--accent); font-variant-numeric: tabular-nums;
}
.c-tiers__period { font-size: var(--step--1); color: var(--ink-muted); }

.c-tiers__summary { margin: 0 0 var(--space-s); color: var(--ink-strong); }

.c-tiers__benefits { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2xs); }
.c-tiers__benefits li {
  display: flex; flex-wrap: wrap; gap: var(--space-2xs); align-items: baseline;
  padding-left: 1.2em; position: relative; line-height: 1.5;
}
.c-tiers__benefits li::before {
  content: ""; position: absolute; left: 0; top: 0.55em;
  width: 0.45em; height: 0.45em; border-radius: 50%; background: var(--state-live);
}
/* A benefit that does not exist yet is dimmed and labelled, never hidden. */
.c-tiers__benefits li.is-planned { color: var(--ink-muted); }
.c-tiers__benefits li.is-planned::before { background: var(--rule-strong); }

.c-tiers__not {
  margin: var(--space-m) 0 0; padding-left: var(--space-s);
  border-left: 3px solid var(--rule-strong);
  font-size: var(--step--1); line-height: 1.55; color: var(--ink-muted);
}
.c-tiers__not strong { color: var(--ink-strong); }

.c-tiers__go { align-self: start; }

@media (min-width: 62em) {
  .c-tiers__row {
    grid-template-columns: minmax(0, 14rem) minmax(0, 10rem) minmax(0, 1fr) auto;
    grid-template-areas: "head price body go";
    gap: var(--space-l);
    align-items: start;
  }
  .c-tiers__head  { grid-area: head; }
  .c-tiers__price { grid-area: price; flex-direction: column; gap: 0; }
  .c-tiers__body  { grid-area: body; }
  .c-tiers__go    { grid-area: go; }
}

/* --------------------------------------------------------------------------
   Bootcamp packages
   --------------------------------------------------------------------------
   Two side-by-side offer cards on the /bootcamp page. One column on a handset,
   two once there is room. The featured card carries a brand border and a corner
   ribbon so the "fastest path" option leads without a second visual language.
   -------------------------------------------------------------------------- */
.c-packages {
  display: grid;
  gap: var(--space-l);
  grid-template-columns: 1fr;
  margin-top: var(--space-s);
}
@media (min-width: 48em) {
  .c-packages { grid-template-columns: 1fr 1fr; gap: var(--space-xl); }
}

.c-package {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-low);
  overflow: hidden;
  transition: transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}
.c-package:hover { transform: translateY(-3px); box-shadow: var(--shadow-mid); }
.c-package--featured { border: 2px solid var(--azure-400); }

.c-package__ribbon {
  position: absolute;
  top: 0;
  right: 0;
  background: var(--azure-400);
  color: #FFFFFF;
  font-size: var(--step--2);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.35em 0.9em;
  border-bottom-left-radius: var(--radius-m);
}

.c-package__body { padding: var(--space-l); flex-grow: 1; }
.c-package__kicker {
  margin: 0 0 var(--space-3xs);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}
.c-package__name { margin: 0 0 var(--space-2xs); font-size: var(--step-2); color: var(--ink-strong); }
.c-package__blurb { margin: 0 0 var(--space-s); color: var(--ink-muted); line-height: 1.5; }

.c-package__price {
  display: flex;
  align-items: baseline;
  gap: var(--space-2xs);
  margin: 0 0 var(--space-m);
  padding-bottom: var(--space-m);
  border-bottom: 1px solid var(--rule);
}
.c-package__amount {
  font-family: var(--font-display);
  font-size: var(--step-4);
  font-weight: 800;
  color: var(--ink-strong);
  line-height: 1;
  letter-spacing: -0.015em;
}
.c-package__unit { font-size: var(--step--1); color: var(--ink-muted); font-weight: 500; }

.c-package__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2xs); }
.c-package__list li { display: flex; align-items: flex-start; gap: var(--space-2xs); line-height: 1.5; }
.c-package__list strong { color: var(--ink-strong); }

.c-package__check {
  flex-shrink: 0;
  width: 1.4rem;
  height: 1.4rem;
  margin-top: 0.1em;
  color: var(--accent);
}
.c-package__check--strong { color: var(--state-live); }

.c-package__foot {
  padding: var(--space-m) var(--space-l) var(--space-l);
  border-top: 1px solid var(--rule);
  background: color-mix(in oklab, var(--silver-400) 8%, transparent);
}
.c-package__cta { width: 100%; }

.c-package__terms {
  margin-top: var(--space-l);
  padding-left: var(--space-s);
  border-left: 3px solid var(--rule-strong);
  color: var(--ink-muted);
  font-size: var(--step--1);
  line-height: 1.55;
}
.c-package__terms p { margin: 0 0 var(--space-2xs); }
.c-package__terms p:last-child { margin-bottom: 0; }
.c-package__terms strong { color: var(--ink-strong); }

/* Lodging add-on callout: sits between the cards and the comparison table. */
.c-lodging {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m);
  margin-top: var(--space-l);
  padding: var(--space-m) var(--space-l);
  background: color-mix(in oklab, var(--azure-400) 8%, var(--paper));
  border: 1px solid color-mix(in oklab, var(--azure-400) 30%, transparent);
  border-radius: var(--radius-l);
}
.c-lodging__body { flex: 1 1 22rem; }
.c-lodging__body p { margin: 0; color: var(--ink-strong); line-height: 1.5; }
.c-lodging__kicker {
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 var(--space-3xs) !important;
}
.c-lodging .c-btn { flex-shrink: 0; }

/* --------------------------------------------------------------------------
   Bootcamp comparison table
   -------------------------------------------------------------------------- */
.c-compare-block { margin-top: var(--space-2xl); }
.c-compare-block__kicker {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 var(--space-3xs);
}
.c-compare-block__title { margin: 0 0 var(--space-2xs); font-size: var(--step-2); color: var(--ink-strong); }
.c-compare-block__lede { margin: 0 0 var(--space-l); max-width: 60ch; color: var(--ink-muted); line-height: 1.6; }
.c-compare-block__note { margin: var(--space-s) 0 0; font-size: var(--step--2); color: var(--ink-muted); line-height: 1.5; }

.c-compare {
  width: 100%;
  min-width: 46rem;
  border-collapse: collapse;
  font-size: var(--step--1);
  text-align: left;
}
.c-compare th,
.c-compare td {
  padding: var(--space-s);
  border-bottom: 1px solid var(--rule);
  vertical-align: top;
}
.c-compare thead th {
  font-size: var(--step--2);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-muted);
  font-weight: 600;
  background: var(--silver-100);
}
.c-compare thead th span { display: block; text-transform: none; letter-spacing: 0; color: var(--ink-strong); font-size: var(--step--1); }
.c-compare tbody th[scope="row"] { font-weight: 600; color: var(--ink-strong); width: 12rem; }
.c-compare td strong { color: var(--ink-strong); font-size: var(--step-0); }
.c-compare__sub { display: block; margin-top: var(--space-3xs); font-size: var(--step--2); color: var(--ink-muted); }
.c-compare__breakdown { list-style: none; margin: var(--space-2xs) 0 0; padding: 0; display: grid; gap: 0.15rem; }
.c-compare__breakdown li { font-size: var(--step--2); color: var(--ink-muted); line-height: 1.4; }

/* The winning column: a soft azure wash top to bottom, and a solid crown so it
   reads as the answer the table is building toward. */
.c-compare__gyro { background: color-mix(in oklab, var(--azure-400) 10%, var(--paper)); }
.c-compare thead th.c-compare__gyro { background: color-mix(in oklab, var(--azure-400) 22%, var(--paper)); color: var(--accent); }
.c-compare thead th.c-compare__gyro span { color: var(--accent); }
td.c-compare__gyro strong { color: var(--accent); }

.c-compare__con { color: var(--state-alert); }
.c-compare__pro { color: var(--state-live); font-weight: 600; }

/* The closing row states the number the whole table argues for. */
.c-compare__valuerow th[scope="row"],
.c-compare__valuerow td { background: var(--navy-900); color: var(--ink-invert-muted); border-bottom: 0; }
.c-compare__valuerow th[scope="row"] { color: #FFFFFF; }
.c-compare__valuerow td.c-compare__gyro { background: var(--accent); color: #FFFFFF; }
.c-compare__valuerow td.c-compare__gyro strong { display: block; color: #FFFFFF; font-size: var(--step-2); margin-bottom: var(--space-3xs); }
.c-compare__valuerow td.c-compare__gyro span { font-size: var(--step--2); color: color-mix(in oklab, #FFFFFF 82%, var(--accent)); }

/* --------------------------------------------------------------------------
   Calculators (/tools)
   --------------------------------------------------------------------------
   Inputs on the left, a live readout on the right. The readout is the dark
   panel because it is the answer, and the answer should be the thing the eye
   lands on when a value changes.
   -------------------------------------------------------------------------- */
.c-tool { display: grid; gap: var(--space-l); align-items: start; }
@media (min-width: 52em) {
  .c-tool { grid-template-columns: 3fr 2fr; }
}
.c-tool__inputs {
  display: grid;
  gap: var(--space-m);
  padding: var(--space-l);
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius-l);
}
.c-tool__results {
  background: var(--navy-900);
  color: var(--ink-invert);
  border-radius: var(--radius-l);
  padding: var(--space-l);
}
.c-tool__rlabel {
  margin: 0;
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  color: var(--ink-invert-muted);
}
.c-tool__big {
  font-family: var(--font-display);
  font-size: var(--step-4);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: #FFFFFF;
  margin: var(--space-3xs) 0 var(--space-m);
  font-variant-numeric: tabular-nums;
}
.c-tool__results .c-calc__stats { padding-top: var(--space-m); }
.c-tool__verdict {
  margin: var(--space-m) 0 0;
  padding-top: var(--space-m);
  border-top: 1px solid color-mix(in oklab, #FFFFFF 14%, transparent);
  font-size: var(--step--1);
  line-height: 1.55;
  color: var(--ink-invert-muted);
}

/* A cell for a figure the manufacturer does not publish. Muted and italic so
   it reads as absent data at a glance and is never mistaken for a value. */
.c-compare__none { color: var(--ink-muted); font-style: italic; }

/* Ground school landing: "what is inside" beside the sign-up / progress card. */
.c-gsplit { display: grid; gap: var(--space-l); margin: var(--space-xl) 0 var(--space-2xl); }
@media (min-width: 56em) { .c-gsplit { grid-template-columns: 1.15fr 1fr; align-items: start; } }
.c-gsignup {
  background: color-mix(in oklab, var(--azure-400) 8%, var(--paper));
  border: 1px solid color-mix(in oklab, var(--azure-400) 30%, transparent);
  border-radius: var(--radius-l);
  padding: var(--space-l);
}
.c-gsignup__big {
  margin: 0 0 var(--space-s);
  font-family: var(--font-display);
  font-size: var(--step-4);
  font-weight: 800;
  line-height: 1;
  color: var(--ink-strong);
  font-variant-numeric: tabular-nums;
}
.c-gsignup__big span { font-size: var(--step-0); font-weight: 600; color: var(--ink-muted); }

.c-progress { height: 10px; border-radius: 999px; background: color-mix(in oklab, var(--navy-900) 12%, transparent); overflow: hidden; }
.c-progress > span { display: block; height: 100%; background: var(--accent); border-radius: 999px; transition: width var(--dur-base) var(--ease-out); }

.c-pill--done { border-color: var(--state-live); color: var(--state-live); font-weight: 700; white-space: nowrap; }

/* --------------------------------------------------------------------------
   Ground school lesson player + quiz
   -------------------------------------------------------------------------- */
.c-lesson__intro {
  background: color-mix(in oklab, var(--azure-400) 7%, var(--paper));
  border: 1px solid color-mix(in oklab, var(--azure-400) 28%, transparent);
  border-radius: var(--radius-l);
  padding: var(--space-l);
  transition: opacity var(--dur-base);
}
.c-lesson__intro.is-done { opacity: 0.55; }
.c-lesson__meta { margin: 0 0 var(--space-2xs); font-size: var(--step--1); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--accent); }
.c-lesson__intro h2 { margin: 0 0 var(--space-s); }
.c-lesson__goals { margin: 0 0 var(--space-l); padding-left: 1.2em; display: grid; gap: var(--space-2xs); color: var(--ink-strong); }
.c-btn--lg { font-size: var(--step-0); padding-block: 0.85em; }

.c-lesson__steps { list-style: none; margin: var(--space-xl) 0 0; padding: 0; display: grid; gap: var(--space-xl); }
.c-lesson__step { scroll-margin-top: calc(var(--header-h, 76px) + var(--space-m)); }
.c-lesson__step-n { margin: 0 0 var(--space-3xs); font-size: var(--step--1); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--accent); }
.c-lesson__step h2 { margin: 0 0 var(--space-s); }
.c-lesson__step > p { max-width: 68ch; line-height: 1.6; }
.c-lesson__step h2:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

.c-lesson__two { display: grid; gap: var(--space-m); margin-top: var(--space-m); }
@media (min-width: 44em) { .c-lesson__two { grid-template-columns: 1fr 1fr; } }
.c-lesson__def { padding: var(--space-m); border-radius: var(--radius-m); background: var(--paper); border: 1px solid var(--rule); border-left: 4px solid var(--accent); }
.c-lesson__def--warn { border-left-color: var(--state-alert); }
.c-lesson__def h3 { margin: 0 0 var(--space-2xs); font-size: var(--step-0); }
.c-lesson__def p { margin: 0; color: var(--ink-muted); line-height: 1.55; }

.c-lesson__figure { margin: var(--space-m) 0 0; padding: var(--space-m); background: var(--paper); border: 1px solid var(--rule); border-radius: var(--radius-l); }
.c-diagram { display: block; width: 100%; max-width: 30rem; height: auto; margin: 0 auto; }
.c-lesson__figure figcaption { margin-top: var(--space-s); text-align: center; font-size: var(--step--1); color: var(--ink-muted); }

.c-lesson__sources { margin-top: var(--space-2xl); font-size: var(--step--2); color: var(--ink-muted); line-height: 1.5; }

/* Quiz */
.c-quiz { margin-top: var(--space-2xl); padding: var(--space-l); background: var(--navy-900); color: var(--ink-invert); border-radius: var(--radius-l); }
.c-quiz__heading { margin: 0 0 var(--space-2xs); color: #FFFFFF; }
.c-quiz__intro { margin: 0 0 var(--space-l); color: var(--ink-invert-muted); }
.c-quiz__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-l); }
.c-quiz__prompt { margin: 0 0 var(--space-s); font-weight: 700; color: #FFFFFF; font-size: var(--step-0); }
.c-quiz__opts { display: grid; gap: var(--space-2xs); }
.c-quiz__opt {
  text-align: left;
  padding: var(--space-2xs) var(--space-s);
  min-height: 2.75rem;
  background: color-mix(in oklab, #FFFFFF 7%, transparent);
  border: 1px solid color-mix(in oklab, #FFFFFF 18%, transparent);
  border-radius: var(--radius-m);
  color: #FFFFFF;
  font: inherit;
  cursor: pointer;
  transition: background var(--dur-fast), border-color var(--dur-fast);
}
.c-quiz__opt:hover:not(:disabled) { background: color-mix(in oklab, #FFFFFF 14%, transparent); }
.c-quiz__opt:disabled { cursor: default; }
.c-quiz__opt.is-correct { background: color-mix(in oklab, var(--state-live) 40%, transparent); border-color: var(--state-live); font-weight: 700; }
.c-quiz__opt.is-wrong { background: color-mix(in oklab, var(--state-alert) 35%, transparent); border-color: var(--state-alert); }
.c-quiz__why { margin: var(--space-s) 0 0; padding-left: var(--space-s); border-left: 3px solid var(--azure-400); color: var(--ink-invert-muted); line-height: 1.55; }
.c-quiz__result { margin-top: var(--space-l); padding-top: var(--space-l); border-top: 1px solid color-mix(in oklab, #FFFFFF 18%, transparent); }
.c-quiz__score { margin: 0 0 var(--space-m); font-family: var(--font-display); font-size: var(--step-1); font-weight: 800; color: #FFFFFF; }

@media (forced-colors: active) {
  .c-quiz__opt.is-correct { border-width: 3px; }
  .c-quiz__opt.is-wrong { border-style: dashed; }
}

/* Responsive 16:9 video embed (model pages, lesson videos). */
.c-video {
  position: relative;
  width: 100%;
  max-width: 56rem;
  aspect-ratio: 16 / 9;
  background: var(--navy-900);
  border-radius: var(--radius-l);
  overflow: hidden;
}
.c-video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* Study notes panel on a lesson. */
.c-notes {
  margin-top: var(--space-xl);
  padding: var(--space-l);
  background: color-mix(in oklab, var(--azure-400) 6%, var(--paper));
  border: 1px solid color-mix(in oklab, var(--azure-400) 25%, transparent);
  border-radius: var(--radius-l);
}
.c-notes__head h2 { margin: 0 0 var(--space-3xs); font-size: var(--step-1); }
.c-notes__head p { margin: 0 0 var(--space-s); color: var(--ink-muted); font-size: var(--step--1); }
.c-notes__area {
  width: 100%;
  padding: var(--space-s);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-m);
  font: inherit;
  line-height: 1.55;
  resize: vertical;
  background: var(--paper);
}
.c-notes__area:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.c-notes__bar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-s); margin-top: var(--space-s); }
.c-notes__status { font-size: var(--step--1); font-weight: 600; color: var(--accent); }

/* Unit heading inside the curriculum list. */
.c-modules__unit {
  margin: var(--space-l) 0 var(--space-2xs);
  font-size: var(--step-0);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--accent);
}

/* Ground school landing: pitch beside the sign-up / progress card. */
.c-gsplit { display: grid; gap: var(--space-l); margin-bottom: var(--space-2xl); }
@media (min-width: 52em) { .c-gsplit { grid-template-columns: 3fr 2fr; align-items: start; } }
.c-gsignup {
  padding: var(--space-l);
  background: color-mix(in oklab, var(--azure-400) 8%, var(--paper));
  border: 1px solid color-mix(in oklab, var(--azure-400) 30%, transparent);
  border-radius: var(--radius-l);
}
.c-gsignup__big {
  margin: 0 0 var(--space-s);
  font-family: var(--font-display);
  font-size: var(--step-3);
  font-weight: 800;
  color: var(--ink-strong);
  line-height: 1;
}
.c-gsignup__big span { font-family: var(--font-body, inherit); font-size: var(--step-0); font-weight: 600; color: var(--ink-muted); }

/* A completed lesson's pill. */
.c-pill--done {
  background: color-mix(in oklab, var(--state-live) 14%, var(--paper));
  border-color: var(--state-live);
  color: var(--state-live);
  font-weight: 700;
}

/* Thin progress bar (dashboard ground-school panel). */
.c-progress {
  width: 100%;
  height: 0.6rem;
  background: var(--silver-200);
  border-radius: 999px;
  overflow: hidden;
}
.c-progress > span { display: block; height: 100%; background: var(--accent); border-radius: 999px; }

/* Numbered step list for the "learn to fly" path. */
.c-steps { list-style: none; margin: var(--space-l) 0 0; padding: 0; display: grid; gap: var(--space-m); counter-reset: step; }
.c-steps > li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-m);
  align-items: start;
  padding: var(--space-m) var(--space-l);
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-low);
}
.c-steps__n {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.5rem; height: 2.5rem; flex-shrink: 0;
  background: var(--navy-900); color: #FFFFFF;
  border-radius: 999px;
  font-family: var(--font-display); font-weight: 800; font-size: var(--step-1);
  font-variant-numeric: tabular-nums;
}
.c-steps h3 { margin: 0 0 var(--space-2xs); font-size: var(--step-1); color: var(--ink-strong); }
.c-steps p { margin: 0 0 var(--space-s); color: var(--ink-muted); line-height: 1.55; max-width: 60ch; }
.c-steps .c-btn { margin-right: var(--space-2xs); }

/* Comparison link lists (the /compare hub and the related block). */
.c-comparelist { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2xs); }
.c-comparelist li {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-s);
  padding-bottom: var(--space-2xs); border-bottom: 1px solid var(--rule);
}
.c-comparelist a { font-weight: 600; }
.c-comparelist__meta { font-size: var(--step--2); color: var(--ink-muted); white-space: nowrap; }
@media (min-width: 48em) {
  .c-comparelist--grid { grid-template-columns: 1fr 1fr; column-gap: var(--space-xl); }
}
@media (min-width: 70em) {
  .c-comparelist--grid { grid-template-columns: repeat(3, 1fr); }
}

/* --------------------------------------------------------------------------
   Partner revenue calculator
   --------------------------------------------------------------------------
   A dark panel: two range sliders on the left, a live results readout on the
   right. Works with no JavaScript too, showing the default cohort's figures.
   -------------------------------------------------------------------------- */
.c-calc {
  margin-top: var(--space-2xl);
  background: var(--navy-900);
  color: var(--ink-invert);
  border-radius: var(--radius-l);
  padding: clamp(1.5rem, 1rem + 2.5vw, 3rem);
}
.c-calc__head { text-align: center; margin-bottom: var(--space-l); }
.c-calc__head h2 { margin: 0 0 var(--space-2xs); color: #FFFFFF; }
.c-calc__head p { margin: 0 auto; max-width: 48ch; color: var(--ink-invert-muted); }

.c-calc__grid { display: grid; gap: var(--space-l); }
@media (min-width: 52em) {
  .c-calc__grid { grid-template-columns: 3fr 2fr; align-items: stretch; }
}

.c-calc__controls { display: grid; gap: var(--space-m); align-content: center; }
.c-calc__control {
  background: color-mix(in oklab, #FFFFFF 6%, transparent);
  border: 1px solid color-mix(in oklab, #FFFFFF 12%, transparent);
  border-radius: var(--radius-m);
  padding: var(--space-m);
}
.c-calc__label { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-s); }
.c-calc__lname { font-weight: 700; color: #FFFFFF; }
.c-calc__lsub { margin: var(--space-3xs) 0 var(--space-s); font-size: var(--step--1); color: var(--ink-invert-muted); }
.c-calc__count {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 800;
  color: var(--azure-300);
  font-variant-numeric: tabular-nums;
}
.c-calc__control input[type="range"] {
  width: 100%;
  accent-color: var(--azure-400);
  cursor: pointer;
  height: 1.5rem;
}

.c-calc__results {
  background: color-mix(in oklab, #FFFFFF 8%, transparent);
  border: 1px solid color-mix(in oklab, #FFFFFF 14%, transparent);
  border-radius: var(--radius-m);
  padding: var(--space-l);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.c-calc__rlabel {
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-invert-muted);
  font-weight: 600;
}
.c-calc__revenue {
  font-family: var(--font-display);
  font-size: var(--step-5, clamp(2.5rem, 1.9rem + 2.8vw, 4rem));
  font-weight: 800;
  line-height: 1.05;
  color: #FFFFFF;
  letter-spacing: -0.02em;
  margin: var(--space-3xs) 0 var(--space-m);
  font-variant-numeric: tabular-nums;
}
.c-calc__stats { margin: 0; padding-top: var(--space-m); border-top: 1px solid color-mix(in oklab, #FFFFFF 14%, transparent); display: grid; gap: var(--space-2xs); }
.c-calc__stats > div { display: flex; align-items: center; justify-content: space-between; gap: var(--space-s); }
.c-calc__stats dt { color: var(--ink-invert-muted); }
.c-calc__stats dd {
  margin: 0;
  font-weight: 700;
  color: var(--azure-300);
  background: color-mix(in oklab, var(--azure-400) 22%, transparent);
  padding: 0.15em 0.6em;
  border-radius: var(--radius-s);
  font-variant-numeric: tabular-nums;
}
.c-calc__note { margin: var(--space-m) 0 0; text-align: center; font-size: var(--step--2); color: var(--ink-invert-muted); }

/* --------------------------------------------------------------------------
   Utility bar
   --------------------------------------------------------------------------
   Sits above the header. Account access, the association and joining it: three
   things that do not belong in primary navigation but that people look for in
   a fixed place at the top of a site.

   It also relieves the main bar. Once a sign-in link and a call to action were
   both in c-header__actions, the row wrapped to two lines at 1440px.

   Desktop only. On a handset these three are in the drawer, where they can be
   real tap targets instead of 6px text competing with the logo.
   -------------------------------------------------------------------------- */
.c-topbar {
  background: var(--bg-inverse-2);
  color: var(--ink-invert-muted);
  font-size: var(--step--1);
}

.c-topbar__inner {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-xs);
  padding-inline: var(--gutter);
  /* 36px keeps the links a comfortable 24px+ target without the bar becoming a
     second header. */
  min-height: 36px;
}

.c-topbar__link {
  color: inherit;
  text-decoration: none;
  padding-block: 0.55rem;   /* target height, not visual weight */
  white-space: nowrap;
}
.c-topbar__link:hover,
.c-topbar__link:focus-visible { color: #FFFFFF; text-decoration: underline; }

.c-topbar__link--strong { font-weight: 700; color: #FFFFFF; }

.c-topbar__sep { opacity: 0.45; }

/* The header is sticky; without this the utility bar scrolls away and the
   header lands on top of the content correctly rather than leaving a gap. */
@media (max-width: 63.99em) {
  .c-topbar { display: none; }
}

/* Founding Partners. Sits between the priced tiers and the limits notice, so a
   reader meets the offer and its boundary in that order. */
.c-founding { padding-block: var(--space-m) var(--space-l); }
.c-founding__lede { font-size: var(--step-1); color: var(--ink-strong); margin: var(--space-s) 0; }
.c-founding__list { margin-bottom: var(--space-m); }

/* --------------------------------------------------------------------------
   Country suggestion banner
   --------------------------------------------------------------------------
   An offer, not a redirect. Sits above the header, is dismissable, and never
   moves anyone automatically. See app/Support/Locale.php for why redirecting
   by IP would stop the other country pages being indexed at all.
   -------------------------------------------------------------------------- */
.c-geo { background: var(--accent); color: #FFFFFF; }

.c-geo__inner {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-s); padding: var(--space-xs) var(--gutter);
}

.c-geo__text { margin: 0; font-size: var(--step--1); }
.c-geo__actions { margin: 0; display: flex; align-items: center; gap: var(--space-s); }

.c-btn--sm { padding: 0.45em 0.9em; font-size: var(--step--1); }
.c-geo .c-btn--sm { --btn-bg: #FFFFFF; --btn-ink: var(--accent); --btn-edge: #FFFFFF; }
.c-geo .c-btn--sm:hover { --btn-bg: #FFFFFF; --btn-ink: var(--navy-900); }

.c-geo__stay { color: #FFFFFF; font-size: var(--step--1); text-decoration: underline; white-space: nowrap; }
.c-geo__stay:hover { color: #FFFFFF; }

/* Glossary term photograph. Sits beside the definition on a wide screen and
   above it on a narrow one. alt is empty on purpose: the photograph illustrates
   text that is right there, so describing it again is repetition for a screen
   reader rather than information. */
.c-termdef--withimage { display: grid; gap: var(--space-l); }
.c-termdef__figure { margin: 0; }
.c-termdef__figure img {
  display: block; width: 100%; height: auto;
  /* Bigger and crisper. The old 16:7 sliver read as a decorative strip; a 4:3
     frame with a soft shadow gives the photograph real presence beside the
     definition, in the deck's key art. */
  border-radius: var(--radius-l); object-fit: cover; aspect-ratio: 4 / 3;
  box-shadow: var(--shadow-mid);
}
@media (min-width: 56em) {
  .c-termdef--withimage {
    grid-template-columns: minmax(0, 1fr) minmax(0, 26rem);
    gap: var(--space-xl);
    align-items: center;
  }
  .c-termdef--withimage .c-termdef__figure { order: 2; }
  .c-termdef--withimage .c-termdef__text  { order: 1; }
  .c-termdef--withimage .c-termdef__aka   { order: 1; grid-column: 1; }
}

/* Auto-linked glossary terms. Underlined like any link but not coloured, so a
   paragraph with four of them still reads as prose rather than a menu. */
.c-autolink {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-underline-offset: 0.15em;
}
.c-autolink:hover, .c-autolink:focus-visible { color: var(--accent); }

/* Article standfirst: the paragraphs before the first heading. Set larger than
   body copy so the opening has weight, which is what an editor would do and
   what a uniform stack of paragraphs never does. */
.c-artintro { padding-block: var(--space-m) var(--space-l); border-bottom: 1px solid var(--rule); }
.c-artintro > p { font-size: var(--step-1); line-height: 1.5; color: var(--ink-strong); }
.c-artintro > p + p { margin-top: var(--space-s); }

/* --------------------------------------------------------------------------
   Article blocks
   --------------------------------------------------------------------------
   Components an author drops into body HTML so two articles do not read as the
   same page with different words. Uniform structure is what makes a blog feel
   generated; the eye learns the shape and stops reading.
   -------------------------------------------------------------------------- */

/* Key points. Sits early, tells a scanner whether to keep going. */
.c-keypoints {
  padding: var(--space-m);
  margin-block: var(--space-l);
  background: var(--bg-sunken);
  border-left: 4px solid var(--accent);
  border-radius: 0 var(--radius-m) var(--radius-m) 0;
}
.c-keypoints__title {
  margin: 0 0 var(--space-s);
  font-size: var(--step--1); font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-muted);
}
.c-keypoints ul { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--space-xs); }
.c-keypoints li { padding-left: 1.4em; position: relative; line-height: 1.55; }
.c-keypoints li::before {
  content: ""; position: absolute; left: 0; top: 0.6em;
  width: 0.5em; height: 0.5em; border-radius: 50%; background: var(--accent);
}

/* Pull quote. Breaks a long run of prose and gives the eye somewhere to land. */
.c-pull {
  margin-block: var(--space-xl);
  padding-left: var(--space-l);
  border-left: 4px solid var(--accent);
  font-size: clamp(1.25rem, 2.4vw, 1.75rem);
  line-height: 1.35;
  font-weight: 700;
  color: var(--ink-strong);
  text-wrap: balance;
}
.c-pull cite {
  display: block; margin-top: var(--space-xs);
  font-size: var(--step--1); font-weight: 400; font-style: normal; color: var(--ink-muted);
}

/* Numbered steps, for a piece answering a "how do I" question.
 *
 * Every real child goes in column two, and the counter in column one.
 *
 * Without that, the li is a two-column grid holding three items: the ::before
 * counter, the h3 and the p. Grid auto-placement puts the counter and the
 * heading on row one and drops the paragraph into column one on row two. That
 * column is auto-sized, so it grows to fit a paragraph, and the heading in the
 * 1fr column collapses to a few characters wide. The heading ends up in a
 * narrow strip at the right of the page with a large hole beside it. */
.c-steps { list-style: none; margin: var(--space-l) 0; padding: 0; counter-reset: step; }

.c-steps > li {
  counter-increment: step;
  display: grid;
  grid-template-columns: 3rem minmax(0, 1fr);
  column-gap: var(--space-m);
  row-gap: var(--space-2xs);
  padding-block: var(--space-l);
  border-top: 1px solid var(--rule);
}

.c-steps > li::before {
  content: counter(step, decimal-leading-zero);
  grid-column: 1;
  grid-row: 1;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
  font-size: var(--step-1);
  line-height: 1.25;
}

/* Everything the author wrote sits in the text column, whatever it is. */
.c-steps > li > * { grid-column: 2; }

.c-steps h3 { margin: 0; font-size: var(--step-1); line-height: 1.25; color: var(--ink-strong); }
.c-steps p  { margin: 0; }
.c-steps h3 + p { margin-top: var(--space-2xs); }

/* Inline call to action. */
.c-cta {
  display: grid; gap: var(--space-s);
  padding: var(--space-l);
  margin-block: var(--space-xl);
  background: var(--bg-inverse-2); color: #FFFFFF;
  border-radius: var(--radius-m);
}
.c-cta h3 { margin: 0; font-size: var(--step-1); color: #FFFFFF; }
.c-cta p  { margin: 0; color: var(--ink-invert-muted); }
.c-cta__actions { display: flex; flex-wrap: wrap; gap: var(--space-s); }
.c-cta .c-btn { --btn-bg: #FFFFFF; --btn-ink: var(--navy-900); --btn-edge: #FFFFFF; }
.c-cta .c-btn:hover { --btn-bg: var(--bg-sunken); --btn-ink: var(--navy-900); }
@media (min-width: 48em) {
  .c-cta { grid-template-columns: minmax(0,1fr) auto; align-items: center; }
  .c-cta__actions { justify-content: flex-end; }
}

/* Read-through article layout (the "feature" layout in journal/show.php).
   Named c-longform, not c-feature: the latter is the marketing two-column grid
   component below, and reusing that name split article prose into two columns. */
.c-longform > * { max-width: 100%; }
.c-longform .c-tablewrap,
.c-longform .c-cta,
.c-longform figure { margin-inline: 0; }

/* Flow spacing inside the read-through body. Its blocks are direct children of
   c-longform, which the .c-prose owl selector does not reach, so headings sat
   tight against the paragraph beneath them. Give them room to breathe. */
/* Paragraph spacing matches the site-wide baseline (base.css: p margin-bottom
   space-s), which the guide and rail articles use, so the feature articles and
   the directory landing pages read with the same rhythm as every other page.
   Headings keep their generous run-up, aligned to the guide layout's values. */
.c-longform > * + * { margin-top: var(--space-m); }
.c-longform > h2 { margin-top: var(--space-xl); margin-bottom: var(--space-s); }
.c-longform > h3 { margin-top: var(--space-l); margin-bottom: var(--space-2xs); }
.c-longform > h2:first-child,
.c-longform > h3:first-child,
.c-longform > :first-child { margin-top: 0; }

/* Guide layout: standfirst, then steps and boxes rather than a heading stack. */
.c-guide h2 {
  margin-top: var(--space-xl);
  /* A heading set hard against its own first line reads as part of the
     sentence. The flow spacing that separates paragraphs does not reach
     across a heading, so the gap has to be stated here. */
  margin-bottom: var(--space-s);
  padding-top: var(--space-m);
  border-top: 1px solid var(--rule);
  font-size: clamp(1.4rem, 3vw, 2rem);
}
.c-guide h3 {
  margin-top: var(--space-l);
  margin-bottom: var(--space-2xs);
  font-size: var(--step-1);
}

/* ==========================================================================
   Feature split

   The deck's signature block: a big edge-to-edge photograph on one side, text
   with icon rows on the other. Full bleed by design — the photo runs floor to
   ceiling and to the outer edge of the viewport, so the page reads as
   photography with words beside it rather than words with a picture near them.

   Placed as its own full-width <section>, outside the l-canvas grid, so the
   media pane can reach the screen edge. Alternate sides with --reverse.
   ========================================================================== */
.c-feature {
  display: grid;
  grid-template-columns: 1fr;
  background: var(--bg-page);
}
.c-feature--dark { background: var(--bg-inverse); color: var(--ink-invert); }

@media (min-width: 60rem) {
  .c-feature { grid-template-columns: 1fr 1fr; }
  /* Photo on the left, text on the right. */
  .c-feature--reverse > .c-feature__media { order: -1; }
}

.c-feature__body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-s);
  padding: var(--space-2xl) var(--gutter);
}
/* Keep the text from stretching to an unreadable measure on a wide half. */
.c-feature__body > * { max-width: 40rem; }

.c-feature__kicker {
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: var(--tracking-kicker);
  text-transform: uppercase;
  color: var(--accent);
}
.c-feature--dark .c-feature__kicker { color: var(--azure-300); }

.c-feature__title {
  font-family: var(--font-display);
  font-size: var(--step-4);
  font-weight: 700;
  line-height: var(--leading-snug);
  letter-spacing: var(--tracking-display);
  color: var(--ink-strong);
  text-wrap: balance;
}
.c-feature--dark .c-feature__title { color: var(--paper); }

.c-feature__lede {
  font-size: var(--step-1);
  color: var(--ink-muted);
  text-wrap: pretty;
}
.c-feature--dark .c-feature__lede { color: var(--ink-invert-muted); }

/* The photo pane: absolutely-filled so the image is floor to ceiling on the
   desktop split and a tall band when stacked on a phone. */
.c-feature__media {
  position: relative;
  min-height: 26rem;
  overflow: hidden;
}
.c-feature__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
@media (max-width: 60rem) {
  .c-feature__media { min-height: 18rem; }
}

/* Icon rows, the deck's feature list: a filled circle glyph, a title, a line. */
.c-featurelist {
  display: grid;
  gap: var(--space-m);
  margin-top: var(--space-2xs);
}
.c-featurerow {
  display: flex;
  align-items: flex-start;
  gap: var(--space-s);
  max-width: 40rem;
  text-decoration: none;
  color: inherit;
}
.c-featurerow__icon {
  flex: 0 0 auto;
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--accent);
  color: #FFFFFF;
}
.c-feature--dark .c-featurerow__icon { background: var(--azure-600); }
.c-featurerow__icon svg { width: 1.4rem; height: 1.4rem; }

.c-featurerow__text { display: block; }
.c-featurerow__title {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--step-1);
  line-height: var(--leading-snug);
  color: var(--ink-strong);
}
.c-featurerow__body { display: block; }
.c-feature--dark .c-featurerow__title { color: var(--paper); }

.c-featurerow__body {
  margin-top: 0.15rem;
  color: var(--ink-muted);
  font-size: var(--step--1);
}
.c-feature--dark .c-featurerow__body { color: var(--ink-invert-muted); }

/* A whole row that is a link lifts its title on hover, so it reads as clickable
   without underlining a heading. */
a.c-featurerow:hover .c-featurerow__title { color: var(--accent); }
.c-feature--dark a.c-featurerow:hover .c-featurerow__title { color: var(--azure-300); }

@media (prefers-reduced-motion: no-preference) {
  a.c-featurerow .c-featurerow__icon { transition: transform var(--dur-fast) var(--ease-out); }
  a.c-featurerow:hover .c-featurerow__icon { transform: translateX(3px); }
}

html[data-contrast="high"] .c-feature--dark {
  background: var(--bg-page);
  color: var(--ink-body);
}
html[data-contrast="high"] .c-feature--dark :is(.c-feature__title, .c-featurerow__title) { color: var(--ink-strong); }
html[data-contrast="high"] .c-feature--dark :is(.c-feature__lede, .c-featurerow__body) { color: var(--ink-body); }
html[data-contrast="high"] .c-feature--dark .c-feature__kicker { color: var(--accent); }

/* ==========================================================================
   Launch empty state

   For a directory that has no rows yet, before the site opens. Reads as a
   deliberate "opening soon, be first" panel, not a broken empty grid.
   ========================================================================== */
.c-launchempty {
  display: grid;
  justify-items: center;
  text-align: center;
  gap: var(--space-s);
  padding: var(--space-2xl) var(--gutter);
  background:
    radial-gradient(120% 120% at 50% 0%, color-mix(in oklab, var(--azure-500) 8%, transparent), transparent 60%),
    var(--bg-sunken);
  border: 1px solid var(--rule);
  border-radius: var(--radius-l);
}
.c-launchempty__badge {
  padding: 0.2rem 0.7rem;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.04em;
}
.c-launchempty__icon {
  display: grid;
  place-items: center;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 50%;
  background: color-mix(in oklab, var(--accent) 12%, transparent);
  color: var(--accent);
}
.c-launchempty__icon svg { width: 1.75rem; height: 1.75rem; }
.c-launchempty__title {
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 700;
  color: var(--ink-strong);
}
.c-launchempty__body {
  max-width: 44ch;
  color: var(--ink-muted);
}
.c-launchempty .c-btn { margin-top: var(--space-2xs); }

/* ==========================================================================
   Welcome popup (first-visit)
   ========================================================================== */
.c-welcome[hidden] { display: none; }
.c-welcome {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: var(--space-s);
}
.c-welcome__backdrop {
  position: absolute;
  inset: 0;
  background: color-mix(in oklab, var(--navy-900) 74%, transparent);
  backdrop-filter: blur(3px);
}
.c-welcome__dialog {
  position: relative;
  width: min(30rem, 100%);
  max-height: calc(100svh - var(--space-l));
  overflow: auto;
  padding: var(--space-xl) var(--space-l) var(--space-l);
  text-align: center;
  background: var(--bg-page);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-high);
  animation: c-welcome-in var(--dur-base) var(--ease-out);
}
@keyframes c-welcome-in {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .c-welcome__dialog { animation: none; } }

.c-welcome__close {
  position: absolute;
  top: var(--space-2xs);
  right: var(--space-2xs);
  width: 2.25rem;
  height: 2.25rem;
  display: grid;
  place-items: center;
  font-size: 1.6rem;
  line-height: 1;
  color: var(--ink-muted);
  background: none;
  border: 0;
  border-radius: var(--radius-s);
  cursor: pointer;
}
.c-welcome__close:hover { color: var(--ink-strong); background: var(--bg-sunken); }

.c-welcome__mark { width: 11rem; margin-bottom: var(--space-m); }
.c-welcome__title {
  margin-bottom: var(--space-2xs);
  font-family: var(--font-display);
  font-size: var(--step-2);
  font-weight: 700;
  color: var(--ink-strong);
}
.c-welcome__body {
  margin-bottom: var(--space-m);
  color: var(--ink-muted);
  font-size: var(--step-0);
}

.c-welcome__row { display: flex; gap: var(--space-2xs); }
@media (max-width: 26rem) { .c-welcome__row { flex-direction: column; } }

.c-welcome__input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0.7rem 0.85rem;
  font: inherit;
  color: var(--ink-strong);
  background: var(--paper);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-s);
}
.c-welcome__submit {
  flex: 0 0 auto;
  padding: 0.7rem 1.1rem;
  font: inherit;
  font-weight: 700;
  color: var(--accent-ink);
  background: var(--accent);
  border: 1px solid transparent;
  border-radius: var(--radius-s);
  cursor: pointer;
}
.c-welcome__submit:hover { background: var(--accent-hover); }
.c-welcome__submit:disabled { opacity: 0.7; cursor: default; }

.c-welcome__err {
  margin-top: var(--space-2xs);
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--state-alert);
}
.c-welcome__ok {
  margin: 0;
  padding: var(--space-2xs) 0;
  font-weight: 700;
  color: var(--state-live);
}
.c-welcome__skip {
  margin-top: var(--space-s);
  font: inherit;
  font-size: var(--step--1);
  color: var(--ink-muted);
  background: none;
  border: 0;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.c-welcome__skip:hover { color: var(--ink-strong); }

.c-welcome__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

:focus-visible { outline-offset: 2px; }

html[data-contrast="high"] .c-welcome__dialog { border: 2px solid var(--rule-strong); }

/* --------------------------------------------------------------------------
   Find-an-instructor demand form (empty CFI directory)
   -------------------------------------------------------------------------- */
.c-findcfi {
  margin-top: var(--space-l);
  padding: clamp(var(--space-m), 4vw, var(--space-xl));
  background: var(--bg-sunken);
  border: 1px solid var(--rule);
  border-radius: var(--radius-m);
}
.c-findcfi h2 { margin: 0 0 var(--space-2xs); font-size: var(--step-1); color: var(--ink-strong); }
.c-findcfi__intro p, .c-findcfi__done p { margin: 0; max-width: 60ch; color: var(--ink-muted); }
.c-findcfi__form { display: grid; gap: var(--space-s); margin-top: var(--space-m); }
.c-findcfi__row { display: grid; gap: var(--space-s); }
@media (min-width: 40em) { .c-findcfi__row { grid-template-columns: 1fr 1fr; } }
.c-findcfi__hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.c-findcfi__checks { display: grid; gap: var(--space-2xs); margin: 0; padding: 0; border: 0; }
.c-findcfi__checks legend { margin-bottom: var(--space-2xs); font-size: var(--step--1); font-weight: 600; }
.c-findcfi__check { display: flex; gap: 0.5rem; align-items: flex-start; }
.c-findcfi__check input { margin-top: 0.2em; }
.c-findcfi__opt { color: var(--ink-muted); font-weight: 400; }
.c-findcfi__err { margin: 0.25rem 0 0; font-size: var(--step--1); color: #b42318; }
.c-findcfi__alert { font-weight: 600; color: #b42318; }
.c-findcfi__fine { margin: 0; font-size: var(--step--1); color: var(--ink-muted); }

/* Report-inaccuracy flag ----------------------------------------------------
   A small, quiet disclosure at the foot of data-heavy pages. Closed it reads
   as a muted link with a red flag; open it reveals a compact report form. All
   native <details>, no JS. */
.c-report {
  margin: var(--space-l) 0 var(--space-s);
}
/* Closed: just a small red-flag icon button, discreet at the end of content. */
.c-report__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  list-style: none;
  width: 1.9rem;
  height: 1.9rem;
  color: #d1422f;
  border: 1px solid color-mix(in srgb, var(--ink-body) 16%, transparent);
  border-radius: var(--radius-s);
  opacity: 0.75;
  transition: opacity 0.15s, background 0.15s, border-color 0.15s;
}
.c-report__btn::-webkit-details-marker { display: none; }
.c-report__btn:hover {
  opacity: 1;
  background: var(--bg-sunken);
  border-color: color-mix(in srgb, #d1422f 45%, transparent);
}
.c-report[open] .c-report__btn { opacity: 1; }

.c-report__body {
  max-width: 40rem;
  margin-top: var(--space-s);
  padding: var(--space-m);
  background: var(--bg-sunken);
  border-radius: var(--radius-m);
}
.c-report__lede,
.c-report__ok {
  font-size: var(--step--1);
  color: var(--ink-body);
  margin: 0 0 var(--space-s);
}
.c-report__ok { color: var(--ink-strong); font-weight: 600; margin: 0; }
.c-report__err {
  font-size: var(--step--1);
  color: #b3271b;
  margin: 0 0 var(--space-s);
}
.c-report__form label {
  display: block;
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--ink-strong);
  margin-bottom: var(--space-3xs);
}
.c-report__opt { font-weight: 400; color: var(--ink-muted); }
.c-report__form textarea,
.c-report__form input[type="email"] {
  width: 100%;
  font: inherit;
  padding: 0.5em 0.65em;
  margin-bottom: var(--space-s);
  border: 1px solid color-mix(in srgb, var(--ink-body) 25%, transparent);
  border-radius: var(--radius-s);
  background: var(--paper);
  color: var(--ink-body);
}
.c-report__form textarea { resize: vertical; }
.c-report__fine {
  font-size: var(--step--1);
  color: var(--ink-muted);
  margin: var(--space-2xs) 0 0;
}
.c-btn--small {
  padding: 0.5em 1em;
  font-size: var(--step--1);
}
/* Off-screen honeypot, matching the other public forms. */
.c-report__hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Cross-category airport nav (CFIs / schools / DPEs / A&Ps at this field) */
.c-airportnav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs);
  margin: var(--space-xl) 0 var(--space-s);
  padding-top: var(--space-m);
  border-top: 1px solid color-mix(in srgb, var(--ink-body) 14%, transparent);
}
.c-airportnav__label {
  font-weight: 700;
  color: var(--ink-strong);
  margin-right: var(--space-3xs);
}
.c-airportnav__item {
  font-size: var(--step--1);
  padding: 0.4em 0.8em;
  border-radius: var(--radius-s);
  text-decoration: none;
  background: var(--bg-sunken);
  color: var(--ink-body);
  border: 1px solid transparent;
  transition: border-color 0.15s, color 0.15s;
}
.c-airportnav__item:hover {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
}
.c-airportnav__item.is-current {
  background: var(--accent);
  color: var(--ink-invert, #fff);
  font-weight: 600;
}

/* Unclaimed FAA-imported listing banner + simple definition list ------------- */
.c-unclaimed {
  border: 1px solid color-mix(in srgb, #d1873f 45%, transparent);
  background: color-mix(in srgb, #d1873f 8%, var(--paper));
  border-radius: var(--radius-m);
  padding: var(--space-m);
  margin-bottom: var(--space-m);
}
.c-unclaimed__bar { display: flex; gap: var(--space-s); align-items: baseline; flex-wrap: wrap; }
.c-unclaimed__badge {
  flex: none;
  font-size: var(--step--1);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #9a5a1a;
  background: color-mix(in srgb, #d1873f 22%, transparent);
  padding: 0.2em 0.6em;
  border-radius: var(--radius-s);
}
.c-unclaimed__note { font-size: var(--step--1); color: var(--ink-body); margin: 0; }
.c-unclaimed__ok  { font-weight: 600; color: var(--ink-strong); margin: var(--space-2xs) 0 0; }
.c-unclaimed__err { color: #b3271b; font-size: var(--step--1); margin: var(--space-2xs) 0 0; }
.c-unclaimed__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  margin-top: var(--space-s);
}
.c-report__btn--text {
  width: auto;
  height: auto;
  border: none;
  padding: 0.4em 0;
  font-size: var(--step--1);
  color: var(--ink-muted);
  text-decoration: underline;
}
.c-report__btn--text:hover { background: none; color: var(--ink-strong); }

.c-deflist { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-2xs) var(--space-m); }
.c-deflist dt { font-weight: 700; color: var(--ink-strong); }
.c-deflist dd { margin: 0; color: var(--ink-body); }
@media (max-width: 34rem) { .c-deflist { grid-template-columns: 1fr; gap: 0 0; } .c-deflist dd { margin-bottom: var(--space-2xs); } }

/* Auto-advancing carousel (home flight-log strip) -------------------------- */
.c-carousel { position: relative; }
.c-carousel__viewport {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
}
.c-carousel__viewport::-webkit-scrollbar { display: none; }
.c-carousel__track {
  display: flex;
  gap: var(--space-l);
  list-style: none;
  margin: 0;
  padding: 0;
}
.c-carousel__item {
  flex: 0 0 auto;
  scroll-snap-align: start;
  width: calc((100% - 2 * var(--space-l)) / 3);
}
@media (max-width: 60rem) { .c-carousel__item { width: calc((100% - var(--space-l)) / 2); } }
@media (max-width: 40rem) { .c-carousel__item { width: 86%; } }
.c-carousel__item > .c-card { height: 100%; }

/* Whole-card click via a stretched title link (one real link, valid markup). */
.c-card--link { position: relative; }
.c-card--link .c-card__link::after { content: ''; position: absolute; inset: 0; }
.c-card--link:hover { transform: translateY(-2px); }
.c-card--link { transition: transform 0.15s; }

.c-carousel__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-s);
  margin-top: var(--space-m);
}
.c-carousel__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--ink-body) 20%, transparent);
  background: var(--paper);
  color: var(--ink-strong);
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.c-carousel__btn:hover { border-color: var(--accent); color: var(--accent); }
.c-carousel__dots { display: flex; gap: 0.4rem; align-items: center; }
.c-carousel__dot {
  width: 0.5rem;
  height: 0.5rem;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ink-body) 25%, transparent);
  cursor: pointer;
  transition: background 0.15s, transform 0.15s;
}
.c-carousel__dot[aria-current="true"] { background: var(--accent); transform: scale(1.35); }

/* A ghost button sits inside the dark CTA box, so it needs on-dark ink, not the
   light-surface ink it defaults to. Without this the secondary CTA button is
   dark text on a dark panel (worse on hover). Mirrors .c-btn--onDark. Fixes
   every article CTA at once. */
.c-cta .c-btn--ghost { --btn-bg: transparent; --btn-ink: #FFFFFF; --btn-edge: rgb(255 255 255 / 0.45); }
.c-cta .c-btn--ghost::before { background: #FFFFFF; }
.c-cta .c-btn--ghost:hover,
.c-cta .c-btn--ghost:focus-visible { --btn-ink: var(--navy-900); --btn-edge: #FFFFFF; }
