/* ============================================================
   GOLDMAN — style.css
   Import order: tokens.css → style.css. Every colour resolves to a
   custom property; there are no hex values in this file.

   Conventions
   -----------
   · Flat specificity — single class selectors. No .section .card h3
     chains. Section padding collisions are the single most common
     failure when a stylesheet is written in pieces.
   · BEM-ish naming: .block, .block__element, .block--modifier.
   · Mobile-first. Every breakpoint lands on a container step
     (576 / 768 / 992 / 1200 / 1400) — a split at 900px sits inside a
     720px container and gives each column ~300px, which is not a column.
   · Radius is 2px on everything. This is load-bearing.
   ============================================================ */

/* ------------------------------------------------------------------
   1. RESET & BASE
   ------------------------------------------------------------------ */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
/* Lenis drives scrolling; native smooth behaviour fights it. */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }

body {
  margin: 0;
  background: var(--gm-paper);
  color: var(--gm-graphite);
  font-family: var(--ff-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  text-rendering: optimizeLegibility;
}

img, svg, video, canvas { display: block; max-width: 100%; }
img, video { height: auto; }

a { color: inherit; text-decoration: none; }

button, input, select, textarea {
  font: inherit;
  color: inherit;
}
button { background: none; border: 0; cursor: pointer; }

h1, h2, h3, h4, h5, h6, p, figure, blockquote, ul, ol, dl { margin: 0; }
ul, ol { padding: 0; list-style: none; }

address { font-style: normal; }

::selection { background: var(--gm-gold); color: var(--gm-obsidian); }

/* Visible focus ring on every interactive element. Never remove this
   without a replacement — keyboard users lose the page otherwise. */
:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
  border-radius: var(--radius);
}
/* Dark panels need the ring to sit against the light side of gold. */
.section--obsidian :focus-visible,
.site-footer :focus-visible,
.mobile-nav :focus-visible { outline-color: var(--gm-gold-lite); }

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

.skip-link {
  position: absolute;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  top: 0; left: 50%;
  transform: translate(-50%, -110%);
  z-index: var(--z-skiplink);
  padding: 12px 24px;
  background: var(--gm-obsidian);
  color: var(--gm-gold);
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  border-radius: 0 0 var(--radius) var(--radius);
  transition: transform var(--dur-fast) var(--ease-out);
}
.skip-link:focus { transform: translate(-50%, 0); }

/* Honeypot — invisible to a person, present for a bot. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* ------------------------------------------------------------------
   2. LAYOUT
   ------------------------------------------------------------------ */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}
.container--wide { max-width: var(--container-wide); }

.section { padding-block: var(--section-y); position: relative; }
.section--tight { padding-block: clamp(48px, 6vw, 88px); }
.section--flush-top { padding-top: 0; }

.section--paper     { background: var(--gm-paper); }
.section--champagne { background: var(--gm-champagne); }
.section--card      { background: var(--gm-card); }

.section--obsidian {
  background: var(--gm-obsidian);
  color: rgba(251, 250, 247, .74);
}
.section--obsidian .h2,
.section--obsidian .h3,
.section--obsidian .h4 { color: var(--gm-paper); }
.section--obsidian .eyebrow { color: var(--gm-gold); }
.section--obsidian .lede { color: rgba(251, 250, 247, .78); }

.stack > * + * { margin-top: var(--space-4); }
.stack--lg > * + * { margin-top: var(--space-6); }

.grid { display: grid; gap: var(--space-5); }
@media (min-width: 768px) {
  .grid--2 { grid-template-columns: repeat(2, 1fr); }
  .grid--3 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 992px) {
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
  .grid--4 { grid-template-columns: repeat(2, 1fr); }
  .grid--split { grid-template-columns: 1fr 1fr; gap: clamp(40px, 6vw, 88px); align-items: start; }
}
@media (min-width: 1200px) {
  .grid--4 { grid-template-columns: repeat(4, 1fr); }
}

.section__head { max-width: 46rem; margin-bottom: clamp(40px, 5vw, 72px); }
.section__head--center { margin-inline: auto; text-align: center; }
.section__head--center .eyebrow { justify-content: center; }

/* ------------------------------------------------------------------
   3. TYPOGRAPHY
   ------------------------------------------------------------------ */

.h1, .h2, .h3, .h4 {
  font-family: var(--ff-display);
  color: var(--gm-ink);
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}

.h1 { font-size: var(--fs-display-xl); line-height: var(--lh-display); font-weight: 700; }
.h2 { font-size: var(--fs-display-l);  line-height: var(--lh-h2); }
.h3 { font-size: var(--fs-display-m);  line-height: var(--lh-h3); }
.h4 { font-size: var(--fs-display-s);  line-height: 1.28; letter-spacing: -.01em; }

/* Eyebrow — the packaging's tracked-out caps. Never below 11px, never
   --gm-slate, and never --gm-gold on a light ground (2.4:1). */
.eyebrow {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-gold-text);
  margin-bottom: var(--space-4);
}
.eyebrow::before {
  content: "";
  width: 32px; height: 1px;
  background: var(--gm-gold);
  flex: none;
}
.section--obsidian .eyebrow::before { background: var(--gm-gold); }

.lede {
  font-size: var(--fs-body-l);
  line-height: var(--lh-body-l);
  color: var(--gm-graphite);
  max-width: var(--measure);
}
.prose { max-width: var(--measure); }
.prose > * + * { margin-top: var(--space-4); }
.prose p { color: var(--gm-graphite); }

.caption {
  font-size: var(--fs-caption);
  line-height: 1.5;
  color: var(--gm-slate);
}

.data {
  font-family: var(--ff-data);
  font-size: var(--fs-data);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}
.data--sm { font-size: var(--fs-data-s); }

.label {
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-ink);
}

.text-gold  { color: var(--gm-gold-text); }   /* any size, light ground */
.text-slate { color: var(--gm-slate); }
.text-ink   { color: var(--gm-ink); }

/* A gold hairline used as a section divider. */
.rule {
  height: 1px;
  background: var(--gm-hairline);
  border: 0;
  margin-block: var(--space-7);
}
.rule--labelled {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-block: clamp(40px, 5vw, 72px);
}
.rule--labelled::before,
.rule--labelled::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--gm-gold);
}
.rule__label {
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-gold-text);
  white-space: nowrap;
}

/* ------------------------------------------------------------------
   4. BUTTONS
   ------------------------------------------------------------------ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  min-height: 48px;               /* >= 44px touch target */
  padding: 14px 28px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}
.btn .icon { flex: none; transition: transform var(--dur-fast) var(--ease-out); }
.btn:hover .icon { transform: translateX(3px); }

.btn--gold {
  background: var(--gm-gold-deep);
  border-color: var(--gm-gold-deep);
  color: var(--gm-paper);
}
.btn--gold:hover { background: var(--gm-ink); border-color: var(--gm-ink); }

.btn--ink {
  background: var(--gm-ink);
  border-color: var(--gm-ink);
  color: var(--gm-paper);
}
.btn--ink:hover { background: var(--gm-obsidian); border-color: var(--gm-obsidian); }

.btn--outline {
  border-color: var(--gm-edge);
  color: var(--gm-ink);
  background: transparent;
}
.btn--outline:hover { border-color: var(--gm-gold); background: var(--gm-gold-wash); }

.btn--ghost {
  color: var(--gm-gold-text);
  background: transparent;
  border-color: transparent;
}
.btn--ghost:hover { background: var(--gm-gold-wash); }

/* On obsidian, --gm-gold is 8.1:1 and legal as text at any size. */
.btn--on-dark {
  border-color: rgba(251, 250, 247, .28);
  color: var(--gm-paper);
  background: transparent;
}
.btn--on-dark:hover { border-color: var(--gm-gold); color: var(--gm-gold); }

.btn--sm { min-height: 44px; padding: 11px 18px; }
.btn--block { width: 100%; }

/* Inline arrow link — not a button, but a nav affordance. */
.link-arrow {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  gap: var(--space-2);
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-gold-text);
  padding-block: var(--space-2);
  border-bottom: 1px solid var(--gm-hairline);
  transition: border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.link-arrow:hover { border-color: var(--gm-gold); color: var(--gm-ink); }
.link-arrow .icon { transition: transform var(--dur-fast) var(--ease-out); }
.link-arrow:hover .icon { transform: translateX(3px); }
.section--obsidian .link-arrow { color: var(--gm-gold); }
.section--obsidian .link-arrow:hover { color: var(--gm-gold-lite); }

/* ------------------------------------------------------------------
   5. HEADER
   A sticky bar ABOVE the hero, not overlaid on it. Overlaying forces
   every hero image to protect a text-safe zone forever.
   ------------------------------------------------------------------ */

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--gm-paper);
  border-bottom: 1px solid var(--gm-edge);
  transition: box-shadow var(--dur-base) var(--ease-out),
              background-color var(--dur-base) var(--ease-out);
}
.site-header.is-scrolled {
  background: rgba(251, 250, 247, .92);
  box-shadow: var(--shadow-md);
}
@supports (backdrop-filter: blur(12px)) {
  .site-header.is-scrolled { backdrop-filter: blur(12px); }
}

/* One source of truth for the header's height. Anything that sticks
   below the header (the depth rail, scroll-margin on anchor targets)
   reads --header-h, so the two cannot drift apart when this changes. */
:root { --header-h: 64px; }
@media (min-width: 992px) { :root { --header-h: 88px; } }

/* ALIGNED TO THE CONTENT COLUMN.
   This used to be max-width: var(--container-wide) — 1440px — while every
   block on every page uses the stepped var(--container), which caps at
   1320px. The logo therefore started 60px left of the first heading below
   it at 1440, and 70px left at 1280, so the page's left edge visibly
   stepped inward under the header. Matching --container is what makes the
   logo, the headings and the footer share one edge at every width.

   The nav has to fit the narrower column, which is what the two rules
   below pay for. */
.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  height: var(--header-h);
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

/* The client's horizontal lockup. tools/make-logos.sh trims the
   transparent margin off the original, so the file's bounding box is the
   artwork and `height` here is the height the logo actually appears at.

   Sized by HEIGHT with width:auto — the lockup is 5.74:1 and driving it
   from width would make its height depend on a ratio written in two
   places. The subtitle lines stay legible down to about 36px, which is
   what sets the mobile size. */
.brand {
  display: flex;
  align-items: center;
  min-height: 44px;
  margin-right: auto;
}
.brand__logo {
  height: 34px;
  width: auto;
  display: block;
}
@media (min-width: 992px) { .brand__logo { height: 44px; } }

.main-nav { display: none; }
@media (min-width: 1200px) { .main-nav { display: block; } }
.main-nav__list { display: flex; align-items: center; gap: var(--space-4); }
/* Only the widest step has room to breathe. Between 1200 and 1399 the
   content column is 1140px and seven links, a logo and a call to action
   have to share it — the gap is the cheapest thing to give up, and it
   costs less than crowding the words themselves. */
@media (min-width: 1400px) { .main-nav__list { gap: var(--space-5); } }
.main-nav__item { position: relative; }

.main-nav__link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding-block: var(--space-3);
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-ink);
  position: relative;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-out);
}
.main-nav__link::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  bottom: 0;
  height: 1px;
  background: var(--gm-gold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-base) var(--ease-out);
}
.main-nav__link:hover::after,
.main-nav__link.is-active::after { transform: scaleX(1); }
.main-nav__caret { display: inline-flex; transition: transform var(--dur-fast) var(--ease-out); }
.main-nav__item--mega.is-open .main-nav__caret { transform: rotate(180deg); }

.site-header__actions { display: none; gap: var(--space-2); }
@media (min-width: 1200px) { .site-header__actions { display: flex; } }
/* The header carries exactly ONE action, whichever it is. Two buttons
   cost 147px more than the content column has spare, and that is what
   used to make the header wider than every heading below it. The markup
   in _header.php decides which one; this rule exists so a second button
   added later is caught here rather than silently breaking alignment. */
.site-header__actions > * ~ * { display: none; }

/* --- Products mega-panel --- */

.mega {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-mega);
  width: min(1100px, calc(100vw - 2 * var(--container-pad)));
  background: var(--gm-card);
  border: 1px solid var(--gm-edge);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: var(--space-6);
}
.mega[hidden] { display: none; }
.mega__inner { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--space-5); }

.mega__heading {
  display: block;
  min-height: 32px;
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-gold-text);
  padding-bottom: var(--space-3);
  margin-bottom: var(--space-3);
  border-bottom: 1px solid var(--gm-hairline);
}
.mega__heading--plain { color: var(--gm-slate); }

.mega__list > li + li { margin-top: 2px; }
.mega__item {
  display: block;
  min-height: 44px;
  padding: var(--space-3);
  margin-inline: calc(var(--space-3) * -1);
  border-radius: var(--radius);
  transition: background-color var(--dur-fast) var(--ease-out);
}
.mega__item:hover { background: var(--gm-champagne); }
.mega__name {
  display: block;
  font-family: var(--ff-display);
  font-size: 1rem;
  font-weight: 600;
  color: var(--gm-ink);
  line-height: 1.2;
}
.mega__meta {
  display: flex;
  gap: var(--space-2);
  align-items: baseline;
  margin-top: 3px;
  font-family: var(--ff-data);
  font-size: .6875rem;
  font-variant-numeric: tabular-nums;
  color: var(--gm-slate);
}
.mega__years { color: var(--gm-gold-text); font-weight: 500; }

.mega__all {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  gap: var(--space-2);
  margin-top: var(--space-4);
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-gold-text);
}
.mega__all:hover { color: var(--gm-ink); }

/* --- Mobile toggle + overlay --- */

.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  margin-right: calc(var(--space-2) * -1);
  border-radius: var(--radius);
}
@media (min-width: 1200px) { .nav-toggle { display: none; } }

.nav-toggle__box { display: block; width: 22px; height: 14px; position: relative; }
.nav-toggle__bar {
  position: absolute;
  left: 0;
  width: 100%;
  height: 1.5px;
  background: var(--gm-ink);
  transition: transform var(--dur-base) var(--ease-out),
              opacity 160ms var(--ease-out);
}
.nav-toggle__bar:nth-child(1) { top: 0; }
.nav-toggle__bar:nth-child(2) { top: 6.25px; }
.nav-toggle__bar:nth-child(3) { top: 12.5px; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) { transform: translateY(6.25px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) { transform: translateY(-6.25px) rotate(-45deg); }

.mobile-nav {
  position: fixed;
  inset: 64px 0 0;
  z-index: var(--z-overlay);
  background: var(--gm-paper);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.mobile-nav[hidden] { display: none; }
@media (min-width: 1200px) { .mobile-nav { display: none !important; } }

.mobile-nav__inner {
  padding: var(--space-6) var(--container-pad) var(--space-9);
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  min-height: 100%;
}
.mobile-nav__item { border-bottom: 1px solid var(--gm-edge-soft); }

.mobile-nav__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  min-height: 56px;
  padding-block: var(--space-4);
  font-family: var(--ff-display);
  font-size: 1.375rem;
  font-weight: 600;
  color: var(--gm-ink);
  text-align: left;
  letter-spacing: -.01em;
}
.mobile-nav__link.is-active { color: var(--gm-gold-text); }
.mobile-nav__caret { display: inline-flex; color: var(--gm-slate); transition: transform var(--dur-fast) var(--ease-out); }
.mobile-nav__link[aria-expanded="true"] .mobile-nav__caret { transform: rotate(180deg); }

.mobile-nav__panel { padding-bottom: var(--space-4); }
.mobile-nav__panel[hidden] { display: none; }
.mobile-nav__sub {
  display: block;
  min-height: 48px;
  padding: var(--space-3) 0 var(--space-3) var(--space-4);
  border-left: 1px solid var(--gm-hairline);
  color: var(--gm-graphite);
  font-size: var(--fs-body);
}
.mobile-nav__sub--all { color: var(--gm-gold-text); font-weight: 600; }

.mobile-nav__actions { display: flex; flex-direction: column; gap: var(--space-3); margin-top: auto; }

body.is-nav-open { overflow: hidden; }

/* ------------------------------------------------------------------
   6. FOOTER — the dark footer anchors a light page.
   ------------------------------------------------------------------ */

.site-footer {
  background: var(--gm-obsidian);
  color: rgba(251, 250, 247, .68);
  padding-top: clamp(56px, 7vw, 96px);
}
.site-footer__inner {
  display: grid;
  gap: var(--space-7);
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--container-pad);
  padding-bottom: var(--space-8);
}
@media (min-width: 768px) { .site-footer__inner { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 992px) { .site-footer__inner { grid-template-columns: 1.6fr 1fr 1fr 1.2fr; gap: var(--space-6); } }

.footer-brand {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.footer-brand__logo {
  height: 46px;
  width: auto;
  display: block;
}
@media (min-width: 992px) { .footer-brand__logo { height: 54px; } }

.site-footer__line {
  margin-top: var(--space-4);
  max-width: 30ch;
  font-size: var(--fs-caption);
  line-height: 1.6;
  color: rgba(251, 250, 247, .58);
}

.social { display: flex; gap: var(--space-2); margin-top: var(--space-5); }
.social__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  border: 1px solid var(--gm-edge-dark);
  border-radius: var(--radius);
  color: rgba(251, 250, 247, .72);
  transition: border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.social__link:hover { border-color: var(--gm-gold); color: var(--gm-gold); }

.site-footer__heading {
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-gold);
  margin-bottom: var(--space-4);
}
.site-footer__list > li + li { margin-top: var(--space-1); }
.site-footer__list a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-block: 7px;
  font-size: var(--fs-caption);
  color: rgba(251, 250, 247, .68);
  transition: color var(--dur-fast) var(--ease-out);
}
.site-footer__list a:hover { color: var(--gm-paper); }

.site-footer__contact {
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--gm-edge-dark);
  display: flex;
  flex-direction: column;
  /* No gap: the links carry their own height now, and a gap on top of
     that would space the block out twice. The address keeps its margin
     below instead. */
  font-size: var(--fs-caption);
  line-height: 1.6;
}
/* A phone number in a footer is TAPPED, on a phone, by someone standing
   next to a car. At 21px tall it was a 21px target. These became real
   links only when company.phone and company.email were confirmed on
   10 Sep 2026 — before that cfg_confirmed() returned null and the block
   rendered nothing, which is why this never showed up earlier.

   inline-flex rather than padding so the 44px is the LINK's box and not
   a gap around it: padding on an inline element does not grow the hit
   area vertically the way it appears to. */
.site-footer__contact a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  align-self: flex-start;   /* the target is the text width, not the column */
  color: rgba(251, 250, 247, .78);
}
.site-footer__contact a:hover { color: var(--gm-gold); }
.site-footer__addr {
  color: rgba(251, 250, 247, .58);
  max-width: 26ch;
  margin-bottom: var(--space-2);
}

.site-footer__bar {
  border-top: 1px solid var(--gm-edge-dark);
  padding-block: var(--space-5);
}
.site-footer__bar {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  align-items: flex-start;
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}
@media (min-width: 768px) {
  .site-footer__bar { flex-direction: row; justify-content: space-between; align-items: center; }
}
.site-footer__copy { font-size: var(--fs-caption); color: rgba(251, 250, 247, .5); }
.site-footer__legal { display: flex; flex-wrap: wrap; gap: var(--space-5); }
.site-footer__legal a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: var(--fs-caption);
  color: rgba(251, 250, 247, .5);
}
.site-footer__legal a:hover { color: var(--gm-gold); }

/* ------------------------------------------------------------------
   7. HERO
   Full-bleed image with copy in the left safe zone on desktop. Below
   992px the copy STACKS BELOW the image — the portrait crop is filled
   edge to edge by the car and overlaid text becomes unreadable.
   ------------------------------------------------------------------ */

/* The image's ideal height per hero variant. At >=992px .hero__media
   reads this as a MIN, so the picture never gets shorter than this and
   never stops the hero growing to fit its copy. clamp() folds the old
   aspect-ratio / min-height / max-height triple into one value. */
.hero {
  display: block;
  background: var(--gm-paper);
  --hero-media-h: clamp(400px, calc(100vw * 750 / 1920), 720px);
}
.hero--range  { --hero-media-h: clamp(380px, calc(100vw * 900 / 2000), 60vh); }
/* ONE HEIGHT FOR EVERY INNER-PAGE BANNER.
   Client request, 12 Sep 2026: the banner must be the same size on every
   page. It was not — the hero grows to fit its copy, so a three-line
   heading made /about and /dealers 503px and /warranty 551px against a
   450px baseline on the other eleven pages.

   A flat 500px, capped so it can still never exceed the viewport it is
   pinned in — a sticky banner taller than the screen is the defect
   /_viewport.html exists to catch. The three long headings were
   shortened to two lines so they fit inside it; see about.php,
   dealers.php and warranty.php. */
.hero--sticky { --hero-media-h: min(500px, calc(100dvh - var(--header-h) - 24px)); }

.hero__media {
  position: relative;
  width: 100%;                                  /* pin explicitly: aspect-ratio
                                                   plus min-height with no width
                                                   makes the box solve for width
                                                   and overflow the viewport */
  aspect-ratio: 4 / 5;
  max-height: 68vh;
  overflow: hidden;
  background: var(--gm-mist);
}
.hero__img { width: 100%; height: 100%; object-fit: cover; }

.hero__body { padding-block: clamp(40px, 6vw, 72px); }
.hero__title { margin-bottom: var(--space-5); }
.hero__lede { max-width: 42rem; margin-bottom: var(--space-6); }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }

@media (min-width: 992px) {
  /* 🔴 A ONE-CELL GRID, not an absolutely-positioned overlay.
     .hero__body used to be `position: absolute; inset: 0`, so it
     contributed NO height. The hero's height came only from the image's
     aspect ratio, and when the copy needed more room than the picture
     happened to give it, the copy spilled over both edges — 38px past
     the top AND bottom on /warranty at 700px tall, with the lede landing
     on bare page background below the image.

     Overlaying both children in one grid cell makes the row
     max(image, copy), so the copy can no longer overflow: it is now one
     of the things deciding how tall the hero is. */
  .hero {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
  }
  .hero__media,
  .hero__body { grid-area: 1 / 1; }

  .hero__media {
    /* Ideal height as a FLOOR, never a cap. A max-height here would stop
       the picture stretching when the copy makes the row taller and leave
       a strip of bare background beneath it — the same bug in a hat. */
    aspect-ratio: auto;
    min-height: var(--hero-media-h);
    max-height: none;
  }
  /* 🔴 THE IMAGE MUST NOT DECIDE HOW TALL THE HERO IS.
     With aspect-ratio removed above, a `height: 100%` image inside an
     auto-height box falls back to its own intrinsic ratio. /technology
     borrows a 4:3 photograph, so at 1280px wide it demanded 960px of
     height in a 690px viewport — and because that hero is sticky, the
     bottom of it could never be reached. Taking the image out of flow
     leaves the row as max(ideal height, copy), which is the whole point,
     and object-fit does the cropping it was always meant to do. */
  .hero__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  .hero__media::after {
    /* Keeps the left safe zone legible over a bright image without
       darkening the whole frame. */
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(
      100deg,
      rgba(251, 250, 247, .97) 0%,
      rgba(251, 250, 247, .90) 26%,
      rgba(251, 250, 247, .30) 52%,
      rgba(251, 250, 247, 0) 72%
    );
  }
  /* Positioning only. This used to ALSO carry max-width, margin-inline
     and padding-inline — the whole container recipe — while the markup
     inside it already has a .container of its own. Two containers meant
     two gutters, so hero copy started 48px right of every other block on
     the page and the left edge visibly stepped inward at the hero. The
     nested .container is the one that sets the width; this only puts the
     copy over the image. */
  .hero__body {
    position: relative;        /* in flow — its height now counts */
    display: flex;
    flex-direction: column;
    justify-content: center;
    /* Breathing room for the case this fix exists for: when the copy is
       what makes the hero tall, it must not touch the edges. */
    padding-block: var(--space-7);
  }
  .hero__inner { max-width: 34rem; }
}

/* Product-range hero — half viewport, depth marker top-right.
   MOBILE ONLY. This selector is more specific than the `.hero__media`
   rule in the >=992px block, so left unscoped its max-height beat the
   grid sizing there and re-capped the image — the copy then overflowed
   by up to 123px on /warranty instead of the row growing to fit it.
   Desktop height comes from --hero-media-h. */
@media (max-width: 991.98px) {
  .hero--range .hero__media { aspect-ratio: 16 / 11; max-height: 56vh; }
}
/* Desktop sizing comes from --hero-media-h; a max-height here would
   re-cap the image and undo the grid fix above. */

.depth-marker {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--gm-hairline);
  border-radius: var(--radius);
  background: var(--gm-card);
  font-family: var(--ff-data);
  font-size: var(--fs-data-s);
  font-variant-numeric: tabular-nums;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--gm-gold-text);
  white-space: nowrap;
}
@media (min-width: 992px) {
  .hero--range .depth-marker { position: absolute; top: var(--space-6); right: var(--container-pad); }
}

/* ------------------------------------------------------------------
   8. THE SIX MARKS — a direct reproduction of the black panel on the
   packaging. --gm-gold is legal as text here (8.1:1 on obsidian).
   ------------------------------------------------------------------ */

.marks { display: grid; grid-template-columns: repeat(2, 1fr); }
@media (min-width: 480px) { .marks { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 992px) { .marks { grid-template-columns: repeat(6, 1fr); } }

.mark {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  text-align: center;
  padding: var(--space-6) var(--space-3);
  border-right: 1px solid rgba(201, 162, 39, .22);
  border-bottom: 1px solid rgba(201, 162, 39, .22);
}
.mark:nth-child(2n) { border-right: 0; }
@media (min-width: 480px) {
  .mark { border-right: 1px solid rgba(201, 162, 39, .22); }
  .mark:nth-child(2n) { border-right: 1px solid rgba(201, 162, 39, .22); }
  .mark:nth-child(3n) { border-right: 0; }
  .mark:nth-last-child(-n+3) { border-bottom: 0; }
}
@media (min-width: 992px) {
  .mark:nth-child(3n) { border-right: 1px solid rgba(201, 162, 39, .22); }
  .mark:last-child { border-right: 0; }
  .mark { border-bottom: 0; }
}
.mark__icon { color: var(--gm-gold); }
.mark__label {
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-gold);
  line-height: 1.4;
}

/* ------------------------------------------------------------------
   9. CARDS
   ------------------------------------------------------------------ */

.card {
  background: var(--gm-card);
  border: 1px solid var(--gm-edge);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: var(--space-6);
  transition: transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.card--link:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
  border-color: var(--gm-hairline);
}
.card__icon { color: var(--gm-gold); margin-bottom: var(--space-4); }
.card__title { margin-bottom: var(--space-2); }
.card__body { font-size: var(--fs-body); color: var(--gm-graphite); }

/* Cards on obsidian invert. */
.section--obsidian .card {
  background: var(--gm-obsidian-2);
  border-color: var(--gm-edge-dark);
  box-shadow: none;
}
.section--obsidian .card__title { color: var(--gm-paper); }
.section--obsidian .card__body { color: rgba(251, 250, 247, .7); }

/* Numbered step list. */
.steps { counter-reset: step; display: grid; gap: var(--space-5); }
@media (min-width: 768px) { .steps { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1200px) { .steps--4 { grid-template-columns: repeat(4, 1fr); } }
.step { counter-increment: step; padding-top: var(--space-5); border-top: 1px solid var(--gm-hairline); }
.step::before {
  content: counter(step, decimal-leading-zero);
  display: block;
  font-family: var(--ff-data);
  font-size: var(--fs-data-s);
  font-variant-numeric: tabular-nums;
  color: var(--gm-gold-text);
  margin-bottom: var(--space-3);
}
.step__title { margin-bottom: var(--space-2); }

/* ------------------------------------------------------------------
   10. THE DEPTH INDEX
   The signature. A rail calibrated in metres rides above full-width
   bands, each film pinned at its depth, illuminating as you scroll past.

   Layout note: the bands are full-width SIBLINGS and the rail lives in
   its own absolutely-positioned column above them. Nesting the bands
   inside a grid alongside the rail and bleeding each background with
   `left:50%; margin-left:-50vw` centres the bleed on the content column
   rather than the viewport — offset by the rail, that runs ~150px past
   the right edge at every desktop width.
   ------------------------------------------------------------------ */

.depth { position: relative; }

/* ── The rail, mobile first ────────────────────────────────────────────
   Under 992px there is no room for a 240px column beside the cards, so
   the same nav becomes a sticky horizontal strip under the header. It
   was previously display:none, which left phone visitors with no index
   of the range at all and nothing to navigate it by. */
.depth__rail-layer {
  position: sticky;
  top: var(--header-h);
  z-index: 3;
}
.depth__rail-layer .container { padding-inline: 0; }

.depth-rail {
  background: var(--gm-paper);
  border-block: 1px solid var(--gm-edge);
}
.depth-rail__title {
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-gold-text);
}

@media (max-width: 991.98px) {
  .depth-rail__title {
    padding: var(--space-3) var(--container-pad) 0;
    margin-bottom: var(--space-2);
  }
  /* Horizontal chip strip. overflow-x lives here so the page body never
     scrolls sideways — the strip scrolls inside itself. */
  .depth-rail__track {
    display: flex;
    gap: var(--space-2);
    overflow-x: auto;
    scroll-snap-type: x proximity;
    padding: 0 var(--container-pad) var(--space-3);
    scrollbar-width: none;
  }
  .depth-rail__track::-webkit-scrollbar { display: none; }
  .depth-tick {
    flex: none;
    scroll-snap-align: center;
    padding: var(--space-2) var(--space-4);
    border: 1px solid var(--gm-edge);
    border-radius: var(--radius);
    background: var(--gm-card);
  }
  .depth-tick__name  { font-size: .8125rem; }
  .depth-tick__depth { font-size: .6875rem; }
  .depth-tick[aria-current] {
    border-color: var(--gm-gold);
    background: var(--gm-gold-wash);
  }
}

/* ── Desktop: the original sticky card ───────────────────────────────── */
@media (min-width: 992px) {
  .depth__rail-layer {
    position: absolute;
    inset: 0 0 0 0;
    pointer-events: none;
    z-index: 2;
    top: 0;
  }
  .depth__rail-layer .container {
    height: 100%;
    padding-inline: var(--container-pad);
  }
  .depth-rail {
    position: sticky;
    /* --header-h, not a hard-coded 88px: the header's height is defined
       once and this has to follow it. */
    top: calc(var(--header-h) + var(--space-6));
    width: 240px;
    pointer-events: auto;
    border: 1px solid var(--gm-edge);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    padding: var(--space-5);

    /* 🔴 A STICKY ELEMENT CANNOT BE SCROLLED PAST — so it must never be
       taller than the space it is pinned in. Nine films made this rail
       722px tall; on a laptop with 690px of page height the last two,
       Sperm Whale and Seadevil, were cut off the bottom and there was no
       way to reach them. Scrolling the page just moved the rail with it.

       This is a VIEWPORT HEIGHT failure, which is why width-based
       testing never caught it. `dvh` rather than `vh` so a mobile
       browser's collapsing toolbar is accounted for; the vh fallback is
       for anything that does not know dvh. */
    max-height: calc(100vh  - var(--header-h) - var(--space-6) * 2);
    max-height: calc(100dvh - var(--header-h) - var(--space-6) * 2);
    overflow-y: auto;
    /* Reaching the end of the rail must not start scrolling the page
       underneath it. */
    overscroll-behavior: contain;
    scrollbar-width: thin;
  }
  .depth-rail__title { margin-bottom: var(--space-5); }
}
.depth-rail__title {
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-gold-text);
  margin-bottom: var(--space-5);
}
@media (min-width: 992px) {
  .depth-rail__track { position: relative; padding-left: var(--space-5); }
  .depth-rail__track::before {
    content: "";
    position: absolute;
    left: 0; top: 4px; bottom: 4px;
    width: 1px;
    background: linear-gradient(
      to bottom,
      var(--gm-hairline) 0%,
      var(--gm-gold) 40%,
      var(--gm-obsidian) 100%
    );
  }
  .depth-tick { padding-block: var(--space-3); }
  .depth-tick::before {
    content: "";
    position: absolute;
    left: calc(var(--space-5) * -1);
    top: 50%;
    width: 9px; height: 1px;
    background: var(--gm-edge);
    transform: translate(-4px, -50%);
    transition: background-color var(--dur-base) var(--ease-out),
                width var(--dur-base) var(--ease-out);
  }
  /* The active mark. `aria-current` drives it rather than a class, so the
     thing a screen reader announces and the thing the eye follows can
     never disagree. */
  .depth-tick[aria-current]::before { background: var(--gm-gold); width: 15px; }
}

.depth-tick {
  position: relative;
  display: block;
  font-family: var(--ff-data);
  font-size: var(--fs-data-s);
  font-variant-numeric: tabular-nums;
  color: var(--gm-slate);
  text-decoration: none;
  transition: color var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out),
              background-color var(--dur-base) var(--ease-out);
}
.depth-tick:hover { color: var(--gm-ink); }
.depth-tick:focus-visible {
  outline: 2px solid var(--gm-gold);
  outline-offset: 3px;
  border-radius: var(--radius);
}
.depth-tick[aria-current] { color: var(--gm-ink); }
.depth-tick[aria-current] .depth-tick__name { color: var(--gm-gold-text); }
.depth-tick__name { display: block; font-family: var(--ff-display); font-size: .9375rem; font-weight: 600; }
.depth-tick__depth { display: block; font-size: .75rem; }

/* Clicking a tick must not land the card under the sticky header (or,
   on mobile, under the header AND the strip). Anchor scrolling honours
   this without any JavaScript. */
/* On mobile the sticky strip sits below the sticky header, so an anchor
   target has to clear BOTH. --depth-strip-h is measured and set by
   main.js because the strip's height depends on its own type and
   wrapping; the fallback here is the measured height at 390px, so the
   offset is close enough to be usable with JavaScript off and exact
   with it on. */
.depth-band,
.product-card {
  scroll-margin-top: calc(var(--header-h) + var(--depth-strip-h, 133px) + var(--space-4));
}
@media (min-width: 992px) {
  .depth-band,
  .product-card { scroll-margin-top: calc(var(--header-h) + var(--space-6)); }
}

/* Bands. Full width, so the surface reaches the viewport edge and the
   page genuinely darkens as the range descends. */
.depth-band { padding-block: clamp(28px, 4vw, 56px); }
.depth-band--paper     { background: var(--gm-paper); }
.depth-band--champagne { background: var(--gm-champagne); }
.depth-band--obsidian  { background: var(--gm-obsidian); }

/* Clear the rail column on desktop. */
@media (min-width: 992px) {
  .depth-band__inner { margin-left: calc(240px + clamp(32px, 5vw, 72px)); }
}

/* --- Product card --- */

.product-card {
  display: grid;
  gap: var(--space-5);
  padding: var(--space-6);
  background: var(--gm-card);
  border: 1px solid var(--gm-edge);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
@media (min-width: 768px) {
  .product-card { grid-template-columns: 1fr 1.35fr; align-items: center; gap: var(--space-6); }
}
.product-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
  border-color: var(--gm-hairline);
}

.product-card__media {
  aspect-ratio: 1 / 1;
  width: 100%;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--gm-mist);
}
.product-card__img { width: 100%; height: 100%; object-fit: cover; }

.product-card__eyebrow {
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-gold-text);
  margin-bottom: var(--space-3);
}
.product-card__name {
  font-family: var(--ff-display);
  font-size: 2rem;
  line-height: 1.05;
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
  color: var(--gm-ink);
  margin-bottom: var(--space-3);
}
.product-card__character {
  color: var(--gm-graphite);
  max-width: 42ch;
  margin-bottom: var(--space-5);
}
.product-card__specs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5);
  padding-block: var(--space-4);
  border-top: 1px solid var(--gm-edge-soft);
  border-bottom: 1px solid var(--gm-edge-soft);
  margin-bottom: var(--space-5);
}
.product-card__spec { display: flex; flex-direction: column; gap: 2px; }
.product-card__spec-label {
  font-size: .6875rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--gm-slate);
}
.product-card__spec-value {
  font-family: var(--ff-data);
  font-size: var(--fs-data-s);
  font-variant-numeric: tabular-nums;
  color: var(--gm-ink);
}

/* Apex tier — Orca. Gold-ruled, per PRD 01 §3. */
.product-card--apex { border-color: var(--gm-gold); box-shadow: 0 0 0 1px var(--gm-gold-wash), var(--shadow-sm); }

/* Cards on the obsidian sections invert. */
.section--obsidian .product-card {
  background: var(--gm-obsidian-2);
  border-color: var(--gm-edge-dark);
  box-shadow: none;
}
.section--obsidian .product-card__name { color: var(--gm-paper); }
.section--obsidian .product-card__character { color: rgba(251, 250, 247, .72); }
.section--obsidian .product-card__eyebrow { color: var(--gm-gold); }
.section--obsidian .product-card__specs { border-color: var(--gm-edge-dark); }
.section--obsidian .product-card__spec-value { color: var(--gm-paper); }
.section--obsidian .product-card__spec-label { color: rgba(251, 250, 247, .5); }
.section--obsidian .product-card__media { background: var(--gm-obsidian); }

/* ------------------------------------------------------------------
   11. SPECIFICATION TABLES
   Below 992px these stack into cards rather than side-scrolling — the
   table needs ~700px and the container only reaches that at 992px.
   ------------------------------------------------------------------ */

.spec-table__wrap { overflow-x: auto; }

.spec-table { width: 100%; border-collapse: collapse; }
.spec-table caption {
  text-align: left;
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-gold-text);
  padding-bottom: var(--space-4);
}
.spec-table th, .spec-table td {
  text-align: left;
  padding: var(--space-4);
  border-bottom: 1px solid var(--gm-edge-soft);
  vertical-align: top;
}
.spec-table thead th {
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-ink);
  border-bottom: 1px solid var(--gm-gold);
  white-space: nowrap;
}
.spec-table tbody tr:nth-child(odd) { background: var(--gm-mist); }
.spec-table__item { color: var(--gm-ink); font-weight: 500; }
.spec-table__value {
  font-family: var(--ff-data);
  font-size: var(--fs-data);
  font-variant-numeric: tabular-nums;
  color: var(--gm-ink);
  white-space: nowrap;
}
.spec-table__method { font-family: var(--ff-data); font-size: var(--fs-data-s); color: var(--gm-slate); white-space: nowrap; }

.spec-tbc {
  display: inline-block;
  margin-left: var(--space-2);
  padding: 1px 6px;
  border: 1px solid var(--gm-hairline);
  border-radius: var(--radius);
  font-family: var(--ff-label);
  font-size: .625rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--gm-gold-text);
  vertical-align: 2px;
}

/* Stacked-card form below 992px. */
@media (max-width: 991px) {
  .spec-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .spec-table, .spec-table tbody, .spec-table tr, .spec-table td { display: block; width: 100%; }
  .spec-table tr {
    border: 1px solid var(--gm-edge);
    border-radius: var(--radius);
    margin-bottom: var(--space-3);
    padding: var(--space-4);
    background: var(--gm-card);
  }
  .spec-table tbody tr:nth-child(odd) { background: var(--gm-card); }
  .spec-table td { border: 0; padding: 0; }
  .spec-table td + td { margin-top: var(--space-2); }
  .spec-table__item { font-size: var(--fs-caption); color: var(--gm-slate); font-weight: 400; }
  .spec-table__value { font-size: 1.0625rem; white-space: normal; }
  .spec-table__method::before {
    content: "Method · ";
    font-family: var(--ff-body);
    color: var(--gm-slate);
  }
}

/* ------------------------------------------------------------------
   12. STAT COUNTERS
   Numbers render at 56px so --gm-gold is legal as text (>= 24px).
   ------------------------------------------------------------------ */

.stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-6); }
@media (min-width: 992px) { .stats { grid-template-columns: repeat(4, 1fr); } }

.stat { padding-top: var(--space-5); border-top: 1px solid var(--gm-hairline); }
.stat__value {
  font-family: var(--ff-display);
  font-size: clamp(2.25rem, 5vw, 3.5rem);
  line-height: 1;
  font-weight: 700;
  letter-spacing: -.03em;
  /* --gm-gold measures 2.32:1 here and AA large text needs 3:1. */
  color: var(--gm-gold-deep);
  font-variant-numeric: tabular-nums;
  margin-bottom: var(--space-3);
}
.stat__label { font-size: var(--fs-body); color: var(--gm-graphite); margin-bottom: 2px; }
.stat__method { font-family: var(--ff-data); font-size: var(--fs-caption); color: var(--gm-slate); }

/* ------------------------------------------------------------------
   13. FORMS
   ------------------------------------------------------------------ */

.field { display: block; margin-bottom: var(--space-5); }
.field__label {
  display: block;
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-ink);
  margin-bottom: var(--space-2);
}
.field__optional { color: var(--gm-slate); font-weight: 400; letter-spacing: .04em; text-transform: none; }

.input, .select, .textarea {
  display: block;
  width: 100%;
  min-height: 48px;
  padding: 13px var(--space-4);
  background: var(--gm-card);
  border: 1px solid var(--gm-edge);
  border-radius: var(--radius);
  color: var(--gm-ink);
  font-family: var(--ff-body);
  font-size: var(--fs-body);
  transition: border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.input::placeholder, .textarea::placeholder { color: var(--gm-slate); }
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--gm-gold);
  box-shadow: 0 0 0 3px var(--gm-gold-wash);
  outline: none;                       /* replaced by the ring above */
}
.input:focus-visible, .select:focus-visible, .textarea:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 1px;
}
.textarea { min-height: 140px; resize: vertical; padding-block: var(--space-4); }

.select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23464E5C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 9 7 7 7-7'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-4) center;
  background-size: 18px;
  padding-right: var(--space-8);
}

.field__help { display: block; margin-top: var(--space-2); font-size: var(--fs-caption); color: var(--gm-slate); }

/* Errors sit beside the field they belong to, never only at the top. */
.field--error .input,
.field--error .select,
.field--error .textarea { border-color: #A3231F; }
.field__error {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin-top: var(--space-2);
  font-size: var(--fs-caption);
  color: #8E1F1B;
}

.form-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-6); }

/* ------------------------------------------------------------------
   14. VERIFY WIDGET + STATUS CHIPS
   Chips carry colour AND text — colour is never the sole carrier of
   meaning (PRD 01 §8).
   ------------------------------------------------------------------ */

.verify-panel {
  background: var(--gm-card);
  border: 1px solid var(--gm-edge);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  padding: clamp(24px, 4vw, 40px);
}
.verify-panel__title { margin-bottom: var(--space-2); }
.verify-panel__lede { margin-bottom: var(--space-6); font-size: var(--fs-body); color: var(--gm-graphite); }

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 5px var(--space-3);
  border: 1px solid;
  border-radius: var(--radius);
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}
.chip::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.chip--active    { color: var(--gm-gold-text); border-color: var(--gm-gold); background: var(--gm-gold-wash); }
.chip--expired   { color: #4C535F; border-color: var(--gm-edge); background: var(--gm-mist); }
.chip--cancelled { color: #8E1F1B; border-color: rgba(142, 31, 27, .3); background: rgba(142, 31, 27, .06); }
.chip--claim     { color: #6E5111; border-color: var(--gm-hairline); background: var(--gm-champagne); }

.record { display: grid; gap: var(--space-4); margin-top: var(--space-6); }
@media (min-width: 576px) { .record { grid-template-columns: repeat(2, 1fr); } }
.record__cell { padding-top: var(--space-3); border-top: 1px solid var(--gm-edge-soft); }
.record__key {
  display: block;
  font-size: .6875rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--gm-slate);
  margin-bottom: 4px;
}
.record__val {
  font-family: var(--ff-data);
  font-size: var(--fs-data);
  font-variant-numeric: tabular-nums;
  color: var(--gm-ink);
}
.record__val--name { font-family: var(--ff-body); }

.notice {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-5);
  border: 1px solid var(--gm-edge);
  border-left: 2px solid var(--gm-gold);
  border-radius: var(--radius);
  background: var(--gm-champagne);
  font-size: var(--fs-body);
  color: var(--gm-graphite);
}
.notice__icon { color: var(--gm-gold-text); flex: none; }
.notice--quiet { border-left-color: var(--gm-edge); background: var(--gm-card); }

/* ------------------------------------------------------------------
   15. FILM CONSTRUCTION DIAGRAM
   ------------------------------------------------------------------ */

.layers { display: grid; gap: var(--space-6); align-items: center; }
@media (min-width: 992px) { .layers { grid-template-columns: 1fr 1fr; gap: clamp(40px, 6vw, 88px); } }

.layer-stack { display: grid; gap: 3px; }
.layer-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--gm-edge);
  border-radius: var(--radius);
  background: var(--gm-card);
  transition: border-color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}
.layer-bar:hover { border-color: var(--gm-gold); background: var(--gm-gold-wash); }
.layer-bar__name { font-family: var(--ff-display); font-weight: 600; font-size: 1rem; color: var(--gm-ink); }
.layer-bar__fn { display: block; font-size: var(--fs-caption); color: var(--gm-slate); margin-top: 2px; max-width: 34ch; }
.layer-bar__thickness {
  font-family: var(--ff-data);
  font-size: var(--fs-data-s);
  font-variant-numeric: tabular-nums;
  color: var(--gm-gold-text);
  white-space: nowrap;
  flex: none;
}
.layer-total {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--gm-gold);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-4);
}
.layer-total__label {
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-ink);
}
.layer-total__value {
  font-family: var(--ff-data);
  font-size: 1.125rem;
  font-variant-numeric: tabular-nums;
  color: var(--gm-gold-text);
}

/* ------------------------------------------------------------------
   16. TIER TABS (product range pages)
   Real anchors, enhanced with JS — they still work with JS off.
   ------------------------------------------------------------------ */

.tiers { border-bottom: 1px solid var(--gm-edge); margin-bottom: var(--space-7); }
.tiers__list { display: flex; gap: var(--space-2); overflow-x: auto; scrollbar-width: none; }
.tiers__list::-webkit-scrollbar { display: none; }
.tier-tab {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2);
  min-height: 48px;
  padding: var(--space-4) var(--space-5);
  border-bottom: 2px solid transparent;
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-slate);
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.tier-tab:hover { color: var(--gm-ink); }
.tier-tab.is-active { color: var(--gm-ink); border-bottom-color: var(--gm-gold); }
.tier-tab__years { font-family: var(--ff-data); font-size: .6875rem; color: var(--gm-gold-text); }

.tier-panel[hidden] { display: none; }

/* ------------------------------------------------------------------
   17. GALLERY
   ------------------------------------------------------------------ */

.filters { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-7); }
.filter-chip {
  min-height: 44px;
  padding: 10px var(--space-4);
  border: 1px solid var(--gm-edge);
  border-radius: var(--radius);
  font-family: var(--ff-label);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--gm-graphite);
  background: var(--gm-card);
  white-space: nowrap;
  transition: border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}
.filter-chip:hover { border-color: var(--gm-gold); }
.filter-chip[aria-pressed="true"] {
  background: var(--gm-ink);
  border-color: var(--gm-ink);
  color: var(--gm-paper);
}

.gallery { display: grid; gap: var(--space-3); grid-template-columns: repeat(2, 1fr); }
@media (min-width: 768px) { .gallery { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1200px) { .gallery { grid-template-columns: repeat(4, 1fr); } }
.gallery__item { position: relative; overflow: hidden; border-radius: var(--radius); background: var(--gm-mist); aspect-ratio: 4 / 3; }
.gallery__item img { width: 100%; height: 100%; object-fit: cover; transition: transform 400ms var(--ease-out); }
.gallery__item:hover img { transform: scale(1.03); }
.gallery__item[hidden] { display: none; }

/* ------------------------------------------------------------------
   18. UTILITIES
   ------------------------------------------------------------------ */

.flow > * + * { margin-top: var(--space-5); }
.mt-0 { margin-top: 0; }
.mt-4 { margin-top: var(--space-4); }
.mt-5 { margin-top: var(--space-5); }
.mt-6 { margin-top: var(--space-6); }
.mt-7 { margin-top: var(--space-7); }
.mb-4 { margin-bottom: var(--space-4); }
.mb-5 { margin-bottom: var(--space-5); }
.mb-6 { margin-bottom: var(--space-6); }
.text-center { text-align: center; }

.list-check > li,
.list-cross > li {
  display: flex;
  gap: var(--space-3);
  padding-block: var(--space-3);
  border-bottom: 1px solid var(--gm-edge-soft);
  color: var(--gm-graphite);
}
.list-check > li::before,
.list-cross > li::before {
  flex: none;
  width: 18px;
  font-family: var(--ff-data);
  font-size: var(--fs-data-s);
  line-height: 1.6;
}
.list-check > li::before { content: "+"; color: var(--gm-gold-text); }
.list-cross > li::before { content: "\2212"; color: var(--gm-slate); }

.badge-tbc {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 4px var(--space-3);
  border: 1px dashed var(--gm-hairline);
  border-radius: var(--radius);
  font-family: var(--ff-label);
  font-size: .625rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--gm-gold-text);
  background: var(--gm-gold-wash);
}

/* ------------------------------------------------------------------
   19. MOTION
   Initial hidden states are gated behind .js so the page is fully
   readable when JavaScript is disabled or fails to load. Nothing may be
   permanently invisible.
   ------------------------------------------------------------------ */

.js [data-reveal] { opacity: 0; }
.js [data-hero-line] { opacity: 0; }

/* Reduced motion short-circuits everything: main.js neither starts Lenis
   nor registers ScrollTrigger, and these rules restore the final state
   in case the stylesheet loads before the script decides. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js [data-reveal],
  .js [data-hero-line] { opacity: 1 !important; transform: none !important; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ------------------------------------------------------------------
   20. PRINT
   ------------------------------------------------------------------ */

@media print {
  .site-header, .mobile-nav, .site-footer, .skip-link, .btn { display: none !important; }
  body { background: #fff; color: #000; }
  .section { padding-block: 12pt; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; }
}

/* ------------------------------------------------------------------
   21. HOME — DEPTH TEASER
   A condensed reading of the Depth Index. The row surface follows the
   finish, so the list genuinely darkens as it descends.
   ------------------------------------------------------------------ */

.depth-teaser { border-top: 1px solid var(--gm-edge); }
.depth-teaser__row { border-bottom: 1px solid var(--gm-edge); }
.depth-teaser__row--paper     { background: var(--gm-paper); }
.depth-teaser__row--champagne { background: var(--gm-champagne); }
.depth-teaser__row--obsidian  { background: var(--gm-obsidian); border-bottom-color: var(--gm-edge-dark); }
.depth-teaser__row--apex      { box-shadow: inset 2px 0 0 var(--gm-gold); }

.depth-teaser__link {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    "depth name"
    "depth meta";
  align-items: center;
  gap: 2px var(--space-5);
  padding: var(--space-5) var(--space-4);
  transition: background-color var(--dur-fast) var(--ease-out);
}
@media (min-width: 768px) {
  .depth-teaser__link {
    grid-template-columns: 8rem 1fr auto auto;
    grid-template-areas: "depth name range years";
    gap: var(--space-5);
    padding-inline: var(--space-5);
  }
}
.depth-teaser__link:hover { background: var(--gm-gold-wash); }
.depth-teaser__row--obsidian .depth-teaser__link:hover { background: rgba(201, 162, 39, .12); }

.depth-teaser__depth {
  grid-area: depth;
  font-family: var(--ff-data);
  font-size: var(--fs-data-s);
  font-variant-numeric: tabular-nums;
  color: var(--gm-gold-text);
  white-space: nowrap;
}
.depth-teaser__name {
  grid-area: name;
  font-family: var(--ff-display);
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: var(--tracking-tight);
  color: var(--gm-ink);
}
.depth-teaser__range {
  grid-area: meta;
  font-size: var(--fs-caption);
  color: var(--gm-slate);
}
@media (min-width: 768px) { .depth-teaser__range { grid-area: range; text-align: right; } }
.depth-teaser__years {
  grid-area: meta;
  justify-self: end;
  font-family: var(--ff-data);
  font-size: var(--fs-data-s);
  font-variant-numeric: tabular-nums;
  color: var(--gm-graphite);
  white-space: nowrap;
}
@media (min-width: 768px) { .depth-teaser__years { grid-area: years; min-width: 5rem; text-align: right; } }

/* Obsidian rows invert. Gold is legal as text here. */
.depth-teaser__row--obsidian .depth-teaser__name  { color: var(--gm-paper); }
.depth-teaser__row--obsidian .depth-teaser__depth { color: var(--gm-gold); }
.depth-teaser__row--obsidian .depth-teaser__range { color: rgba(251, 250, 247, .55); }
.depth-teaser__row--obsidian .depth-teaser__years { color: rgba(251, 250, 247, .78); }

/* ------------------------------------------------------------------
   22. TRACE LIST + CTA BAND
   ------------------------------------------------------------------ */

.trace-list > li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
  padding-block: var(--space-4);
  border-top: 1px solid var(--gm-edge);
  color: var(--gm-graphite);
}
.trace-list > li > .icon { color: var(--gm-gold); flex: none; margin-top: 2px; }

.cta-band { text-align: center; }
.cta-band__inner { max-width: 44rem; margin-inline: auto; }
.cta-band__inner .lede { margin-inline: auto; }

/* ------------------------------------------------------------------
   23. VERIFY RESULT
   Rendered by JavaScript into an aria-live region. Status chips carry
   colour AND text — colour is never the sole carrier of meaning.
   ------------------------------------------------------------------ */

.verify-result:empty { display: none; }
.verify-result { margin-top: var(--space-6); }
.verify-result__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--gm-gold);
}
.verify-result__no {
  font-family: var(--ff-data);
  font-size: 1.0625rem;
  font-variant-numeric: tabular-nums;
  color: var(--gm-ink);
}
.verify-form .field:last-of-type { margin-bottom: var(--space-6); }
.btn[aria-busy="true"] { opacity: .65; pointer-events: none; }

/* ------------------------------------------------------------------
   24. (Depth bands moved to §10 with the rest of the Depth Index.)
   ------------------------------------------------------------------ */

/* ------------------------------------------------------------------
   25. TIER PANELS
   ------------------------------------------------------------------ */

.tier-panel__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-5);
  margin-bottom: var(--space-7);
}
.tier-panel__head > div { flex: 1 1 24rem; }

/* ------------------------------------------------------------------
   26. COVERAGE DIAGRAM
   The option buttons carry the meaning in text. The diagram is
   decorative and aria-hidden — coverage is never communicated by the
   highlight alone.
   ------------------------------------------------------------------ */

.coverage { display: grid; gap: var(--space-7); align-items: start; }
@media (min-width: 992px) {
  .coverage { grid-template-columns: 1fr 22rem; gap: clamp(40px, 5vw, 80px); }
}

.coverage__options { display: grid; gap: var(--space-3); }
.coverage__btn {
  display: block;
  width: 100%;
  text-align: left;
  padding: var(--space-5);
  background: var(--gm-card);
  border: 1px solid var(--gm-edge);
  border-left: 2px solid var(--gm-edge);
  border-radius: var(--radius);
  transition: border-color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}
.coverage__btn:hover { border-color: var(--gm-hairline); }
.coverage__btn[aria-pressed="true"] {
  border-left-color: var(--gm-gold);
  background: var(--gm-gold-wash);
}
.coverage__label {
  display: block;
  font-family: var(--ff-display);
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--gm-ink);
  margin-bottom: 4px;
}
.coverage__blurb { display: block; font-size: var(--fs-caption); color: var(--gm-graphite); }

.coverage__figure { margin: 0; display: grid; gap: var(--space-4); justify-items: center; }
.coverage-svg { width: 100%; max-width: 15rem; height: auto; }

.coverage-svg__shell path {
  fill: var(--gm-card);
  stroke: var(--gm-edge);
  stroke-width: 1.5;
}
.coverage-svg__glass * { fill: var(--gm-mist); }

/* Panels default to unfilled and light up when their group is selected.
   Transitioning `fill` rather than opacity keeps the shell edges crisp. */
.coverage-svg__panel * {
  fill: transparent;
  transition: fill var(--dur-base) var(--ease-out);
}
.coverage-svg__panel.is-on * { fill: var(--gm-gold); }
.coverage-svg__panel.is-on-soft * { fill: var(--gm-gold-lite); }

/* ------------------------------------------------------------------
   27. LEGAL / PROSE PAGES
   ------------------------------------------------------------------ */

.legal { max-width: 44rem; }
.legal h2 { margin-top: var(--space-8); margin-bottom: var(--space-4); }
.legal h3 { margin-top: var(--space-6); margin-bottom: var(--space-3); }
.legal p, .legal li { color: var(--gm-graphite); }
.legal p + p { margin-top: var(--space-4); }
.legal ul { margin-top: var(--space-4); }
.legal ul > li {
  position: relative;
  padding-left: var(--space-5);
  padding-block: var(--space-2);
}
.legal ul > li::before {
  content: "";
  position: absolute;
  left: 0; top: 15px;
  width: 8px; height: 1px;
  background: var(--gm-gold);
}
.legal__updated {
  font-family: var(--ff-data);
  font-size: var(--fs-caption);
  color: var(--gm-slate);
  padding-bottom: var(--space-5);
  border-bottom: 1px solid var(--gm-edge);
  margin-bottom: var(--space-6);
}

/* ------------------------------------------------------------------
   28. PAGE HEADER (non-hero pages)
   ------------------------------------------------------------------ */

.page-head { padding-block: clamp(48px, 7vw, 104px) clamp(32px, 4vw, 56px); }
.page-head__inner { max-width: 48rem; }

/* ------------------------------------------------------------------
   29. TWO-COLUMN COVERED / NOT COVERED
   ------------------------------------------------------------------ */

.cover-cols { display: grid; gap: var(--space-6); }
@media (min-width: 992px) { .cover-cols { grid-template-columns: repeat(3, 1fr); gap: var(--space-7); } }
.cover-col__title {
  padding-bottom: var(--space-4);
  margin-bottom: var(--space-4);
  border-bottom: 1px solid var(--gm-gold);
}

/* ------------------------------------------------------------------
   30. TECHNOLOGY LIST
   ------------------------------------------------------------------ */

.tech-list { display: grid; gap: 0; border-top: 1px solid var(--gm-edge); }
.tech-item {
  display: grid;
  gap: var(--space-3) var(--space-6);
  grid-template-columns: 1fr;
  padding-block: var(--space-6);
  border-bottom: 1px solid var(--gm-edge);
}
@media (min-width: 768px) { .tech-item { grid-template-columns: 5rem 1fr; } }
.tech-item__index {
  font-family: var(--ff-data);
  font-size: var(--fs-data-s);
  font-variant-numeric: tabular-nums;
  color: var(--gm-gold-text);
}
.tech-item__body { max-width: var(--measure); }
.tech-item__icon {
  display: inline-flex;
  vertical-align: -4px;
  margin-right: var(--space-3);
  color: var(--gm-gold);
}

/* ------------------------------------------------------------------
   31. DOWNLOADS
   ------------------------------------------------------------------ */

.downloads { display: grid; gap: var(--space-3); }
@media (min-width: 768px) { .downloads { grid-template-columns: repeat(2, 1fr); } }

.download {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5);
  background: var(--gm-card);
  border: 1px solid var(--gm-edge);
  border-radius: var(--radius);
  transition: border-color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
a.download:hover {
  border-color: var(--gm-gold);
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
}
.download__icon { color: var(--gm-gold); flex: none; }
.download__text { flex: 1; min-width: 0; }
.download__label { display: block; font-weight: 600; color: var(--gm-ink); }
.download__sub { display: block; font-size: var(--fs-caption); color: var(--gm-slate); margin-top: 2px; }
.download__arrow { color: var(--gm-gold-text); flex: none; }
.download--pending { opacity: .68; }

/* ------------------------------------------------------------------
   32. TECHNICAL REFERENCE PANEL
   A quiet bordered card. Deliberately NOT a badge: no seal, no
   checkmark, no laboratory logo, no "certified". PRD 01 §7.1.
   ------------------------------------------------------------------ */

.tech-ref {
  max-width: 52rem;
  padding: clamp(24px, 4vw, 40px);
  background: var(--gm-card);
  border: 1px solid var(--gm-edge);
  border-left: 2px solid var(--gm-gold);
  border-radius: var(--radius);
}
.tech-ref__title { margin-bottom: var(--space-4); }
.tech-ref__intro { color: var(--gm-graphite); margin-bottom: var(--space-5); }
.tech-ref__list { display: grid; gap: 0; }
.tech-ref__list > li {
  padding-block: var(--space-3);
  border-top: 1px solid var(--gm-edge-soft);
  font-family: var(--ff-data);
  font-size: var(--fs-data-s);
  line-height: 1.6;
  color: var(--gm-graphite);
}

/* ------------------------------------------------------------------
   33. CLAIM STEPS
   ------------------------------------------------------------------ */

.claim-steps { counter-reset: claim; }
.claim-steps > li {
  counter-increment: claim;
  display: flex;
  gap: var(--space-4);
  padding-block: var(--space-3);
  border-bottom: 1px solid var(--gm-edge-soft);
  color: var(--gm-graphite);
}
.claim-steps > li::before {
  content: counter(claim);
  flex: none;
  width: 24px; height: 24px;
  display: grid;
  place-items: center;
  border: 1px solid var(--gm-hairline);
  border-radius: var(--radius);
  font-family: var(--ff-data);
  font-size: .75rem;
  color: var(--gm-gold-text);
  margin-top: 2px;
}

/* ------------------------------------------------------------------
   34. ABOUT
   ------------------------------------------------------------------ */

.about-grid { display: grid; gap: var(--space-7); }
@media (min-width: 992px) { .about-grid { grid-template-columns: repeat(2, 1fr); gap: var(--space-8) clamp(40px, 6vw, 88px); } }
.about-item { max-width: 34rem; }
.about-item p { color: var(--gm-graphite); }

.about-figures { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-5); }
.about-figures > li { padding-top: var(--space-4); border-top: 1px solid var(--gm-hairline); }
.about-figures__n {
  display: block;
  font-family: var(--ff-display);
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.03em;
  color: var(--gm-gold-deep);
  font-variant-numeric: tabular-nums;
}
.about-figures__l { display: block; margin-top: var(--space-2); font-size: var(--fs-caption); color: var(--gm-graphite); }

/* ------------------------------------------------------------------
   35. FORMS — layout
   ------------------------------------------------------------------ */

.field-row { display: grid; gap: 0 var(--space-4); }
@media (min-width: 576px) { .field-row { grid-template-columns: repeat(2, 1fr); } }

.form-status:empty { display: none; }
.form-status {
  margin-top: var(--space-5);
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--gm-edge);
  border-left: 2px solid var(--gm-gold);
  border-radius: var(--radius);
  background: var(--gm-champagne);
  font-size: var(--fs-body);
}
.form-status--error { border-left-color: #A3231F; background: rgba(163, 35, 31, .05); color: #8E1F1B; }

.contact-details { display: grid; gap: var(--space-4); }
.contact-details__row { display: flex; gap: var(--space-4); align-items: flex-start; color: var(--gm-graphite); }
.contact-details__icon { color: var(--gm-gold); flex: none; margin-top: 2px; }
.contact-details a:hover { color: var(--gm-gold-text); }

/* ------------------------------------------------------------------
   36. VERIFY PAGE
   ------------------------------------------------------------------ */

.verify-page__inner { max-width: 40rem; margin-inline: auto; }
.verify-page__help {
  margin-top: var(--space-7);
  padding-top: var(--space-6);
  border-top: 1px solid var(--gm-edge);
  text-align: center;
}
.verify-page__help p { color: var(--gm-graphite); }
.verify-samples[hidden] { display: none; }

/* ------------------------------------------------------------------
   37. EMPTY STATE
   ------------------------------------------------------------------ */

.empty-state {
  max-width: 34rem;
  margin-inline: auto;
  text-align: center;
  padding: clamp(40px, 6vw, 80px) var(--space-5);
  border: 1px dashed var(--gm-hairline);
  border-radius: var(--radius);
  background: var(--gm-card);
}
.empty-state__icon { display: inline-flex; color: var(--gm-gold); margin-bottom: var(--space-5); }
.empty-state .lede { margin-inline: auto; }

/* ------------------------------------------------------------------
   38. HERO SLIDER
   Four slides, each with its own copy.

   Stacking is gated behind `.js`. Without JavaScript the slides render
   as four normal sections rather than three of them being hidden by a
   rule whose controls never arrived.
   ------------------------------------------------------------------ */

.hero-slider { position: relative; background: var(--gm-paper); }
.hero-slider__viewport { position: relative; }

/* No JS: slides stack and read as ordinary sections. */
.hero-slide { position: relative; }
.hero-slide + .hero-slide { border-top: 1px solid var(--gm-edge); }

/* With JS: one slide occupies the box, the rest are stacked under it.
   grid-template-columns is minmax(0, 1fr), not the implicit `auto`.

   At 992px the media has aspect-ratio 2400/1000 AND min-height 460px,
   so its content demands 460 x 2.4 = 1104px of width. An auto-sized
   grid track honours that max-content request and the page overflows by
   112px. minmax(0, 1fr) caps the track at the container width and lets
   the image crop instead, which is what object-fit: cover is for. */
.js .hero-slider__viewport {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}
.js .hero-slide {
  grid-area: 1 / 1;
  border-top: 0;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 700ms var(--ease-out), visibility 0s linear 700ms;
}
.js .hero-slide.is-active {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity 700ms var(--ease-out), visibility 0s;
}

/* GSAP owns the crossfade once main.js confirms it loaded — see the
   hero slider block in main.js. Only the OPACITY transition is dropped;
   the visibility one has to stay or the outgoing slide is pulled out of
   the accessibility tree the instant the class flips and the fade has
   nothing left to fade. The CSS above remains the fallback for a visitor
   whose GSAP request failed. */
.hero-slider--anim .hero-slide            { transition: visibility 0s linear 700ms; }
.hero-slider--anim .hero-slide.is-active  { transition: visibility 0s; }

.hero-slide__media {
  position: relative;
  width: 100%;                       /* pinned: aspect-ratio + max-height
                                        with no width solves for width and
                                        overflows the viewport */
  aspect-ratio: 16 / 11;
  max-height: 62vh;
  overflow: hidden;
  background: var(--gm-mist);
}
.hero-slide__img { width: 100%; height: 100%; object-fit: cover; }

.hero-slide__body { padding-block: clamp(36px, 5vw, 64px) clamp(0px, 6vw, 76px); }
.hero-slide__title { margin-bottom: var(--space-5); }
.hero-slide__lede  { max-width: 40rem; margin-bottom: var(--space-6); }
.hero-slide__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }

@media (min-width: 992px) {
  /* Same one-cell grid as .hero, for the same reason: .hero-slide__body
     is absolutely positioned and contributes no height, so the tallest
     slide's buttons ran into the control strip pinned at the bottom.
     Reserving space in the body alone only narrowed it from 37px to 29px
     — the copy has to be able to make the SLIDE taller, not just sit
     higher inside a fixed one. */
  .hero-slide {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
  }
  .hero-slide__media,
  .hero-slide__body { grid-area: 1 / 1; }

  .hero-slide__media {
    /* Ideal height as a floor, not a cap — see .hero__media. */
    aspect-ratio: auto;
    min-height: clamp(460px, calc(100vw * 1000 / 2400), 760px);
    max-height: none;
  }
  /* Out of flow, for the same reason as .hero__img above. */
  .hero-slide__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  /* The scrim that keeps the left third legible. Every hero image is
     commissioned with this in mind — see docs/IMAGE-PROMPTS.md. */
  .hero-slide__media::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(
      100deg,
      rgba(251, 250, 247, .97) 0%,
      rgba(251, 250, 247, .93) 28%,
      rgba(251, 250, 247, .45) 52%,
      rgba(251, 250, 247, .04) 74%,
      rgba(251, 250, 247, 0) 100%
    );
  }
  /* Positioning only — the same double-gutter bug .hero__body had.
     The markup inside already has a .container, so carrying max-width
     and padding-inline here too gave the slider copy two gutters and
     started the home page's first headline 48px right of everything
     below it. */
  .hero-slide__body {
    position: relative;      /* in flow — its height now counts */
    display: flex;
    flex-direction: column;
    justify-content: center;
    /* RESERVE THE CONTROL STRIP. The prev/next/dots/pause row is pinned
       to the bottom of the slider, while this copy is centred and grows
       downward — so the tallest slide ("Sell a film you can stand
       behind", three heading lines plus two buttons) ran its buttons 37px
       INTO the controls at 1280x700. Padding the bottom biases the
       centring upward by exactly the strip's height, so the two can no
       longer meet however tall the copy gets.
       44px control + its --space-6 offset + a --space-4 gap. */
    /* 44px control + its 32px bottom offset = a 76px strip, plus a
       32px gap so the buttons do not merely miss the controls but sit
       clear of them. Measured: at 1200x600 a 92px reservation still left
       8px of overlap on the tallest slide. */
    padding-block: 0 calc(44px + var(--space-6) + var(--space-6));
  }
  .hero-slide__inner { max-width: 34rem; }
}

/* --- Controls --------------------------------------------------------
   Revealed by main.js. Hidden by default so they never appear without
   anything to drive. */
.hero-slider__controls[hidden] { display: none; }
.hero-slider__controls { padding-block: var(--space-4); border-bottom: 1px solid var(--gm-edge); }
@media (min-width: 992px) {
  .hero-slider__controls {
    position: absolute;
    left: 0; right: 0;
    bottom: var(--space-6);
    z-index: 3;
    padding-block: 0;
    border-bottom: 0;
  }
}

.hero-slider__controls-inner {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  /* Wrap rather than overflow. At 320px the row wanted 384px against
     280px of available width and pushed the pause button 84px off the
     right edge of the page. The narrow-screen sizing below normally
     keeps it on one line; this is the safety net for a width nobody
     tested — 320px was not in /_audit.html's list, which is how it got
     this far. */
  flex-wrap: wrap;
  justify-content: start;
  row-gap: var(--space-2);
}
@media (min-width: 992px) {
  .hero-slider__controls-inner { max-width: 34rem; flex-wrap: nowrap; justify-content: flex-start; }
}


.hero-slider__arrow,
.hero-slider__pause {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  flex: none;
  border: 1px solid var(--gm-edge);
  border-radius: var(--radius);
  background: var(--gm-card);
  color: var(--gm-ink);
  transition: border-color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}
.hero-slider__arrow:hover,
.hero-slider__pause:hover { border-color: var(--gm-gold); background: var(--gm-gold-wash); }

.hero-slider__pause-icon {
  width: 10px; height: 12px;
  border-left: 3px solid currentColor;
  border-right: 3px solid currentColor;
}
/* Paused: the control offers "play", so it shows a triangle. */
.hero-slider__pause[aria-pressed="true"] .hero-slider__pause-icon {
  width: 0; height: 0;
  border: 6px solid transparent;
  border-left: 10px solid currentColor;
  border-right: 0;
}
.hero-slider__dots { display: flex; align-items: center; gap: var(--space-2); margin-inline: var(--space-2); }
.hero-slider__dot {
  position: relative;
  width: 44px; height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  /* A <button> carries a few px of UA padding. At 44px wide that was
     invisible; once the dot narrows to 28px on a phone the padding ate
     12px and the 28px mark rendered at 16px, no longer matching the
     progress fill running underneath it. */
  padding: 0;
}
/* The visible mark is a rule, not a circle — 2px radius everywhere. */
.hero-slider__dot::before {
  content: "";
  width: 28px; height: 2px;
  flex: none;                 /* a flex item, and it must not be shrunk */
  background: var(--gm-edge);
  transition: background-color var(--dur-fast) var(--ease-out);
}
.hero-slider__dot:hover::before { background: var(--gm-slate); }
.hero-slider__dot.is-active::before { background: var(--gm-gold); }

/* Progress fill on the active dot, driven by main.js. Width, not
   transform, because it is 28px wide and never composited. */
.hero-slider__dot-fill {
  position: absolute;
  left: 8px; top: 21px;
  height: 2px; width: 0;
  background: var(--gm-gold-deep);
}

/* ── Narrow screens ───────────────────────────────────────────────────
   The dots give up their spare WIDTH, never their height. A dot is a
   44x44 tap target wrapping a 28px bar, so 28px wide still fits the bar
   exactly and stays above the 24px WCAG 2.5.8 floor; the full 44px
   height is untouched, and the three buttons keep 44x44 throughout
   because those are what people actually aim at.

   ⚠️ This block MUST stay below the .hero-slider__dot rules above. It
   was first written higher up, next to the controls, where it lost the
   cascade to the later `width: 44px` and silently did nothing — the row
   still wrapped onto two lines at every common phone width.

   The fill offset has to move with the dot. Its 8px left inset centres
   a 28px bar inside a 44px box; in a 28px box the bar starts at 0, and
   leaving the inset would have pushed the progress line off its own
   track. */
@media (max-width: 479.98px) {
  .hero-slider__controls-inner { gap: var(--space-2); }
  .hero-slider__dots     { gap: var(--space-1); margin-inline: 0; }
  .hero-slider__dot      { width: 28px; }
  .hero-slider__dot-fill { left: 0; }
}

/* ------------------------------------------------------------------
   39. PARALLAX
   Background images only. Never the hero — copy sits over it and would
   drift against the text.

   The image is scaled inside an overflow-hidden box so the drift can
   never expose an edge, and only `transform` is animated.
   ------------------------------------------------------------------ */

.parallax {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 100%;
}
.parallax__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* The overscan is applied by main.js via gsap.set(), NOT here.
   A `transform: scale()` in the stylesheet is overwritten the moment
   GSAP writes its own inline transform for the drift, so the two cannot
   both live in CSS. This class only hints the compositor. */
.js .parallax.is-parallaxing .parallax__img { will-change: transform; }

@media (prefers-reduced-motion: reduce) {
  .js .parallax.is-parallaxing .parallax__img {
    transform: none !important;
    will-change: auto;
  }
}

/* A full-bleed band that carries a parallax image behind its content. */
.media-band { position: relative; overflow: hidden; }
.media-band__media { position: absolute; inset: 0; z-index: 0; }
.media-band__media .parallax,
.media-band__media picture,
.media-band__media img { width: 100%; height: 100%; }
/* object-fit: cover, not the browser default of `fill`.
   The band's height comes from the copy inside it, so it is never the
   image's own ratio — 599px of picture was being squeezed into 557px of
   band and every car in one of these was 7% shorter than it should be.
   `cover` crops instead of distorting, which is what the images are
   commissioned for. */
.media-band__media img { object-fit: cover; object-position: center; }
.media-band__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg, rgb(11 15 21 / 62%) 0%, rgb(11 15 21 / 46%) 100%);
}
.media-band > .container { position: relative; z-index: 2; }

/* ------------------------------------------------------------------
   40. SECTION FIGURES
   A framed image beside a block of copy. Used on technology, warranty,
   dealers, about and contact.
   ------------------------------------------------------------------ */

/* ---------- Home: finish showcase ----------------------------------
   Two up from 768, staying two at desktop rather than going to four.
   Four across puts each card near 300px, and the photograph is the point
   of this section — a small one is not premium, it is a thumbnail. */
.showcase {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 768px) {
  .showcase { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.showcase__card {
  background: var(--gm-card);
  border: 1px solid var(--gm-edge);
  border-radius: var(--radius);
  overflow: hidden;
}
.showcase__link {
  display: flex;
  flex-direction: column;
  height: 100%;
  text-decoration: none;
  color: inherit;
}
.showcase__link:focus-visible { outline: 2px solid var(--gm-gold); outline-offset: -2px; }

.showcase__media { aspect-ratio: 4 / 3; overflow: hidden; background: var(--gm-mist); }
.showcase__media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 500ms var(--ease-out);
}
/* Hover only where hovering is a thing. On touch this fires on tap and
   the card appears to twitch as the page navigates away. */
@media (hover: hover) {
  .showcase__link:hover .showcase__media img { transform: scale(1.04); }
}

.showcase__body {
  padding: var(--space-6);
  display: flex; flex-direction: column; gap: var(--space-3);
  flex: 1;                      /* equal heights, CTA pinned to the foot */
}
.showcase__eyebrow {
  font-family: var(--ff-label); font-size: var(--fs-eyebrow); font-weight: 600;
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  color: var(--gm-gold-text);
}
.showcase__title { font-family: var(--ff-display); font-size: 1.5rem; color: var(--gm-ink); }
.showcase__text  { color: var(--gm-graphite); }
.showcase__cta   { margin-top: auto; }

/* ---------- Home: what the film stops ------------------------------- */
.defends {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 640px) { .defends { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 992px) { .defends { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.defends__card {
  background: var(--gm-card);
  border: 1px solid var(--gm-edge);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex; flex-direction: column;
}
.defends__media { aspect-ratio: 4 / 3; overflow: hidden; background: var(--gm-mist); }
.defends__media img { width: 100%; height: 100%; object-fit: cover; }
.defends__body {
  padding: var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-3);
  flex: 1;
}
/* --gm-gold is a FILL here, never text — see CLAUDE.md §12.1. An icon
   stroke is not text and passes at this size on a light ground. */
.defends__icon { color: var(--gm-gold-deep); line-height: 0; }
.defends__title { font-family: var(--ff-display); font-size: 1.0625rem; color: var(--gm-ink); }
.defends__text  { color: var(--gm-graphite); font-size: .9375rem; }

.figure-panel { margin: 0; }
.figure-panel__media {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border: 1px solid var(--gm-edge);
  border-radius: var(--radius);
  background: var(--gm-mist);
}
.figure-panel__media img { width: 100%; height: 100%; object-fit: cover; }
.figure-panel--wide .figure-panel__media { aspect-ratio: 8 / 5; }
.figure-panel__caption {
  margin-top: var(--space-3);
  font-size: var(--fs-caption);
  color: var(--gm-slate);
}

/* A small image alongside each technology behaviour. */
.tech-item__media {
  width: 100%;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border: 1px solid var(--gm-edge);
  border-radius: var(--radius);
  background: var(--gm-mist);
  margin-top: var(--space-4);
}
.tech-item__media img { width: 100%; height: 100%; object-fit: cover; }
@media (min-width: 992px) {
  .tech-item { grid-template-columns: 5rem 1fr 18rem; align-items: start; }
  .tech-item__media { margin-top: 0; }
}

/* ------------------------------------------------------------------
   41. LIGHT COMPONENTS ON DARK SECTIONS
   A component that paints its own light surface must also declare its
   own text colour. Otherwise .section--obsidian's heading and body rules
   reach inside it and paint paper-on-white — 1.04:1.

   Found by the contrast audit after /warranty moved onto an obsidian
   media band; the verify panel had been white-on-champagne until then,
   so nothing had exercised it.
   ------------------------------------------------------------------ */

.section--obsidian .verify-panel { color: var(--gm-graphite); }
.section--obsidian .verify-panel .h2,
.section--obsidian .verify-panel .h3,
.section--obsidian .verify-panel .h4 { color: var(--gm-ink); }
.section--obsidian .verify-panel .field__label { color: var(--gm-ink); }
.section--obsidian .verify-panel .field__help,
.section--obsidian .verify-panel .verify-panel__lede { color: var(--gm-slate); }
.section--obsidian .verify-panel .record__val { color: var(--gm-ink); }
.section--obsidian .verify-panel .record__key { color: var(--gm-slate); }

/* The trace list is body copy, so on obsidian it takes the section's
   body colour rather than --gm-graphite. */
.section--obsidian .trace-list > li {
  color: rgba(251, 250, 247, .82);
  border-top-color: var(--gm-edge-dark);
}
.section--obsidian .trace-list > li > .icon { color: var(--gm-gold); }

/* Same for a notice sitting on a dark band. */
.section--obsidian .notice {
  background: var(--gm-obsidian-2);
  border-color: var(--gm-edge-dark);
  color: rgba(251, 250, 247, .82);
}
.section--obsidian .notice__icon { color: var(--gm-gold); }

/* ------------------------------------------------------------------
   42. STICKY PAGE BANNER
   The banner stays where it is and the page scrolls over it.

   Pure CSS. Nothing animates and nothing is transformed, so the image
   is never scaled and stays exactly as sharp as it was delivered —
   which is why this is used here rather than the translate-based
   parallax on the section bands. An overscanned 1536px source across a
   full-bleed banner is visibly soft; this is not.

   Not used on the home page: a sticky banner under a rotating slider
   fights itself.
   ------------------------------------------------------------------ */

.hero--sticky {
  position: sticky;
  top: 0;
  z-index: 0;
}

/* Everything after the banner rides over it. Each section already paints
   an opaque background, so the banner is covered as the stack arrives. */
.hero-stack {
  position: relative;
  z-index: 1;
  background: var(--gm-paper);
}

/* The banner is only revealed while it is the top-most thing on screen,
   so it never needs to be taller than the viewport. */
/* Banner height is --hero-media-h on .hero--sticky. */

/* Below 992px the copy stacks under the image, so the section is taller
   than the viewport and sticky would pin the copy off-screen. Static. */
@media (max-width: 991px) {
  .hero--sticky { position: static; }
  .hero-stack { background: none; }
}

/* Sticky positioning fails inside a scroll container. body carries
   overflow-x: hidden for the full-bleed bands, which is enough to break
   it in some engines — clip does the same job without establishing one. */
@supports (overflow: clip) {
  body { overflow-x: clip; }
}
