/* ==========================================================================
   Northern Snow - 2026 Chevy Trailblazer Sweepstakes landing page
   Tokens and values are taken verbatim from the design handoff README.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Fonts
   The page runs on Saira + Roboto, loaded from Google Fonts in index.html.

   The Conthrax face below is NO LONGER USED - the display token points at
   Saira. It is left declared because an unused @font-face is never
   downloaded, so it costs nothing and makes going back a one-token change.
   If Conthrax is gone for good, delete this block and assets/fonts/, and
   with them the open question about its web licence: Saira is open source,
   Conthrax was a paid face from typodermicfonts.com.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: 'Conthrax';
  src: url('../fonts/Conthrax-SemiBold.otf') format('opentype');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

/* --------------------------------------------------------------------------
   Design tokens
   -------------------------------------------------------------------------- */
:root {
  /* Surfaces */
  --c-bg: #000000;
  --c-surface: #141A1F;
  --c-border: #252B31;

  /* Brand */
  --c-cyan: #00B2BB;

  /* The design-system name is the source of truth; --c-ice is kept pointing
     at it so the existing usages keep working and there is still only one
     place the value lives. Icy blue carries the accents - links, rules,
     separators, the FAQ toggle, the Sweepstakes tag - while cyan keeps the
     three filled surfaces that hold white text: the announcement bar, the
     primary button and the skip link. On black it also reads better than
     cyan did: 14.2:1 against 8.1:1. */
  --ns-icy-blue: #A5DDED;
  --c-ice: var(--ns-icy-blue);
  --c-ice-deep: #7CC9DE;
  --c-teal-deep: #00777D;

  /* Text */
  --c-text: #FFFFFF;
  --c-body: rgba(255, 255, 255, 0.8);
  --c-muted: #AAB3BC;
  --c-label: #7B848E;
  --c-faint: #565E67;

  --grad-ice: linear-gradient(180deg, var(--c-ice) 0%, var(--c-ice-deep) 100%);
  --grad-prize-scrim: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.82) 60%, rgba(0, 0, 0, 0.94) 100%);
  --grad-caption: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.75) 100%);

  /* Hero headline. The wrap's ice blue desaturated and darkened, so the
     display type reads as the same colour as the image it overlaps rather
     than competing with it. --grain is the fractal-noise texture laid over
     the gradient inside the glyphs. */
  --c-headline-dull: #A8C3CD;
  --grad-headline: linear-gradient(180deg, #E4EFF3 0%, #BAD3DB 34%, #8AA6B1 68%, #5E7783 100%);
  --grain: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="170" height="170"><filter id="g"><feTurbulence type="fractalNoise" baseFrequency="0.8" numOctaves="4" stitchTiles="stitch"/><feColorMatrix type="saturate" values="0"/></filter><rect width="170" height="170" filter="url(%23g)" opacity="0.5"/></svg>');

  /* Flip-clock leaves: the upper leaf catches the light, the lower one sits
     in the crease shadow. */
  --c-fold-top: #1B232A;
  --c-fold-bottom: #121820;

  /* Highlighter yellow. Used once, on the hero note - the only place on the
     page that borrows a colour from outside the brand palette. */
  --c-highlight: #FFE94A;

  /* Saira + Roboto, matching the main site. This also retires the Conthrax
     licensing question: Saira is open source, Conthrax was not. The
     @font-face block above is now unused - an unused face is never
     downloaded, so it is left in place to make reverting a two-token
     change. */
  --font-display: Saira, system-ui, sans-serif;
  --font-body: Roboto, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --maxw: 1240px;
  /* The hero picture and headline share one narrow centred column, so the
     image reads as a framed photograph on black rather than a full-width
     band. 70px of Conthrax measures 808px for "NORTHERN SNOW" (11.548 x the
     font size), which is what sets this figure. */
  --hero-width: 820px;
  --header-offset: 80px;
}

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

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

body {
  margin: 0;
  background: var(--c-bg);
  color: var(--c-text);
  font-family: var(--font-body);
  /* Roboto 400 at the specified 17px / 26px. Unitless so the ratio holds
     where components set their own smaller sizes. */
  font-size: 17px;
  line-height: 1.53;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; }

a {
  color: var(--ns-icy-blue);
  text-decoration: none;
}
/* Links are icy blue now, so hovering to ice would be no change at all. */
a:hover { color: var(--c-text); }

h1, h2, h3, p { margin: 0; }

:where(a, button, summary):focus-visible {
  outline: 2px solid var(--c-ice);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    /* Without this, an `infinite` animation is not stopped - it is set
       running at 0.01ms per cycle, which is a busy loop of style
       recalculation rather than the stillness that was asked for. The CTA
       heartbeat and glow are both infinite, so this matters here. */
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

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

.skip-link {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 100;
  background: var(--c-cyan);
  color: var(--c-text);
  padding: 12px 18px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transition: top 0.15s ease;
}
.skip-link:focus {
  top: 12px;
  color: var(--c-text);
}

/* --------------------------------------------------------------------------
   Layout primitives
   -------------------------------------------------------------------------- */
.section {
  padding: 0 32px 64px;
  scroll-margin-top: var(--header-offset);
}
.section--how { padding: 64px 32px; }
.section--hero { padding: 0 24px 56px; }

.wrap {
  max-width: var(--maxw);
  margin: 0 auto;
}

/* --------------------------------------------------------------------------
   Type patterns
   -------------------------------------------------------------------------- */
.section-heading {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(32px, 5.2vw, 54px);
  line-height: 0.98;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--c-text);
}

.section-subhead {
  font-size: 15px;
  color: var(--c-muted);
  margin: 10px 0 0;
}

.kicker {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--c-label);
}

.tile__label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-label);
  margin-top: 6px;
}

/* --------------------------------------------------------------------------
   Buttons
   Taken from snow.northernsnow.ca so the two pages feel like one product:
   pill radius, a cyan glow cast below, and a small lift on hover. Their
   palette is already ours - their --teal is #00b2bb (--c-cyan) and their
   --green is #a5dded (--c-ice) - so only the shape and depth changed.

   Their `.btn` also carries a permanent heartbeat pulse. That is applied
   here to the large primary button only: it is the conversion CTA and the
   one place the nudge is worth it. Putting it on the header chip and every
   small button as well would leave the page perpetually twitching.
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-family: var(--font-display);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease,
              color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}

.btn--sm {
  min-height: 38px;
  padding: 0 20px;
  font-size: 12px;
}
.btn--lg {
  min-height: 56px;
  padding: 0 30px;
  font-size: 14px;
}

.btn--primary {
  background: var(--c-cyan);
  color: var(--c-text);
  border-color: transparent;
  box-shadow: 0 20px 58px rgba(0, 178, 187, 0.4);
}
.btn--primary:hover {
  background: #00C8D2;
  color: var(--c-text);
  transform: translateY(-2px);
  box-shadow: 0 28px 80px rgba(0, 178, 187, 0.55);
}

/* Their `.btn.dark`: an ice wash rather than a hollow outline. */
.btn--secondary {
  background: rgba(165, 221, 237, 0.1);
  border-color: rgba(165, 221, 237, 0.42);
  color: var(--c-ice);
}
.btn--secondary:hover {
  background: rgba(165, 221, 237, 0.18);
  border-color: rgba(165, 221, 237, 0.6);
  color: var(--c-ice);
}

/* The hero CTA only. isolation + z-index keeps the blurred halo behind the
   button without it dropping behind the page. */
.btn--lg.btn--primary {
  position: relative;
  isolation: isolate;
  animation: cta-heartbeat 2s ease-in-out infinite;
}
.btn--lg.btn--primary::after {
  content: '';
  position: absolute;
  inset: -9px;
  z-index: -1;
  border-radius: inherit;
  background: rgba(165, 221, 237, 0.34);
  filter: blur(18px);
  opacity: 0.55;
  pointer-events: none;
  animation: cta-glow 2s ease-in-out infinite;
}
/* Settle while the visitor is actually pointing at it. */
.btn--lg.btn--primary:hover,
.btn--lg.btn--primary:hover::after { animation-play-state: paused; }

@keyframes cta-heartbeat {
  0%, 100% { transform: scale(1); }
  44% { transform: scale(1.035); }
  60% { transform: scale(1.012); }
}
@keyframes cta-glow {
  0%, 100% { opacity: 0.32; transform: scale(0.98); }
  50% { opacity: 0.86; transform: scale(1.08); }
}

/* --------------------------------------------------------------------------
   Card patterns
   A - accent-rail card (how it works, mail-in)
   B - bordered tile (spec tiles, entry tiers, FAQ items, address block)
   -------------------------------------------------------------------------- */
.card-a {
  background: var(--c-surface);
  border-left: 3px solid var(--ns-icy-blue);
  padding: 26px 28px;
}
.card-a__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(22px, 3vw, 26px);
  line-height: 1.1;
  text-transform: uppercase;
  margin: 10px 0 0;
}
.card-a__body {
  font-size: 15px;
  line-height: 1.6;
  color: var(--c-body);
  margin: 12px 0 0;
}
.card-a__body strong { color: inherit; }
.card-a__cta { margin-top: 20px; }
/* The button is the end of the argument the card makes, so it sits under the
   middle of it rather than off to one side. */
.card-a__cta--centre { display: flex; justify-content: center; }

.card-b {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  padding: 20px 22px;
}

/* --------------------------------------------------------------------------
   1. Announcement bar
   -------------------------------------------------------------------------- */
.announce {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  background: var(--c-cyan);
  color: var(--c-text);
  padding: 4px 12px;
}
.announce__viewport {
  /* One line, centred, and wide enough that stepping between messages of
     different lengths does not shift the arrows. */
  flex: 0 1 auto;
  min-width: 0;
  text-align: center;
}
.announce__item {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.5;
}
.announce__arrow {
  flex: none;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: currentColor;
  cursor: pointer;
}
.announce__arrow svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.announce__arrow:hover { background: rgba(0, 0, 0, 0.18); }
.announce__arrow:focus-visible {
  outline: 2px solid var(--c-bg);
  outline-offset: 1px;
}

/* --------------------------------------------------------------------------
   2. Sticky header
   Three zones, as in the reference: left cluster, centred wordmark, right
   actions. The wordmark is centred against the viewport rather than against
   whatever the two clusters leave over, so the left and right zones are
   given equal flex and allowed to shrink.
   -------------------------------------------------------------------------- */
.header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--c-bg);
  border-bottom: 1px solid var(--c-border);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
  padding: 18px 32px;
}
.header__left,
.header__actions {
  display: flex;
  align-items: center;
  flex: 1 1 0;
  min-width: 0;
  white-space: nowrap;
}
.header__left { gap: 16px; }
.header__actions { gap: 14px; justify-content: flex-end; }

.menu-toggle {
  flex: none;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  margin-left: -4px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}
/* Three bars from one element: the box is the middle bar, the shadows are
   the outer two. */
.menu-toggle__bars,
.menu-toggle__bars::before,
.menu-toggle__bars::after {
  display: block;
  width: 19px;
  height: 2px;
  background: var(--c-text);
}
.menu-toggle__bars::before,
.menu-toggle__bars::after {
  content: '';
  position: absolute;
}
.menu-toggle__bars {
  position: relative;
}
.menu-toggle__bars::before { top: -6px; }
.menu-toggle__bars::after { top: 6px; }
.menu-toggle:hover .menu-toggle__bars,
.menu-toggle:hover .menu-toggle__bars::before,
.menu-toggle:hover .menu-toggle__bars::after { background: var(--ns-icy-blue); }

/* Saira 700 / 18px / 31px, white - matching the main site header. Five
   links at this size measure 427px with their gaps, and the rest of the
   header (hamburger, logo, tag, Membership) takes about 530px, so the row
   needs roughly 957px. That is why the nav now collapses into the menu at
   1000px rather than 900px. Letter-spacing is 0, as it is on the main
   site - at 0.1em the same row would need 1015px. */
.header__nav {
  display: flex;
  /* Opens up with the viewport instead of staying bunched at the left on a
     wide screen. The cap matters: the gap sets how far the last link
     reaches, and that is what decides where the nav has to give way to the
     menu - see the handover note at the foot of this file. */
  gap: clamp(18px, 2vw, 34px);
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  line-height: 31px;
  letter-spacing: 0;
  text-transform: uppercase;
  white-space: nowrap;
  /* Without min-width: 0 a nowrap flex item refuses to shrink below its
     content width, which would push the whole page wider than the viewport
     instead of scrolling inside itself. */
  min-width: 0;
}
.header__nav a { color: var(--c-text); }
.header__nav a:hover { color: var(--ns-icy-blue); }

.brand {
  display: flex;
  align-items: center;
  flex: none;
  color: var(--c-text);
}
.brand__logo {
  /* Two stacked lines of type, so it needs height to stay legible - below
     about 30px "SNOW" starts to close up. 36px measures 116px wide. */
  display: block;
  height: 36px;
  width: auto;
}

.header__tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ns-icy-blue);
}
.header__trophy {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The menu panel. Holds the legal and outbound links - the things the five
   section anchors do not cover - so it is not a duplicate of the nav. */
/* :not([hidden]) matters - a bare `display: flex` here would beat the UA
   stylesheet's [hidden] { display: none } and the panel would never close. */
.header__menu:not([hidden]) {
  display: flex;
}
.header__menu {
  flex-basis: 100%;
  flex-direction: column;
  gap: 2px;
  padding: 10px 0 2px;
  border-top: 1px solid var(--c-border);
  margin-top: 2px;
}
.header__menu-sections { display: none; }
.header__menu a {
  display: flex;
  align-items: center;
  min-height: 40px;
  color: var(--c-body);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.header__menu a:hover { color: var(--ns-icy-blue); }

/* --------------------------------------------------------------------------
   3. Hero
   -------------------------------------------------------------------------- */
/* The hero is a photograph now, not a cutout render on a gradient. The
   picture fills the frame edge to edge, so there is no panel padding and no
   ice gradient behind it - the photo carries its own sky and road. */
.hero-shot {
  position: relative;
  z-index: 0;
  max-width: var(--hero-width);
  margin-inline: auto;
  /* The source is 3:2. Cropping to 16:9 in CSS rather than in the export
     keeps the hero compact and leaves the crop adjustable without
     re-encoding the image. */
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--c-bg);
}
.hero-shot__img {
  display: block;
  width: 100%;
  height: 100%;
  /* Biased low: it holds the vehicle and the road, and drops some sky. */
  object-fit: cover;
  object-position: center 58%;
  /* Pushed in past what `cover` already crops, so the vehicle carries more
     of the frame. The parent clips the overflow. */
  transform: scale(1.16);
  transform-origin: center 58%;
}
/* Vignette plus foot fade. The picture no longer ends on a hard edge - it
   sinks into the page black, which is what lets the headline overlap it and
   still read as part of the same image. */
.hero-shot::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    /* Sides and top, so the picture dissolves into the page instead of
       sitting on it as a hard-edged rectangle. Kept to the outer ~11% and
       top ~9%: the vehicle occupies the middle of the frame and anything
       deeper starts eating it. */
    linear-gradient(90deg,
      var(--c-bg) 0%, rgba(0, 0, 0, 0.78) 6%, rgba(0, 0, 0, 0.34) 12%,
      rgba(0, 0, 0, 0) 19%, rgba(0, 0, 0, 0) 81%, rgba(0, 0, 0, 0.34) 88%,
      rgba(0, 0, 0, 0.78) 94%, var(--c-bg) 100%),
    linear-gradient(180deg,
      var(--c-bg) 0%, rgba(0, 0, 0, 0.7) 5%, rgba(0, 0, 0, 0.3) 10%,
      rgba(0, 0, 0, 0) 17%),
    radial-gradient(130% 100% at 50% 24%, rgba(0, 0, 0, 0) 46%, rgba(0, 0, 0, 0.4) 100%),
    /* Held low deliberately. The render this replaced had nothing below the
       car worth keeping, so the fade could start at 28%; a photograph has
       the vehicle sitting on a road, and starting that high buried its
       wheels. It now stays clear until 52% and only gets heavy under the
       car, which is still enough dark ground for the headline. */
    linear-gradient(180deg,
      rgba(0, 0, 0, 0) 52%, rgba(0, 0, 0, 0.45) 72%,
      rgba(0, 0, 0, 0.88) 88%, var(--c-bg) 100%);
}

.hero__headline {
  position: relative;
  z-index: 1;
  /* Bites into the foot of the image. em-based, so the overlap stays
     proportional as the headline scales. */
  max-width: var(--hero-width);
  margin-top: -0.44em;
  margin-inline: auto;
  padding: 0 6px;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 900;
  /* Saira 900 measured at letter-spacing -0.02em: "NORTHERN SNOW" is
     8.320 x the font size, "TRAILBLAZER GIVEAWAY" 11.625 x - both far
     narrower than Conthrax was. The spec called for 75px, but that puts the
     long line at 872px against an 808px column, so it is capped at 68px
     (790px). To get the literal 75px, widen --hero-width to 890px.
     Line height is a ratio rather than a fixed 53px, so it holds when the
     clamp scales the size down. Opened up from the specs 53/75 (0.71) to
     0.78 for a little air between the two lines - they read as one block at
     0.71, which is the LGND look but too tight for a two-line name. */
  font-size: clamp(28px, 8vw, 68px);
  line-height: 0.78;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--c-headline-dull);
}
.hero__headline span { display: block; color: inherit; }
/* Dulled ice sampled off the wrap, plus grain, both clipped to the glyphs
   so the type carries the image's colour instead of sitting on top of it in
   flat white. Browsers without background-clip: text keep the solid
   --c-headline-dull set above. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .hero__headline {
    background-image: var(--grain), var(--grad-headline);
    background-size: 170px 170px, 100% 100%;
    background-repeat: repeat, no-repeat;
    background-blend-mode: overlay, normal;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
    filter: drop-shadow(0 4px 18px rgba(0, 0, 0, 0.8));
  }
  .hero__headline span { -webkit-text-fill-color: transparent; }
}

.countdown {
  text-align: center;
  margin-top: 30px;
}
.countdown__label {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--c-headline-dull);
}
/* Flip clock. Geometry follows the reference implementation: two static
   halves carry the current digit, two leaves rotate over them on a tick, and
   a 1px crease is painted across the middle at the top of the stack. The
   digit spans are pushed to the fold line from either side, so each half
   shows exactly one half of the glyph. */
.countdown__grid {
  /* Label block height: 12px line + 11px margin-top. */
  --cd-label-h: 23px;
  display: grid;
  /* Explicit auto columns hold the separators, so the four cards keep equal
     widths whatever the separator measures. */
  grid-template-columns:
    minmax(0, 1fr) auto minmax(0, 1fr) auto minmax(0, 1fr) auto minmax(0, 1fr);
  gap: 12px;
  align-items: start;
  max-width: 630px;
  margin: 18px auto 0;
}
.countdown__cell { min-width: 0; }
.countdown__separator {
  /* Centred against the CARD, not the cell. The cell is taller than the card
     by exactly the label block (--cd-label-h), so an equal bottom margin on a
     centre-aligned item puts it back on the card's centre line:
       cell centre - label/2  ==  card centre
     That holds at any card size, which the old hardcoded padding did not. */
  align-self: center;
  margin-bottom: var(--cd-label-h);
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 1;
  color: var(--ns-icy-blue);
}

.flip-card {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 2;
  perspective: 600px;
  filter: drop-shadow(0 14px 22px rgba(0, 0, 0, 0.34));
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(28px, 6.4vw, 62px);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.flip-card__half,
.flip-card__leaf {
  position: absolute;
  left: 0;
  width: 100%;
  height: 50%;
  overflow: hidden;
  border: 1px solid var(--c-border);
  background: var(--c-fold-bottom);
  backface-visibility: hidden;
}
.flip-card__half--top,
.flip-card__leaf--top {
  top: 0;
  border-bottom: 0;
  border-radius: 8px 8px 0 0;
  background: var(--c-fold-top);
}
.flip-card__half--bottom,
.flip-card__leaf--bottom {
  bottom: 0;
  border-top-color: rgba(0, 0, 0, 0.78);
  border-radius: 0 0 8px 8px;
}
.flip-card__half span,
.flip-card__leaf span {
  position: absolute;
  left: 0;
  width: 100%;
  text-align: center;
  color: var(--c-text);
}
/* Each half is a window onto one half of the digit. */
.flip-card__half--top span,
.flip-card__leaf--top span { top: 100%; transform: translateY(-50%); }
.flip-card__half--bottom span,
.flip-card__leaf--bottom span { bottom: 100%; transform: translateY(50%); }

.flip-card__leaf {
  z-index: 2;
  visibility: hidden;
}
.flip-card__leaf--top { transform-origin: bottom; }
.flip-card__leaf--bottom {
  transform: rotateX(90deg);
  transform-origin: top;
}
.flip-card.is-flipping .flip-card__leaf { visibility: visible; }
.flip-card.is-flipping .flip-card__leaf--top {
  animation: fold-top 0.32s ease-in forwards;
}
.flip-card.is-flipping .flip-card__leaf--bottom {
  animation: fold-bottom 0.32s 0.32s ease-out forwards;
}
@keyframes fold-top {
  from { transform: rotateX(0); }
  to { transform: rotateX(-90deg); }
}
@keyframes fold-bottom {
  from { transform: rotateX(90deg); }
  to { transform: rotateX(0); }
}

/* The crease, above everything so it cuts across the digit and the leaves. */
.flip-card::after {
  content: '';
  position: absolute;
  z-index: 4;
  top: 50%;
  left: 0;
  width: 100%;
  height: 1px;
  background: rgba(0, 0, 0, 0.88);
  transform: translateY(-50%);
  pointer-events: none;
}

/* No leaves when motion is not wanted. main.js checks the same query and
   writes both halves directly instead of animating. */
@media (prefers-reduced-motion: reduce) {
  .flip-card__leaf { display: none; }
}

.countdown__unit {
  font-size: 11px;
  /* Explicit line-height so the label block is exactly --cd-label-h tall.
     The separator centring below depends on that number. */
  line-height: 12px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--c-label);
  margin-top: 11px;
}

/* Post-deadline state. Swapped in by main.js once entries close. */
.countdown__closed {
  display: none;
  background: var(--c-surface);
  border: 1px solid var(--ns-icy-blue);
  padding: 24px 28px;
  max-width: 560px;
  margin: 16px auto 0;
}
.countdown__closed h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(24px, 4vw, 32px);
  line-height: 1;
  text-transform: uppercase;
  color: var(--c-ice);
}
.countdown__closed p {
  font-size: 15px;
  line-height: 1.6;
  color: var(--c-body);
  margin: 10px 0 0;
}
.countdown.is-closed .countdown__grid,
.countdown.is-closed .countdown__label { display: none; }
.countdown.is-closed .countdown__closed { display: block; }

/* Sits between the clock and the button, so the gap above it carries the
   separation and the button tucks in close beneath. */
.hero__note {
  margin: 26px auto 0;
  text-align: center;
}
/* A marker swipe, not a label chip: uneven corner radii and a colour that
   sits outside the palette, because the point is that it looks drawn on.
   The line is held to one line by nowrap, so the size has to be governed by
   the viewport - the string measures 26.410 x the font size in Roboto, which
   at 320px leaves room for 10.5px. 3.25vw stays under that at every width up
   to the 17px cap. Shorten the copy and the vw term can rise. */
.hero__mark {
  display: inline-block;
  white-space: nowrap;
  padding: 0.18em 0.55em;
  border-radius: 0.7em 0.25em 0.6em 0.3em;
  background: var(--c-highlight);
  color: #0B0F12;
  font-size: clamp(10px, 3.25vw, 17px);
  line-height: 1.45;
}
.hero__mark strong { color: inherit; font-weight: 700; }

.hero__cta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
  margin-top: 16px;
}

/* Second call to action, repeating the hero's further down the page. Its own
   wrapper rather than a reuse of .hero__cta: that one belongs to the hero and
   sharing it would tie the two layouts together, so a change to the hero
   spacing would silently move this button too. Centred, because every other
   button on the page is. */
.section-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
  /* Sits above the section heading, so the gap belongs underneath it. No
     top margin: it is the first thing in the wrap and the section's own
     padding already carries the space above. */
  margin-bottom: 30px;
}

/* --------------------------------------------------------------------------
   4. How it works
   -------------------------------------------------------------------------- */
.grid-2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
  margin-top: 30px;
}

/* --------------------------------------------------------------------------
   5. Prize overview
   -------------------------------------------------------------------------- */
.prize-panel {
  position: relative;
  background: var(--c-bg);
  overflow: hidden;
}
.prize-panel__car {
  display: block;
  width: 100%;
  /* height: auto is load-bearing. The img carries a height attribute, which
     is a presentational hint; with no height in CSS it wins, both axes end
     up definite and aspect-ratio is ignored entirely - the panel renders at
     the file's own proportions instead of the 2:1 crop, and the edge blend
     below (which is 2:1) then covers only part of it. */
  height: auto;
  aspect-ratio: 2 / 1;
  object-fit: cover;
  object-position: center 55%;
}
/* Edge blend, the same treatment the hero picture gets: the photograph
   dissolves into the page instead of ending on a hard rectangle. It shares
   the image's 2/1 ratio and is pinned to the top, so it covers exactly the
   picture and not the copy below it. */
.prize-panel::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  aspect-ratio: 2 / 1;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(90deg,
      var(--c-bg) 0%, rgba(0, 0, 0, 0.78) 6%, rgba(0, 0, 0, 0.34) 12%,
      rgba(0, 0, 0, 0) 19%, rgba(0, 0, 0, 0) 81%, rgba(0, 0, 0, 0.34) 88%,
      rgba(0, 0, 0, 0.78) 94%, var(--c-bg) 100%),
    linear-gradient(180deg,
      var(--c-bg) 0%, rgba(0, 0, 0, 0.7) 5%, rgba(0, 0, 0, 0.3) 10%,
      rgba(0, 0, 0, 0) 17%),
    radial-gradient(130% 100% at 50% 24%, rgba(0, 0, 0, 0) 46%, rgba(0, 0, 0, 0.4) 100%);
}
.prize-panel__scrim {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 2;
  height: 62%;
  background: var(--grad-prize-scrim);
  pointer-events: none;
}
.prize-panel__text {
  position: relative;
  z-index: 3;
  padding: 0 32px 34px;
  margin-top: -18px;
}
.prize-panel__heading {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(28px, 4.6vw, 48px);
  line-height: 1;
  text-transform: uppercase;
  color: var(--c-text);
}
.prize-panel__body {
  font-size: 16px;
  line-height: 1.6;
  color: var(--c-text);
  max-width: 78ch;
  margin: 12px 0 0;
}

.grid-4 {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  margin-top: 20px;
}

.spec__value {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(20px, 2.4vw, 24px);
}
.card-b--highlight { border-color: var(--ns-icy-blue); }
.card-b--highlight .spec__value { color: var(--c-ice); }

/* --------------------------------------------------------------------------
   6. Image gallery
   -------------------------------------------------------------------------- */
/* The cells used to be ice-coloured grounds with transparent cutouts floating
   on them at 76-100% width. They hold photographs now, so each cell is a
   window the picture fills. Stretching the left cell still matters: it is
   shorter than the two stacked beside it, and without this the row ended
   with a strip of bare black under it. */
.gallery {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: 16px;
  margin-top: 28px;
  align-items: stretch;
}
.gallery__sub {
  display: grid;
  gap: 16px;
  /* Splits the row height set by the main cell below. Without definite rows
     here the stacked cells have no height to give their images, and
     `height: 100%` on the image resolves against nothing. */
  grid-template-rows: 1fr 1fr;
}
.gallery__cell {
  position: relative;
  background: var(--c-bg);
  overflow: hidden;
  min-height: 0;
}
/* The main cell's ratio is what establishes the row height for the whole
   grid, including the two cells stacked beside it. */
.gallery__cell--main { aspect-ratio: 3 / 2; }
/* Each cell holds a stack of frames. They are all absolutely positioned so
   they occupy the same box and crossfade in place; the cell's own height
   comes from the ratios above, not from the images. */
.gallery__cell img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.9s ease;
}
.gallery__cell img.is-active { opacity: 1; }
/* The two stacked cells are near-square, so the vehicle is pulled off centre
   to keep it in frame rather than cropping to empty road. */
.gallery__cell--front img { object-position: center 60%; }
.gallery__cell--rear img { object-position: center 55%; }

.gallery__caption {
  position: absolute;
  z-index: 1;
  inset: auto 0 0 0;
  background: var(--grad-caption);
  font-family: var(--font-display);
  font-weight: 400;
  text-transform: uppercase;
  color: var(--c-text);
  padding: 14px 18px;
  font-size: 17px;
}
.gallery__cell--main .gallery__caption {
  padding: 18px 22px;
  font-size: clamp(17px, 2.2vw, 22px);
}

/* --------------------------------------------------------------------------
   7. Overview video
   -------------------------------------------------------------------------- */
.video-frame {
  margin-top: 28px;
  border: 1px solid var(--c-border);
  background: var(--c-surface);
  aspect-ratio: 16 / 9;
  position: relative;
  overflow: hidden;
}
/* The Vidalytics embed carries its own shape as inline padding-top on the
   div it injects into, so the frame must not also impose 16/9 - the two
   fight and the player ends up clipped. Height comes from the child.

   The video is square (720x720), so at full column width it would stand
   1240px tall on a wide desktop - a screen and a half of scrolling. The cap
   holds it to 600px there. No media query needed: a phone column is already
   narrower than the cap, so mobile keeps the full-bleed square it has. */
.video-frame--embed {
  aspect-ratio: auto;
  max-width: 760px;
  margin-inline: auto;
  /* No outline on this one. The edges below dissolve into the page, and a
     1px border drawn over that fade puts the hard rectangle straight back. */
  border: 0;
  background: var(--c-bg);
}
/* The same trick as the hero shot, turned right down. The hero has to carry
   a headline over it, so it runs to 0.78 at the sides; here the only job is
   to stop the player sitting on the page as a hard-edged square, so it stays
   in the outer ~10% and never touches the middle 78% - the play button and
   the control bar keep their contrast. pointer-events: none is load-bearing:
   without it this layer would swallow every click meant for the player. */
.video-frame--embed::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background:
    linear-gradient(90deg,
      var(--c-bg) 0%, rgba(0, 0, 0, 0.6) 2.5%, rgba(0, 0, 0, 0.2) 6%,
      rgba(0, 0, 0, 0) 11%, rgba(0, 0, 0, 0) 89%, rgba(0, 0, 0, 0.2) 94%,
      rgba(0, 0, 0, 0.6) 97.5%, var(--c-bg) 100%),
    linear-gradient(180deg,
      var(--c-bg) 0%, rgba(0, 0, 0, 0.45) 2.5%, rgba(0, 0, 0, 0.15) 6%,
      rgba(0, 0, 0, 0) 11%, rgba(0, 0, 0, 0) 89%, rgba(0, 0, 0, 0.15) 94%,
      rgba(0, 0, 0, 0.45) 97.5%, var(--c-bg) 100%);
}

.video-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* --------------------------------------------------------------------------
   8. Shop to enter
   -------------------------------------------------------------------------- */
/* Three tiles that add up, with the plus signs in their own auto columns so
   the tiles keep equal widths whatever the separator measures. */
.tiers {
  display: grid;
  grid-template-columns:
    minmax(0, 1fr) auto minmax(0, 1fr) auto minmax(0, 1fr) auto minmax(0, 1fr);
  gap: 16px;
  align-items: stretch;
  margin-top: 28px;
}
.tier__plus {
  align-self: center;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(20px, 2.6vw, 30px);
  line-height: 1;
  color: var(--ns-icy-blue);
}
.tier {
  padding: 24px 22px;
  text-align: center;
}
.tier__value {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(28px, 3.4vw, 34px);
}
.tier--free {
  background: var(--c-ice);
  border-color: transparent;
  color: #000000;
}
.tier--free .tile__label { color: var(--c-teal-deep); }

/* One card now - the mail-in card that shared this row was removed. Kept as
   a grid so a second card can be dropped back in without rewriting this. */
.mailin {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
  gap: 20px;
  margin-top: 20px;
}
/* Heading on the left, the sum on the right, on one line. Wraps to two rows
   when there is not room for both, which is what happens on a phone. */
.earns__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 28px;
  margin-bottom: 20px;
}
.earns__head > div { min-width: 0; }

/* The sum. This is the number the section exists to deliver, so it is set
   larger than anything else on the page bar the hero headline. */
.tally {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0;
}
.tally__value {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(46px, 7vw, 76px);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--ns-icy-blue);
}
.tally__unit {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(15px, 1.8vw, 20px);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--c-text);
}
.earns__note {
  font-size: 13px;
  line-height: 1.6;
  color: var(--c-muted);
  margin: 14px 0 0;
}

/* Entries by service. A plain list, one row per service, with the figure
   right-aligned so the numbers form a column the eye can compare down. */
.earns {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: grid;
  gap: 2px;
}
.earns li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 9px 0;
  border-bottom: 1px solid var(--c-border);
}
.earns__name {
  font-size: 15px;
  color: var(--c-body);
}
.earns__count {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 16px;
  color: var(--c-text);
  white-space: nowrap;
}
/* The last row needs no rule under it - nothing follows it to separate from. */
.earns li:last-child { border-bottom: 0; }

/* --------------------------------------------------------------------------
   9. FAQ - native <details> so the open/close semantics, the ARIA state and
   the keyboard behaviour come from the browser rather than from script.
   -------------------------------------------------------------------------- */
.faq {
  display: grid;
  gap: 10px;
  margin-top: 28px;
}
.faq__item {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
}
.faq__trigger {
  padding: 20px 24px;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  gap: 20px;
  align-items: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(15px, 2vw, 18px);
  line-height: 1.3;
  text-transform: uppercase;
  color: var(--c-text);
  list-style: none;
}
.faq__trigger::-webkit-details-marker { display: none; }
.faq__trigger:hover { color: var(--c-ice); }
.faq__trigger::after {
  content: '+';
  color: var(--ns-icy-blue);
  font-size: 20px;
  line-height: 1;
  flex: none;
}
.faq__item[open] > .faq__trigger::after { content: '\2212'; }

.faq__panel {
  font-size: 15px;
  line-height: 1.7;
  color: var(--c-body);
  padding: 0 24px 22px;
  /* Runs the full width of the card. There was an 88ch cap here, which is
     the usual comfortable measure, but it stopped the text around 75% of the
     card and left the right side looking unfinished. The answers are only a
     few lines each, so the long measure costs little. */
}

/* --------------------------------------------------------------------------
   10. Footer
   -------------------------------------------------------------------------- */
.footer {
  background: var(--c-bg);
  border-top: 1px solid var(--c-border);
  padding: 48px 32px 64px;
}

.footer__cols {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 32px;
  padding-bottom: 36px;
  border-bottom: 1px solid var(--c-border);
}
.footer__heading {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-text);
}
.footer__links {
  display: grid;
  gap: 8px;
  margin-top: 14px;
  font-size: 14px;
}
/* Not cyan. Six stacked links in the link colour read as a block of raw
   blue; light text that warms to ice on hover sits back and lets the
   headings lead. */
.footer__links a {
  color: var(--c-body);
  transition: color 0.15s ease;
}
.footer__links a:hover { color: var(--c-ice); }
.footer__links span { color: var(--c-muted); }

.rules { padding-top: 32px; }
.rules__heading {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(20px, 3vw, 24px);
  text-transform: uppercase;
}
.rules__body {
  font-size: 13px;
  line-height: 1.75;
  color: var(--c-muted);
  /* Full width, like the FAQ answers. The 120ch cap that was here stopped
     the legal block around 70% of the footer and left the right side
     looking unfinished. */
  margin: 14px 0 0;
}
.rules__body strong { color: var(--c-text); }

.social {
  margin-top: 34px;
  padding-top: 28px;
  border-top: 1px solid var(--c-border);
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  align-items: center;
  justify-content: space-between;
}
.social__heading {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(17px, 2.4vw, 20px);
  text-transform: uppercase;
}
.social__note {
  font-size: 14px;
  color: var(--c-muted);
  margin: 8px 0 0;
  max-width: 46ch;
}
.social__list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.pill {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-height: 44px;
  border: 1px solid var(--c-border);
  border-radius: 999px;
  padding: 10px 18px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--c-text);
  transition: border-color 0.15s ease, color 0.15s ease;
}
.pill:hover {
  border-color: var(--ns-icy-blue);
  color: var(--c-ice);
}
/* No `fill: currentColor` here - each mark carries its own brand colours,
   and the ones whose counters are holes (the Facebook f, the YouTube play
   triangle, the LinkedIn "in") have a white shape behind them so those
   counters read white rather than showing the black page through. */
.pill svg {
  display: block;
  width: 16px;
  height: 16px;
  flex: none;
}

.footer__bottom {
  margin-top: 28px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  color: var(--c-faint);
}
.footer__tagline {
  font-family: var(--font-display);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* ==========================================================================
   Responsive
   The prototype was desktop-only; these breakpoints implement the behaviour
   described in the handoff's Responsive notes.
   ========================================================================== */

/* Tablet ------------------------------------------------------------------ */
@media (max-width: 1000px) {
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
  /* The header is one row here, as in the reference: menu button, wordmark,
     Membership. The section anchors move into the menu panel. */
  :root { --header-offset: 76px; }

  .section { padding: 0 20px 48px; }
  .section--how { padding: 48px 20px; }
  .section--hero { padding: 0 16px 40px; }
  .footer { padding: 40px 20px 48px; }

  .header {
    padding: 10px 16px;
    gap: 10px;
  }
  .header__tag { display: none; }
  .brand__logo { height: 32px; }

  /* Mobile hit targets: 44px minimum. The 38px small button is the desktop
     spec height, so it is only raised here. */
  .btn--sm { min-height: 44px; }
  .brand { min-height: 44px; }
  /* Hero, full bleed. The section keeps its 16px gutter for the countdown and
     the buttons; the picture cancels it with a negative margin so it runs
     edge to edge, as the reference's does. */
  .hero-shot {
    max-width: none;
    margin-inline: -16px;
    padding: 24px 0 40px;
  }
  .hero-shot__img { width: 100%; }

  /* Two lines, not three. The headline is the loudest thing on a phone, so
     it wants the full bleed width: at 390px, 8.2vw is 32px and "NORTHERN
     SNOW" measures 369px against ~378px of room. The 26px floor (rather
     than 28px) is what keeps it to two lines down at 320px. */
  .hero__headline {
    max-width: none;
    margin-inline: -16px;
    padding: 0 4px;
    margin-top: -0.3em;
    font-size: clamp(26px, 8.2vw, 67px);
  }

  /* All four cards on one row, as in the reference. The 2x2 wrap cost about
     100px of vertical space and pushed the buttons off the first screen. */
  .countdown__grid {
    gap: 4px;
    /* Keeps the desktop cap rather than running full width. Without it the
       row stretched to ~868px at the 900px breakpoint - wider than it is on
       a 1440px screen - while the digits stayed at their phone size. */
    max-width: 630px;
    margin-top: 14px;
  }
  .countdown__separator { font-size: 13px; }
  /* Tracks the card instead of sitting at a flat phone size, so the digits
     keep their proportion (~46% of card width) all the way up to the 62px
     the desktop row uses. */
  .flip-card { font-size: clamp(20px, 10vw, 62px); }
  .countdown__unit { letter-spacing: 0.08em; margin-top: 8px; }
  .countdown__grid { --cd-label-h: 20px; }

  /* Two tight lines rather than two loose ones - the announcement copy is
     the client's and is too long for one line on a phone. The side padding is
     12px, not 6px, because the arrows carry an invisible 10px hit expander -
     at 6px that expander reached past the viewport and the page scrolled
     sideways by 4px. */
  .announce { padding: 3px 12px; }
  .announce__item { font-size: 11px; letter-spacing: 0.07em; line-height: 1.4; }
  .announce__arrow { width: 24px; height: 24px; }


  .hero__note { margin-top: 20px; }
  .hero__cta { margin-top: 14px; }
  /* Hug the label. Stretching it to the full row left a wide band of empty
     cyan either side of the text. */
  .hero__cta .btn {
    flex: 0 1 auto;
    max-width: 100%;
  }

  .grid-2 { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .card-a { padding: 22px; }

  /* The 16px top margin was for the old cutout floating on an ice ground;
     a full-bleed photograph wants to meet the panel edge. */
  .prize-panel__car { width: 100%; }
  /* The heading normally tucks up over the foot of the picture. The mobile
     crop is only about 175px tall, so that overlap put it across the car
     instead of under it - it sits below the image here. */
  .prize-panel__text {
    margin-top: 0;
    padding: 18px 20px 26px;
  }

  /* One column outside, front and rear side by side inside. */
  /* One column outside, front and rear side by side inside. The sub grid
     is one row here, so the cells carry their own ratio instead of
     splitting a height handed down by the main cell. */
  .gallery { grid-template-columns: minmax(0, 1fr); }
  .gallery__sub {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: auto;
  }
  .gallery__cell--front,
  .gallery__cell--rear { aspect-ratio: 4 / 3; }


  /* Two columns of links, with Contact across the full row beneath - as a
     half column its address lines wrapped awkwardly and left dead space. */
  .footer__cols {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 26px 20px;
  }
  .footer__cols > div:last-child {
    grid-column: 1 / -1;
    padding-top: 4px;
    border-top: 1px solid var(--c-border);
  }
  .social { gap: 24px; }
}

/* Phone ------------------------------------------------------------------- */
@media (max-width: 560px) {
  /* Below this the three header zones stop fitting on one row and the
     Membership button starts overlapping the wordmark. The side zones give
     up their equal-flex centring, the brand takes the middle, and the
     wordmark truncates rather than being covered. */
  .header__left,
  .header__actions { flex: none; }
  .brand {
    flex: 1 1 auto;
    min-width: 0;
    justify-content: center;
  }
  .brand__logo { height: 28px; }
  .header__actions .btn--sm { padding: 8px 10px; }
  .header { gap: 10px 12px; }

  /* `white-space: nowrap` on a button makes its min-content width the full
     label, which a long label ("Enter free by mail") pushes past a 360-390px
     viewport. On phones the buttons are full-width anyway, so let them wrap. */
  .btn {
    white-space: normal;
    text-align: center;
  }
  .btn--lg {
    padding: 12px 18px;
    font-size: 14px;
  }
  .btn--sm { padding: 8px 14px; }

  /* Spec tiles stay two across rather than stacking into four rows - there
     is room for it, and four full-width bands was a lot of scrolling for
     four short values. Tighter padding and a smaller value size so
     "Trailblazer LS" still fits a half column at 320px. */
  .grid-4 { gap: 12px; }
  .grid-4 .card-b { padding: 16px 14px; }
  .spec__value { font-size: 17px; }

  .gallery__sub { grid-template-columns: minmax(0, 1fr); }

  /* Deliberately still two columns. Collapsing to one turned six short
     links into a long thin ladder with a lot of empty space beside it. */
  .footer__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .social__list { width: 100%; }
  .pill { padding: 10px 14px; }

  .footer__bottom { flex-direction: column; align-items: flex-start; }
}

/* Gallery frames do not crossfade when motion is not wanted; main.js also
   stops advancing them, so the first frame simply stays put. */
@media (prefers-reduced-motion: reduce) {
  .gallery__cell img { transition: none; }
}

/* Entry tiers ---------------------------------------------------------------
   Three across needs roughly 700px before the labels start breaking badly.
   Below that the chain runs down the page instead, plus signs and all, which
   still reads as "these add up". */
@media (max-width: 760px) {
  .tiers {
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
  }
  .tier__plus { justify-self: center; }
}

/* Header nav handover -------------------------------------------------------
   Measured, not estimated. The logo is centred, so its left edge sits at
   about viewport/2 - 58, while the last nav link ends at a fixed distance
   from the left. They only clear each other from 1220px, where there is
   25px between them; below that "ENTER" and "FAQ" run under the wordmark.
   Hence the handover at 1210px rather than the 900px the rest of the layout
   uses. The anchors are never visible in both places at once.

   The nav gap is the lever here. It was 18px flat, which cleared at 1140px;
   opening it to clamp(18px, 2vw, 34px) to fill the header on wide screens
   pushed that to 1220px. Narrow the gap to bring the nav back on smaller
   laptops. */
@media (max-width: 1210px) {
  .header__nav { display: none; }
  .header__menu-sections {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding-bottom: 8px;
    margin-bottom: 8px;
    border-bottom: 1px solid var(--c-border);
  }
}

/* Touch targets ------------------------------------------------------------
   Everything you can tap needs about 44px of finger, but several controls
   here are deliberately small objects: a 24px chevron, a 30px hamburger. The
   fix is to grow the hit area without growing the thing you can see - an
   absolutely positioned, invisible ::after does that and costs no layout, so
   the announcement strip and header keep their heights. */
.announce__arrow,
.menu-toggle { position: relative; }
.announce__arrow::after,
.menu-toggle::after {
  content: '';
  position: absolute;
  /* Grows a 24px control to 44px, a 30px one to 50px. */
  inset: -10px;
}

/* The skip link was 42px - two short of the mark, and it is the very first
   thing a keyboard or screen-reader user lands on. */
.skip-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

@media (max-width: 900px) {
  /* Footer links sat at 21px tall: readable, but a small target stacked 8px
     from its neighbour. Padding gives each one a full row to be tapped in.
     Inline links inside prose are left alone - they are part of a sentence,
     not standalone controls, and padding them would break the line box. */
  .footer__links a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  .footer__links { gap: 0; }
}
