/* ============================================================
   VEBODY — Homepage
   Design tokens per .impeccable/surfaces/index-html.md
   ============================================================ */

@import url('../fonts/fonts.css');

:root {
  /* Color: official VEBODY brand palette (brand guide, Sept 2026).
     Black + carbon fibre as the base material, gunmetal as neutral
     secondary, VEBODY Blue reserved as the one accent hue. */
  --black: #050505;
  --vebody-blue: #0a3d7a;
  --vebody-blue-bright: #1554a3;
  --vebody-blue-text: #4a8fd6; /* lightened for text directly on black (6.0:1); raw brand blue is only 1.9:1 there */
  --gunmetal: #6b6f74;
  --gunmetal-text: #5a5e64; /* darkened from #7d8188 — the old value read 3.62:1 on offwhite, below AA. .on-dark/.hero/.footer/.filmstrip-wrap redefine this token lighter for dark surfaces below. */
  --gunmetal-dim: #454850;
  --grey-100: #e9eaec;
  --offwhite: #f5f6f7;
  --ink: #111214;
  --white: #ffffff;
  --hairline-dark: rgba(255, 255, 255, 0.14);
  --hairline-blue: rgba(21, 84, 163, 0.4);
  --hairline-light: rgba(17, 18, 20, 0.12);

  /* Type */
  --font-display: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --font-body: 'IBM Plex Sans', 'Helvetica Neue', Arial, sans-serif;
  --font-mono: 'IBM Plex Mono', 'SFMono-Regular', Consolas, monospace;

  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.375rem;
  --text-2xl: 1.75rem;
  --text-3xl: 2.25rem;
  --text-4xl: 3rem;
  --text-5xl: 4rem;
  --text-6xl: 5.25rem;

  /* Space */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 1rem;
  --space-4: 1.5rem;
  --space-5: 2rem;
  --space-6: 3rem;
  --space-7: 4rem;
  --space-8: 6rem;
  --space-9: 8rem;

  --page-gutter: clamp(1.25rem, 4vw, 4rem);
  --max-content: 1400px;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);

  /* ----------------------------------------------------------
     Design system v2 (2026-09). Documented in CLAUDE.md.
     Six type sizes, one spacing scale (--space-1…9 above), one
     section rhythm, one hairline weight. New work uses these only.
     ---------------------------------------------------------- */
  --fs-display: clamp(2.5rem, 1.55rem + 3.4vw, 4.25rem);  /* hero H1 only */
  --fs-h2: clamp(2rem, 1.3rem + 2.3vw, 3.25rem);          /* section headings */
  --fs-h3: 1.3125rem;                                      /* card / column titles */
  --fs-lead: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);      /* intro paragraphs */
  --fs-body: 1rem;
  --fs-small: 0.875rem;                                    /* captions, lists, meta */
  --fs-label: 0.75rem;                                     /* mono labels + spec data */

  --lh-display: 1.02;
  --lh-heading: 1.12;
  --lh-body: 1.6;

  --measure: 62ch;
  --section-y: clamp(4.5rem, 3rem + 5vw, 7.5rem);         /* every section, top + bottom */
  --grid-gap: clamp(1.5rem, 0.9rem + 2.2vw, 3rem);         /* every column gap */

  --rule-light: 1px solid var(--hairline-light);
  --rule-dark: 1px solid var(--hairline-dark);

  color-scheme: light;
}

/* ============================================================
   Reset
   ============================================================ */

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

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

body {
  margin: 0;
  background: var(--offwhite);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  display: block;
}

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

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

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

/* Selection, caret, focus ring, scrollbar theming */
::selection {
  background: var(--vebody-blue);
  color: var(--white);
}

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

.on-dark :focus-visible {
  outline-color: var(--offwhite);
}

/* Skip link: hidden off-screen until keyboard focus */
.skip-link {
  position: absolute;
  top: -100%;
  left: var(--space-4);
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--vebody-blue);
  color: var(--white);
  font-weight: 600;
  font-size: var(--text-sm);
  transition: top 200ms var(--ease-out);
}
.skip-link:focus {
  top: var(--space-4);
}

html {
  scrollbar-color: var(--gunmetal-text) var(--grey-100);
}

/* ============================================================
   Layout utilities
   ============================================================ */

.wrap {
  max-width: var(--max-content);
  margin-inline: auto;
  padding-inline: var(--page-gutter);
}

.section {
  position: relative;
}

/* The nav is a flush full-width bar, ~61px tall (1rem padding + 26px
   logo + 1px border). Every section gets that clearance (rounded up,
   plus a little breathing room) so an anchor jump or scrollIntoView()
   never rests with content under the fixed header — this applies to
   every <section>, not just .section, since .hero/.close/.filmstrip-wrap
   don't carry that class. */
section {
  scroll-margin-top: 96px;
}

.section-label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  color: var(--gunmetal-text);
}

.on-dark,
.hero,
.footer,
.filmstrip-wrap {
  /* Same token, brighter here — a grey tuned for offwhite backgrounds
     reads as too dim once it's sitting directly on black. */
  --gunmetal-text: #9aa0a8;
}

.on-dark {
  background-color: var(--black);
  color: var(--offwhite);
}

.hairline-top {
  border-top: 1px solid var(--hairline-light);
}
.on-dark.hairline-top {
  border-top-color: var(--hairline-dark);
}

/* ============================================================
   Buttons
   ============================================================ */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0.9rem 1.6rem;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
  border: 1px solid transparent;
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 12px 100%, 0 calc(100% - 12px));
  transition: transform 160ms var(--ease-out), border-color 200ms var(--ease-out), color 200ms var(--ease-out);
}

.btn:active {
  transform: scale(0.97);
}

.btn-primary {
  background: var(--vebody-blue);
  color: var(--white);
}
.btn-primary::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: 0;
  background: var(--vebody-blue-bright);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 380ms var(--ease-out);
}
.btn-primary:hover::before {
  transform: scaleX(1);
}

.btn-outline {
  border-color: rgba(255, 255, 255, 0.45);
  color: var(--white);
}
.btn-outline::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: 0;
  background: var(--white);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 380ms var(--ease-out);
}
.btn-outline:hover {
  border-color: var(--white);
  color: var(--black);
}
.btn-outline:hover::before {
  transform: scaleX(1);
}

/* Industrial corner-bracket accent: always faintly present, sharpens on hover */
.brackets {
  position: relative;
}
.brackets::before,
.brackets::after {
  content: '';
  position: absolute;
  width: 18px;
  height: 18px;
  border: 2px solid var(--vebody-blue);
  opacity: 0.55;
  transition: opacity 280ms var(--ease-out);
  pointer-events: none;
  z-index: 2;
}
.brackets::before {
  top: 12px;
  left: 12px;
  border-right: none;
  border-bottom: none;
}
.brackets::after {
  bottom: 12px;
  right: 12px;
  border-left: none;
  border-top: none;
}
.brackets:hover::before,
.brackets:hover::after {
  opacity: 1;
}

.text-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-weight: 600;
  font-size: var(--text-sm);
  padding-bottom: 2px;
  border-bottom: 1px solid currentColor;
}

/* Selective accent word inside a heading. Raw brand blue fails contrast
   directly on black (1.9:1) so dark-background contexts use a lightened variant. */
.accent {
  color: var(--vebody-blue);
}
.on-dark .accent{
  color: var(--vebody-blue-text);
}

/* ============================================================
   Nav
   ============================================================ */

/* Full-width bar, flush to the viewport edge — not the floating rounded
   pill a page-builder defaults to. Solid rather than translucent (a
   heavy-engineering brand reads as a fixed plate, not a glass chip), with
   the same blue accent-line device used everywhere else on the site
   (.hero-rule, .about-statement-rule, .tech-divider-accent) marking its
   lower edge instead of an all-around soft border. */
.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  /* Vertical padding trimmed as the logo grew (client asked for a larger
     logo twice); bar is ~74px, still under scroll-margin and mastheads. */
  padding: 0.625rem var(--page-gutter);
  background: rgba(5, 5, 5, 0.94);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  transition: background-color 300ms var(--ease-out);
}

.nav::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 96px;
  height: 2px;
  background: var(--vebody-blue);
}

.nav-mark {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.nav-mark img {
  display: block;
  height: 64px;
  width: auto;
}
@media (max-width: 520px) {
  .nav-mark img {
    height: 42px;
  }
}

.nav-links {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.nav-links-cta {
  /* Only meant for the mobile dropdown (shown below 860px) — the
     desktop row already has its own "Request a Quote" button. */
  display: none;
}

.nav-links a {
  position: relative;
  padding-bottom: 3px;
  font-size: var(--text-sm);
  font-weight: 500;
  color: rgba(255, 255, 255, 0.78);
  transition: color 200ms var(--ease-out);
}
.nav-links a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--vebody-blue);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 250ms var(--ease-out);
}
.nav-links a:hover,
.nav-links a[aria-current="page"] {
  color: var(--white);
}
.nav-links a:hover::after,
.nav-links a[aria-current="page"]::after {
  transform: scaleX(1);
}

.nav .btn-primary {
  padding: 0.65rem 1.3rem;
  font-size: var(--text-sm);
}

.nav-toggle {
  display: none;
  width: 40px;
  height: 40px;
  align-items: center;
  justify-content: center;
  color: var(--white);
  flex-shrink: 0;
}

.nav-toggle-line {
  transform-origin: 10px 1px;
  transition: transform 220ms var(--ease-out), opacity 220ms var(--ease-out);
}
.nav-toggle[aria-expanded="true"] .nav-toggle-line-top {
  transform: translateY(6px) rotate(45deg);
}
.nav-toggle[aria-expanded="true"] .nav-toggle-line-mid {
  opacity: 0;
}
.nav-toggle[aria-expanded="true"] .nav-toggle-line-bottom {
  transform: translateY(-6px) rotate(-45deg);
}

/* Collapses to the menu button below 1280px (larger logo, Trailers link): with Trailers in the nav,
   six links + phone + quote button no longer fit a narrower bar. */
@media (max-width: 1280px) {
  .nav-links {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    /* Fully opaque, not 96% — that residual 4% was still enough for
       high-contrast hero/heading text behind it to ghost through
       visibly once blurred. */
    background: var(--black);
    backdrop-filter: blur(20px) saturate(140%);
    -webkit-backdrop-filter: blur(20px) saturate(140%);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-top: none;
    padding: var(--space-2);
  }
  .nav-links.is-open {
    display: flex;
  }
  .nav-links a {
    padding: var(--space-3);
  }
  .nav-links a:hover,
  .nav-links a[aria-current="page"] {
    background: rgba(255, 255, 255, 0.08);
  }
  .nav-toggle {
    display: inline-flex;
  }
  /* Six nav links plus the notched primary button plus the toggle don't
     fit the collapsed bar at small viewports without crowding — the quote
     CTA moves into the dropdown below instead of competing for space. */
  .nav > .btn-primary {
    display: none;
  }
  .nav-links-cta {
    display: block;
    margin-top: var(--space-2);
    padding-top: var(--space-3);
    border-top: 1px solid var(--hairline-dark);
  }
  .nav-links-cta a {
    display: block;
    text-align: center;
    padding: var(--space-3) !important;
    background: var(--vebody-blue);
    color: var(--white) !important;
    font-weight: 700;
  }
  .nav-links-cta a::after {
    display: none;
  }
}

/* ============================================================
   Hero
   ============================================================ */

.hero {
  position: relative;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
  background: var(--black);
}

.hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 40%;
  filter: saturate(0.82) contrast(1.05) brightness(0.92);
  transform: scale(1.06);
}

.hero-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(5, 5, 5, 0.55) 0%, rgba(5, 5, 5, 0.15) 32%, rgba(5, 5, 5, 0.55) 68%, rgba(5, 5, 5, 0.94) 100%),
    linear-gradient(90deg, rgba(5, 5, 5, 0.5) 0%, rgba(5, 5, 5, 0) 40%);
}

.hero-headline {
  font-family: var(--font-display);
  font-weight: 800;
  color: var(--white);
  font-size: clamp(2.75rem, 8vw, var(--text-6xl));
  line-height: 0.98;
  letter-spacing: -0.02em;
  max-width: 18ch;
}

.hero-headline span {
  display: block;
  overflow: hidden;
}

.hero-headline span > em {
  display: block;
  font-style: normal;
  transform: translateY(110%);
}

.hero-rule {
  display: block;
  width: 72px;
  height: 3px;
  margin-top: var(--space-4);
  background: var(--vebody-blue);
  transform-origin: left center;
  transform: scaleX(0);
}

@media (prefers-reduced-motion: reduce) {
  .hero-rule {
    transform: scaleX(1);
  }
}

.hero-foot {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--hairline-dark);
}

@media (max-width: 720px) {
  
  
  .hero-foot {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* ============================================================
   Proof strip
   ============================================================ */

.proof {
  position: relative;
  z-index: 2;
  background: var(--offwhite);
  margin-top: -2.25rem;
  padding-block: var(--space-8);
  box-shadow: 0 -24px 48px rgba(5, 5, 5, 0.22);
}

@media (max-width: 560px) {
  .proof {
    padding-block: var(--space-7);
  }
  
  
  
  
  
}

/* ============================================================
   Heritage
   ============================================================ */

.heritage {
  padding-block: var(--space-8);
}

/* ============================================================
   The fork
   ============================================================ */

.fork {
  /* A little extra over the base --space-8 so the heading clears the
     fixed nav's real bottom edge (~61px) with room to spare. */
  padding-top: calc(var(--space-8) + 1.5rem);
  padding-bottom: var(--space-8);
  background: var(--offwhite);
}

.fork-visual {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  margin-right: calc(-1 * var(--page-gutter));
}

.fork-visual > img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.85) contrast(1.05);
}

.fork-visual .is-repair {
  opacity: 0.4;
  /* Now a placeholder <div>, not an <img> — .fork-visual img's
     absolute-fill positioning doesn't reach it, so repeat it here. */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

@media (max-width: 860px) {
  
  .fork-visual {
    aspect-ratio: 16 / 10;
    margin-right: 0;
  }
}

/* ============================================================
   Product filmstrip
   ============================================================ */

.filmstrip-wrap {
  position: relative;
  overflow: hidden;
  background-color: var(--black);
}

.filmstrip-track {
  display: flex;
  will-change: transform;
}

/* Unpinned fallback (reduced motion, or GSAP unavailable): a native
   horizontal scroll row so panels past the viewport stay reachable. */
.filmstrip-track.is-scrollable {
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
}

/* Mobile never runs the GSAP pin/scrub (initFilmstrip bails out under
   721px) — a stacked column of 8 near-full-height panels was the actual
   fallback, which turned "seven body types" into several screens of
   vertical scroll. A swipeable horizontal scroll-snap row keeps the
   filmstrip's own identity (cards, not a list) and the same total
   footprint as any other section instead of dominating the page. */
@media (max-width: 720px) {
  .filmstrip-track {
    height: auto;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .filmstrip-track::-webkit-scrollbar {
    display: none;
  }
  
}

/* ============================================================
   Repairs & Modifications
   ============================================================ */

.repairs {
  /* Plain black — overrides the carbon-texture .on-dark otherwise
     applies, per request. */
  background-color: var(--black);
  background-image: none;
  padding-block: var(--space-8);
}

/* Before / after slider — .repairs-photo is the single held-space frame
   the homepage uses until a real pair exists; same size and overlap. */
.compare{
  position: relative;
  z-index: 1;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  margin-left: calc(-1 * var(--space-6));
  box-shadow: -24px 24px 56px rgba(5, 5, 5, 0.45);
  user-select: none;
  touch-action: pan-y;
}

.compare-after-wrap {
  position: absolute;
  inset: 0;
  width: 50%;
  overflow: hidden;
}

.compare-after-wrap > img {
  width: var(--compare-w, 200%);
  max-width: none;
}

.compare-handle {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 2px;
  background: var(--white);
  transform: translateX(-1px);
  cursor: ew-resize;
}

.compare-handle::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--white);
  box-shadow: 0 6px 20px rgba(5, 5, 5, 0.35);
}

.compare-handle::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 16px;
  height: 10px;
  transform: translate(-50%, -50%);
  border-left: 2px solid var(--black);
  border-right: 2px solid var(--black);
  z-index: 1;
}

@media (max-width: 860px) {
  
  
  .compare{
    order: -1;
    margin-left: 0;
    box-shadow: 0 18px 36px rgba(5, 5, 5, 0.35);
  }
}

/* Hairline-ruled band of equal cells: top and bottom rules close the
   roster, verticals divide it, so every mark sits in the same-sized
   slot instead of floating at whatever width its file happens to be. */
.client-logos-row {
  margin-top: var(--space-6);
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  border-top: 1px solid var(--hairline-light);
  border-bottom: 1px solid var(--hairline-light);
}

.client-logos-item {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 136px;
  padding: var(--space-5) var(--space-4);
  border-left: 1px solid var(--hairline-light);
}
.client-logos-item:first-child {
  border-left: none;
}
.client-logos-item-tagged {
  flex-direction: column;
  gap: var(--space-1);
}
.client-logo-caption {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.client-logo {
  /* Same visual height for every mark; monochrome until hover. */
  height: 40px;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  filter: grayscale(1) contrast(1.05);
  opacity: 0.75;
  transition: filter 300ms var(--ease-out), opacity 300ms var(--ease-out);
}
.client-logos-item:hover .client-logo {
  filter: none;
  opacity: 1;
}

@media (max-width: 960px) {
  .client-logos-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
  }
  .client-logos-item {
    min-height: 112px;
    padding: var(--space-4) var(--space-3);
    border-left: 1px solid var(--hairline-light);
    border-top: 1px solid var(--hairline-light);
  }
  .client-logo {
    height: 34px;
  }
  .client-logos-item:nth-child(3n+1) {
    border-left: none;
  }
  .client-logos-item:nth-child(-n+3) {
    border-top: none;
  }
  /* 5 logos over 3 columns: the last one spans the leftover pair so the
     band has no empty cell. */
  .client-logos-item:last-child:nth-child(3n+2) {
    grid-column: span 2;
  }
}
@media (max-width: 600px) {
  .client-logos-row {
    grid-template-columns: repeat(2, 1fr);
  }
  .client-logos-item:nth-child(3n+1) {
    border-left: 1px solid var(--hairline-light);
  }
  .client-logos-item:nth-child(2n+1) {
    border-left: none;
  }
  .client-logos-item:nth-child(-n+3) {
    border-top: 1px solid var(--hairline-light);
  }
  .client-logos-item:nth-child(-n+2) {
    border-top: none;
  }
  /* Odd count over 2 columns: last logo takes the full row. */
  .client-logos-item:last-child:nth-child(3n+2) {
    grid-column: auto;
  }
  .client-logos-item:last-child:nth-child(odd) {
    grid-column: 1 / -1;
    border-left: none;
  }
}

/* ============================================================
   Close
   ============================================================ */

.close {
  position: relative;
  min-height: 72vh;
  display: flex;
  align-items: center;
  overflow: hidden;
}

/* ============================================================
   Footer
   ============================================================ */

.footer {
  background-color: var(--black);
  color: rgba(245, 246, 247, 0.7);
  padding-block: var(--space-7) var(--space-5);
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.3fr repeat(3, 1fr);
  gap: var(--space-6);
}

.footer-logo {
  width: 100%;
  max-width: 300px;
  height: auto;
}

.footer-col-title {
  font-size: var(--text-xs);
  font-family: var(--font-mono);
  letter-spacing: 0.04em;
  color: var(--gunmetal-text);
  margin-bottom: var(--space-3);
}

.footer-col a,
.footer-col p {
  display: block;
  padding: 0.3rem 0;
  font-size: var(--text-sm);
}

.footer-col a:hover {
  color: var(--white);
}

.footer-phone {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: 0.3rem 0;
}
.footer-phone-label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--gunmetal-text);
  white-space: nowrap;
}
.footer-phone a {
  display: inline;
  padding: 0;
  font-size: var(--text-sm);
}
.footer-phone .whatsapp-btn {
  font-size: var(--text-xs);
}

.footer-bottom {
  margin-top: var(--space-7);
  padding-top: var(--space-4);
  border-top: 1px solid var(--hairline-dark);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: var(--text-xs);
  color: var(--gunmetal-text);
}

@media (max-width: 720px) {
  .footer-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ============================================================
   Reveal utility (scroll entrance)
   ============================================================ */

.reveal {
  opacity: 0;
  transform: translateY(20px);
}
.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 700ms var(--ease-out), transform 700ms var(--ease-out);
}

@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ============================================================
   Contact / Request a Quote page
   Full-dark, technical-console treatment — the form is the
   product here, not a supporting element, so the page stays on
   one carbon surface throughout rather than alternating light/dark
   bands like the narrative pages.
   ============================================================ */

.contact-page .footer {
  background-color: var(--black);
}

.quote-intro {
  padding: calc(var(--space-9) + 2.5rem) 0 var(--space-7);
}

.quote-intro-heading {
  margin-top: var(--space-3);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2.25rem, 4.6vw, var(--text-5xl));
  line-height: 1.08;
  letter-spacing: -0.02em;
  max-width: 20ch;
  color: var(--white);
}

.quote-intro-sub {
  margin-top: var(--space-4);
  max-width: 58ch;
  font-size: var(--text-lg);
  line-height: 1.6;
  color: rgba(245, 246, 247, 0.82);
}

.quote-trust {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--hairline-blue);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6) var(--space-8);
}
.quote-trust li {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.quote-trust-figure {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--text-3xl);
  line-height: 1;
  color: var(--white);
}
.quote-trust-label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  color: var(--gunmetal-text);
}

/* ----------------------------------------------------------
   Form + contact rail grid
   ---------------------------------------------------------- */

.quote-main {
  padding-block: var(--space-8);
}

.quote-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
  gap: var(--space-8);
  align-items: start;
}

@media (max-width: 860px) {
  .quote-grid {
    grid-template-columns: 1fr;
    gap: var(--space-7);
  }
}

/* ----------------------------------------------------------
   Quote form
   ---------------------------------------------------------- */

.quote-form {
  min-width: 0;
}

.quote-form-head {
  margin-bottom: var(--space-6);
}
.quote-form-title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--text-2xl);
  color: var(--white);
}
.quote-form-sub {
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  color: var(--gunmetal-text);
}

.req-mark {
  color: var(--vebody-blue-text);
}

/* Spam trap: off-screen for people and screen readers (aria-hidden),
   still in the form for bots. */
.quote-honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.quote-step {
  position: relative;
  margin: 0 0 var(--space-7);
  padding: var(--space-6) 0 0;
  border: none;
  border-top: 1px solid var(--hairline-dark);
}
.quote-step:first-of-type {
  border-top: none;
  padding-top: 0;
}

.quote-step-legend {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
  padding: 0;
}
.quote-step-index {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 2.75rem;
  line-height: 1;
  color: rgba(255, 255, 255, 0.08);
}
.quote-step-name {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--vebody-blue-text);
}

.form-row {
  margin-bottom: var(--space-4);
}
.form-row-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}
@media (max-width: 520px) {
  .form-row-2 {
    grid-template-columns: 1fr;
  }
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.form-field label,
.segmented-field legend {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  color: rgba(245, 246, 247, 0.72);
}

.form-field input[type="text"],
.form-field input[type="tel"],
.form-field input[type="email"],
.form-field select,
.form-field textarea {
  width: 100%;
  padding: 0.85rem 1rem;
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--ink);
  background: var(--offwhite);
  border: 1px solid transparent;
  border-radius: 2px;
  transition: border-color 200ms var(--ease-out), background-color 200ms var(--ease-out);
}
.form-field input::placeholder,
.form-field textarea::placeholder {
  color: var(--gunmetal-text);
}
.form-field input:hover,
.form-field select:hover,
.form-field textarea:hover {
  background: var(--white);
}
.form-field input:focus-visible,
.form-field select:focus-visible,
.form-field textarea:focus-visible {
  outline: none;
  border-color: var(--vebody-blue);
  background: var(--white);
}
.form-field textarea {
  resize: vertical;
  min-height: 6.5rem;
  line-height: 1.5;
}

.form-field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%234a8fd6' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  padding-right: 2.5rem;
}
.form-field select option {
  color: var(--ink);
}

/* Field marked invalid only after the visitor has actually left it
   (JS adds .is-touched on blur) — avoids a wall of red on first paint. */
.form-field.is-touched input:invalid,
.form-field.is-touched select:invalid,
.form-field.is-touched textarea:invalid {
  border-color: #d6564a;
}

/* ----------------------------------------------------------
   Segmented control (Type of work / Preferred contact method)
   ---------------------------------------------------------- */

.segmented-field {
  border: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.segmented {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

.segmented-option {
  position: relative;
}
.segmented-option input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}
.segmented-option label {
  display: inline-flex;
  align-items: center;
  padding: 0.7rem 1.3rem;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  color: rgba(245, 246, 247, 0.72);
  border: 1px solid var(--hairline-dark);
  border-radius: 2px;
  cursor: pointer;
  transition: border-color 200ms var(--ease-out), color 200ms var(--ease-out), background-color 200ms var(--ease-out);
}
.segmented-option input:hover + label {
  border-color: rgba(255, 255, 255, 0.32);
}
.segmented-option input:focus-visible + label {
  outline: 2px solid var(--vebody-blue-text);
  outline-offset: 2px;
}
.segmented-option input:checked + label {
  color: var(--white);
  background: var(--vebody-blue);
  border-color: var(--vebody-blue);
}

/* ----------------------------------------------------------
   File dropzone
   ---------------------------------------------------------- */

.dropzone {
  position: relative;
  border: 1px dashed var(--hairline-dark);
  border-radius: 2px;
  padding: var(--space-5);
  text-align: center;
  transition: border-color 200ms var(--ease-out), background-color 200ms var(--ease-out);
}
.dropzone.is-dragover {
  border-color: var(--vebody-blue-text);
  background: rgba(74, 143, 214, 0.06);
}
.dropzone input[type="file"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}
.dropzone-prompt {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--text-sm);
  color: rgba(245, 246, 247, 0.6);
  pointer-events: none;
}
.dropzone-prompt svg {
  color: var(--vebody-blue-text);
}
.dropzone-browse {
  color: var(--vebody-blue-text);
  text-decoration: underline;
}

.dropzone-files {
  position: relative;
  z-index: 1;
  margin: var(--space-4) 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: center;
  pointer-events: none;
}
.dropzone-files li {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.7rem;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--offwhite);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--hairline-dark);
  border-radius: 999px;
}
.dropzone-files button {
  pointer-events: all;
  color: var(--gunmetal-text);
  font-size: var(--text-sm);
  line-height: 1;
}
.dropzone-files button:hover {
  color: var(--white);
}

/* ----------------------------------------------------------
   Submit / success / error states
   ---------------------------------------------------------- */

.quote-form-foot {
  margin-top: var(--space-6);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
}
.quote-submit:disabled {
  opacity: 0.55;
  pointer-events: none;
}
.quote-form-privacy {
  font-size: var(--text-xs);
  color: var(--gunmetal-text);
  max-width: 32ch;
}

.quote-form-error {
  margin-top: var(--space-4);
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
  color: #f3b7b0;
  background: rgba(214, 86, 74, 0.1);
  border: 1px solid rgba(214, 86, 74, 0.4);
}
.quote-form-error a {
  text-decoration: underline;
}

.quote-success {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}
.quote-success svg {
  color: var(--vebody-blue-text);
}
.quote-success h2 {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--text-2xl);
  color: var(--white);
}
.quote-success p {
  max-width: 48ch;
  color: rgba(245, 246, 247, 0.82);
}
.quote-success .text-link {
  margin-top: var(--space-2);
  color: var(--vebody-blue-text);
}

/* ----------------------------------------------------------
   Contact rail
   ---------------------------------------------------------- */

.contact-rail-block {
  padding: var(--space-6);
  border: 1px solid var(--hairline-dark);
  background: rgba(255, 255, 255, 0.02);
}

.contact-rail-item {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-5);
  color: var(--offwhite);
  transition: color 200ms var(--ease-out);
}
.contact-rail-item svg {
  flex-shrink: 0;
  margin-top: 0.15rem;
  color: var(--vebody-blue-text);
}
a.contact-rail-item:hover {
  color: var(--vebody-blue-text);
}
.contact-rail-value a {
  color: inherit;
  text-decoration: none;
}
.contact-rail-value a:hover {
  color: var(--vebody-blue-text);
}
.contact-rail-whatsapp {
  margin-left: auto;
  margin-top: 0.15rem;
}
.contact-rail-label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  color: var(--gunmetal-text);
}
.contact-rail-value {
  display: block;
  margin-top: 0.15rem;
  font-size: var(--text-base);
  line-height: 1.4;
}
.contact-rail-static .contact-rail-value {
  color: rgba(245, 246, 247, 0.82);
}

.contact-rail-note {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--hairline-dark);
  font-size: var(--text-xs);
  line-height: 1.5;
  color: var(--gunmetal-text);
}

/* ----------------------------------------------------------
   WhatsApp button. Icon + label in the current text colour
   (never the WhatsApp-brand green) so it sits on any surface.
   ---------------------------------------------------------- */
.whatsapp-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: inherit;
  text-decoration: none;
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  white-space: nowrap;
}
.whatsapp-btn svg {
  flex-shrink: 0;
}
.whatsapp-btn:hover {
  color: var(--vebody-blue-text);
}
.whatsapp-btn-icon {
  padding: 0.2rem;
}

/* WhatsApp hidden sitewide (2026-10-23, client instruction): every
   wa.me link, icon and the "Prefer WhatsApp?" panel stay in the markup —
   delete this rule (and the .whatsapp-only rule below) to switch it back on. */
.whatsapp-btn,
.whatsapp-only {
  display: none !important;
}

/* ----------------------------------------------------------
   Map
   ---------------------------------------------------------- */

.quote-map {
  padding-block: var(--space-7) var(--space-8);
}

.quote-map-frame {
  position: relative;
  margin-top: var(--space-5);
  aspect-ratio: 21 / 8;
  overflow: hidden;
  border: 1px solid var(--hairline-dark);
  filter: grayscale(0.15) contrast(1.05);
}
.quote-map-frame iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

.quote-map-note {
  margin-top: var(--space-3);
  font-size: var(--text-xs);
  color: var(--gunmetal-text);
}

@media (max-width: 720px) {
  .quote-map-frame {
    aspect-ratio: 4 / 3;
  }
}

/* .quote-success and .dropzone-files each set their own `display`,
   which otherwise wins the cascade over the browser's default
   [hidden]{display:none} at equal specificity — restore it explicitly
   so toggling the `hidden` attribute/property actually hides them. */
.quote-success[hidden],
.dropzone-files[hidden] {
  display: none;
}

/* ----------------------------------------------------------
   Repair quote form — single contained column (no contact-rail;
   this page's form is the whole point, not one half of a split
   layout), everything else reused from Contact's quote-form.
   ---------------------------------------------------------- */

.repairs-quote {
  padding-block: var(--space-8);
}

.repairs-quote-wrap {
  max-width: 720px;
}

.repairs-quote .quote-form-head {
  margin-bottom: var(--space-6);
}
.repairs-quote .quote-form-title {
  margin-top: var(--space-3);
  font-size: clamp(1.75rem, 3.2vw, var(--text-3xl));
}

/* No red anywhere on this page: invalid fields and the submission-
   error message use ink/navy with an icon instead of the red used
   on Contact's form. */
.repairs-page .form-field.is-touched input:invalid,
.repairs-page .form-field.is-touched select:invalid,
.repairs-page .form-field.is-touched textarea:invalid {
  border-color: var(--ink);
}
.repairs-page .quote-form-error {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  color: var(--white);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--hairline-dark);
}
/* Same [hidden]-vs-display fix as .quote-success/.dropzone-files below —
   setting our own `display` here wins the cascade over the browser's
   default [hidden]{display:none} at equal specificity. */
.repairs-page .quote-form-error[hidden] {
  display: none;
}
.repairs-page .quote-form-error svg {
  flex-shrink: 0;
  margin-top: 0.1rem;
  color: var(--vebody-blue-text);
}

/* Per-field inline error — the invalid-border colour alone (near-black)
   doesn't read as an error against this page's dark sections, so it's
   paired with an icon + message injected on blur (see initQuoteForm). */
.field-error {
  margin-top: 0.5rem;
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  font-size: var(--text-xs);
  line-height: 1.5;
  color: var(--gunmetal-text);
}
.field-error svg {
  flex-shrink: 0;
  margin-top: 0.15rem;
  color: var(--vebody-blue-text);
}

/* ============================================================
   Product detail pages (/products/[slug]/)
   Reuses existing devices throughout rather than inventing a new
   vocabulary: the masthead pattern from about/products/repairs, the
   .handle-list hairline spec rows from Repairs, .brackets-framed
   images, .img-placeholder for missing photography, and the site's
   own .close CTA band. Only breadcrumb, the uses list and the
   related-products strip are genuinely new, and they borrow the
   existing mono/label typography rather than introducing a new one.
   ============================================================ */

.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  color: var(--gunmetal-text);
}
.breadcrumb a {
  color: var(--gunmetal-text);
  transition: color 200ms var(--ease-out);
}
.breadcrumb a:hover {
  color: var(--white);
}
.breadcrumb [aria-current="page"] {
  color: var(--offwhite);
}

/* ============================================================
   Mobile vertical rhythm
   The desktop section rhythm leans on generous --space-8/--space-9
   padding-block (96-176px) by design. On a phone-height viewport that
   reads as dead scroll distance before content rather than breathing
   room, so it scales down here across every section that uses the
   plain --space-8 measure or the masthead-style extra-top variant,
   rather than carrying the desktop measure straight through. Section
   rhythm (which layout each section uses) is untouched — only the
   amount of air around it.
   ============================================================ */
@media (max-width: 720px) {
  .heritage,
  .repairs,
  .quote-main,
  .quote-map,
  .repairs-quote{
    padding-block: var(--space-6);
  }

    

  .quote-intro {
    padding: calc(var(--space-7) + 1.5rem) 0 var(--space-6);
  }

  .fork {
    padding-top: calc(var(--space-6) + 1.5rem);
    padding-bottom: var(--space-6);
  }

  

  

  .quote-trust {
    gap: var(--space-4) var(--space-6);
  }
}

/* ============================================================
   DESIGN SYSTEM v2 — components (2026-09)
   One version of each: type roles, surfaces, section rhythm,
   labels, hairlines, spec rows, panels, photo slots. See CLAUDE.md.
   ============================================================ */

/* Surfaces: sections are grouped into dark and light bands, not
   alternated one by one. */
.surface-dark {
  --gunmetal-text: #9aa0a8;
  --rule: var(--rule-dark);
  --fg: var(--offwhite);
  --fg-muted: rgba(245, 246, 247, 0.72);
  --accent-text: var(--vebody-blue-text);
  background: var(--black);
  color: var(--fg);
}
.surface-light,
.surface-grey {
  --rule: var(--rule-light);
  --fg: var(--ink);
  --fg-muted: var(--gunmetal-dim);
  --accent-text: var(--vebody-blue);
  background: var(--offwhite);
  color: var(--fg);
}
.surface-grey {
  background: var(--grey-100);
}

.band {
  padding-block: var(--section-y);
}
.band + .band {
  border-top: var(--rule);
}

/* Type roles */
.t-display {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  letter-spacing: -0.025em;
  text-wrap: balance;
}
.t-h2 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-h2);
  line-height: var(--lh-heading);
  letter-spacing: -0.015em;
  text-wrap: balance;
  max-width: 22ch;
}
.t-h3 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-h3);
  line-height: 1.25;
  letter-spacing: -0.005em;
}
.t-lead {
  font-size: var(--fs-lead);
  line-height: 1.55;
  color: var(--fg-muted);
  max-width: var(--measure);
}
.t-body {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--fg-muted);
  max-width: var(--measure);
}
.t-small {
  font-size: var(--fs-small);
  line-height: 1.5;
  color: var(--fg-muted);
}

/* Section label: the one label style, everywhere. Sits above a
   heading with a fixed gap. */
.label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--gunmetal-text);
}
.label + .t-h2,
.label + .t-display,
.label + .t-h3 {
  margin-top: var(--space-3);
}

/* Section head: label, heading, optional lead — same spacing on
   every section. */
.band-head {
  margin-bottom: var(--space-7);
}
.band-head .t-lead {
  margin-top: var(--space-4);
}

/* Secondary button on light surfaces (the base .btn-outline is the
   dark-surface version). */
.surface-light .btn-outline,
.surface-grey .btn-outline {
  border-color: var(--ink);
  color: var(--ink);
}
.surface-light .btn-outline::before,
.surface-grey .btn-outline::before {
  background: var(--ink);
}
.surface-light .btn-outline:hover,
.surface-grey .btn-outline:hover {
  color: var(--white);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-4);
}

/* Spec row: label/value pairs on a measured grid, divided by
   hairlines. Used for company facts and any other hard data. */
.spec {
  display: grid;
  grid-template-columns: repeat(var(--spec-cols, 5), minmax(0, 1fr));
  margin: 0;
  border-top: var(--rule);
  border-bottom: var(--rule);
}
.spec > div {
  padding: var(--space-4) var(--space-4) var(--space-4) 0;
}
.spec > div + div {
  padding-left: var(--space-4);
  border-left: var(--rule);
}
.spec dt {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: 0.04em;
  color: var(--gunmetal-text);
}
.spec dd {
  margin: var(--space-2) 0 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-h3);
  line-height: 1.2;
  color: var(--fg);
}

/* Panel: the one card. Hairline border, square corners, no shadow. */
.panel {
  position: relative;
  display: flex;
  flex-direction: column;
  border: var(--rule);
  background: transparent;
}

/* Tick list: short service lists. */
.ticks {
  display: grid;
  gap: var(--space-2);
  font-size: var(--fs-small);
  color: var(--fg);
}
.ticks li {
  position: relative;
  padding-left: var(--space-4);
}
.ticks li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 10px;
  height: 1px;
  background: var(--accent-text);
}

/* Photo slot: shows its fallback (a drawing, or nothing) until the
   file named in data-photo exists; main.js then swaps the photo in.
   Adding a real photo = adding one file with that name. */
.slot {
  position: relative;
  margin: 0;
  overflow: hidden;
}
.slot > img {
  display: block;
  width: 100%;
  height: 100%;
}
.slot.has-photo > img {
  object-fit: cover;
}
.slot[data-photo-only]:not(.has-photo) {
  display: none;
}

@media (max-width: 860px) {
  .spec {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .spec > div,
  .spec > div + div {
    padding: var(--space-3) var(--space-3) var(--space-3) 0;
    border-left: none;
  }
  .spec > div:nth-child(even) {
    padding-left: var(--space-3);
    border-left: var(--rule);
  }
  .spec > div:nth-child(n+3) {
    border-top: var(--rule);
  }
  .spec > div:last-child:nth-child(odd) {
    grid-column: 1 / -1;
  }
}

/* ============================================================
   HOMEPAGE v2
   ============================================================ */

/* Header phone(s): accessible people read as credible. Office + Mobile,
   each labelled, down to 1180px, where both collapse to an icon-only
   Mobile (the WhatsApp number) + WhatsApp pair. Below 768px that swaps
   to an icon-only Office (the one that actually rings a desk) +
   WhatsApp pair instead, with no text labels at all. */
.nav-phones {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}
.nav-phone {
  display: inline-flex;
  flex-direction: column;
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--white);
  white-space: nowrap;
  line-height: 1.3;
}
.nav-phone-label {
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  color: var(--gunmetal-text);
}
.nav-phone:hover {
  color: var(--vebody-blue-text);
}
.nav-phone svg {
  display: none;
}
.nav-phones .whatsapp-btn-icon {
  color: var(--white);
}
@media (max-width: 1180px) {
  .nav-phone-office {
    display: none;
  }
  .nav-phone-text,
  .nav-phone-mobile .nav-phone-label {
    display: none;
  }
  .nav-phone svg {
    display: block;
  }
  .nav-phone {
    display: inline-flex;
    flex-direction: row;
    padding: var(--space-2);
  }
}
@media (max-width: 768px) {
  .nav-phone-mobile {
    display: none;
  }
  .nav-phone-office {
    display: inline-flex;
    flex-direction: row;
    padding: var(--space-2);
  }
  .nav-phone-office .nav-phone-label,
  .nav-phone-office .nav-phone-text {
    display: none;
  }
  .nav-phone-office svg {
    display: block;
  }
}

/* VEBODY cellphone number retired as a public contact point (2026-10-23,
   client instruction): the office landline is shown everywhere instead.
   Every tel: link for the mobile number stays in the markup under these
   classes — delete this block to show it again at every width. */
.nav-phone-mobile,
.footer-phone-mobile,
.contact-rail-item-mobile {
  display: none;
}
@media (max-width: 1180px) {
  .nav-phone-office {
    display: inline-flex;
    flex-direction: row;
    padding: var(--space-2);
  }
  .nav-phone-office .nav-phone-label,
  .nav-phone-office .nav-phone-text {
    display: none;
  }
  .nav-phone-office svg {
    display: block;
  }
}

/* ---- Hero ---- */
.home-hero,
.page-hero {
  padding-top: calc(84px + var(--space-7));
  padding-bottom: var(--space-7);
}
.home-hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 6fr);
  grid-template-areas:
    "copy photo"
    "paths paths";
  gap: var(--grid-gap);
  align-items: center;
}
.home-hero-copy { grid-area: copy; }
.home-hero-drawing { grid-area: photo; }
.home-hero .paths { grid-area: paths; }
.home-hero .t-display,
.page-hero .t-display {
  max-width: 15ch;
}
.home-hero-tagline {
  margin-top: var(--space-4);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-h3);
  color: var(--fg);
}
.home-hero .t-lead,
.page-hero .t-lead {
  margin-top: var(--space-3);
  max-width: 42ch;
}
/* Header's own "Request a Quote" button is hidden below 1280px (behind
   the collapsed nav), so the mobile hero gets its own clear CTA instead. */
.home-hero-quote-mobile {
  display: none;
}
@media (max-width: 860px) {
  .home-hero-quote-mobile {
    display: inline-block;
    margin-top: var(--space-5);
  }
}
.home-hero-phone {
  display: inline-block;
  margin-top: var(--space-5);
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--fg-muted);
}
.home-hero-phone strong {
  font-weight: 500;
  color: var(--fg);
  border-bottom: 1px solid var(--vebody-blue-text);
}

.home-hero-drawing {
  margin: 0;
}
.home-hero-drawing svg {
  display: block;
  width: 100%;
  height: auto;
}

.parts {
  list-style: none;
  padding-left: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-2) var(--space-4);
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: var(--rule);
  font-size: var(--fs-small);
  color: var(--fg-muted);
  counter-reset: part;
}
.parts li {
  counter-increment: part;
  display: flex;
  gap: var(--space-2);
}
.parts li::before {
  content: counter(part);
  font-family: var(--font-mono);
  color: var(--fg);
  min-width: 1.25em;
}

/* Two equal paths */
.paths {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--grid-gap);
  margin-top: var(--space-7);
}
.path {
  padding: var(--space-5);
  gap: var(--space-2);
  transition: border-color 200ms var(--ease-out), background-color 200ms var(--ease-out);
}
.path:hover {
  border-color: var(--vebody-blue-text);
  /* colour only: panels with their own surface (e.g. carbon) keep it,
     so light text never ends up on a light background */
  background-color: rgba(74, 143, 214, 0.06);
}
.path .t-small {
  max-width: 46ch;
}
.path-cta {
  margin-top: auto;
  padding-top: var(--space-4);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: 600;
  font-size: var(--fs-small);
  color: var(--fg);
}
.path-cta svg {
  transition: transform 200ms var(--ease-out);
}
.path:hover .path-cta svg {
  transform: translateX(4px);
}

/* Assembly: the page's one motion moment. Chassis and cab draw in,
   the subframe follows, the body lowers onto it, then the part
   numbers appear in fitting order. Whole sequence finishes by
   ~2.3s, once, never looping. Static under reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  .asm [pathLength] {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    animation: asm-draw 0.55s var(--ease-out) forwards;
  }
  .asm-ground [pathLength] { animation-duration: 0.4s; }
  .asm-cab [pathLength] { animation-delay: 0.18s; }
  .asm-sub [pathLength] { animation-delay: 0.4s; animation-duration: 0.35s; }
  .asm-body {
    opacity: 0;
    transform: translateY(-36px);
    animation: asm-lower 0.45s var(--ease-out) 0.58s forwards;
  }
  .asm-body [pathLength] {
    animation-delay: 0.58s;
  }
  .asm .callout {
    opacity: 0;
    animation: asm-fade 0.3s ease-out forwards;
    animation-delay: calc(1.1s + var(--i) * 0.08s);
  }
}
@keyframes asm-draw { to { stroke-dashoffset: 0; } }
@keyframes asm-lower { to { opacity: 1; transform: translateY(0); } }
@keyframes asm-fade { to { opacity: 1; } }

/* ---- Two sides of the business ---- */
.sides {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.side {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding-right: var(--grid-gap);
}
.side + .side {
  padding-right: 0;
  padding-left: var(--grid-gap);
  border-left: var(--rule);
}
.side .ticks {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--space-4);
}
.side .btn-row {
  margin-top: auto;
  padding-top: var(--space-3);
}

/* ---- Body types ---- */
.types {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: var(--rule);
  border-left: var(--rule);
}
.type {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  border-right: var(--rule);
  border-bottom: var(--rule);
  transition: background-color 200ms var(--ease-out);
}
a.type:hover {
  background: var(--white);
}
.type .slot {
  aspect-ratio: 840 / 312;
  margin: 0 calc(-1 * var(--space-2)) var(--space-3);
}
.type .slot.has-photo {
  aspect-ratio: 4 / 3;
}
.type .t-small {
  flex: 1;
}
.type-use {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  line-height: 1.5;
  color: var(--gunmetal-text);
}
.type-other {
  justify-content: center;
  background: var(--grey-100);
}

/* ---- Heritage ---- */
.heritage2 {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: calc(var(--grid-gap) * 2);
  align-items: center;
}
.heritage2 .spec {
  --spec-cols: 3;
  margin-top: var(--space-6);
}
.heritage2 .spec dd {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--fs-small);
  line-height: 1.45;
}
.heritage2 .text-link {
  margin-top: var(--space-5);
}

/* ---- Proof ---- */
.proof2 .client-logos-row {
  margin-top: 0;
}
.recent {
  margin-top: var(--space-7);
}
.recent[hidden] {
  display: none;
}
.recent-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-3);
  margin-top: var(--space-4);
}
.recent-grid .slot {
  aspect-ratio: 4 / 3;
}
.recent-grid figcaption {
  position: absolute;
  left: 0;
  bottom: 0;
  padding: var(--space-2) var(--space-3);
  background: rgba(5, 5, 5, 0.72);
  color: var(--white);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
}

/* ---- Repairs ---- */
.repairs2 {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--grid-gap);
  align-items: start;
}
.repairs2 .slot {
  aspect-ratio: 860 / 392;
}
.repairs2 .parts {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.repair-groups {
  display: grid;
  gap: var(--space-5);
}
.repair-groups .t-h3 {
  font-size: var(--fs-body);
  margin-bottom: var(--space-2);
}
.steps {
  list-style: none;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin-top: var(--space-7);
  border-top: var(--rule);
  counter-reset: step;
}
.steps li {
  counter-increment: step;
  padding: var(--space-4) var(--space-4) 0 0;
  font-size: var(--fs-small);
  color: var(--fg-muted);
}
.steps li + li {
  padding-left: var(--space-4);
  border-left: var(--rule);
}
.steps li::before {
  content: '0' counter(step);
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  color: var(--accent-text);
}
.steps strong {
  display: block;
  margin-bottom: var(--space-1);
  font-family: var(--font-display);
  font-size: var(--fs-body);
  color: var(--fg);
}
.repairs2-cta {
  margin-top: var(--space-6);
}

/* ---- Close ---- */
.close2 {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--grid-gap);
  align-items: end;
}
.close2 .btn-row {
  margin-top: var(--space-5);
}
.close2-phone {
  padding: var(--space-5);
}
.close2-phone a {
  display: block;
  margin-top: var(--space-2);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-h2);
  line-height: 1.1;
  color: var(--fg);
}
.close2-phone a:hover {
  color: var(--vebody-blue-text);
}
.close2-phone .whatsapp-btn {
  display: inline-flex;
  margin-top: var(--space-3);
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: var(--fs-small);
  line-height: 1.3;
  color: var(--fg-muted);
}
.close2-phone .whatsapp-btn:hover {
  color: var(--vebody-blue-text);
}

/* ---- Homepage responsive ---- */
@media (max-width: 1100px) {
  .types {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .recent-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 960px) {
  .home-hero-grid,
  .heritage2,
  .repairs2,
  .close2 {
    grid-template-columns: 1fr;
  }
  .home-hero-grid {
    grid-template-areas:
      "copy"
      "photo"
      "paths";
  }
  .sides {
    grid-template-columns: 1fr;
  }
  .side,
  .side + .side {
    padding: 0;
    border-left: none;
  }
  .side + .side {
    margin-top: var(--space-6);
    padding-top: var(--space-6);
    border-top: var(--rule);
  }
}
@media (max-width: 720px) {
  .home-hero,
  .page-hero {
    padding-top: calc(70px + var(--space-6));
  }
  .paths {
    grid-template-columns: 1fr;
    gap: var(--space-3);
    margin-top: var(--space-6);
  }
  .path {
    padding: var(--space-4);
  }
  .parts,
  .repairs2 .parts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .types {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .type {
    padding: var(--space-3);
  }
  .type .slot {
    margin: 0 0 var(--space-2);
  }
  .type .t-h3 {
    font-size: var(--fs-body);
  }
  .type .t-small {
    font-size: 0.8125rem;
  }
  .type-use {
    display: none;
  }
  .steps {
    grid-template-columns: 1fr 1fr;
  }
  .steps li:nth-child(3) {
    padding-left: 0;
    border-left: none;
  }
  .steps li:nth-child(n+3) {
    margin-top: var(--space-4);
  }
  .heritage2 .spec {
    --spec-cols: 1;
  }
  .band-head {
    margin-bottom: var(--space-6);
  }
}

/* ============================================================
   HOMEPAGE v2.1 — blueprint language + motion (2026-09-25)
   ============================================================ */

/* Blue surface: the body-type blueprint sheet. White on VEBODY
   Blue is 10.7:1; muted white stays above 7:1. */
.surface-blue {
  --gunmetal-text: rgba(255, 255, 255, 0.72);
  --rule: 1px solid rgba(255, 255, 255, 0.2);
  --fg: var(--white);
  --fg-muted: rgba(255, 255, 255, 0.8);
  --accent-text: var(--white);
  background-color: var(--vebody-blue);
  color: var(--fg);
}
.surface-blue .text-link {
  color: var(--white);
}

/* Drafting-sheet grid: 24px minor, 120px major, faded at the edges so
   it reads as paper, not pattern. */
.blueprint-grid {
  position: relative;
  isolation: isolate;
  --grid-minor: rgba(74, 143, 214, 0.05);
  --grid-major: rgba(74, 143, 214, 0.11);
}
.surface-blue.blueprint-grid {
  --grid-minor: rgba(255, 255, 255, 0.045);
  --grid-major: rgba(255, 255, 255, 0.1);
}
.blueprint-grid::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(var(--grid-major) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-major) 1px, transparent 1px),
    linear-gradient(var(--grid-minor) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-minor) 1px, transparent 1px);
  background-size: 120px 120px, 120px 120px, 24px 24px, 24px 24px;
  background-position: center top;
  -webkit-mask-image: radial-gradient(ellipse 80% 75% at 60% 45%, #000 40%, transparent 100%);
  mask-image: radial-gradient(ellipse 80% 75% at 60% 45%, #000 40%, transparent 100%);
}

/* Labels carry a short accent rule: the one labelling device. */
.label::before {
  content: '';
  display: inline-block;
  width: 18px;
  height: 1px;
  margin-right: 10px;
  vertical-align: middle;
  background: var(--accent-text, var(--vebody-blue));
}

/* Hero title block, set like the title block of an engineering drawing. */
.title-block {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin-top: var(--space-4);
  border: var(--rule);
}
.title-block > * {
  padding: var(--space-2) var(--space-3);
  font-size: var(--fs-small);
  line-height: 1.35;
  color: var(--fg);
}
.title-block > * + * {
  border-left: var(--rule);
}
.title-block span span,
.title-block div span {
  display: block;
  margin-bottom: 2px;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  color: var(--gunmetal-text);
}

/* Hero visual sits bigger and slightly into the right gutter. */
@media (min-width: 961px) {
  .home-hero-drawing {
    margin-right: calc(-1 * var(--space-5));
  }
}

/* Body-type cards on the blueprint sheet */
.surface-blue .types {
  border-color: rgba(255, 255, 255, 0.2);
}
.surface-blue .type {
  border-color: rgba(255, 255, 255, 0.2);
  transition: background-color 250ms var(--ease-out);
}
.surface-blue a.type:hover {
  background: rgba(255, 255, 255, 0.07);
}
.surface-blue .type-use {
  color: rgba(255, 255, 255, 0.65);
}
.surface-blue .type-other {
  background: rgba(5, 5, 5, 0.18);
}
.type .t-h3 {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-2);
}
a.type .t-h3::after {
  content: '→';
  font-family: var(--font-body);
  font-weight: 400;
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity 200ms var(--ease-out), transform 250ms var(--ease-out);
}
a.type:hover .t-h3::after,
a.type:focus-visible .t-h3::after {
  opacity: 1;
  transform: translateX(0);
}

/* Inlined drawings */
.slot > svg.drawing {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.slot.has-photo > svg.drawing,
.slot.has-photo > img[data-inline] {
  display: none;
}
.dw-body {
  transition: transform 350ms var(--ease-out);
}
a.type:hover .dw-body {
  transform: translateY(-6px);
}

/* Panels + paths: brackets extend on hover (scaled from their own
   corner, transform only) */
.brackets::before,
.brackets::after {
  transition: opacity 280ms var(--ease-out), transform 280ms var(--ease-out);
}
.brackets::before { transform-origin: top left; }
.brackets::after { transform-origin: bottom right; }
.path:hover::before,
.path:hover::after {
  transform: scale(1.5);
}

/* ------------------------------------------------------------
   Motion. Everything below runs only with JS and without a
   reduced-motion preference; otherwise content is simply there.
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: no-preference) {

  /* Hero: copy and paths rise in immediately on their own short
     delays and never wait on the drawing. The assembly draws itself
     (see .asm rules below) in parallel; parts/title-block are timed
     to land right behind its callouts, the whole sequence finishing
     by ~2.3s. */
  .home-hero-copy > *,
  .home-hero .path,
  .home-hero .parts,
  .home-hero .title-block {
    animation: rise 0.8s var(--ease-out) both;
  }
  .home-hero-copy > :nth-child(1) { animation-delay: 0.05s; }
  .home-hero-copy > :nth-child(2) { animation-delay: 0.12s; }
  .home-hero-copy > :nth-child(3) { animation-delay: 0.22s; }
  .home-hero-copy > :nth-child(4) { animation-delay: 0.3s; }
  .home-hero-copy > :nth-child(5) { animation-delay: 0.38s; }
  .home-hero .path:nth-child(1) { animation-delay: 0.5s; }
  .home-hero .path:nth-child(2) { animation-delay: 0.6s; }
  .home-hero .parts { animation-delay: 1.4s; }
  .home-hero .title-block { animation-delay: 1.55s; }

  /* rise: children lift in, staggered */
  .js [data-anim="rise"] > * {
    opacity: 0;
    transform: translateY(22px);
    transition: opacity 0.7s var(--ease-out), transform 0.8s var(--ease-out);
  }
  .js [data-anim="rise"].is-in > * { opacity: 1; transform: none; }
  .js [data-anim="rise"] > :nth-child(2) { transition-delay: 0.08s; }
  .js [data-anim="rise"] > :nth-child(3) { transition-delay: 0.16s; }
  .js [data-anim="rise"] > :nth-child(4) { transition-delay: 0.24s; }
  .js [data-anim="rise"] > :nth-child(5) { transition-delay: 0.32s; }
  .js figure[data-anim="rise"] { opacity: 0; transform: translateY(22px); transition: opacity 0.7s var(--ease-out) 0.15s, transform 0.8s var(--ease-out) 0.15s; }
  .js figure[data-anim="rise"] > * { opacity: 1; transform: none; }
  .js figure[data-anim="rise"].is-in { opacity: 1; transform: none; }

  /* stagger: direct children fade up one after another */
  .js [data-anim="stagger"] > * {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.6s var(--ease-out), transform 0.7s var(--ease-out);
  }
  .js [data-anim="stagger"].is-in > * { opacity: 1; transform: none; }
  .js [data-anim="stagger"] > :nth-child(2) { transition-delay: 0.07s; }
  .js [data-anim="stagger"] > :nth-child(3) { transition-delay: 0.14s; }
  .js [data-anim="stagger"] > :nth-child(4) { transition-delay: 0.21s; }
  .js [data-anim="stagger"] > :nth-child(5) { transition-delay: 0.28s; }

  /* draw: each body-type drawing traces itself, chassis then body */
  .js [data-anim="draw"] .type {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 0.6s var(--ease-out) var(--d, 0ms), transform 0.7s var(--ease-out) var(--d, 0ms);
  }
  .js [data-anim="draw"].is-in .type { opacity: 1; transform: none; }
  .js [data-anim="draw"] .drawing [pathLength] {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
  }
  .js [data-anim="draw"].is-in .drawing .dw-base [pathLength] {
    animation: asm-draw 1.1s var(--ease-out) forwards;
    animation-delay: calc(var(--d, 0ms) + 0.15s);
  }
  .js [data-anim="draw"].is-in .drawing .dw-body [pathLength] {
    animation: asm-draw 1.2s var(--ease-out) forwards;
    animation-delay: calc(var(--d, 0ms) + 0.7s);
  }

  /* callouts: repair areas marked one by one */
  .js [data-anim="callouts"] .drawing .callout {
    opacity: 0;
    transform: scale(0.6);
    transform-box: fill-box;
    transform-origin: center;
    transition: opacity 0.4s var(--ease-out), transform 0.5s var(--ease-out);
  }
  .js [data-anim="callouts"].is-in .drawing .callout {
    opacity: 1;
    transform: none;
    transition-delay: calc(0.2s + var(--i) * 0.12s);
  }

  /* steps: a line runs across the process, each step lands in turn */
  .js [data-anim="steps"] {
    position: relative;
  }
  .js [data-anim="steps"]::before {
    content: '';
    position: absolute;
    left: 0;
    top: -1px;
    width: 100%;
    height: 1px;
    background: var(--accent-text);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 1.4s var(--ease-out);
  }
  .js [data-anim="steps"].is-in::before { transform: scaleX(1); }
  .js [data-anim="steps"] > li {
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 0.5s var(--ease-out), transform 0.6s var(--ease-out);
  }
  .js [data-anim="steps"].is-in > li { opacity: 1; transform: none; }
  .js [data-anim="steps"] > li:nth-child(2) { transition-delay: 0.3s; }
  .js [data-anim="steps"] > li:nth-child(3) { transition-delay: 0.6s; }
  .js [data-anim="steps"] > li:nth-child(4) { transition-delay: 0.9s; }
}
@keyframes rise {
  from { opacity: 0; transform: translateY(22px); }
  to { opacity: 1; transform: none; }
}

@media (max-width: 720px) {
  .title-block {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .title-block > :nth-child(3) {
    border-left: none;
  }
  .title-block > :nth-child(n+3) {
    border-top: var(--rule);
  }
  .blueprint-grid::before {
    background-size: 96px 96px, 96px 96px, 16px 16px, 16px 16px;
  }
}

/* ============================================================
   ABOUT PAGE: layouts the homepage doesn't have. Built only
   from existing tokens and components (panel, label, t-*).
   ============================================================ */

/* Hero key-facts strip sits under the headline */
.page-hero-spec {
  margin-top: var(--space-7);
}

/* A section head inside a two-column layout sits at the top of its
   column; the grid gap does the spacing. */
.split > .band-head,
.heritage2 > .band-head {
  margin-bottom: 0;
}

/* Story: short paragraphs with even spacing */
.prose {
  display: grid;
  gap: var(--space-4);
}

/* 5/7 split: a narrow column beside a wide one */
.split {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--grid-gap);
  align-items: start;
}


/* Workshop fact cards */
.facts {
  display: grid;
  gap: var(--space-3);
}
.fact {
  gap: var(--space-2);
  padding: var(--space-4);
}

/* Two-column tick list */
.ticks-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--space-5);
}

/* Drawing inside a panel */
.path .home-hero-drawing {
  margin-top: var(--space-4);
}
.path .title-block {
  margin-bottom: var(--space-2);
}

@media (max-width: 1100px) {
}
@media (max-width: 960px) {
  .split {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 720px) {
  .ticks-2 {
    grid-template-columns: 1fr;
  }
}

/* ============================================================
   PRODUCTS: layouts the homepage doesn't have. Existing tokens,
   type roles and components only.
   ============================================================ */

/* Hero CTA row takes the hero grid's third row (after copy on phones) */
.hero-cta {
  grid-area: paths;
}

/* Breadcrumb: mono label style, slash separators */
.breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: 0 0 var(--space-4);
  padding: 0;
  list-style: none;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: 0.04em;
  color: var(--gunmetal-text);
}
.breadcrumb li + li::before {
  content: '/';
  margin-right: var(--space-2);
}
.breadcrumb a:hover,
.breadcrumb a[aria-current] {
  color: var(--fg);
}

/* Industry filter: chips are small outline buttons; the pressed one
   takes the primary fill. Non-matching bodies dim. */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.chips[hidden] {
  display: none;
}
.chip {
  padding: 0.6rem 1.1rem;
}
.surface-blue .chip {
  border-color: rgba(255, 255, 255, 0.45);
}
.chip[aria-pressed="true"] {
  background: var(--white);
  border-color: var(--white);
  color: var(--vebody-blue);
}
.type {
  transition: background-color 250ms var(--ease-out), opacity 250ms var(--ease-out);
}
/* Three-up card grid (six "other" bodies) */
.types-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* Spec table: label/value rows on hairlines, like .spec */
.spec-table {
  width: 100%;
  border-collapse: collapse;
  border-top: var(--rule);
}
.spec-table th,
.spec-table td {
  padding: var(--space-3) 0;
  border-bottom: var(--rule);
  text-align: left;
  vertical-align: top;
}
.spec-table th {
  width: 40%;
  padding-right: var(--space-4);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--gunmetal-text);
}
.spec-table td {
  font-size: var(--fs-body);
  color: var(--fg);
}
.tbc {
  color: var(--gunmetal-text);
}
.spec-download {
  margin-top: var(--space-4);
}
.spec-download:not(:has(a:not([hidden]))) {
  display: none;
}

/* FAQs: hairline rows that open in place */
.faqs {
  border-top: var(--rule);
}
.faq {
  border-bottom: var(--rule);
}
.faq summary {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-body);
  color: var(--fg);
}
.faq summary::-webkit-details-marker {
  display: none;
}
.faq summary::after {
  content: '+';
  font-family: var(--font-mono);
  color: var(--accent-text);
}
.faq[open] summary::after {
  content: '\2212';
}
.faq .t-body {
  padding-bottom: var(--space-4);
}

@media (max-width: 1100px) {
  .types-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 720px) {
  .types-3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ============================================================
   Carbon fibre (brand texture), subtle. One class: the weave sits
   under a 95.5% black overlay. The photographed weave is high-contrast,
   so at 90% (10% showing) it read as stripes that competed with the
   content; this setting was tuned by screenshot until type comes first. Only on the header, the
   footer, closing sections and text-only CTA panels; never behind
   body copy, forms, drawings or spec tables.
   ============================================================ */
.surface-carbon {
  --gunmetal-text: #9aa0a8;
  --rule: var(--rule-dark);
  --fg: var(--offwhite);
  --fg-muted: rgba(245, 246, 247, 0.72);
  --accent-text: var(--vebody-blue-text);
  color: var(--fg);
  background-color: var(--black);
  background-image:
    linear-gradient(rgba(5, 5, 5, 0.955), rgba(5, 5, 5, 0.955)),
    url('../images/carbon.jpg');
  background-image:
    linear-gradient(rgba(5, 5, 5, 0.955), rgba(5, 5, 5, 0.955)),
    image-set(url('../images/carbon.webp') type('image/webp'), url('../images/carbon.jpg') type('image/jpeg'));
  background-size: auto, 320px 320px;
  background-repeat: repeat;
}
.nav.surface-carbon {
  background-color: var(--black);
}

/* Body-type cards: line drawings only, in a 3:2 tile. */
.types-photo .slot {
  aspect-ratio: 3 / 2;
  margin: 0 0 var(--space-3);
}
/* Cards with a matching photo (scripts/build-products.py PHOTOS):
   the drawing sits in the same dark tile as photo-less cards; on
   desktop the real photo crossfades in on hover/focus. Mobile has no
   reliable hover, so the photo shows by default with the drawing as
   a small corner detail instead. */
.types-photo .type-photo {
  position: relative;
  padding: var(--space-3);
  background: rgba(5, 5, 5, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.16);
}
.types-photo .type-photo > img:first-child {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.type-photo-img {
  position: absolute;
  inset: 0;
  opacity: 0;
}
@media (min-width: 721px) {
  .type-photo-img {
    transition: opacity 450ms var(--ease-out);
  }
  a.type:hover .type-photo-img,
  a.type:focus-visible .type-photo-img {
    opacity: 1;
  }
}
@media (max-width: 720px) {
  .types-photo .type-photo {
    padding: 0;
    background: none;
    border: none;
  }
  .type-photo-img {
    opacity: 1;
  }
  .types-photo .type-photo > img:first-child {
    position: absolute;
    left: var(--space-2);
    bottom: var(--space-2);
    width: 36px;
    height: 36px;
    padding: 5px;
    background: rgba(5, 5, 5, 0.82);
    border: 1px solid rgba(255, 255, 255, 0.3);
  }
}
/* Nine-card grids (homepage, products hub): three across, no gaps */
@media (min-width: 1101px) {
  .types-9 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* "Not sure which body?": a slim band under the grid */
.types-cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4) var(--grid-gap);
  flex-wrap: wrap;
  margin-top: var(--space-5);
  padding: var(--space-4) var(--space-5);
  border: var(--rule);
}
.types-cta .t-small {
  margin-top: var(--space-1);
}

/* Product hero: Illustration / Photo switch (drawing is the default) */
.view-switch {
  margin-bottom: var(--space-4);
}
.view-panel[hidden] {
  display: none;
}
.view-photo img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}

/* ---- Repairs page ---- */
.repair-groups-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--grid-gap);
}
.page-index ol {
  margin: var(--space-5) 0 0;
  gap: var(--space-2) var(--space-4);
}
.page-index li + li::before {
  content: none;
}
.page-index a {
  border-bottom: 1px solid var(--hairline-dark);
}
.before-after {
  display: grid;
  gap: var(--space-5);
}
.ba-item {
  margin: 0;
}
/* Drag-to-reveal slider (js/main.js initCompareSlider): the "before"
   photo is the base layer, the "after" wrap clips over it. Reset the
   .compare component's own margin/shadow (built for a single hero-
   adjacent use) for this plain 3-up grid. */
.before-after .compare {
  margin-left: 0;
  box-shadow: none;
  border: var(--rule);
}
.compare > img:first-child {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.compare-after-wrap > img {
  display: block;
  height: 100%;
  object-fit: cover;
}
/* Drawing fallback shown until initComparePhotos (js/main.js) swaps
   in a real before/after pair. */
.compare-placeholder {
  object-fit: contain !important;
  padding: var(--space-4);
  opacity: 0.55;
  background: var(--grey-100);
}
.ba-caption {
  margin-top: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gunmetal-text);
}
/* No-JS form results: the PHP handler redirects to #quote-sent or
   #quote-failed, and :target shows the matching message. */
.quote-success[hidden]:target,
.repairs-page .quote-form-error[hidden]:target,
.contact-page .quote-form-error[hidden]:target {
  display: flex;
}
@media (max-width: 860px) {
  .repair-groups-3 {
    grid-template-columns: 1fr;
  }
}

/* ---- Industries carousel (products hub) ---- */
.carousel-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: var(--space-4);
  margin-bottom: var(--space-7);
}
.carousel-head .band-head {
  margin-bottom: 0;
}
.carousel-controls[hidden] {
  display: none;
}
.carousel-controls .chip:disabled {
  opacity: 0.35;
  cursor: default;
}
.carousel-track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(280px, calc((100% - 2 * var(--space-4)) / 3));
  gap: var(--space-4);
  margin: 0;
  padding: 0 0 var(--space-3);
  list-style: none;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: thin;
}
.carousel-track:focus-visible {
  outline: 2px solid var(--vebody-blue-text);
  outline-offset: 4px;
}
.industry {
  scroll-snap-align: start;
  gap: var(--space-2);
  padding: var(--space-5) var(--space-4);
}
.industry-drawing {
  display: block;
  width: 100%;
  height: auto;
  margin-bottom: var(--space-3);
  opacity: 0.8;
}
.industry-bodies {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  margin: auto 0 0;
  padding: var(--space-3) 0 0;
  list-style: none;
  border-top: var(--rule);
}
@media (prefers-reduced-motion: reduce) {
  .carousel-track {
    scroll-behavior: auto;
  }
}
@media (max-width: 720px) {
  .carousel-track {
    grid-auto-columns: 82%;
  }
  .carousel-head {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* Links inside paragraphs keep the link colour, not the muted body colour */
.t-body .text-link,
.t-lead .text-link,
.t-small .text-link {
  color: var(--fg);
}

/* When a product has no confirmed build options yet (build-products.py
   comments the whole "Build options" .side out), the remaining .side
   takes the full width instead of leaving an empty second column. */
.sides:has(> .side:only-child) {
  grid-template-columns: minmax(0, 1fr);
}

/* Three fact cards in a row ("How we work" on product pages) */
.facts-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
  align-items: stretch;
}
.facts-3 .ticks-2 {
  margin: var(--space-2) 0;
}
@media (max-width: 960px) {
  .facts-3 {
    grid-template-columns: 1fr;
  }
}

/* Homepage: the logo is the brand's first impression, so it's larger in
   the header here (client request). Same header component, page class. */
.home .nav-mark img {
  height: 88px;
}
.home .home-hero {
  padding-top: calc(108px + var(--space-7));
}
/* Just above the menu breakpoint the full bar is tight: step the
   homepage logo down a little so the links stay on one line. */
@media (max-width: 1320px) {
  .home .nav-mark img {
    height: 72px;
  }
}
@media (max-width: 1240px) {
  .home .nav-mark img {
    height: 64px;
  }
}
@media (max-width: 520px) {
  .home .nav-mark img {
    height: 54px;
  }
  .home .home-hero {
    padding-top: calc(74px + var(--space-6));
  }
}


/* Before/after: three pairs side by side on desktop, stacked on phones */
@media (min-width: 961px) {
  .before-after {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--grid-gap);
  }
}

/* ============================================================
   Photo feature: the one treatment for every photo. Framed photo
   (brackets, hairline, its own ratio) with a label, title and spec
   list beside it, like the title block under a drawing. Always a
   full row of its own, below the section's content.
   ============================================================ */
.photo-row {
  margin-top: var(--space-7);
}
.photo-row + .photo-row,
.photo-row .photo-feature + .photo-feature {
  margin-top: var(--space-6);
}
.photo-feature {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--grid-gap);
  align-items: center;
}
.photo-feature-frame {
  margin: 0;
  overflow: hidden;
  border: var(--rule);
}
.photo-feature-frame picture,
.photo-feature-frame img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.photo-feature-text {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.photo-feature-text .spec {
  margin-top: var(--space-2);
  grid-template-columns: 1fr;
}
.photo-feature-text .spec > div:nth-child(n) {
  padding-left: 0;
  border-left: none;
  grid-column: auto;
}
.photo-feature-text .spec > div {
  display: grid;
  grid-template-columns: 7rem 1fr;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  border-left: none;
}
.photo-feature-text .spec > div + div {
  border-top: var(--rule);
}
.photo-feature-text .spec dd {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--fs-small);
}
@media (max-width: 960px) {
  .photo-feature {
    grid-template-columns: 1fr;
  }
}

/* ============================================================
   Homepage refinements (29 Sept)
   ============================================================ */

/* Showcase: full-width photo, one horizontal caption row under it */
.photo-row-showcase {
  margin-top: var(--section-y);
}
.photo-feature-wide {
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
}
.photo-feature-caption {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
  gap: var(--grid-gap);
  align-items: center;
  padding-top: var(--space-4);
}
.photo-feature-caption .t-h3 {
  margin-top: var(--space-2);
}
.photo-feature-caption .spec {
  border-bottom: none;
}

/* Heritage: very large year, stronger timeline, photo + quote */
.heritage3 {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--grid-gap);
  align-items: end;
}
.heritage3-year {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(6rem, 2rem + 13vw, 15rem);
  line-height: 0.8;
  letter-spacing: -0.05em;
  color: var(--vebody-blue);
}
.heritage3-text .t-lead {
  margin-top: var(--space-4);
}
.heritage3-text .text-link {
  margin-top: var(--space-5);
}
.timeline3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
  margin: var(--space-6) 0 0;
  padding: 0;
  list-style: none;
  border-top: 2px solid var(--vebody-blue);
}
.timeline3 li {
  position: relative;
  padding-top: var(--space-4);
  font-size: var(--fs-small);
  line-height: 1.45;
  color: var(--fg);
}
.timeline3 li::before {
  content: '';
  position: absolute;
  top: -7px;
  left: 0;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--offwhite);
  border: 2px solid var(--vebody-blue);
}
.timeline3-when {
  display: block;
  margin-bottom: var(--space-2);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--fs-h3);
  color: var(--vebody-blue);
}
.heritage3-media {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--grid-gap);
  align-items: center;
  margin-top: var(--space-7);
}

/* Truck brands: their own hairline row */
.brand-row {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(0, 9fr);
  gap: var(--grid-gap);
  align-items: center;
  margin-top: var(--section-y);
  padding: var(--space-5) 0;
  border-top: var(--rule);
  border-bottom: var(--rule);
}
.brand-row-head .t-small {
  margin-top: var(--space-2);
}
.brand-row-list {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}
.brand-row-list li {
  padding: var(--space-3) var(--space-4);
  border-left: var(--rule);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-body);
  color: var(--fg);
}
.brand-row-list li:nth-child(n+5) {
  border-top: var(--rule);
}

/* Dark repairs section into the carbon close: a visible seam */
.surface-dark + .surface-carbon {
  position: relative;
  border-top: 1px solid rgba(255, 255, 255, 0.18);
}
.surface-dark + .surface-carbon::before {
  content: '';
  position: absolute;
  top: -1px;
  left: 0;
  width: 96px;
  height: 2px;
  background: var(--vebody-blue-text);
}

@media (max-width: 960px) {
  .heritage3,
  .heritage3-media,
  .brand-row,
  .photo-feature-caption {
    grid-template-columns: minmax(0, 1fr);
  }
}
@media (max-width: 720px) {
  .timeline3 {
    grid-template-columns: minmax(0, 1fr);
    border-top: none;
    border-left: 2px solid var(--vebody-blue);
    padding-left: var(--space-4);
    gap: var(--space-4);
  }
  .timeline3 li {
    padding-top: 0;
  }
  .timeline3 li::before {
    top: 4px;
    left: calc(-1 * var(--space-4) - 7px);
  }
  .brand-row-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .brand-row-list li:nth-child(odd) {
    border-left: none;
    padding-left: 0;
  }
  .brand-row-list li:nth-child(n+3) {
    border-top: var(--rule);
  }
}

/* A <picture> inside a photo slot fills the slot like a plain <img> */
.slot > picture {
  display: block;
  width: 100%;
  height: 100%;
}
.slot > picture img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Cards without a photo: the drawing sits in the same framed 3:2 tile
   as the photo cards, so every card in the grid has the same visual. */
.types-photo .slot:not(.type-photo) {
  padding: var(--space-3);
  background: rgba(5, 5, 5, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.16);
}
.types-photo .slot:not(.type-photo) > .drawing,
.types-photo .slot:not(.type-photo) > img {
  object-fit: contain;
}

/* Heritage: quote card sits on the bottom edge of the workshop photo */


/* ============================================================
   Real photos (29 Sept): their own sections, never over drawings.
   Hairline frame, corner brackets, cover crop, mono caption.
   ============================================================ */
.build-photo {
  margin: 0;
}
.build-photo-frame {
  position: relative;
  overflow: hidden;
  border: var(--rule);
}
.build-photo-frame picture,
.build-photo-frame picture img,
.build-photo-frame > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--pos, 50% 50%);
}
.build-photo-drawing {
  padding: var(--space-5);
  background: var(--white);
}
.build-photo-drawing > img {
  object-fit: contain;
}
.build-caption {
  padding-top: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gunmetal-text);
}
/* Feature: full container width, 21:9, capped at 520px tall (the cap
   crops a little top and bottom rather than narrowing the frame) */
.build-gallery > .build-photo:first-child .build-photo-frame {
  width: 100%;
  aspect-ratio: auto !important;
  height: min(520px, calc(min(100vw - 2 * var(--page-gutter), var(--max-content)) * 9 / 21));
}
.build-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--grid-gap);
  margin-top: var(--space-6);
}
.build-row:has(> :nth-child(2):last-child) {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.build-row .build-photo-frame {
  aspect-ratio: 3 / 2;
}
.build-more {
  margin-top: var(--space-6);
}

/* Fleet strip: full-bleed photo directly under the hero, no side
   margins, a mono caption underneath. */
.fleet-strip {
  padding: 0;
}
.fleet-strip-photo {
  margin: 0;
  overflow: hidden;
  height: 55vh;
}
.fleet-strip-photo picture,
.fleet-strip-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 62%;
}
.fleet-strip-caption {
  padding: var(--space-3) 0 var(--space-5);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
@media (max-width: 720px) {
  .fleet-strip-photo {
    height: auto;
    aspect-ratio: 16 / 9;
  }
}
/* Desktop: lean the crop up so the VEBODY wall sign is in frame,
   rather than mostly empty workshop floor. */
@media (min-width: 1024px) {
  .fleet-strip-photo img {
    object-position: 50% 90%;
  }
}
/* Subtle scroll-linked zoom, max 5%: a progressive enhancement, inert
   without animation-timeline support, and off under reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .fleet-strip-photo img {
      animation: fleet-zoom 1s linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 60%;
    }
  }
}
@keyframes fleet-zoom {
  from { transform: scale(1); }
  to { transform: scale(1.05); }
}
.drawn-built {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--grid-gap);
}
.recent-builds {
  margin-top: var(--space-7);
}
.recent-builds .build-row {
  margin-top: var(--space-4);
}

/* Heritage: portrait workshop photo; quote card the same height,
   its text sitting on the bottom edge */
.heritage3-media {
  grid-template-columns: minmax(0, 440px) minmax(0, 480px);
  align-items: stretch;
}
@media (max-width: 960px) {
  .build-row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .heritage3-media {
    grid-template-columns: minmax(0, 1fr);
  }
  .heritage3-media .photo-feature-frame {
    max-width: 440px;
  }
}
@media (max-width: 720px) {
  .build-row,
  .drawn-built {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* "Add-on" marker beside a card title (Trailers) */
.type-tag {
  margin-right: auto;
  margin-left: var(--space-2);
  padding: 2px var(--space-2);
  border: var(--rule);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: 400;
  letter-spacing: 0.04em;
  color: var(--gunmetal-text);
  white-space: nowrap;
}

/* Mobile header: logo centred and a little larger; phone icon left,
   menu button right. */
@media (max-width: 720px) {
  .nav {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
  }
  .nav-mark {
    grid-column: 2;
    grid-row: 1;
    justify-self: center;
  }
  .nav-phones {
    grid-column: 1;
    grid-row: 1;
    justify-self: start;
  }
  .nav-toggle {
    grid-column: 3;
    grid-row: 1;
    justify-self: end;
  }
  .nav-mark img,
  .home .nav-mark img {
    height: 52px;
  }
  .home .nav-mark img {
    height: 60px;
  }
  .home-hero,
  .page-hero {
    padding-top: calc(80px + var(--space-6));
  }
  .home .home-hero {
    padding-top: calc(88px + var(--space-6));
  }
}

/* Location map band (shared, above the footer) */
.map-grid {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
  gap: var(--grid-gap);
  align-items: stretch;
}
.map-text {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: flex-start;
}
.map-text .t-h3 {
  margin-top: var(--space-2);
}
.map-hours {
  width: 100%;
  margin: var(--space-4) 0;
  grid-template-columns: 1fr;
}
.map-hours > div:nth-child(n) {
  display: grid;
  grid-template-columns: 7rem 1fr;
  align-items: baseline;
  padding: var(--space-2) 0;
  border-left: none;
}
.map-hours > div + div {
  border-top: var(--rule);
}
.map-hours dd {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--fs-small);
}
.map-frame {
  position: relative;
  min-height: 360px;
  border: var(--rule);
  overflow: hidden;
}
.map-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  /* muted to sit with the black/blue palette; full colour on hover */
  filter: grayscale(1) contrast(1.05);
  transition: filter 300ms var(--ease-out);
}
.map-frame:hover iframe {
  filter: none;
}
@media (max-width: 860px) {
  .map-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .map-frame {
    min-height: 300px;
  }
}


/* ============================================================
   Pre-launch refinements (2026-09-30)
   ============================================================ */

/* Heritage: the quote card sizes to its content and sits on the
   photo's bottom edge, instead of stretching into an empty box. */
.heritage3-media {
  grid-template-columns: minmax(0, 440px) minmax(0, 560px);
  align-items: end;
}

/* Heritage: the quote card was removed (no live quote to show); the
   photo takes the column alone, at the same size it was paired at. */
.heritage3-media:has(> :only-child) {
  grid-template-columns: minmax(0, 1fr);
}
.heritage3-media:has(> :only-child) .photo-feature-frame {
  max-width: 440px;
}

/* Client logos: equal optical weight, not equal height. Wide
   wordmarks sit lower, compact marks sit taller. */
.client-logo { height: calc(var(--logo-h, 40px) * var(--logo-scale, 1)); }
.client-logo[src*="isuzu"]                     { --logo-h: 34px; }
.client-logo[src*="ud-trucks"]                 { --logo-h: 66px; }
.client-logo[src*="foton"]                     { --logo-h: 56px; }
.client-logo[src*="orbit-commercial-vehicles"] { --logo-h: 44px; }
.client-logo[src*="city-of-cape-town"]         { --logo-h: 50px; }
@media (max-width: 960px) {
  .client-logo { --logo-scale: 0.8; height: calc(var(--logo-h, 40px) * var(--logo-scale, 1)); }
}
