/* ==========================================================================
   SNS Motorcycles — core stylesheet
   Light theme: white ground, light-grey bands, red primary, blue secondary,
   deep navy for the footer and the photographic scrims.
   ========================================================================== */

/* --------------------------------------------------------------- 1. Fonts */

@font-face {
  font-family: 'Archivo';
  src: url('../fonts/archivo-var-latin.woff2') format('woff2-variations');
  font-weight: 400 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Barlow';
  src: url('../fonts/barlow-regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Barlow';
  src: url('../fonts/barlow-medium.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Barlow';
  src: url('../fonts/barlow-semibold.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Barlow';
  src: url('../fonts/barlow-bold.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}

/* -------------------------------------------------------------- 2. Tokens */

:root {
  /* Brand red — primary action colour */
  --red:          #D61113;   /* 5.09:1 on white — safe for small text */
  --red-deep:     #A50D0F;   /* hover / pressed */
  --red-on-dark:  #FF4144;   /* 4.8:1 on navy — small red text over dark only */
  --red-soft:     #FDEDED;

  /* Blue — secondary accent and the dark anchor */
  --navy:         #0B1E3D;   /* footer keyline, photo scrims, navy CTA bar */
  --navy-2:       #13315F;
  --charcoal:     #24272B;   /* neutral dark — spare, kept for dark strips */
  --blue:         #1B4FD8;   /* 6.4:1 on white */
  --blue-deep:    #1740AE;
  --blue-on-dark: #7FA6FF;
  --blue-soft:    #E9EFFC;

  /* Surfaces */
  --white:        #FFFFFF;
  --bg:           #FFFFFF;
  --surface:      #F4F6F9;   /* light grey band */
  --surface-2:    #EBEFF5;
  --surface-3:    #DFE5EE;   /* inputs, stronger fills */

  /* Type */
  --ink:          #0D1728;   /* headings — 16.5:1 on white */
  --ink-2:        #44506A;   /* body — 8.3:1 */
  --muted:        #5F6B82;   /* secondary — 5.6:1 */
  --on-dark:      #FFFFFF;
  --on-dark-dim:  #C3CDDE;

  /* Lines */
  --line:         rgba(11, 30, 61, .13);
  --line-2:       rgba(11, 30, 61, .07);
  --line-dark:    rgba(255, 255, 255, .16);

  /* Elevation */
  --shadow-sm:    0 1px 2px rgba(11,30,61,.06), 0 2px 8px rgba(11,30,61,.05);
  --shadow-md:    0 4px 14px rgba(11,30,61,.08), 0 14px 32px rgba(11,30,61,.07);
  --shadow-lg:    0 10px 30px rgba(11,30,61,.10), 0 26px 60px rgba(11,30,61,.09);

  /* Families */
  --font-display: 'Archivo', 'Arial Narrow', 'Helvetica Neue', Arial, sans-serif;
  --font-body:    'Barlow', 'Helvetica Neue', Arial, sans-serif;

  /* Rhythm — overridden per breakpoint in responsive.css */
  --section-y:    100px;
  --gutter:       clamp(20px, 5vw, 60px);
  --maxw:         1500px;

  /* Motion */
  --ease:         cubic-bezier(.22, .61, .36, 1);
  --dur:          .45s;

  --header-h:     100px;
}

/* --------------------------------------------------------------- 3. Reset */

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

/* ⚠️ The `hidden` attribute is only `display: none` in the BROWSER's stylesheet,
   so ANY author `display` rule beats it. `.btn` is `display: inline-flex`, which
   meant `el.hidden = true` set the attribute and the button carried on painting
   — that is why the gallery's Load More stayed on screen for the filters that
   have nothing more to load. This makes the attribute mean what it says, for
   every element on the site. Toggle visibility with `el.hidden`, not by writing
   inline `style.display`. */
[hidden] { display: none !important; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 20px);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink-2);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  font-weight: 400;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body.nav-open { overflow: hidden; }

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

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

button, input, select, textarea { font: inherit; color: inherit; }

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

:focus-visible {
  outline: 3px solid var(--blue);
  outline-offset: 2px;
  border-radius: 2px;
}

::selection { background: var(--red); color: #fff; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--red); color: #fff; padding: 12px 20px; font-weight: 600;
}
.skip-link:focus { left: 0; }

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

/* ----------------------------------------------------------- 4. Typography */

.display,
h1, h2, h3, .h1, .h2, .h3, .h4 {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-weight: 800;
  font-variation-settings: 'wdth' 100, 'wght' 850;
  line-height: .95;
  letter-spacing: -.015em;
  color: var(--ink);
}

.h1, h1 {
  font-size: clamp(2.5rem, 6.2vw, 4.5rem);
  line-height: .92;
  font-variation-settings: 'wdth' 100, 'wght' 880;
  letter-spacing: -.025em;
}

.h2, h2 {
  font-size: clamp(1.9rem, 4vw, 3rem);
  line-height: .95;
  font-variation-settings: 'wdth' 100, 'wght' 870;
  letter-spacing: -.02em;
}

.h3, h3 { font-size: clamp(1.25rem, 2vw, 1.6rem); }
.h4     { font-size: 1.05rem; letter-spacing: 0; }

.accent { color: var(--red); display: block; }
/* keeps the accent on the same line as the words before it */
.accent--inline { display: inline; }

.eyebrow {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 700;
  text-transform: uppercase;
  font-size: .78rem;
  letter-spacing: .22em;
  color: var(--red);
  margin-bottom: 18px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.eyebrow--plain { display: block; }

/* Centres the dash + label as a unit inside a centred block */
.eyebrow--center { justify-content: center; }

/* Short red rule before the label */
.eyebrow--dash::before {
  content: '';
  width: 36px; height: 3px;
  background: var(--red);
  flex: none;
}

.lede {
  color: var(--ink-2);
  font-size: clamp(1rem, 1.3vw, 1.125rem);
  max-width: 56ch;
}

.body-text { color: var(--ink-2); max-width: 62ch; }
/* ⚠️ Paragraph spacing lives HERE and nowhere else.
   The service pages used to carry `style="margin-top:20px"` on every
   `.body-text`, including ones that followed another paragraph, so consecutive
   paragraphs sat 20px apart on top of a 1.7 line-height — the gap the client
   asked to tighten. Those duplicate inline margins were removed from the
   paragraphs that follow a paragraph; the inline margin is kept only on the
   FIRST paragraph of a block, where it is setting the distance from the
   heading above. An inline style beats any selector, so if this rule ever
   looks like it is being ignored, check the markup for a stray margin-top
   before adding `!important`. */
.body-text + .body-text { margin-top: .7em; }

.text-mute { color: var(--muted); }

/* Anything sitting on navy or on a photograph flips to the dark-safe set.
   The footer is deliberately NOT in this list — it runs on its own light
   palette, declared in §22. */
.hero, .mediaband, .ctabar, .brands--dark, .lightbox, .approvalband {
  --ink: var(--on-dark);
  --ink-2: var(--on-dark-dim);
  --muted: var(--on-dark-dim);
  --red: var(--red-on-dark);
  --blue: var(--blue-on-dark);
  --line: var(--line-dark);
}

/* ------------------------------------------------------------- 5. Layout */

/* --maxw is the width of the *content*, not of the box. The gutters sit outside
   it, so a section actually measures 1500px of usable width on a wide screen
   rather than 1500 minus two 60px gutters. */
.container {
  width: 100%;
  max-width: calc(var(--maxw) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--wide { max-width: calc(1560px + var(--gutter) * 2); }

/* Every major section carries the same vertical rhythm — 100px desktop,
   75px tablet, 50px mobile (see responsive.css). There are deliberately no
   "flush" or "tight" modifiers: where two blocks belong to one band, nest them
   in a single .section and separate them with .block-gap instead of stacking
   two sets of section padding. */
.section { padding-block: var(--section-y); position: relative; }

/* Gap between sibling blocks inside one section */
.block-gap { margin-top: clamp(40px, 5vw, 64px); }

.section--light { background: var(--surface); }
.section--surface { background: var(--surface); }
.section--black { background: var(--navy); color: var(--on-dark); }
/* the warm off-white shared with .trackband and .reviews — used on the Home
   gallery so it separates from the white service band directly above it */
.section--offwhite { background: #FAF9F6; }

.section-head { margin-bottom: 52px; max-width: 62ch; }
.section-head--center { margin-inline: auto; text-align: center; }
/* the lede carries its own measure, so it needs centring in its own right */
.section-head--center .lede { margin-inline: auto; }
.section-head--center .btn-row { justify-content: center; }
/* wide measure, for a centred head whose intro should stay on one or two lines
   rather than breaking over four — same treatment as .trackband__head */
.section-head--wide { max-width: 1020px; }
.section-head--wide .lede { max-width: none; }

.section-head .lede { margin-top: 20px; }

/* Heading on the left, a single action pinned to the right of the same row.
   The modifier drops the 62ch cap — that measure belongs on the text column,
   not on a block that now spans the full container. */
.section-head--split {
  max-width: none;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: clamp(24px, 4vw, 60px);
}
.section-head__text { max-width: 62ch; min-width: 0; }
.section-head__action { flex: none; }

/* ⚠️ `--fill` is on the FOUR SECTION HEADS OF services.php ONLY, at the
   client's request, and it is deliberately not the default.

   A `.section-head--split` is a heading block with a right-aligned action, so
   the space between them is normally white space doing its job — and the 62ch
   on the text and 56ch on the lede are a reading measure. On the Services page
   the client marked that space twice as an error: at 1440 the h2 wrapped
   "SERVICING & / MAINTENANCE" over two lines with 500px of empty row beside
   it, purely because 62ch is narrower than the heading needs.

   Dropping both caps lets the text block take everything the button does not,
   so the heading sits on one line and the lede runs the width of the row.

   The trade is line length: at 1440 the lede runs about 118 characters and at
   2560 about 145, well past a comfortable measure. That is the explicit ask —
   both those widths were named. Do NOT promote this to `.section-head--split`
   generally: the same change on index.php and about.php would stretch their
   ledes for no reason anyone has asked for. */
.section-head--fill .section-head__text { max-width: none; flex: 1 1 auto; }
.section-head--fill .lede { max-width: none; }

/* Grid and flex children default to min-width:auto, so one long unbreakable
   string — an email address, say — can push its column wider than the track
   and overflow the page on narrow screens. Reset it, and let such strings wrap. */
.grid > *,
.contact-grid > *,
.split > *,
.trackband__cards > *,
.pillars > *,
.svcband > *,
.svclist > *,
.gpeek__grid > *,
.svcstrip__grid > *,
.footer__grid > * { min-width: 0; }

.infocard__text,
.footer__contact,
.prose,
.card__text { overflow-wrap: break-word; }

.grid { display: grid; gap: 24px; }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }

.stack > * + * { margin-top: 20px; }

.rule { height: 1px; background: var(--line); border: 0; margin: 0; }

/* ------------------------------------------------------------ 6. Buttons */

.btn {
  --btn-bg: var(--red);
  --btn-fg: #fff;
  --btn-bd: var(--red);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 17px 34px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid var(--btn-bd);
  border-radius: 999px;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 700;
  text-transform: uppercase;
  font-size: .86rem;
  letter-spacing: .1em;
  line-height: 1;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  box-shadow: var(--shadow-sm);
  transition: background var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              transform .25s var(--ease);
}

/* Solid buttons keep true brand red inside dark-scoped blocks, where --red is
   remapped to the lighter on-dark tint. :not(.btn--ghost) so the outlined
   secondary is not repainted into a solid red twin of the primary. */
.hero .btn:not(.btn--ghost), .mediaband .btn:not(.btn--ghost),
.ctabar .btn:not(.btn--ghost), .brands--dark .btn:not(.btn--ghost),
.ctaband .btn:not(.btn--ghost), .wcta .btn:not(.btn--ghost),
.approvalband .btn:not(.btn--ghost) {
  --btn-bg: #D61113; --btn-bd: #D61113;
}

.btn::before {
  content: '';
  position: absolute; inset: 0;
  background: var(--red-deep);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
  z-index: -1;
}
.btn:hover::before { transform: scaleX(1); }
.btn:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.btn:active { transform: translateY(0); }

.btn .arw { transition: transform .35s var(--ease); flex: none; }
.btn:hover .arw { transform: translateX(5px); }

/* Outline on light backgrounds — fills brand red on hover, matching the
   primary button rather than washing to navy */
.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--ink);
  --btn-bd: rgba(11, 30, 61, .28);
  box-shadow: none;
}
.btn--ghost::before { background: var(--red); }
.btn--ghost:hover { color: #fff; border-color: var(--red); box-shadow: var(--shadow-sm); }

/* Outline on dark photography / navy — a dark border would disappear there */
.hero .btn--ghost, .mediaband .btn--ghost, .brands--dark .btn--ghost,
.ctabar--dark .btn--ghost, .ctaband .btn--ghost, .wcta .btn--ghost,
.approvalband .btn--ghost {
  --btn-fg: #fff;
  --btn-bd: rgba(255, 255, 255, .45);
}
.hero .btn--ghost::before, .mediaband .btn--ghost::before,
.brands--dark .btn--ghost::before, .ctabar--dark .btn--ghost::before,
.ctaband .btn--ghost::before, .wcta .btn--ghost::before,
.approvalband .btn--ghost::before { background: #fff; }
.hero .btn--ghost:hover, .mediaband .btn--ghost:hover,
.brands--dark .btn--ghost:hover, .ctabar--dark .btn--ghost:hover,
.ctaband .btn--ghost:hover, .wcta .btn--ghost:hover,
.approvalband .btn--ghost:hover {
  color: var(--navy); border-color: #fff; box-shadow: none;
}

/* Blue secondary */
.btn--blue {
  --btn-bg: var(--blue); --btn-fg: #fff; --btn-bd: var(--blue);
}
.btn--blue::before { background: var(--blue-deep); }

.btn--dark {
  --btn-bg: transparent;
  --btn-fg: var(--ink);
  --btn-bd: rgba(11,30,61,.25);
  box-shadow: none;
}
.btn--dark::before { background: var(--red); }
.btn--dark:hover { color: #fff; border-color: var(--red); }

.btn--sm { padding: 14px 28px; font-size: .78rem; }
.btn--block { display: flex; width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 34px; }

/* Quiet inline link with arrow — the blue secondary action */
.link-arrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 700;
  text-transform: uppercase; font-size: .76rem; letter-spacing: .12em;
  color: var(--blue);
  transition: color .3s var(--ease);
}
.link-arrow .arw { transition: transform .3s var(--ease); }
.link-arrow:hover { color: var(--blue-deep); }
.link-arrow:hover .arw { transform: translateX(5px); }

/* ------------------------------------------------------------- 7. Header */

.header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--header-h);
  display: flex;
  align-items: center;
  /* Opaque, not translucent: the navy hero sits directly behind the fixed bar,
     and any transparency tints the white grey and muddies the logo. */
  background: #fff;
  border-bottom: 1px solid var(--line-2);
  transition: border-color .35s var(--ease), box-shadow .35s var(--ease);
}
.header.is-stuck {
  border-bottom-color: var(--line);
  box-shadow: var(--shadow-sm);
}

.header__inner {
  width: 100%;
  max-width: calc(var(--maxw) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  gap: 28px;
}

.brand { display: flex; align-items: center; flex: none; }
/* The mark is wide and short (1.795:1), so it needs a generous height to carry
   any visual weight against the nav — 66px reads as ~118px wide, about two
   thirds of the header bar. */
/* ⚠️ Sized by the WIDTH budget, not by eye.

   The logo is `images/sns-logo.png` at 391 × 150 — a 2.61:1 lockup (rider mark,
   SNS, "motorcycles", "Street N Sport"). The mark it replaced was 1.80:1, so at
   the old 66px height this one would run 172px wide instead of 119px and eat
   53px out of the nav row, which is the tightest part of the bar.

   62px gives 162px of width. Two constraints meet there:
     - it still fits: measured collision-free from 1025 (narrowest in-bar nav)
       up to 1920;
     - it stays sharp: 162 × 2 = 324px, inside the file's 391px. A raster logo
       goes soft the moment the displayed width crosses half its pixel width, so
       every height below is chosen to keep 2 × width ≤ 391. */
.brand img { height: 62px; width: auto; }

/* Nav takes the space between the brand and the CTA and centres itself in it,
   so the links sit in the middle of the bar rather than pushed to the right. */
.nav { flex: 1 1 auto; min-width: 0; display: flex; justify-content: center; }
.nav__list { display: flex; align-items: center; gap: 4px; }

.nav__link {
  display: block;
  padding: 10px 14px;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 650;
  text-transform: uppercase;
  font-size: .8rem;
  letter-spacing: .08em;
  color: var(--ink-2);
  position: relative;
  transition: color .3s var(--ease);
  white-space: nowrap;
}
.nav__link::after {
  content: '';
  position: absolute;
  left: 14px; right: 14px; bottom: 4px;
  height: 2px;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .35s var(--ease);
}
.nav__link:hover { color: var(--ink); }
.nav__link:hover::after { transform: scaleX(1); transform-origin: left; }
.nav__link.is-active { color: var(--ink); }
.nav__link.is-active::after { transform: scaleX(1); }

.header__cta { flex: none; display: flex; align-items: center; gap: 18px; }

/* Click-to-call sitting before the Book button: an outlined pill, matched to
   .btn--sm's height so the two read as a pair. Outlined rather than solid —
   two solid buttons side by side would compete for the same attention. */
.header__tel {
  position: relative;
  isolation: isolate;
  overflow: hidden;              /* clips the wipe to the pill */
  display: inline-flex; align-items: center; gap: 9px;
  padding: 13px 22px;
  border: 1px solid rgba(11, 30, 61, .20);
  border-radius: 999px;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 750;
  font-size: .82rem;
  letter-spacing: .02em;
  line-height: 1;
  color: var(--ink);
  white-space: nowrap;
  transition: color .3s var(--ease), border-color .3s var(--ease);
}
/* red wipes in from the left, the same gesture as .btn--ghost */
.header__tel::before {
  content: '';
  position: absolute; inset: 0;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
  z-index: -1;
}
.header__tel svg {
  width: 16px; height: 16px; flex: none;
  color: var(--red);
  transition: color .3s var(--ease);
}
.header__tel:hover { color: #fff; border-color: var(--red); }
.header__tel:hover svg { color: #fff; }
.header__tel:hover::before { transform: scaleX(1); }

/* In-drawer CTA — only surfaces once the nav collapses (see responsive.css) */
.nav__cta { display: none; }

/* --------------------------------------------- 7b. Services mega menu

   Full-width panel under the header: four grouped columns of services and a
   help panel. Opens on hover and on focus for pointer users, and on click via
   the caret button, which is what keyboard and touch users get.             */

.nav__item--mega { position: static; }   /* panel spans the header, not the item */

.nav__toggle-sub {
  display: none;                          /* desktop uses hover; see below */
  background: none; border: 0; padding: 6px 4px;
  /* pulled back under the link's own right padding so the caret sits against
     the word "Services" rather than floating in the gap after it */
  margin-left: -12px;
  color: var(--ink-2); cursor: pointer;
  line-height: 0;
}
.nav__toggle-sub svg { width: 15px; height: 15px; transition: transform .3s var(--ease); }
.nav__item--mega:hover .nav__toggle-sub svg,
.nav__toggle-sub[aria-expanded="true"] svg { transform: rotate(180deg); }

/* ⚠️ 1025px, NOT 941px — this must match the drawer breakpoint exactly.

   The drawer starts at ≤1024. These two rules used to start at ≥1025, which left
   941-1024 as a dead band (when the drawer sat at 940): too wide for the drawer accordion, too narrow for
   the desktop dropdown, so the caret was hidden AND the panel could not open.
   The Services menu was simply unreachable in an 84px-wide window of viewport
   sizes — found at 956 × 785. If you ever move the drawer breakpoint, move this
   one and the `.mega` open rule below with it. */
@media (min-width: 1025px) {
  .nav__item--mega { display: flex; align-items: center; }
  .nav__toggle-sub { display: block; }
}

.mega {
  position: absolute;
  left: 0; right: 0; top: 100%;
  background: #fff;
  border-top: 1px solid var(--line);
  border-bottom: 3px solid var(--red);
  box-shadow: 0 24px 48px rgba(11, 30, 61, .13);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-10px);
  transition: opacity .3s var(--ease), transform .3s var(--ease),
              visibility .3s var(--ease);
}
/* hover/focus for pointer + keyboard tabbing, .is-open for the caret button.
   ⚠️ 1025px — must match the drawer breakpoint; see the note above. */
@media (min-width: 1025px) {
  .nav__item--mega:hover > .mega,
  .nav__item--mega:focus-within > .mega,
  .mega.is-open {
    opacity: 1; visibility: visible; transform: none;
  }
}

.mega__inner {
  display: grid;
  grid-template-columns: 1fr 300px;
  gap: clamp(30px, 3.4vw, 56px);
  padding-block: clamp(30px, 3vw, 44px);
  align-items: start;
}

.mega__cols {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(20px, 2.2vw, 40px);
}
/* Flex column so the "View All" link can be pinned to the base — Support &
   Protection has two services where the others have four, and without this its
   link floated two rows above the rest of the row. */
.mega__col { min-width: 0; display: flex; flex-direction: column; }

/* ⚠️ `min-height` reserves TWO lines even for a one-line title.

   Three of the four headings wrap — "Repair & Diagnostics", "Performance &
   Track", "Support & Protection" — and "Maintenance" does not. Without this the
   Maintenance column's rule, its first link and its "View All" all sat a line
   higher than the other three, and the panel read as though that column had
   been pasted in crooked. Reserving the second line puts all four rules on one
   horizontal line and starts all four lists together.

   `align-items: flex-start` rather than `center`: with a reserved second line,
   centring would float "Maintenance" into the middle of its box and its
   baseline would land between the other columns' two lines. Top-aligned, the
   first line of all four headings shares a baseline. */
.mega__title {
  display: flex; align-items: flex-start; gap: 10px;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 800;
  text-transform: uppercase;
  font-size: .82rem;
  letter-spacing: .1em;
  line-height: 1.3;
  color: var(--ink);
  /* two lines + the padding below, plus 2px of slack: a wrapped two-line box
     rounds its line boxes up and measured 47px against the reserved 46.1px,
     which put the Maintenance column's rule a pixel above the other three */
  min-height: calc(2.6em + 14px);
  padding-bottom: 12px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--line);
}
.mega__title svg { width: 20px; height: 20px; color: var(--red); flex: none; }

.mega__list li + li { margin-top: 2px; }
.mega__list a {
  display: block;
  padding: 7px 0;
  font-size: .89rem;
  line-height: 1.35;
  color: var(--ink-2);
  transition: color .25s var(--ease), transform .25s var(--ease);
}
.mega__list a:hover { color: var(--red); transform: translateX(3px); }

.mega__all {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: 7px;
  margin-top: auto;          /* pinned to the base of the tallest column */
  padding-top: 18px;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 750;
  text-transform: uppercase;
  font-size: .74rem;
  letter-spacing: .1em;
  color: var(--red);
}
.mega__all .arw { transition: transform .3s var(--ease); }
.mega__all:hover .arw { transform: translateX(4px); }

/* Dark aside against the white panel — the contrast is what stops it reading
   as a fifth column of links. Same gradient as the track band cards. */
.mega__aside {
  position: relative;
  background: linear-gradient(168deg, #282B31 0%, #191B1F 62%, #141619 100%);
  border-radius: 5px;
  overflow: hidden;
  padding: 26px 26px 28px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07);
}
/* red rule across the head of the panel */
.mega__aside::before {
  content: '';
  position: absolute; left: 0; right: 0; top: 0;
  height: 3px;
  background: #D61113;
}

.mega__aside-icon {
  width: 42px; height: 42px;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 2px solid #D61113;
  color: #fff;
  margin-bottom: 16px;
}
.mega__aside-icon svg { width: 19px; height: 19px; }

.mega__aside-title {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 820;
  text-transform: uppercase;
  font-size: 1.05rem;
  letter-spacing: .02em;
  color: #fff;
  margin-bottom: 9px;
}
.mega__aside-text {
  font-size: .85rem;
  line-height: 1.55;
  color: rgba(255, 255, 255, .66);
  margin-bottom: 18px;
}

/* the number itself, given prominence — most "need help" clicks are a phone call */
.mega__aside-tel {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 800;
  font-size: 1.12rem;
  letter-spacing: .01em;
  color: #fff;
  margin-bottom: 20px;
  transition: color .3s var(--ease);
}
.mega__aside-tel svg { width: 17px; height: 17px; color: var(--red-on-dark); flex: none; }
.mega__aside-tel:hover { color: var(--red-on-dark); }

.mega__aside .btn { width: 100%; justify-content: center; }

.nav-toggle {
  display: none;
  width: 44px; height: 44px;
  margin-left: auto;
  background: none; border: 1px solid var(--line); border-radius: 3px;
  cursor: pointer;
  padding: 0;
  place-items: center;
}
.nav-toggle span {
  display: block; width: 20px; height: 2px; background: var(--ink);
  position: relative;
  transition: background .2s var(--ease);
}
.nav-toggle span::before,
.nav-toggle span::after {
  content: ''; position: absolute; left: 0; width: 20px; height: 2px; background: var(--ink);
  transition: transform .3s var(--ease), top .3s var(--ease);
}
.nav-toggle span::before { top: -6px; }
.nav-toggle span::after  { top: 6px; }
.nav-toggle[aria-expanded="true"] span { background: transparent; }
.nav-toggle[aria-expanded="true"] span::before { top: 0; transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] span::after  { top: 0; transform: rotate(-45deg); }

/* ---------------------------------------------------------------- 8. Hero */

.hero {
  position: relative;
  min-height: 640px;
  display: flex;
  align-items: flex-end;
  padding-top: calc(var(--header-h) + 80px);
  padding-bottom: 90px;
  overflow: hidden;
  background: var(--navy);
  color: var(--on-dark);
}
.hero--home {
  min-height: min(92vh, 860px);
  align-items: center;
}
.hero--inner { min-height: 520px; padding-bottom: 70px; }

.hero__media { position: absolute; inset: 0; z-index: 0; }
.hero__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
  transform: scale(1.06);
  animation: heroDrift 14s var(--ease) forwards;
}
@keyframes heroDrift { to { transform: scale(1); } }

/* Navy scrim — dark enough on the left for white type, clear over the bike */
.hero__media::after {
  content: '';
  position: absolute; inset: 0;
  background:
    linear-gradient(90deg, rgba(11,30,61,.95) 0%, rgba(11,30,61,.84) 34%, rgba(11,30,61,.34) 62%, rgba(11,30,61,.58) 100%),
    linear-gradient(180deg, rgba(11,30,61,.62) 0%, rgba(11,30,61,0) 30%, rgba(11,30,61,.20) 70%, rgba(8,20,41,.86) 100%);
}

.hero__inner { position: relative; z-index: 2; width: 100%; }

/* ⚠️ The home hero is the ONE two-column block on the site that is not 1fr /
   1fr, and that is deliberate. The site-wide rule (see the width-modifier
   warning above `.split`) exists so alternating photo/copy rows keep their
   edges on one line down the page. Nothing alternates here: there is a single
   hero, the right column is a form whose width is set by what a form needs to
   be usable rather than by the grid, and the left column is display type that
   wants the remaining room. `minmax` rather than a fraction so the panel never
   drops below 330px — narrower than that and the two paired fields collide. */
.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(330px, 400px);
  gap: clamp(32px, 4vw, 64px);
  align-items: center;
}
.hero__copy { max-width: 660px; }

/* ----------------------------------------------- McAMS approval badge

   Supplied artwork, used as supplied. ⚠️ The white ground is NOT knocked out
   and must not be: it is part of an approval mark issued by someone else, and
   re-cutting it to suit a dark hero would be altering another company's badge.
   It sits in a white plate so it reads as a badge applied to the page rather
   than a picture that failed to load its background. */
.approval {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: clamp(26px, 3vw, 36px);
  flex-wrap: wrap;
}
/* The white plate lives on the wrapper, never on the <img> itself: padding on
   an image makes its border box a different aspect ratio from the file, which
   both softens the artwork's edge and trips the ratio audit. */
.approval__plate {
  display: block;
  background: #fff;
  border-radius: 4px;
  padding: 5px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .22);
}
.approval__badge {
  width: 148px;
  height: auto;
  display: block;
}
.approval__label {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 760;
  text-transform: uppercase;
  font-size: .74rem;
  letter-spacing: .1em;
  line-height: 1.35;
  color: var(--on-dark);
  max-width: 150px;
  margin: 0;
}

/* ------------------------------------- Approvals band (About page)

   A full-bleed navy band, not a boxed section: the approval is a standing fact
   about the workshop rather than one more chapter of the page, and a band reads
   that way. It sits between the gallery and the credentials split, so the page
   runs off-white → navy → white and the three blocks separate by ground colour
   without needing a rule between them.

   No photograph behind it, unlike .mediaband and .wcta — the badge is the
   subject here, and a picture under it would fight the one piece of artwork the
   band exists to show. The flat navy is lifted by a red hairline along the top
   and a soft red wash off the right edge instead.

   The badge sits on a white plate for the same reason it does in the hero: it
   is another company's approval mark, shown as issued, not re-cut to suit a
   dark page. */
.approvalband {
  position: relative;
  overflow: hidden;
  background: var(--navy);
  color: var(--on-dark);
}
.approvalband::before {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 3px;
  background: linear-gradient(90deg, var(--red) 0%, var(--red) 38%, rgba(214, 17, 19, 0) 100%);
}
/* off-canvas on purpose — only the falloff shows, which keeps it a wash rather
   than a circle sitting on the band */
.approvalband::after {
  content: '';
  position: absolute;
  top: 50%;
  right: -12%;
  width: min(760px, 62%);
  aspect-ratio: 1;
  transform: translateY(-50%);
  background: radial-gradient(circle, rgba(214, 17, 19, .22) 0%, rgba(214, 17, 19, 0) 68%);
  pointer-events: none;
}
.approvalband__inner {
  position: relative;
  z-index: 2;
  padding-block: var(--section-y);
}

.approvalband__head {
  display: grid;
  grid-template-columns: minmax(0, 400px) minmax(0, 1fr);
  gap: clamp(32px, 4.4vw, 72px);
  align-items: center;
}
.approvalband__mark {
  background: #fff;
  border-radius: 5px;
  padding: clamp(18px, 1.8vw, 26px);
  box-shadow: 0 22px 48px rgba(4, 12, 26, .45);
}
.approvalband__mark img { width: 100%; height: auto; display: block; }

.approvalband__copy { min-width: 0; }
/* wider than the 56ch default on purpose: this is a full-bleed band, and a
   normal measure left the right third of it empty */
.approvalband__copy .lede { margin-top: 20px; max-width: 74ch; }
.approvalband .btn-row { margin-top: 28px; }

/* ⚠️ The divided points row under this band is styled with `.wcta__points`,
   further down the file in §14c — including the override that gives this one
   three columns instead of four. It cannot live here: same specificity, and the
   shared rule comes later, so a column count written at this point in the file
   would simply lose. */

/* ------------------------------------------------- Hero enquiry form

   A white card floating on the hero photograph. It reuses `.field`,
   `.field-row`, `.form-status` and `.hp` from the contact form so the two
   behave identically and `initForm()` needs no per-form special casing.

   ⚠️ The card re-lights its own tokens. `.hero` remaps `--ink`, `--line` and
   friends to their on-dark values for the whole section; without this reset the
   labels inside a white panel would inherit near-white text on white. */
.heroform {
  --ink: var(--navy);
  --ink-2: #4A5568;
  --muted: #6B7280;
  --line: rgba(11, 30, 61, .16);
  --red: #D61113;

  background: rgba(255, 255, 255, .97);
  border: 1px solid rgba(255, 255, 255, .5);
  border-radius: 6px;
  padding: clamp(22px, 2.4vw, 30px);
  box-shadow: 0 26px 60px rgba(4, 14, 32, .42);
  color: var(--navy);
}
.heroform__title {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 820;
  text-transform: uppercase;
  font-size: clamp(1.05rem, 1.5vw, 1.25rem);
  letter-spacing: .04em;
  line-height: 1.15;
  color: var(--navy);
  margin: 0 0 6px;
}
.heroform__sub {
  font-size: .88rem;
  line-height: 1.5;
  color: #5A6577;
  margin: 0 0 18px;
}
/* tighter than the contact page card — this one has to fit beside a hero */
.heroform .field { margin-bottom: 12px; }
.heroform .field-row { gap: 12px; }
.heroform label { font-size: .72rem; }
.heroform input,
.heroform textarea { padding: 11px 13px; font-size: .92rem; }
.heroform textarea { min-height: 84px; resize: vertical; }
.heroform .btn { margin-top: 4px; }
/* the status line is a light-on-dark panel by default; re-light it here */
.heroform .form-status {
  border-color: rgba(27, 79, 216, .3);
  background: #EEF3FF;
  color: var(--navy);
  font-size: .84rem;
  padding: 11px 13px;
}
.hero__copy .lede { margin-top: 22px; color: var(--on-dark-dim); }

.crumbs {
  display: flex; align-items: center; gap: 10px;
  font-size: .82rem; color: rgba(255,255,255,.62);
  margin-bottom: 26px;
  position: relative; z-index: 2;
}
.crumbs a { color: rgba(255,255,255,.62); transition: color .3s var(--ease); }
.crumbs a:hover { color: #fff; }
.crumbs [aria-current] { color: rgba(255,255,255,.88); }
.crumbs .sep { opacity: .5; }

.hero__baseline {
  position: absolute; left: 0; bottom: 0; height: 4px; width: 100%;
  background: linear-gradient(90deg, #D61113 0%, #D61113 24%, var(--blue-deep) 24%, var(--blue-deep) 34%, rgba(11,30,61,0) 62%);
  z-index: 3;
}

/* -------------------------------------- 9a. Track band (intro + card row)

   Light cream block, no photograph: a centred heading and two-line intro
   above a full-width row of four dark service cards.                        */

.trackband {
  position: relative;
  background: #FAF9F6;
  padding-block: var(--section-y);
}

.trackband__head {
  text-align: center;
  /* wide measure on purpose — the brief asks for a two-line intro, and the
     default 56ch on .lede would break it over four */
  max-width: 1020px;
  margin-inline: auto;
  margin-bottom: clamp(38px, 4.4vw, 62px);
}
.trackband__head .lede {
  margin-top: 18px;
  margin-inline: auto;
  max-width: none;
}

/* --- the card row --- */

.trackband__cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(18px, 1.9vw, 30px);
  align-items: stretch;
}

/* Dark cards against the cream ground — the contrast is the point of the
   section, so these stay near-solid. The vertical gradient plus the inset top
   highlight is what stops a flat fill reading as a plain grey box. */
.tcard {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  background: linear-gradient(168deg, #282B31 0%, #191B1F 62%, #141619 100%);
  border: 1px solid rgba(255, 255, 255, .10);
  border-radius: 5px;
  overflow: hidden;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07),
              0 14px 34px rgba(12, 16, 22, .30);
  transition: border-color .45s var(--ease), transform .45s var(--ease),
              box-shadow .45s var(--ease);
}
.tcard:hover,
.tcard:focus-within {
  border-color: rgba(214, 17, 19, .55);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .10),
              0 26px 54px rgba(12, 16, 22, .42);
  transform: translateY(-6px);
}

.tcard__media {
  position: relative;
  flex: none;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: #0F1114;
}
.tcard__media img {
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 1.2s var(--ease);
}
.tcard:hover .tcard__media img,
.tcard:focus-within .tcard__media img { transform: scale(1.07); }

/* Shades the foot of the photograph so it settles into the body instead of
   meeting it on a hard horizontal seam. */
.tcard__media::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(180deg,
              rgba(15, 17, 20, 0) 52%,
              rgba(15, 17, 20, .30) 78%,
              rgba(15, 17, 20, .72) 100%);
}

/* Red rule sitting on the image/body seam, drawn in from the left on hover.
   It replaces the old fixed 28px tick — a line the full width of the card
   reads as intent, a stub reads as a stray dash. Anchored to the media rather
   than the card because the media's height is set by its aspect ratio, so
   there is no percentage of the card to measure from. */
.tcard__media::before {
  content: '';
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  height: 3px;
  background: #D61113;
  /* short at rest so the brand accent is always present, running the full
     width of the card on hover */
  transform: scaleX(.17);
  transform-origin: left;
  transition: transform .5s var(--ease);
}
.tcard:hover .tcard__media::before,
.tcard:focus-within .tcard__media::before { transform: scaleX(1); }

.tcard__body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  padding: 24px 24px 22px;
}

.tcard__title {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 790;
  text-transform: uppercase;
  font-size: 1rem;
  letter-spacing: .012em;
  line-height: 1.22;
  color: #FFFFFF;
  margin-bottom: 11px;
}
/* Title stays white on hover — red small text only measures 4.4:1 on the
   charcoal ground. The red rule and the arrow button carry the accent. */
.tcard__title a { color: inherit; }
/* the whole card is the hit area, so the link's own outline would float in the
   middle of it — .tcard:focus-within lights the card edge instead */
.tcard__title a:focus-visible { outline: none; }

.tcard__text {
  font-size: .88rem;
  line-height: 1.58;
  color: rgba(255, 255, 255, .62);
  margin-bottom: 10px;
}

/* Footer action: hairline rule, then a circular arrow button on the right.
   `margin-top: auto` pins it to the base of whichever card is tallest, so the
   buttons line up across the row however long the descriptions run. */
.tcard__foot {
  display: flex;
  justify-content: flex-end;
  margin-top: auto;
  padding-top: 20px;
  /* full-bleed hairline: cancels the body's side padding so the rule reaches
     both edges of the card, which is what makes the foot read as a footer */
  margin-inline: -24px;
  padding-inline: 24px;
  border-top: 1px solid rgba(255, 255, 255, .09);
}
.tcard__arw {
  position: relative;
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .22);
  color: rgba(255, 255, 255, .72);
  transition: background .38s var(--ease), border-color .38s var(--ease),
              color .38s var(--ease), transform .38s var(--ease);
}
.tcard__arw svg { width: 17px; height: 17px; }
.tcard:hover .tcard__arw,
.tcard:focus-within .tcard__arw {
  background: #D61113;
  border-color: #D61113;
  color: #fff;
  transform: translateX(4px);
}

/* ------------------------------ 9c. Service band (photograph + white panel)

   Full-bleed: workshop photograph running to the left edge of the viewport,
   white copy panel on the right holding the full service list.              */

.svcband {
  display: grid;
  grid-template-columns: 1fr 0.96fr;   /* photograph ~51% of the viewport */
  align-items: stretch;
  background: #fff;
}
/* the copy column is narrower now the photograph takes half the width — trim
   the display size so "Specialist Knowledge." still sets on one line */
.svcband .h2 { font-size: clamp(1.6rem, 2.3vw, 2.3rem); }

.svcband__media {
  position: relative;
  min-height: 520px;
  overflow: hidden;
  background: var(--surface-2);
}
.svcband__media img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
}
/* red tick on the seam side */
.svcband__media::after {
  content: '';
  position: absolute; right: 0; bottom: 0; z-index: 2;
  width: 5px; height: 76px; background: var(--red);
}

.svcband__copy {
  padding-block: var(--section-y);
  padding-left: clamp(28px, 3.2vw, 56px);
  /* Right inset tracks the container so the panel lines up with the page, but
     is capped: past ~1600px the untracked value would eat the copy column and
     force the heading to wrap. --maxw is the content width and the gutters sit
     outside it, so the container's content edge is exactly (100vw - maxw) / 2. */
  padding-right: clamp(var(--gutter), calc((100vw - var(--maxw)) / 2), 170px);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* Two-column bullet list of every service.

   CSS multi-column, not grid: with a grid the columns share row heights, so a
   label that wraps to two lines opens a matching gap in the opposite column.
   Multi-column lets each column size independently, and still flows the first
   seven services (everyday work) into the left column and the specialist work
   into the right — which also keeps the single-column mobile order sensible. */
.svclist {
  columns: 2;
  column-gap: clamp(20px, 3vw, 46px);
  margin-top: clamp(24px, 3vw, 34px);
}
.svclist li {
  break-inside: avoid;
  display: grid;
  grid-template-columns: 18px 1fr;
  gap: 12px;
  align-items: start;
  margin-bottom: 13px;
  /* plain text, not links — these name the services, the button below goes
     to the Services page */
  color: var(--ink-2);
  font-size: 1rem;
  line-height: 1.5;
}
.svclist li:last-child { margin-bottom: 0; }
/* chevron sized to match the cap-height of the label beside it */
.svclist .chev {
  color: var(--red);
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 900;
  font-size: 1.25rem;
  line-height: 1.2;
}

/* ------------------------------------------- 9b. Service strip (grey band) */

/* Compact quick-links bar directly under the hero. Deliberately does NOT take
   the 100/75/50 section rhythm — it is a strip, not a content section. */
.svcstrip {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  padding-block: clamp(24px, 3vw, 40px);
}
.svcstrip__grid { display: grid; grid-template-columns: repeat(4, 1fr); }

/* ⚠️ Centred in its cell, at every width. It used to be left-aligned, which
   left roughly 160px of dead space trailing each item in a 330px column and
   read as a row of content pushed to one side. The dividers mark the cells;
   the content sits in the middle of them. */
.svcstrip__item {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 4px clamp(18px, 2.4vw, 30px);
  border-left: 1px solid var(--line);
  transition: transform .35s var(--ease);
}
/* ⚠️ `> li:first-child`, NOT `.svcstrip__item:first-child`.

   The markup is `<li><a class="svcstrip__item">`, so every anchor is the only
   child of its own `<li>` and `:first-child` on the anchor matched ALL FOUR.
   The effect was invisible-but-wrong twice over: every divider was removed, so
   the desktop strip never actually showed the dividers it was designed with,
   and every item lost its left padding while keeping its right — which sat the
   contents 8px left of centre in each cell. That is what made the strip look
   shoved to one side once it went to two columns.

   ⚠️ It drops the divider only. The old `padding-left: 0` that went with it is
   gone: with the contents centred, zeroing one side's padding pulls the first
   item off-centre by half the other side — which is the same bug in miniature. */
.svcstrip__grid > li:first-child .svcstrip__item { border-left: 0; }
.svcstrip__item:hover { transform: translateY(-3px); }

.svcstrip__item svg {
  width: 36px; height: 36px;
  color: var(--red);
  flex: none;
  transition: transform .4s var(--ease);
}
.svcstrip__item:hover svg { transform: translateY(-3px); }

/* ⚠️ The label carries a red underline so these read as links.

   All four items are anchors — Servicing, Performance, Track Day and TEXA
   Diagnostics each go somewhere — but on a light strip with no colour change,
   no underline and no arrow, nothing said so and they were being read as a
   decorative "what we do" list. The rule is at 35% by default and goes solid
   on hover/focus, so the affordance is there without four hard red bars
   shouting across the strip.

   `inline-block` is what makes it work: the label contains a `<br>`, and on a
   plain inline span the underline would attach to the first line box only. */
.svcstrip__item span {
  display: inline-block;
  position: relative;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 770;
  text-transform: uppercase;
  font-size: .86rem;
  letter-spacing: .05em;
  line-height: 1.25;
  color: var(--ink);
}
.svcstrip__item span::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: -5px;
  height: 2px;
  background: var(--red);
  opacity: .35;
  transition: opacity .3s var(--ease);
}
.svcstrip__item:hover span::after,
.svcstrip__item:focus-visible span::after { opacity: 1; }

/* --------------------------------------------------------- 10. Split band */

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}
.split--reverse .split__media { order: -1; }

/* ⚠️ EVERY `.split` ON THIS SITE IS 1fr / 1fr. DO NOT ADD A WIDTH MODIFIER.

   There used to be four — `--wide-media` (1fr 1.2fr), `--narrow-media`
   (1.15fr 1fr), `--media-left` (1.35fr 1fr) and `--compact` (1fr 1.5fr). Each
   was a reasonable call in isolation and together they wrecked the page.

   A `.split` alternates: photo right, photo left, photo right. With an even
   split the column boundary IS the page centre, so every photograph's inner
   edge lands on the same vertical line no matter which side it is on. Tilt the
   ratio and that line moves — and it moves in OPPOSITE directions on alternate
   sections, because the wide track swaps sides with the photo. Measured at
   1440px before this rule, against a half-gap of 36px:

   | variant | inner edge vs. page centre |
   |---|---|
   | `.split` (even) | +36 — correct, the photo stops at the gap |
   | `--narrow-media` | +50 to +110 — photo short of the line |
   | `--media-left` | +27 — photo 9px past the centre |
   | `--wide-media` | +9 — photo 27px past the centre |
   | `--compact` | **−89 / +89** — photo 89px past the centre, alternating |

   Hold a ruler down the page and the photo edges zig-zag across it. That is
   what the client saw, and it is not fixable by tuning the numbers: any ratio
   other than 1:1 puts the boundary off centre by construction.

   If a photograph needs to read larger, make the whole section wider or use a
   full-bleed band — do not widen one column of a `.split`. */

.split__copy .lede { margin-top: 20px; }

.split__media {
  position: relative;
  border-radius: 3px;
  overflow: hidden;
  box-shadow: var(--shadow-md);
}
/* No forced ratio and no `cover`: the whole photograph is shown. A fixed 4/3
   box was slicing the edges off portrait and square-ish shots — the tyre stack
   lost its top and bottom, the stripped Tiger lost its nose. The images are
   cropped once, when they are generated, and not again by the layout. */
.split__media img {
  display: block;
  width: 100%; height: auto;
  transition: transform 1.1s var(--ease);
}
.split__media:hover img { transform: scale(1.04); }

/* Compact media — used by the four service category pages.

   Those pages run one `.split` per service, and every section is meant to read
   at the same medium size. That is done in the FILES, not here: each of the
   fourteen photographs has its own `images/<name>-split.jpg` cut to exactly
   1100 × 825 (4:3), so every media column fills edge to edge at an identical
   shape. See "Photographs are not cropped by the layout".

   ⚠️ The originals are a mix of landscape, square and portrait. Before they
   were cut to one ratio, a 2:3 portrait rendered over 1000px tall at full
   column width — taller than the viewport, so the whole photograph could not be
   seen at once and read as though it had been cut in half; and capping the
   height alone left the narrow shots floating at 347px wide beside a full-width
   text column, so the sections no longer matched each other.

   ⚠️ This variant briefly carried `1fr 1.5fr` to make the photographs larger.
   It was reverted — see the width-modifier warning above for why no `.split`
   may be anything but 1fr / 1fr. It now changes **no** column widths; all it
   does is guarantee the photo fills its column exactly.

   ⚠️ The old `max-height: min(560px, 76vh)` safety net is **gone**, and so is
   `justify-self: center`. Both fought the alignment: on a short window the cap
   bound, the photo shrank a few pixels, and `center` then inset it from the
   column edge — so a section here and there stopped lining up with the rest.
   The photo now always fills its column exactly, and its height is always
   three-quarters of that width. That is safe **because every one of the
   fourteen files is cut to 4:3 at generation** (see "Photographs are not cropped
   by the layout"). Drop in a portrait file and it will render tall — recut it
   to 1100 × 825 instead of capping it here. */
.split--compact .split__media {
  justify-self: stretch;
  max-width: 100%;
}
.split--compact .split__media img {
  width: 100%;
  height: auto;
}

/* Red corner tick — small motorsport detail on media frames */
.split__media::after {
  content: '';
  position: absolute; left: 0; bottom: 0;
  width: 64px; height: 5px; background: var(--red);
}

/* Panel variant: copy on a raised card */
.panel {
  background: #fff;
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  padding: clamp(30px, 4vw, 56px);
  border-radius: 3px;
}
.section--surface .panel { background: #fff; }

/* ------------------------------------------------------------- 11. Cards */

.card {
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 3px;
  overflow: hidden;
  height: 100%;
  box-shadow: var(--shadow-sm);
  transition: border-color .4s var(--ease), transform .4s var(--ease),
              box-shadow .4s var(--ease);
}
.card:hover {
  border-color: rgba(214, 17, 19, .45);
  box-shadow: var(--shadow-lg);
  transform: translateY(-5px);
}

/* A row of cards has to keep one tile height, so the box stays 4/3, and the
   photograph fills it edge to edge.

   ⚠️ Every image in a card is a dedicated `*-card.jpg` cut to exactly 700×525.
   The originals are a mix of landscape, square and portrait, so they are
   cropped ONCE at generation (scratchpad `cards43.ps1`, anchors chosen per
   photo) rather than by this rule — which is the site-wide rule for every
   photograph here. Because the file is already 4/3, `cover` removes nothing;
   it is the guard that stops a wrongly-sized drop-in from pillarboxing.
   This was `contain` before, and the grey bars either side of the portrait
   and square shots were what the client asked to have removed.

   Do NOT point a card at a plain `-sm.jpg`: those keep their natural aspect
   because the gallery and the split sections need them uncropped, and `cover`
   would then crop them a second time. Cut a new `-card.jpg` instead. */
.card__media {
  position: relative;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--surface-2);
}
.card__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 1s var(--ease);
}
.card:hover .card__media img { transform: scale(1.04); }

.card__body { padding: 24px 24px 28px; display: flex; flex-direction: column; flex: 1; }

/* A card is a plain container, not a wrapping <a> — an anchor around the whole
   card makes any drag start a link-drag, so the copy cannot be selected.
   The title holds the real link; JS adds whole-card click in main.js. */
.card--linked { cursor: pointer; }

.card__title {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 800;
  text-transform: uppercase;
  font-size: 1.02rem;
  letter-spacing: .01em;
  line-height: 1.15;
  color: var(--ink);
  margin-bottom: 10px;
}
.card__title a { color: inherit; transition: color .3s var(--ease); }
.card:hover .card__title a,
.card__title a:hover { color: var(--red); }
.card__text { font-size: .9rem; color: var(--muted); line-height: 1.55; }
/* auto pushes the link to the card base so it aligns across a row of cards
   whose descriptions run to different lengths */
.card__body .link-arrow { margin-top: auto; padding-top: 18px; }

/* The blue .card__num index badge was removed at the client's request — the
   services are a set, not a numbered sequence. Nothing uses it now. */

/* ------------------------------------------ 11b. Brand bar (marquee strip)

   Compact light strip of brand names scrolling right-to-left on a duplicated
   track. It sits between the media band and the gallery preview.            */

/* ⚠️ White, not the off-white it used to be. Six of the twenty logos are raster
   files that ship with a solid white background baked in (Datatool's GIF, the
   Power Commander and Bazzaz JPEGs, Dunlop, Michelin, Nitron) — on a tinted
   band each of those painted a visible white rectangle around itself. Knocking
   the white out of a JPEG leaves halos, so the band matches the logos instead.
   The hairline top and bottom rule is what separates the strip now. */
.brandbar {
  background: #fff;
  border-block: 1px solid var(--line);
  padding-block: clamp(18px, 2.4vw, 30px);
  overflow: hidden;
}
.brandbar__inner { display: flex; align-items: center; }

.marquee {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  /* fade the leading and trailing edge so items enter and leave softly */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 56px, #000 calc(100% - 56px), transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 56px, #000 calc(100% - 56px), transparent 100%);
}
.marquee__track {
  display: flex;
  align-items: center;
  gap: clamp(30px, 4vw, 66px);
  width: max-content;
  animation: marqueeSlide 42s linear infinite;
}
.marquee:hover .marquee__track,
.marquee:focus-within .marquee__track { animation-play-state: paused; }

@keyframes marqueeSlide {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }   /* track holds the set twice */
}

/* Each item is the manufacturer's or supplier's own logo, not a set word.

   ⚠️ The logos are NOT given a fixed box. Twenty real trademarks span aspect
   ratios from 8.7:1 (the Bazzaz wordmark) to 0.94:1 (the Ducati shield), so a
   fixed box would leave most of them floating in dead space and the gaps in
   the track would stop reading as even. Instead every logo is capped on BOTH
   axes and takes whatever size fits inside — wide wordmarks hit the width cap,
   compact marks hit the height cap, and the flex gap does the spacing.

   The caps also keep every file at or below its natural pixel size, so nothing
   is upscaled: the smallest raster here is 144px wide and the width cap tops
   out at 150px. */
.marquee__item {
  display: grid;
  place-items: center;
  flex: none;
}
.marquee__item img {
  display: block;
  width: auto;
  height: auto;
  max-width: clamp(96px, 10vw, 150px);
  max-height: clamp(26px, 2.8vw, 40px);
  object-fit: contain;
}

@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
  .marquee { -webkit-mask-image: none; mask-image: none; overflow-x: auto; }
}

/* ------------------------------------------------------------- 12. Stats */

.stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 3px;
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.stat {
  padding: 38px 28px;
  text-align: center;
  border-left: 1px solid var(--line);
  position: relative;
}
.stat:first-child { border-left: 0; }

/* Red / blue alternating rule above each figure */
.stat::before {
  content: '';
  position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 44px; height: 4px;
}
.stat:nth-child(odd)::before  { background: var(--red); }
.stat:nth-child(even)::before { background: var(--blue); }

.stat__num {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 880;
  text-transform: uppercase;
  font-size: clamp(1.7rem, 3vw, 2.4rem);
  line-height: 1;
  letter-spacing: -.02em;
  margin-bottom: 10px;
}
.stat:nth-child(odd) .stat__num  { color: var(--red); }
.stat:nth-child(even) .stat__num { color: var(--blue); }

.stat__label {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 700;
  text-transform: uppercase;
  font-size: .78rem; letter-spacing: .12em;
  color: var(--ink);
  margin-bottom: 4px;
}
.stat__sub { font-size: .82rem; color: var(--muted); line-height: 1.45; }

.stats-caption {
  text-align: center;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 700;
  text-transform: uppercase;
  letter-spacing: .24em;
  font-size: .78rem;
  color: var(--muted);
  margin-bottom: 34px;
}

/* ------------------------------------------------------------ 13. Brands */

.brands { background: var(--surface); }

.brands__grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: 3px;
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.brands__item {
  background: #fff;
  display: grid;
  place-items: center;
  padding: 28px 16px;
  min-height: 104px;
  text-align: center;
  transition: background .35s var(--ease);
}
.brands__item:hover { background: var(--blue-soft); }
.brands__name {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 92, 'wght' 800;
  text-transform: uppercase;
  font-size: clamp(.86rem, 1.3vw, 1.05rem);
  letter-spacing: .04em;
  line-height: 1.1;
  color: var(--ink);
  transition: color .35s var(--ease);
}
.brands__item:hover .brands__name { color: var(--blue); }

.brands__note {
  margin-top: 26px;
  font-size: .78rem;
  color: var(--muted);
  text-align: center;
  max-width: 78ch;
  margin-inline: auto;
  line-height: 1.6;
}

/* Navy variant used on the Services page */
.brands--dark { background: var(--navy); }
.brands--dark .brands__grid { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.14); box-shadow: none; }
.brands--dark .brands__item { background: var(--navy); }
.brands--dark .brands__item:hover { background: var(--navy-2); }
.brands--dark .brands__name { color: rgba(255,255,255,.9); }
.brands--dark .brands__item:hover .brands__name { color: var(--blue-on-dark); }
.brands--dark .stats-caption { color: rgba(255,255,255,.7); }
.brands--dark .brands__note { color: rgba(255,255,255,.6); }

/* -------------------------------------------------------- 14. Media band */

/* Full-bleed band: runs edge to edge, so no rounding or shadow.
   The height scales with the viewport so the photograph is not sliced to a
   thin strip on wide screens. */
.mediaband {
  position: relative;
  min-height: clamp(420px, 38vw, 620px);
  display: grid;
  align-items: center;
  overflow: hidden;
}
.mediaband__bg { position: absolute; inset: 0; }
.mediaband__bg img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* bias upward — dead centre cuts the rider's head off */
  object-position: center 34%;
}
/* Two stacked gradients: one weighted to the left where the heading sits, one
   running down the band to ground the four pillars across its full width.
   Both are needed — the copy now spans the whole band, not just the left. */
.mediaband__bg::after {
  content: '';
  position: absolute; inset: 0;
  background:
    linear-gradient(90deg, rgba(8,17,33,.86) 0%, rgba(10,22,42,.70) 44%, rgba(8,17,33,.52) 100%),
    linear-gradient(180deg, rgba(8,17,33,.16) 0%, rgba(8,17,33,.04) 34%, rgba(8,17,33,.44) 100%);
}
.mediaband__inner {
  position: relative; z-index: 2;
  /* horizontal inset comes from .container; vertical follows the section rhythm */
  padding-block: var(--section-y);
  width: 100%;
}
.mediaband__inner .lede { color: rgba(255,255,255,.86); }

/* Copy block: eyebrow, heading, one paragraph. Held to a measure so it stays a
   column of text over the photograph rather than a full-width band of it. */
/* 720px, not 640: at 640 "Specialist Knowledge." broke over two lines and the
   heading read as three lines instead of two */
.mediaband__copy { max-width: 720px; }
.mediaband__copy .lede { max-width: 46ch; margin-top: 20px; }

/* ------------------------------------------------ 14b. Pillars (why us)

   Four numbered credentials sitting under the media band heading: an outlined
   index numeral, a red ring icon, a title with a red rule, and one line of
   copy. Divided by hairlines rather than boxed.                              */

.pillars {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  margin-top: clamp(40px, 4.8vw, 68px);
}

/* Two-column grid: the numeral sits in column 1, everything else in column 2.
   That puts the icon to the *right* of the numeral rather than over it, and
   makes the title and description start exactly under the icon — the alignment
   falls out of the grid instead of being chased with matched paddings. */
.pillar {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: clamp(10px, 1vw, 16px);
  align-content: start;
  padding: 6px clamp(18px, 3vw, 52px) 0 clamp(16px, 2vw, 30px);
  border-left: 1px solid rgba(255, 255, 255, .18);
}
/* first numeral lines up with the heading above it */
.pillar:first-child { border-left: 0; padding-left: 0; }

/* Outlined numeral, deliberately low-contrast — it is a counter, not a fact to
   read. Centred against the icon ring beside it. */
.pillar__num {
  grid-column: 1; grid-row: 1;
  align-self: center;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 800;
  font-size: clamp(2.6rem, 3.4vw, 3.5rem);
  line-height: 1;
  letter-spacing: -.02em;
  color: transparent;
  -webkit-text-stroke: 1.5px rgba(255, 255, 255, .24);
  user-select: none;
  pointer-events: none;
}

.pillar__icon {
  grid-column: 2; grid-row: 1;
  justify-self: start;
  width: 54px; height: 54px;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 2px solid #D61113;
  background: rgba(9, 13, 20, .55);
  color: #fff;
  margin-bottom: 22px;
}
.pillar__icon svg { width: 24px; height: 24px; }

.pillar__title {
  grid-column: 2; grid-row: 2;
  display: flex;
  flex-direction: column;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 800;
  text-transform: uppercase;
  font-size: clamp(.95rem, 1.1vw, 1.06rem);
  line-height: 1.24;
  letter-spacing: .015em;
  color: #fff;
  /* Reserve two lines plus the rule. "Professional Diagnostics" wraps where the
     other three do not, and without this its red rule and description sat a
     line lower than the rest of the row. 2.48em = two lines at 1.24; 31px =
     the rule and its two margins. */
  min-height: calc(2.48em + 31px);
}
/* red rule between the title and its description, pinned to the base of that
   reserved box so all four rules land on the same line */
.pillar__title::after {
  content: '';
  align-self: flex-start;   /* a column flex item would otherwise stretch */
  width: 30px; height: 3px;
  background: #D61113;
  margin-top: auto;
  margin-bottom: 14px;
}

.pillar__text {
  grid-column: 2; grid-row: 3;
  font-size: .88rem;
  line-height: 1.6;
  color: rgba(255, 255, 255, .72);
}

.play {
  width: 84px; height: 84px; flex: none;
  border-radius: 50%;
  border: 2px solid rgba(255,255,255,.6);
  background: rgba(11,30,61,.35);
  display: grid; place-items: center;
  cursor: pointer;
  color: #fff;
  transition: background .4s var(--ease), border-color .4s var(--ease), transform .4s var(--ease);
  position: relative;
}
.play::before {
  content: '';
  position: absolute; inset: -14px;
  border: 1px solid rgba(255,255,255,.25);
  border-radius: 50%;
  animation: pulseRing 2.8s var(--ease) infinite;
}
@keyframes pulseRing {
  0%   { transform: scale(.9); opacity: .9; }
  70%  { transform: scale(1.25); opacity: 0; }
  100% { transform: scale(1.25); opacity: 0; }
}
.play:hover { background: #D61113; border-color: #D61113; transform: scale(1.06); }

/* ------------------------------------------ 14c. Workshop CTA (`.wcta`)

   Full-bleed dark band closing the Services page: a workshop photograph under
   a heavy scrim, copy and two actions on the left, and a row of four
   credentials along the base.                                               */

.wcta {
  position: relative;
  overflow: hidden;
  background: #0C0E11;
}
.wcta__bg { position: absolute; inset: 0; }
.wcta__bg img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 42%;
}
/* left-weighted so the copy has a ground, with the whole frame knocked back —
   this band carries more text than the other photographic bands */
.wcta__bg::after {
  content: '';
  position: absolute; inset: 0;
  background:
    linear-gradient(90deg, rgba(8,10,13,.95) 0%, rgba(8,10,13,.86) 42%, rgba(8,10,13,.62) 100%),
    linear-gradient(180deg, rgba(8,10,13,.30) 0%, rgba(8,10,13,.18) 40%, rgba(8,10,13,.72) 100%);
}

/* Deliberately shorter than a content section — this is a closing band, not a
   chapter, and at the full 100/75/50 rhythm it dominated the page. */
.wcta__inner {
  position: relative; z-index: 2;
  padding-block: clamp(44px, 4.6vw, 72px);
}
.wcta__copy { max-width: 620px; }
.wcta__copy .lede {
  color: rgba(255,255,255,.80);
  max-width: 50ch;
  margin-top: 16px;
  font-size: .96rem;
}
.wcta .h2 { color: #fff; font-size: clamp(1.6rem, 2.9vw, 2.4rem); }
.wcta .btn-row { margin-top: 26px; }
.wcta .eyebrow { color: var(--red-on-dark); }
.wcta .eyebrow--dash::before { background: var(--red); }

/* the call button carries an icon, so it needs to lay out as a row */
.wcta .btn--ghost { gap: 10px; }

/* The About page's approvals band uses the same divided row, so the rules are
   written once here rather than copied. Only the column count differs — three
   points there, four here — and that override lives with `.approvalband`. */
.wcta__points, .approvalband__points {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  margin-top: clamp(28px, 3.2vw, 44px);
  border-top: 1px solid rgba(255,255,255,.16);
  padding-top: clamp(20px, 2.2vw, 28px);
}
.wcta__points li, .approvalband__points li {
  display: flex; align-items: center; gap: 12px;
  padding-inline: clamp(12px, 1.6vw, 24px);
  border-left: 1px solid rgba(255,255,255,.16);
}
.wcta__points li:first-child,
.approvalband__points li:first-child { border-left: 0; padding-left: 0; }
.wcta__points svg,
.approvalband__points svg { width: 23px; height: 23px; color: var(--red-on-dark); flex: none; }
.wcta__points span, .approvalband__points span {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 780;
  text-transform: uppercase;
  font-size: .76rem;
  letter-spacing: .06em;
  line-height: 1.28;
  color: #fff;
}
/* The approvals band runs three points. This has to sit after the shared rule
   above, not up in §14b with the rest of `.approvalband` — equal specificity,
   so whichever comes last wins. */
.approvalband__points { grid-template-columns: repeat(3, 1fr); }

/* --------------------------------------------- 14d. Icon cards (`.icard`)

   Icon-led service cards for sections that list what is covered without
   needing a photograph per item.                                            */

.icard {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: clamp(26px, 2.6vw, 34px);
  transition: border-color .4s var(--ease), transform .4s var(--ease),
              box-shadow .4s var(--ease);
}
.icard:hover {
  border-color: rgba(214, 17, 19, .38);
  box-shadow: var(--shadow-md);
  transform: translateY(-4px);
}
.icard__icon {
  width: 52px; height: 52px;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 2px solid var(--red);
  color: var(--red);
  margin-bottom: 20px;
  transition: background .4s var(--ease), color .4s var(--ease);
}
.icard__icon svg { width: 23px; height: 23px; }
.icard:hover .icard__icon { background: var(--red); color: #fff; }

.icard__title {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 800;
  text-transform: uppercase;
  font-size: 1rem;
  letter-spacing: .01em;
  line-height: 1.22;
  color: var(--ink);
  margin-bottom: 12px;
}
.icard__text { font-size: .92rem; line-height: 1.6; color: var(--muted); }

/* ---------------------------------------------------------- 15. CTA bars */

.ctabar {
  background: var(--red);
  color: #fff;
  border-radius: 3px;
  padding: clamp(28px, 4vw, 46px) clamp(28px, 4vw, 56px);
  display: flex; align-items: center; justify-content: space-between;
  gap: 30px; flex-wrap: wrap;
  box-shadow: var(--shadow-md);
}
.ctabar { background: #D61113; }
.ctabar__title {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 870;
  text-transform: uppercase;
  font-size: clamp(1.35rem, 2.6vw, 2rem);
  line-height: 1.05;
  letter-spacing: -.015em;
  color: #fff;
}
.ctabar__sub { color: rgba(255,255,255,.88); margin-top: 8px; font-size: .95rem; }

.ctabar .btn:not(.btn--ghost) { --btn-bg: #fff; --btn-fg: #0D1728; --btn-bd: #fff; }
.ctabar .btn:not(.btn--ghost)::before { background: var(--navy); }
.ctabar .btn:not(.btn--ghost):hover { color: #fff; border-color: var(--navy); }

/* Navy secondary bar. Scoped with :not(.btn--ghost) so the outlined secondary
   button keeps its white border instead of being repainted solid red. */
.ctabar--dark { background: var(--navy); }
.ctabar--dark .ctabar__sub { color: rgba(255,255,255,.72); }
.ctabar--dark .btn:not(.btn--ghost) { --btn-bg: #D61113; --btn-fg: #fff; --btn-bd: #D61113; }
.ctabar--dark .btn:not(.btn--ghost)::before { background: var(--red-deep); }
.ctabar--dark .btn:not(.btn--ghost):hover { color: #fff; border-color: var(--red-deep); }

/* ------------------------------------- 15b. Closing CTA band (photo back)

   Full-bleed strip before the footer: photograph behind, scrim over it, copy
   and two actions on top. Deliberately shorter than a content section.      */

.ctaband {
  position: relative;
  overflow: hidden;
  background: var(--navy);
  color: #fff;
  padding-block: clamp(44px, 5vw, 72px);

  --ink:   #FFFFFF;
  --ink-2: rgba(255, 255, 255, .84);
  --muted: rgba(255, 255, 255, .7);
  --red:   var(--red-on-dark);
}

.ctaband__bg { position: absolute; inset: 0; z-index: 0; }
.ctaband__bg img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 55%;
}
.ctaband__bg::after {
  content: '';
  position: absolute; inset: 0;
  background:
    linear-gradient(90deg, rgba(8,17,33,.94) 0%, rgba(8,17,33,.84) 38%, rgba(8,17,33,.46) 68%, rgba(8,17,33,.66) 100%),
    linear-gradient(180deg, rgba(8,17,33,.45) 0%, rgba(8,17,33,.18) 45%, rgba(8,17,33,.62) 100%);
}

.ctaband__inner { position: relative; z-index: 2; }
.ctaband__title {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 870;
  text-transform: uppercase;
  font-size: clamp(1.5rem, 2.9vw, 2.3rem);
  line-height: 1.05;
  letter-spacing: -.015em;
  color: #fff;
}
.ctaband__sub {
  color: rgba(255, 255, 255, .84);
  margin-top: 12px;
  max-width: 60ch;
  font-size: .96rem;
}

/* --------------------------------------------------------------- 16. Tabs */

/* Segmented pills on an off-white track, rather than four bare words over a
   hairline — the old version read as body text and gave no sense that the
   panel below changes when you press one. */
.tabs {
  display: inline-flex;
  gap: 6px;
  padding: 6px;
  background: #FAF9F6;
  border: 1px solid var(--line);
  border-radius: 999px;
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }

.tab {
  appearance: none;
  background: none;
  border: 0;
  border-radius: 999px;
  padding: 13px 26px;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 750;
  text-transform: uppercase;
  font-size: .8rem;
  letter-spacing: .08em;
  line-height: 1;
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
  transition: color .3s var(--ease), background .3s var(--ease),
              box-shadow .3s var(--ease);
}
.tab:hover { color: var(--ink); background: rgba(11, 30, 61, .05); }
.tab[aria-selected="true"] {
  color: #fff;
  background: var(--red);
  box-shadow: 0 6px 16px rgba(214, 17, 19, .28);
}
.tab[aria-selected="true"]:hover { color: #fff; background: var(--red); }

.tabpanel { padding-top: 48px; }
.tabpanel[hidden] { display: none; }

/* --------------------------------------------------------- 17. Check list */

/* Each point is a panel with a red rule down its edge and a red disc marker,
   rather than a run of hairline-separated rows — at four or six items the old
   version read as an afterthought next to the photograph beside it. */
.checklist { display: grid; gap: 12px; }

/* About page credentials — photograph left, the seven points right.

   ⚠️ This list used to run the full width of the section in two columns. It was
   correct but inert: a band of text under a band of text, with the section's
   only photograph already spent above it. Paired with a picture it reads as
   evidence rather than a list, so the two-column variant is gone and the block
   is a `.split` whose copy column happens to hold a list instead of prose.
   The photograph is first in the DOM, so it takes the left column and the
   reading order matches the layout — no modifier, and none is allowed.

   ⚠️ `.creds` carries **no top margin**. It used to sit inside the Who We Are
   section and needed `margin-top: clamp(56px, 6vw, 92px)` to separate itself
   from the split above. It is now its own `<section class="section">` — the
   gallery band was inserted between the two — so the section's own 100/75/50
   padding does that job. Putting the margin back would stack on top of the
   padding and open a gap half as deep again as every other section break. */

/* Heading for that list. Not an `.h2` — the section already has one, and a
   second display-size heading would read as a new section starting.
   ⚠️ No top margin: the block's spacing lives on `.creds` above. Putting it
   here instead would push the heading down inside its own grid cell while the
   photograph beside it stayed put, and the two columns would stop aligning. */
.creds__title {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 780;
  text-transform: uppercase;
  font-size: .92rem;
  letter-spacing: .1em;
  color: var(--ink);
  margin: 0 0 22px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
}
.checklist li {
  display: grid;
  grid-template-columns: 34px 1fr;
  gap: 16px;
  align-items: start;
  padding: 18px 22px;
  background: #FAF9F6;
  border: 1px solid var(--line);
  border-left: 3px solid var(--red);
  border-radius: 4px;
  transition: background .35s var(--ease), box-shadow .35s var(--ease),
              transform .35s var(--ease);
}
.checklist li:hover {
  background: #fff;
  box-shadow: var(--shadow-sm);
  transform: translateX(3px);
}
/* on an off-white section the panels invert so they still separate */
.section--offwhite .checklist li,
.section--surface .checklist li { background: #fff; }
.section--offwhite .checklist li:hover,
.section--surface .checklist li:hover { background: #FAF9F6; }

/* Marker is the red chevron alone — no disc behind it. A filled circle at this
   size fought the red rule on the panel edge and made every row shout. */
.checklist .chev {
  width: 34px;
  display: grid; place-items: center;
  color: var(--red);
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 900;
  font-size: 1.15rem;
  line-height: 1.35;
}
.checklist strong {
  display: block;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 780;
  text-transform: uppercase;
  font-size: .95rem;
  letter-spacing: .01em;
  color: var(--ink);
  margin-bottom: 3px;
}
.checklist p { font-size: .89rem; color: var(--muted); line-height: 1.55; }

/* Icon list — the blue technical set */
/* Two-up tiles rather than a stack of thin rows. Four short labels in a single
   column read as an afterthought beside a photograph; paired up with a ringed
   red icon they read as equipment the workshop actually has. */
.iconlist {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
}
.iconlist li {
  display: flex; flex-direction: column; align-items: flex-start; gap: 14px;
  padding: 22px 20px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 4px;
  transition: border-color .35s var(--ease), transform .35s var(--ease),
              box-shadow .35s var(--ease);
}
.iconlist li:hover {
  border-color: rgba(214, 17, 19, .38);
  box-shadow: var(--shadow-md);
  transform: translateY(-3px);
}
.iconlist .ic {
  width: 44px; height: 44px; flex: none;
  display: grid; place-items: center;
  color: var(--red);
  border: 2px solid var(--red);
  border-radius: 50%;
  background: transparent;
  transition: background .35s var(--ease), color .35s var(--ease);
}
.iconlist li:hover .ic { background: var(--red); color: #fff; }
.iconlist .ic svg { width: 20px; height: 20px; }
.iconlist span {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 780;
  text-transform: uppercase;
  font-size: .88rem; letter-spacing: .04em;
  line-height: 1.25;
  color: var(--ink);
}

/* The `.iconstats` icon+label row was removed from Track Day at the client's
   request and used nowhere else, so its rules went with it. `.icard` (§14d) is
   the replacement where a section needs icon-led items. */

/* --------------------------------------------------------- 18. Quote box */

.quote {
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 4px solid var(--red);
  padding: clamp(28px, 4vw, 44px);
  border-radius: 3px;
}
.quote p {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 620;
  text-transform: none;
  font-size: clamp(1.15rem, 2vw, 1.5rem);
  line-height: 1.3;
  letter-spacing: -.01em;
  color: var(--ink);
}
.quote cite {
  display: block; margin-top: 20px; font-style: normal;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 700;
  text-transform: uppercase; font-size: .78rem; letter-spacing: .16em;
  color: var(--red);
}

/* --------------------------------------------- 18b. Gallery preview (home)

   Three tiles with a permanently visible caption, and a link through to the
   full gallery. Captions stay on rather than appearing on hover, because this
   is a teaser — the visitor should read what they are looking at.           */

.gpeek__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(14px, 1.8vw, 24px);
}

.gpeek__item {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: 3px;
  aspect-ratio: 4 / 3;
  background: var(--surface-2);
  box-shadow: var(--shadow-sm);
  transition: box-shadow .4s var(--ease), transform .4s var(--ease);
}
.gpeek__item:hover { box-shadow: var(--shadow-lg); transform: translateY(-4px); }

.gpeek__item img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 1s var(--ease);
}
.gpeek__item:hover img { transform: scale(1.06); }

.gpeek__item::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(11,30,61,0) 45%, rgba(8,20,41,.86) 100%);
}


/* The "View More" link lives in the section head (.section-head--split), not
   under the tiles — there is deliberately no footer row here. */

/* ------------------------------------------- 18b. Reviews (moving cards)

   Off-white band holding genuine Google reviews on a right-to-left marquee.
   Same duplicated-track technique as .brandbar, but the items are cards, so
   the track is full-bleed and the section clips it.                         */

.reviews {
  background: #FAF9F6;
  padding-block: var(--section-y);
  overflow: hidden;
}
.reviews .section-head { margin-bottom: clamp(34px, 4vw, 50px); }

.rmarquee {
  /* soften both ends so cards enter and leave rather than popping */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 90px, #000 calc(100% - 90px), transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 90px, #000 calc(100% - 90px), transparent 100%);
}
.rmarquee__track {
  display: flex;
  align-items: stretch;      /* every card takes the height of the tallest */
  gap: clamp(16px, 1.6vw, 26px);
  width: max-content;
  /* the cards carry no shadow, so the track needs no clearance for one */
  padding-block: 2px;

  /* ⚠️ One continuous right-to-left glide — `linear`, `infinite`, no easing and
     no JavaScript. `marqueeSlide` runs 0 → -50%, and the markup holds the
     eleven reviews TWICE (the second set `aria-hidden`), so at -50% the track
     is pixel-identical to its start position: the loop has no seam, no jump,
     no gap and no reset.

     This replaced a JS stepper that held four seconds and advanced one card at
     a time. Two rules keep it seamless:
       1. the two halves must stay identical — add a review and add it twice;
       2. nothing may write an inline `transform` to this element, because an
          inline style outranks the animation and freezes the band dead. */
  animation: marqueeSlide 88s linear infinite;
  will-change: transform;
}
.rmarquee:hover .rmarquee__track,
.rmarquee:focus-within .rmarquee__track { animation-play-state: paused; }

/* Flat white panels with a hairline edge — deliberately no drop shadow. On an
   off-white ground the shadows read as smudges between the cards rather than
   as lift, so the border alone carries the edge. */
.rcard {
  flex: none;
  width: clamp(290px, 25vw, 380px);
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 28px 28px 26px;
  transition: border-color .4s var(--ease), background .4s var(--ease);
}
.rcard:hover { border-color: rgba(214, 17, 19, .38); }

.rcard__stars { display: flex; gap: 3px; margin-bottom: 16px; }
.star {
  width: 17px; height: 17px;
  flex: none;
  /* amber reads as a rating; the brand red would read as a warning */
  fill: #F0A417;
}

/* auto pushes the attribution to the card base, so names line up across a row
   of reviews that run to very different lengths */
.rcard__text {
  font-size: .92rem;
  line-height: 1.62;
  color: var(--ink-2);
  flex: 1 1 auto;
  margin-bottom: 20px;
}

.rcard__name {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 780;
  text-transform: uppercase;
  font-size: .84rem;
  letter-spacing: .04em;
  color: var(--ink);
}
.rcard__meta {
  font-size: .76rem;
  color: var(--muted);
  margin-top: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .rmarquee__track { animation: none; }
  .rmarquee {
    -webkit-mask-image: none; mask-image: none;
    overflow-x: auto;
    padding-inline: var(--gutter);
  }
}

/* ------------------------------------------------------------ 19. Gallery */

.filters { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 40px; }
.filter {
  appearance: none; cursor: pointer;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 10px 22px;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 700;
  text-transform: uppercase;
  font-size: .76rem; letter-spacing: .1em;
  color: var(--ink-2);
  transition: background .3s var(--ease), color .3s var(--ease),
              border-color .3s var(--ease), box-shadow .3s var(--ease);
}
/* red, not blue — blue was a leftover from the secondary palette and read as a
   link colour against the red active pill beside it */
.filter:hover { color: var(--red); border-color: var(--red); background: var(--red-soft); }
.filter[aria-pressed="true"] {
  background: var(--red); border-color: var(--red); color: #fff;
  box-shadow: var(--shadow-sm);
}

/* ⚠️ A uniform grid, NOT masonry — and the history matters, because this has
   now been both.

   It began as a fixed 4/3 grid, was changed to CSS multi-column so each
   photograph could keep its own proportions, and is a grid again at the
   client's request. Multi-column balances by column height, and with
   `break-inside: avoid` on tiles of wildly different heights that produced
   ragged columns: at 1440 the first column ran three tall frames deep while
   the other three stopped level with each other, leaving a large blank area
   across the bottom right. That is what the client reported as "images
   appearing only on one side".

   The trade is back to cropping: portrait frames lose their top and bottom to
   `object-fit: cover`. The client asked for equal widths, consistent gaps and
   "proper image cropping", so that is the accepted cost. The lightbox still
   opens the full uncropped frame from `data-full`, so nothing is actually
   lost — do not "fix" the cropping by going back to columns without reading
   the paragraph above. */
.gallery {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
}
.gallery__item {
  position: relative;
  overflow: hidden;
  border-radius: 3px;
  background: var(--surface-2);
  cursor: pointer;
  border: 0; padding: 0;
  display: block;
  width: 100%;
  box-shadow: var(--shadow-sm);
  transition: box-shadow .4s var(--ease), transform .4s var(--ease);
}
.gallery__item:hover { box-shadow: var(--shadow-lg); transform: translateY(-3px); }

/* Every tile is the same 4/3 box so the rows line up and the gaps stay even.
   `object-fit: cover` is also what keeps these out of the sweep's distortion
   check, which ignores images that declare cover or contain. */
.gallery__item img {
  display: block;
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.gallery__item::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(11,30,61,0) 50%, rgba(8,20,41,.82) 100%);
  opacity: 0; transition: opacity .4s var(--ease);
}
.gallery__item:hover::after { opacity: 1; }


.gallery__item.is-hidden { display: none; }

.gallery-more { display: flex; justify-content: center; margin-top: 44px; }

/* Lightbox */
.lightbox {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(6, 15, 31, .95);
  display: grid; place-items: center;
  padding: clamp(16px, 5vw, 60px);
  opacity: 0; visibility: hidden;
  transition: opacity .35s var(--ease), visibility .35s var(--ease);
}
.lightbox.is-open { opacity: 1; visibility: visible; }
.lightbox img {
  max-width: 100%; max-height: 82vh; object-fit: contain;
  border-radius: 3px;
  transform: scale(.97);
  transition: transform .4s var(--ease);
}
.lightbox.is-open img { transform: none; }
.lightbox__close, .lightbox__nav {
  position: absolute;
  background: rgba(255,255,255,.10);
  border: 1px solid rgba(255,255,255,.28);
  color: #fff;
  width: 48px; height: 48px;
  border-radius: 3px;
  cursor: pointer;
  display: grid; place-items: center;
  transition: background .3s var(--ease), border-color .3s var(--ease);
}
.lightbox__close:hover, .lightbox__nav:hover { background: #D61113; border-color: #D61113; }
.lightbox__close { top: 20px; right: 20px; }
.lightbox__nav--prev { left: 20px; top: 50%; transform: translateY(-50%); }
.lightbox__nav--next { right: 20px; top: 50%; transform: translateY(-50%); }

/* -------------------------------------------------------------- 20. Forms */

.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1.15fr;
  gap: clamp(28px, 4vw, 56px);
  align-items: start;
}

.infocard {
  display: flex; gap: 18px; align-items: flex-start;
  padding: 22px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 3px;
  box-shadow: var(--shadow-sm);
  transition: border-color .35s var(--ease), transform .35s var(--ease),
              box-shadow .35s var(--ease);
}
.infocard + .infocard { margin-top: 14px; }
.infocard:hover {
  border-color: rgba(214,17,19,.4);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.infocard__icon {
  width: 46px; height: 46px; flex: none;
  background: var(--red);
  border-radius: 3px;
  display: grid; place-items: center;
  color: #fff;
}

.infocard__icon svg { width: 20px; height: 20px; }

.infocard__title {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 780;
  text-transform: uppercase;
  font-size: .88rem; letter-spacing: .08em;
  color: var(--ink);
  margin-bottom: 6px;
}
.infocard__text { font-size: .92rem; color: var(--ink-2); line-height: 1.55; }
.infocard__text a { color: var(--blue); transition: color .3s var(--ease); }
.infocard__text a:hover { color: var(--red); }

.socials { display: flex; gap: 10px; margin-top: 12px; }
.social {
  width: 38px; height: 38px;
  border: 1px solid var(--line);
  border-radius: 50%;
  display: grid; place-items: center;
  color: var(--ink-2);
  transition: background .3s var(--ease), color .3s var(--ease),
              border-color .3s var(--ease), transform .3s var(--ease);
}
.social svg { width: 17px; height: 17px; }
.social:hover { background: var(--red); border-color: var(--red); color: #fff; transform: translateY(-2px); }

.formcard {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 3px;
  box-shadow: var(--shadow-md);
  padding: clamp(24px, 3.5vw, 40px);
}

.field { margin-bottom: 18px; }
.field label {
  display: block;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 700;
  text-transform: uppercase;
  font-size: .74rem; letter-spacing: .12em;
  color: var(--ink);
  margin-bottom: 8px;
}
.field .req { color: var(--red); }

.field input,
.field select,
.field textarea {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 13px 15px;
  color: var(--ink);
  font-size: .95rem;
  transition: border-color .3s var(--ease), background .3s var(--ease),
              box-shadow .3s var(--ease);
}
.field textarea { min-height: 130px; resize: vertical; }
.field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%235F6B82' stroke-width='1.6'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 15px center;
  background-size: 12px;
  padding-right: 40px;
}
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--blue);
  background: #fff;
  box-shadow: 0 0 0 3px rgba(27, 79, 216, .16);
}
.field input::placeholder, .field textarea::placeholder { color: #939DB0; }

.field--error input,
.field--error select,
.field--error textarea {
  border-color: var(--red);
  background: var(--red-soft);
}
.field--error input:focus,
.field--error select:focus,
.field--error textarea:focus { box-shadow: 0 0 0 3px rgba(214, 17, 19, .16); }

.field__msg { display: none; margin-top: 7px; font-size: .8rem; color: var(--red); }
.field--error .field__msg { display: block; }

.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }

.form-note { font-size: .8rem; color: var(--muted); margin-top: 16px; line-height: 1.55; }
.form-note a { color: var(--blue); }

.form-status {
  display: none;
  margin-top: 18px;
  padding: 14px 16px;
  border: 1px solid rgba(27, 79, 216, .35);
  background: var(--blue-soft);
  color: var(--ink);
  border-radius: 3px;
  font-size: .9rem;
}
.form-status.is-visible { display: block; }
.form-status:focus { outline: none; }
/* send.php's verdict. Same specificity as `.heroform .form-status` and later
   in the file, so these win inside the hero card too. */
.form-status.is-ok { border-color: rgba(22, 128, 61, .45); background: #EAF7EF; }
.form-status.is-error { border-color: rgba(214, 17, 19, .45); background: var(--red-soft); }

/* reCAPTCHA v3 loads when a visitor first uses a form. Google allows hiding
   its floating badge only while `.form-legal` stays with every form — remove
   one and the other has to go too. */
.grecaptcha-badge { visibility: hidden; }
.form-legal { margin-top: 12px; font-size: .72rem; line-height: 1.5; color: var(--muted); }
.form-legal a { color: inherit; text-decoration: underline; }
.heroform .form-legal { margin-top: 10px; font-size: .68rem; line-height: 1.45; }

/* Honeypot — a field people never see and bots fill in anyway.
   ⚠️ Deliberately NOT `display: none` or `hidden`. The better scrapers skip
   anything the browser would not paint, which defeats the whole trick. This
   takes it out of the flow and off-screen instead, so it is in the DOM, has a
   real label, and is still invisible and unreachable by pointer or keyboard
   (the markup adds `tabindex="-1"` and `aria-hidden`). */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* ---------------------------------------------------------------- 21. Map */

/* A full-bleed band, edge to edge and floor to ceiling — not a tile in a
   two-column grid. It replaced a `.map-grid` that put the map beside an
   "Easy To Find" panel; the panel went at the client's request and the map took
   the whole width.

   `.mapband` is a direct child of <main> with no `.container`, which is all it
   takes to go full width. No section padding either: the band butts the form
   section's own bottom padding above it and the footer's red rule below. */
.mapband {
  position: relative;
  background: var(--surface-2);
  border-top: 1px solid var(--line);
}
.mapwrap {
  position: relative;
  overflow: hidden;
  /* not min-height: the iframe needs a definite height to fill */
  height: clamp(360px, 42vw, 600px);
  background: var(--surface-2);
}
.mapwrap iframe {
  width: 100%; height: 100%; border: 0; display: block;
  filter: grayscale(.35) contrast(1.02);
}

/* ------------------------------------------------------------- 22. Footer */

/* The footer runs on its own light palette, independent of the page tokens,
   so it renders identically on every page regardless of the section above it. */
.footer {
  --footer-bg:            #F3F3F3;
  --footer-heading:       #172033;
  --footer-text:          #4B5563;
  --footer-link:          #596273;
  --footer-link-hover:    #E30613;
  --footer-accent:        #E30613;
  --footer-border:        #D9DDE2;
  --footer-icon:          #E30613;
  --footer-social-border: #CBD1D8;
  --footer-copyright:     #6B7280;

  background: var(--footer-bg);
  color: var(--footer-text);
  border-top: 4px solid var(--footer-accent);
  /* Same rhythm as every content section; the copyright bar forms the base */
  padding-top: var(--section-y);
}

.footer__grid {
  display: grid;
  grid-template-columns: 1.7fr 1fr 1.2fr 1.4fr;
  gap: clamp(30px, 4vw, 56px);
  padding-bottom: clamp(38px, 5vw, 60px);
}

/* Footer logo — 250.63px wide, at the client's request.

   ⚠️ The ask was "250.63 x 118". Those two numbers describe a 2.124:1 box and
   the artwork is 2.6067:1, so both cannot hold — forcing them would squash the
   logo horizontally by 18.5%. The WIDTH is the half that was honoured, because
   it is the half that changed: the previous ask was "212.63 x 118", which was
   read as a height and rendered 308px wide, and the follow-up moved the width
   figure while leaving the height at 118. The height now lands at 96.1px, so
   the logo sits inside the 250.63 x 118 box that was named.

   ⚠️ Sized with `min(250.63px, 100%)`, never a fixed height. A fixed height
   cannot shrink, and the footer brand column is only 248px at a 1025px viewport
   and 280px on a 320px phone — a fixed height there would either overflow the
   column or, with `max-width`, letterbox the logo inside a too-tall box.
   Driving from the width lets the height follow the ratio all the way down:
   250.63 x 96.1 where there is room, proportional everywhere else, never
   distorted at any width.

   Resolution: 250.63px displayed from a 391px file needs 501px to be sharp at
   2x, so this is still short (about 0.78x density) — better than the 308px it
   replaced, but a vector of this lockup is the only real fix. See §5. */
.footer__brand img {
  width: min(250.63px, 100%);
  height: auto;
  margin-bottom: 26px;
}
.footer__about {
  font-size: 1rem;
  color: var(--footer-text);
  line-height: 1.7;
  max-width: 36ch;
}

.footer__title {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 800;
  text-transform: uppercase;
  font-size: .86rem; letter-spacing: .14em;
  color: var(--footer-heading);
  margin-bottom: 22px;
  position: relative;
  padding-bottom: 14px;
}
.footer__title::after {
  content: ''; position: absolute; left: 0; bottom: 0;
  width: 30px; height: 3px; background: var(--footer-accent);
}

.footer__list li + li { margin-top: 11px; }
.footer__list a {
  position: relative;
  display: inline-block;
  font-size: 1rem;
  color: var(--footer-link);
  transition: color .3s var(--ease), padding-left .3s var(--ease);
}
.footer__list a::before {
  content: '';
  position: absolute; left: 0; top: 50%;
  width: 9px; height: 2px;
  background: var(--footer-accent);
  opacity: 0;
  transform: translateY(-50%);
  transition: opacity .3s var(--ease);
}
.footer__list a:hover { color: var(--footer-link-hover); padding-left: 17px; }
.footer__list a:hover::before { opacity: 1; }

.footer__contact li {
  display: flex; gap: 14px; align-items: flex-start;
  font-size: 1rem; color: var(--footer-text); line-height: 1.6;
}
.footer__contact li + li { margin-top: 16px; }
.footer__contact svg {
  width: 16px; height: 16px;
  color: var(--footer-icon);
  flex: none; margin-top: 5px;
}
.footer__contact a { color: var(--footer-text); transition: color .3s var(--ease); }
.footer__contact a:hover { color: var(--footer-link-hover); }

.footer__socials { display: flex; gap: 10px; margin-top: 26px; }
.footer .social {
  width: 42px; height: 42px;
  border-color: var(--footer-social-border);
  color: var(--footer-link);
}
.footer .social:hover {
  background: var(--footer-accent);
  border-color: var(--footer-accent);
  color: #fff;
}

/* Copyright and build credit read as one centred line, wrapping to two centred
   lines when there is not room. The trademark disclaimer and the Privacy /
   Terms / Sitemap row that used to sit above this were removed at the client's
   request — see §6. */
.footer__bar {
  border-top: 1px solid var(--footer-border);
  padding-block: 24px;
  display: flex; align-items: center; justify-content: center;
  gap: 6px 10px; flex-wrap: wrap;
  text-align: center;
  font-size: 1rem; color: var(--footer-copyright);
}
/* the build credit carries a little more weight than the copyright beside it */
.footer__credit { font-weight: 600; }
.footer__credit a {
  color: var(--footer-link);
  font-weight: 600;
  transition: color .3s var(--ease);
}
.footer__credit a:hover { color: var(--footer-link-hover); }

/* ------------------------------------------------------------- 23. Prose */

.prose { max-width: 78ch; }
.prose h2 {
  font-size: clamp(1.2rem, 2vw, 1.5rem);
  margin-top: 44px;
  margin-bottom: 14px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
}
.prose h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.prose h3 { font-size: 1rem; letter-spacing: .04em; margin-top: 26px; margin-bottom: 8px; }
.prose p, .prose li { color: var(--ink-2); }
.prose p + p { margin-top: 1em; }
.prose ul { margin-top: 12px; }
.prose ul li { position: relative; padding-left: 20px; margin-bottom: 8px; }
.prose ul li::before {
  content: '';
  position: absolute; left: 0; top: .68em;
  width: 8px; height: 3px; background: var(--red);
}
.prose a { color: var(--blue); text-decoration: underline; text-underline-offset: 3px; }
.prose a:hover { color: var(--red); }
.prose__updated {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100, 'wght' 700;
  text-transform: uppercase; letter-spacing: .14em; font-size: .74rem;
  color: var(--muted);
  margin-bottom: 34px;
}

/* ------------------------------------------------- 24. Scroll animations */

/* Reveals are gated behind `.js` (set by an inline script in <head>) so that a
   JavaScript failure leaves the page fully readable rather than blank. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .8s var(--ease), transform .8s var(--ease);
  will-change: opacity, transform;
}
.js [data-reveal].is-in { opacity: 1; transform: none; }

.js [data-reveal="left"]  { transform: translateX(-30px); }
.js [data-reveal="right"] { transform: translateX(30px); }
.js [data-reveal="fade"]  { transform: none; }
.js [data-reveal="left"].is-in,
.js [data-reveal="right"].is-in { transform: none; }

.js [data-reveal-group] > * {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.js [data-reveal-group].is-in > * { opacity: 1; transform: none; }
.js [data-reveal-group].is-in > *:nth-child(1) { transition-delay: .00s; }
.js [data-reveal-group].is-in > *:nth-child(2) { transition-delay: .08s; }
.js [data-reveal-group].is-in > *:nth-child(3) { transition-delay: .16s; }
.js [data-reveal-group].is-in > *:nth-child(4) { transition-delay: .24s; }
.js [data-reveal-group].is-in > *:nth-child(5) { transition-delay: .32s; }
.js [data-reveal-group].is-in > *:nth-child(6) { transition-delay: .40s; }
.js [data-reveal-group].is-in > *:nth-child(7) { transition-delay: .48s; }
.js [data-reveal-group].is-in > *:nth-child(8) { transition-delay: .56s; }
.js [data-reveal-group].is-in > *:nth-child(9) { transition-delay: .64s; }

/* Hero copy runs on load rather than on scroll. This is a CSS animation with
   `forwards`, so it completes on its own and needs no `.js` gate. */
.hero__copy > * {
  opacity: 0;
  transform: translateY(24px);
  animation: heroIn .9s var(--ease) forwards;
}
.hero__copy > *:nth-child(1) { animation-delay: .12s; }
.hero__copy > *:nth-child(2) { animation-delay: .24s; }
.hero__copy > *:nth-child(3) { animation-delay: .36s; }
.hero__copy > *:nth-child(4) { animation-delay: .48s; }
.hero__copy > *:nth-child(5) { animation-delay: .60s; }
@keyframes heroIn { to { opacity: 1; transform: none; } }

/* Back-to-top */
.to-top {
  position: fixed; right: 22px; bottom: 22px; z-index: 90;
  width: 46px; height: 46px;
  background: var(--red);
  border: 0; border-radius: 50%;
  color: #fff; cursor: pointer;
  display: grid; place-items: center;
  box-shadow: var(--shadow-md);
  opacity: 0; visibility: hidden; transform: translateY(10px);
  transition: opacity .35s var(--ease), visibility .35s var(--ease),
              transform .35s var(--ease), background .3s var(--ease);
}
.to-top.is-visible { opacity: 1; visibility: visible; transform: none; }
.to-top:hover { background: var(--red-deep); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  [data-reveal], [data-reveal-group] > *, .hero__copy > *,
  .js [data-reveal], .js [data-reveal-group] > * {
    opacity: 1 !important; transform: none !important;
  }
}
