/* ==========================================================================
   OMEGA AUTOBODY — Visual System v2
   Direction: quiet luxury, precision craftsmanship. Dark, tactile, restrained.

   Two rules govern everything below:
     1. Blue appears ONLY on primary CTAs and true interactive affordances.
        Never on icons, never decorative. Everything else is silver/gunmetal.
     2. Nothing is rounded, bouncy, or bright. Corners are near-sharp, motion
        is slow and eased-out, contrast does the work instead of colour.
   ========================================================================== */

:root {

  /* ======================================================================
     PALETTE — light.

     Surfaces are near-white, text is graphite, and the single accent is
     steel blue reserved for primary CTAs and real interactive affordances.

     The site was originally built dark and converted; the transitional
     `--ink-*` / `--silver-*` aliases that made that possible have been
     removed. If you find one in a diff or an old branch, it is dead — the
     mapping is in DESIGN.md 1.1 and verify.py check 13 fails the build on
     any that reappear. `--silver-100` in particular used to be the
     BRIGHTEST text and now maps to the DARKEST, which is exactly the sort
     of trap the removal exists to prevent.

     The footer is the one dark block. It re-declares these same tokens with
     dark values further down; see DESIGN.md 1.8.
     ====================================================================== */

  /* ---- Surfaces -------------------------------------------------------- */
  --surface-page:   #FFFFFF;   /* page background */
  --surface-band:   #F6F6F4;   /* alternating section band */
  --surface-card:   #FFFFFF;   /* card face */
  --surface-sunken: #EFEFEC;   /* trust bar, deepest field */
  --surface-hover:  #F4F4F2;   /* hover surface */

  /* ---- Hairlines -------------------------------------------------------
     Alpha-black, never a solid grey, so they sit correctly on any surface
     beneath them and read as an edge catching light, not as a drawn box. */
  --line:         rgba(0, 0, 0, 0.09);
  --line-soft:    rgba(0, 0, 0, 0.055);
  --line-strong:  rgba(0, 0, 0, 0.17);

  /* ---- Text (graphite) -------------------------------------------------
     Graphite stays NEUTRAL against the cool surfaces on purpose. Tinting the
     text blue as well would push the whole page toward a single hue and lose
     the metal reading; the faint blue-green cast already in --graphite-500 is
     enough.

     Re-derived after the grounds went back to neutral. Worst case is the
     sunken band: 17.1 / 11.8 / 6.2 / 5.0. Against the page itself:
     19.7 / 13.6 / 7.1 / 5.8. Near-neutral grounds are pale, so this
     ramp has more headroom than the tinted one did. tools/contrast_audit.py re-measures every
     rendered text node against its real background and must stay clean.

     --graphite-100 is BORDERS ONLY at ~1.5:1. Never put words in it;
     verify.py check 12 fails the build if you do. */
  --graphite-900: #0B0B0C;   /* headings, high-emphasis */
  --graphite-700: #2C2E31;   /* body copy */
  --graphite-500: #55585E;   /* secondary body, ALL icons */
  --graphite-300: #63666C;   /* tertiary, labels, placeholders */
  --graphite-100: #E4E4E0;   /* borders and rules only — never text */

  /* White is for text sitting ON steel (buttons, skip link, selection).
     It is NOT a surface token — use --surface-page for that. */
  --white:        #FFFFFF;

  /* ---- Steel (accent — CTAs and interaction only) --------------------- */
  --steel:        #0B5FFF;
  --steel-hover:  #0A4CD6;
  --steel-deep:   #0838A0;
  --steel-glow:   rgba(11, 95, 255, 0.42);

  /* Review stars only. This is ICONOGRAPHY, not a second accent colour —
     a gold star is a universally read symbol, the way a red heart is, and
     reading it as "brand colour" is what would break the palette rule.
     Never use it for text, borders, backgrounds or anything else.
     #B8860B is the lightest gold that clears the 3:1 non-text threshold on
     white; #C9971F (2.65:1) and #D4A017 (2.38:1) both fail. */
  --star:         #B8860B;

  /* ---- Type ----------------------------------------------------------- */
  /* One family, carrying hierarchy through weight, width and tracking rather
     than through a second typeface. The serif accent that previously set the
     index numerals was dropped with them — it is no longer downloaded. */
  --font-sans:    'Archivo', 'Helvetica Neue', Helvetica, Arial, sans-serif;

  /* ---- Spacing scale (8px base, widening at the top for air) ---------- */
  --sp-1:  0.25rem;   /*  4 */
  --sp-2:  0.5rem;    /*  8 */
  --sp-3:  0.75rem;   /* 12 */
  --sp-4:  1rem;      /* 16 */
  --sp-5:  1.5rem;    /* 24 */
  --sp-6:  2rem;      /* 32 */
  --sp-7:  3rem;      /* 48 */
  --sp-8:  4rem;      /* 64 */
  --sp-9:  6rem;      /* 96 */
  --sp-10: 8rem;      /* 128 */
  --sp-11: 11rem;     /* 176 */

  /* Section rhythm — deliberately generous. This is most of the "expensive". */
  --section-y:    clamp(5.5rem, 11vw, 10rem);
  --gutter:       clamp(1.5rem, 5vw, 4rem);
  --maxw:         1320px;
  --maxw-text:    1140px;
  --maxw-narrow:  720px;

  /* ---- Form ----------------------------------------------------------- */
  --radius:       2px;      /* near-sharp. Never "startup rounded". */
  --radius-lg:    3px;

  /* ---- Motion — expo-out. Slow, cinematic, never bouncy. -------------- */
  --ease:         cubic-bezier(0.22, 1, 0.36, 1);
  --ease-inout:   cubic-bezier(0.65, 0, 0.35, 1);
  --t-fast:       220ms;
  --t-mid:        420ms;
  --t-slow:       900ms;

  --header-h:     84px;
}

/* --------------------------------------------------------------------------
   DARK ISLAND — the footer, and only the footer.

   It re-declares the palette tokens with dark values, so every descendant
   picks them up through the cascade without needing a single component rule
   rewritten. Anything added inside the footer inherits the dark treatment
   for free — that is the whole point of scoping it this way rather than
   writing `.footer .thing` overrides.

   Why it is dark: the client asked for it, and `images/whitelogo.png` (the
   DSB credit mark) is white on transparent and is the only version we hold.
   Either reason alone is sufficient. The mark is DSB's own artwork, so a
   dark-on-light export is obtainable if the decision ever changes.

   Contrast inside here is measured against #0A0A0A, not against the light
   surfaces — tools/contrast_audit.py resolves the real background per node,
   so it covers both without special-casing.
   -------------------------------------------------------------------------- */
.footer,
.section--deep {
  --surface-page:   #081A3F;
  --surface-band:   #0C2149;
  --surface-card:   #102954;
  --surface-sunken: #05122C;
  --surface-hover:  #16315F;

  --line:        rgba(255, 255, 255, 0.07);
  --line-soft:   rgba(255, 255, 255, 0.045);
  --line-strong: rgba(255, 255, 255, 0.14);

  --graphite-900: #FFFFFF;
  --graphite-700: #CBD6E8;
  --graphite-500: #9DACC4;
  --graphite-300: #7D8CA6;
  --graphite-100: #33456B;

  color: var(--graphite-700);
}

/* --------------------------------------------------------------------------
   Reset
   -------------------------------------------------------------------------- */

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

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

body {
  margin: 0;
  background: var(--surface-page);
  color: var(--graphite-700);
  font-family: var(--font-sans);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.75;
  font-variation-settings: 'wdth' 100;
  letter-spacing: 0.004em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* Film grain. Sits above the page, below content. This is what stops large
   flat black areas reading as "empty div" and makes them read as photographic. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  /* On the dark build this was `overlay` at 0.16, which lifted flat black out
     of "empty div" territory. Overlay on white just reads as dirt, so the
     light theme uses multiply at a much lower strength — enough to keep large
     white fields from looking like untextured paper, not enough to see. */
  opacity: 0.045;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");
}

img, svg, video { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }

/* --------------------------------------------------------------------------
   Type scale
   Weight + tracking contrast carries the hierarchy. Large sizes get tighter
   tracking and slightly expanded width — the detail that separates
   art-directed from default.
   -------------------------------------------------------------------------- */

h1, h2, h3, h4 {
  color: var(--graphite-900);
  font-family: var(--font-sans);
  margin: 0 0 0.55em;
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.75rem, 6.6vw, 6.25rem);
  font-weight: 700;
  font-variation-settings: 'wdth' 112;
  letter-spacing: -0.035em;
  line-height: 0.96;
}

h2 {
  font-size: clamp(2.2rem, 4.6vw, 4rem);
  font-weight: 650;
  font-variation-settings: 'wdth' 108;
  letter-spacing: -0.028em;
  line-height: 1.06;
}

h3 {
  font-size: clamp(1.15rem, 1.65vw, 1.5rem);
  font-weight: 600;
  letter-spacing: -0.012em;
  line-height: 1.3;
}

h4 {
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: -0.005em;
}

p { margin: 0 0 1.25rem; }
p:last-child { margin-bottom: 0; }

ul, ol { margin: 0 0 1.25rem; padding-left: 1.15rem; }
li { margin-bottom: 0.55rem; }

strong { color: var(--graphite-900); font-weight: 600; }

::selection { background: var(--steel); color: var(--white); }

:focus-visible {
  outline: 1px solid var(--steel);
  outline-offset: 4px;
}

/* --------------------------------------------------------------------------
   Layout
   -------------------------------------------------------------------------- */

.container {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
  position: relative;
  z-index: 2;
}

.container--narrow { max-width: var(--maxw-narrow); }

.section { padding-block: var(--section-y); position: relative; }

/* Alternating band — separated by a hairline that fades at both ends rather
   than a hard full-width border. Reads considerably more refined. */
.section--surface {
  /* Not a flat fill. A soft highlight falls from the top edge and the band
     settles into its full value lower down, so it reads as a lit surface
     rather than a grey rectangle laid over the page. The effect is ~2 values
     wide — you should feel the dimension without being able to point at a
     gradient. */
  background: var(--surface-band);
  position: relative;
}
.section--surface::before,
.section--surface::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--line-strong) 22%, var(--line-strong) 78%, transparent);
}
.section--surface::before { top: 0; }
.section--surface::after  { bottom: 0; }

/* --------------------------------------------------------------------------
   Deep section — the page's one full-bleed dark moment.

   The light grounds are deliberately near-neutral and barely separated, so
   the page reads as calm and spacious rather than as banded panels. That
   removes the alternating-panel look, but it also removes the rhythm, so one
   genuinely deep block carries it instead.

   This is the distinction the palette work kept getting wrong: a PALE TINT
   reads dated, while real DEPTH in the same hue reads premium. Colour belongs
   in a dark full-bleed block, not spread thinly across every other section.

   Inherits the footer's dark tokens through the shared selector above, so its
   contents need no variants. Keep it to ONE per page — two would be stripes.
   -------------------------------------------------------------------------- */
.section--deep {
  position: relative;
  background:
    radial-gradient(ellipse 70% 90% at 12% 0%, rgba(11, 95, 255, 0.16), transparent 62%),
    var(--surface-page);
  color: var(--graphite-700);
}

.section--brushed {
  background:
    radial-gradient(ellipse 70% 50% at 50% 0%, rgba(0,0,0,0.022), transparent 70%),
    var(--surface-page);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--steel);
  color: var(--white);
  padding: 0.9rem 1.5rem;
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.skip-link:focus { left: 0; }

/* --------------------------------------------------------------------------
   Eyebrow — hairline + wide-tracked label. Silver, never blue.
   -------------------------------------------------------------------------- */

.eyebrow {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin-bottom: 1.5rem;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--graphite-500);
}

.eyebrow::before {
  content: "";
  width: 40px;
  height: 1px;
  background: linear-gradient(90deg, var(--graphite-300), transparent);
  flex-shrink: 0;
}

.section-head {
  max-width: 760px;
  margin-bottom: clamp(3rem, 6vw, 5rem);
}

.section-head--center {
  margin-inline: auto;
  text-align: center;
}
.section-head--center .eyebrow { justify-content: center; }
.section-head--center .eyebrow::after {
  content: "";
  width: 40px;
  height: 1px;
  background: linear-gradient(270deg, var(--graphite-300), transparent);
}

.section-head p {
  font-size: clamp(1rem, 1.3vw, 1.12rem);
  color: var(--graphite-500);
  margin-bottom: 0;
  max-width: 62ch;
}
.section-head--center p { margin-inline: auto; }

/* Brushed-metal text fill. Reserved for the logotype and ONE hero word.

   The dark build ran this white→silver, which vanishes on white. The light
   theme runs it graphite→steel-grey→graphite: the same polished-panel
   optical language, read as dark metal catching light instead of light metal
   catching shadow. The stop positions are unchanged so the highlight still
   lands in the same place across the letterforms. */
.metal-text {
  /* Range deliberately compressed next to the dark build's. The gradient runs
     174deg across the WHOLE element, so on a headline that wraps to three
     lines the mid stop lands on the last line. Light metal on black read as
     shine; a mid-grey word sitting under near-black type just reads as faded
     text, so every stop here stays dark enough to look deliberate. */
  background: linear-gradient(174deg, #2E3237 0%, #0B0B0C 34%, #3A3E44 60%, #121417 84%, #292D32 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

/* The omega glyph carries `stroke="url(#ometal)"` as a presentation attribute
   in every page's inline SVG. CSS beats presentation attributes, so the fill
   can be corrected here rather than by editing 16 HTML files — and it means
   the dark islands can keep the original light treatment below. */
.logo__glyph path { stroke: #26292D; }

/* Same trick for the oversized hero watermark, which is hardcoded to
   stroke="#FFFFFF" inline on every page. */
.hero__watermark path { stroke: #0B0B0C; }

/* Inside the dark footer the original light metal is correct again.

   `.icbc-band` was on this list while it was a dark island. It is light now,
   so leaving it here would render light metal on white — invisible. Nothing
   currently uses .metal-text inside the band, which is why it never showed
   up, but it was a live trap for the next person to add a logo lockup there.
   If a section ever becomes a dark island again, add it back here. */
.footer .metal-text {
  background: linear-gradient(174deg, #FFFFFF 0%, #E2E2E0 30%, #96999D 58%, #E8E8E6 82%, #B4B6B8 100%);
  -webkit-background-clip: text;
  background-clip: text;
}
.footer .logo__glyph path { stroke: #D5D5D5; }

/* --------------------------------------------------------------------------
   Buttons — sharp, wide-tracked, with a metallic sheen sweep on hover.
   -------------------------------------------------------------------------- */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 1.15rem 2.35rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-sans);
  font-size: 0.74rem;
  font-weight: 650;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-align: center;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  transition: background var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease),
              transform var(--t-fast) var(--ease),
              box-shadow var(--t-fast) var(--ease);
}

/* The sheen — a soft specular band that travels across on hover. */
.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(105deg, transparent 30%, rgba(255,255,255,0.20) 48%, transparent 66%);
  transform: translateX(-140%);
  transition: transform var(--t-slow) var(--ease);
}

.btn--primary {
  background: var(--steel);
  border-color: var(--steel);
  color: var(--white);
  box-shadow: 0 1px 0 rgba(255,255,255,0.14) inset,
              0 14px 34px -10px var(--steel-glow);
}

.btn--secondary {
  background: transparent;
  border-color: var(--steel);
  color: var(--graphite-900);
}

.btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--graphite-500);
  padding-inline: 0;
}

.btn--sm { padding: 0.85rem 1.55rem; font-size: 0.68rem; letter-spacing: 0.14em; }
.btn--block { width: 100%; }

@media (hover: hover) {
  .btn:hover::after { transform: translateX(140%); }

  .btn--primary:hover {
    background: var(--steel-hover);
    border-color: var(--steel-hover);
    transform: translateY(-2px);
    box-shadow: 0 1px 0 rgba(255,255,255,0.18) inset,
                0 20px 46px -12px var(--steel-glow);
  }

  /* The border is steel now, so hover deepens it and washes in a faint steel
     tint. Reverting to a neutral line on hover — as this did — would have
     read as the button switching off. */
  .btn--secondary:hover {
    border-color: var(--steel-hover);
    background: rgba(11, 95, 255, 0.06);
    color: var(--graphite-900);
    transform: translateY(-2px);
  }

  .btn--ghost:hover { color: var(--graphite-900); }
}

.btn:active { transform: translateY(0); }

.btn-row { display: flex; flex-wrap: wrap; gap: 0.9rem; }

/* Text link with an underline that draws in from the left */
.arrow-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding-bottom: 3px;
  font-size: 0.72rem;
  font-weight: 650;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--graphite-900);
}
.arrow-link svg { width: 14px; height: 14px; transition: transform var(--t-mid) var(--ease); }
.arrow-link::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--graphite-300);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-mid) var(--ease), background var(--t-mid) var(--ease);
}
@media (hover: hover) {
  .arrow-link:hover::after { transform: scaleX(1); background: var(--steel); }
  .arrow-link:hover svg { transform: translateX(4px); }
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.header {
  position: sticky;
  top: 0;
  z-index: 100;
  border-bottom: 1px solid transparent;
  transition: border-color var(--t-mid) var(--ease);

  /* NOTE: the translucent background and blur deliberately live on ::before,
     not here. `backdrop-filter` on an element makes it a containing block for
     its position:fixed descendants — which trapped the mobile nav overlay
     inside the 73px header box (an 81px scroll sliver holding 506px of links)
     instead of letting it fill the viewport. Do not move these back. */
}

/* Translucent blurred bar, painted behind the header's own content. */
.header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(255, 255, 255, 0.78);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  transition: background var(--t-mid) var(--ease);
}

.header.is-scrolled::before { background: rgba(255, 255, 255, 0.94); }
.header.is-scrolled { border-bottom-color: var(--line); }

.header__inner {
  height: var(--header-h);
  display: flex;
  align-items: center;
  gap: 2rem;
}

/* ---- Logo lockup ---- */
.logo {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  flex-shrink: 0;
  margin-right: auto;
}

.logo__glyph {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  transition: transform var(--t-slow) var(--ease);
}
@media (hover: hover) {
  .logo:hover .logo__glyph { transform: rotate(-6deg) scale(1.04); }
}

.logo__text { display: flex; flex-direction: column; line-height: 1; }

.logo__name {
  font-size: 1.12rem;
  font-weight: 700;
  font-variation-settings: 'wdth' 108;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.logo__sub {
  margin-top: 5px;
  font-size: 0.5rem;
  font-weight: 500;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--graphite-300);
}

/* ---- Nav ---- */
.nav { display: flex; align-items: center; gap: 2.6rem; }

.nav__link {
  position: relative;
  padding: 0.4rem 0;
  font-size: 0.74rem;
  font-weight: 550;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--graphite-500);
  white-space: nowrap;
  transition: color var(--t-fast) var(--ease);
}

.nav__link::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--steel);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--t-mid) var(--ease);
}

@media (hover: hover) {
  .nav__link:hover { color: var(--graphite-900); }
  .nav__link:hover::after { transform: scaleX(1); transform-origin: left; }
}

.nav__link.is-active { color: var(--graphite-900); }
.nav__link.is-active::after { transform: scaleX(1); }

/* Nav carries its own CTA for the mobile overlay only */
.nav > .btn { display: none; }
.header__cta { flex-shrink: 0; }

/* ---- Hamburger ---- */
.nav-toggle {
  display: none;
  width: 44px; height: 44px;
  padding: 0;
  background: none;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
  place-items: center;
  flex-shrink: 0;
  transition: border-color var(--t-fast) var(--ease);
}
.nav-toggle span {
  display: block;
  width: 18px; height: 1px;
  margin: 4px auto;
  background: var(--graphite-900);
  transition: transform var(--t-mid) var(--ease), opacity var(--t-fast) var(--ease);
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

/* --------------------------------------------------------------------------
   Hero — full-bleed, near-full-viewport, content anchored low-left.

   PHOTOGRAPHY SLOT: set --hero-image on .hero to drop a photo in behind the
   scrim. The layered gradients below are tuned to sit over a real image and
   still read correctly while it's absent.
   -------------------------------------------------------------------------- */

/* Content is centred, not bottom-anchored. The hero originally carried a lede
   paragraph, a supporting note and a scroll cue; with those removed, anchoring
   to the bottom of a 94vh block left a large void above the headline. */
.hero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: min(76vh, 720px);
  padding-block: clamp(4rem, 8vw, 6.5rem) clamp(4rem, 8vw, 6.5rem);
  overflow: hidden;
  background-color: var(--surface-sunken);
  isolation: isolate;
}

/* Layer 1 — the light. A cool key from upper right, a warm bounce lower left:
   the standard two-source setup for photographing a car in a dark bay. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(ellipse 55% 60% at 78% 18%, rgba(120, 130, 150, 0.07), transparent 62%),
    radial-gradient(ellipse 60% 50% at 12% 92%, rgba(90, 100, 115, 0.055), transparent 68%),
    linear-gradient(180deg, #FFFFFF 0%, #FCFCFB 52%, #F6F6F4 100%);
}

/* Layer 2 — a slow specular sweep across the field, like light moving over
   a panel. Very low contrast; you should feel it more than see it. */
.hero::after {
  content: "";
  position: absolute;
  inset: -20%;
  z-index: -1;
  background: linear-gradient(102deg, transparent 38%, rgba(0,0,0,0.022) 50%, transparent 62%);
  animation: sheen 14s var(--ease-inout) infinite;
}

@keyframes sheen {
  0%, 100% { transform: translateX(-22%); }
  50%      { transform: translateX(22%); }
}

/* Optional real photograph */
.hero__media {
  position: absolute;
  inset: 0;
  z-index: -3;
  object-fit: cover;
  width: 100%;
  height: 100%;
  filter: saturate(0.72) contrast(1.06) brightness(0.62);
}

/* Oversized omega, cropped off the right edge — a watermark you read as
   architecture rather than a logo drop. */
.hero__watermark {
  position: absolute;
  right: -9%;
  top: 46%;
  transform: translateY(-50%);
  width: min(52vw, 720px);
  z-index: -1;
  opacity: 0.032;
  pointer-events: none;
  user-select: none;
}

/* NOTE: this element is both .container and .hero__inner. Constrain the
   children rather than the element itself — putting a max-width here would
   override the 1320px container and re-centre it, throwing the hero copy out
   of alignment with the header logo above it. */
.hero__inner > * { max-width: 1020px; }

.hero h1 { margin-bottom: 2rem; }

/* Brand line, set to match the tagline in the logo lockup: wide tracking,
   silver, flanked by hairlines the way the artwork flanks "AUTOBODY". */
.hero__tagline {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: -0.5rem 0 2.75rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--graphite-500);
  white-space: nowrap;
}

.hero__tagline::before,
.hero__tagline::after {
  content: "";
  height: 1px;
  background: var(--graphite-100);
}
.hero__tagline::before { width: 28px; flex: none; }
.hero__tagline::after  { flex: 1; max-width: 190px; }

@media (max-width: 640px) {
  .hero__tagline {
    font-size: 0.6rem;
    letter-spacing: 0.24em;
    gap: 0.7rem;
    white-space: normal;
  }
  .hero__tagline::before { width: 18px; }
  .hero__tagline::after  { display: none; }
}


.hero .btn-row { gap: 1rem; }


/* ---- Interior page hero ---- */
.page-hero {
  position: relative;
  padding-block: clamp(5rem, 10vw, 8.5rem) clamp(3.5rem, 6vw, 5.5rem);
  background:
    radial-gradient(ellipse 60% 80% at 76% 8%, rgba(120, 140, 170, 0.07), transparent 64%),
    linear-gradient(180deg, #FBFBFA, var(--surface-page));
  overflow: hidden;
}
.page-hero::after {
  content: "";
  position: absolute;
  left: var(--gutter); right: var(--gutter);
  bottom: 0; height: 1px;
  background: linear-gradient(90deg, var(--line-strong), transparent 70%);
}
.page-hero h1 { margin-bottom: 1.5rem; }
.page-hero__lede {
  max-width: 58ch;
  margin-bottom: 0;
  font-size: clamp(1rem, 1.3vw, 1.15rem);
  color: var(--graphite-500);
  line-height: 1.7;
}

.breadcrumb {
  margin-bottom: 1.75rem;
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--graphite-300);
}
.breadcrumb ol { display: flex; flex-wrap: wrap; gap: 0.65rem; margin: 0; padding: 0; list-style: none; }
.breadcrumb li { display: flex; align-items: center; gap: 0.65rem; margin: 0; }
.breadcrumb li + li::before { content: "/"; color: var(--graphite-300); }
@media (hover: hover) { .breadcrumb a:hover { color: var(--graphite-900); } }

/* --------------------------------------------------------------------------
   Trust bar — set as an inline row of quiet statements divided by hairlines.
   Icons are gunmetal, never blue: these are quality signals, not buttons.
   -------------------------------------------------------------------------- */

.trustbar {
  background: var(--surface-sunken);
  padding-block: clamp(2.5rem, 4vw, 3.5rem);
  border-bottom: 1px solid var(--line-soft);
}

.trustbar__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.5rem, 3vw, 3rem);
}

.trustbar__item {
  display: flex;
  align-items: flex-start;
  gap: 0.95rem;
  padding-left: clamp(1.5rem, 3vw, 3rem);
  border-left: 1px solid var(--line-soft);
}
.trustbar__item:first-child { padding-left: 0; border-left: none; }

.trustbar__item svg {
  width: 21px; height: 21px;
  margin-top: 3px;
  flex-shrink: 0;
  color: var(--graphite-500);
  stroke-width: 1.25;
  transition: color var(--t-mid) var(--ease);
}
.trustbar__item:hover svg { color: var(--graphite-900); }

.trustbar__label {
  font-size: 0.83rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: 1.4;
  color: var(--graphite-900);
}

.trustbar__sub {
  margin-top: 5px;
  font-size: 0.78rem;
  line-height: 1.55;
  color: var(--graphite-300);
}

/* --------------------------------------------------------------------------
   Grids + cards
   -------------------------------------------------------------------------- */

.grid { display: grid; gap: clamp(1rem, 1.6vw, 1.5rem); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }

/* Tactile card: vertical gradient body, hairline border, a 1px inner top
   highlight (reads as a lit edge), and a deep ambient shadow. */
.card {
  position: relative;
  padding: clamp(1.85rem, 2.6vw, 2.5rem);
  background: var(--surface-card);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  overflow: hidden;
  isolation: isolate;
  /* On light, depth comes from a soft contact shadow and a real border rather
     than from an inset highlight — a white top edge on a white card is
     invisible. Shadows are tinted with the graphite hue, never pure black,
     which is what keeps them from looking like grey smudge. */
  box-shadow: 0 1px 2px rgba(16,24,40,0.055),
              0 12px 28px -18px rgba(16,24,40,0.18);
  transition: transform var(--t-mid) var(--ease),
              border-color var(--t-mid) var(--ease),
              box-shadow var(--t-mid) var(--ease);
}

/* Diagonal sheen sweep on hover — the same specular language as the buttons */
.card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(115deg, transparent 34%, rgba(0,0,0,0.028) 50%, transparent 64%);
  transform: translateX(-120%);
  transition: transform 1.1s var(--ease);
}

@media (hover: hover) {
  .card:hover {
    transform: translateY(-4px);
    border-color: var(--line-strong);
    box-shadow: 0 4px 10px rgba(16,24,40,0.08),
                0 24px 48px -24px rgba(16,24,40,0.26);
  }
  .card:hover::after { transform: translateX(120%); }
}

/* Icons: thin gunmetal monoline. Brightens on hover — no colour, ever. */
.card__icon {
  width: 26px; height: 26px;
  margin-bottom: 1.5rem;
  color: var(--graphite-500);
  transition: color var(--t-mid) var(--ease);
}
.card__icon svg { width: 100%; height: 100%; stroke-width: 1.15; }
@media (hover: hover) { .card:hover .card__icon { color: var(--graphite-900); } }

.card h3 { margin-bottom: 0.7rem; }

.card p {
  margin-bottom: 0;
  font-size: 0.925rem;
  line-height: 1.7;
  color: var(--graphite-500);
}

.card__link { display: inline-block; margin-top: 1.5rem; }
.card--link .card__stretch::after { content: ""; position: absolute; inset: 0; }

/* --------------------------------------------------------------------------
   Service index — the editorial treatment for the homepage services.
   Numbered rows on hairlines, no boxes. Reads as a considered index of
   capability rather than a grid of checkboxes.
   -------------------------------------------------------------------------- */

.service-index {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  column-gap: clamp(2.5rem, 5vw, 5rem);
  border-top: 1px solid var(--line);
}

.service-row {
  position: relative;
  padding: clamp(2rem, 3vw, 2.75rem) 0;
  padding-right: 2.5rem;   /* room for the hover chevron */
  border-bottom: 1px solid var(--line);
}

/* Blue hairline draws across the row's top edge on hover — the only blue
   in this section, and it only appears on interaction. */
.service-row::before {
  content: "";
  position: absolute;
  top: -1px; left: 0;
  width: 100%; height: 1px;
  background: var(--steel);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-mid) var(--ease);
}
/* Chevron replaces the index numeral — it earns its place by signalling the
   row is clickable, which a number never did. */
.service-row::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 12px;
  width: 7px;
  height: 7px;
  border-top: 1px solid var(--graphite-500);
  border-right: 1px solid var(--graphite-500);
  transform: translateY(-50%) rotate(45deg);
  opacity: 0;
  transition: opacity var(--t-mid) var(--ease), right var(--t-mid) var(--ease);
}

@media (hover: hover) {
  .service-row:hover::before { transform: scaleX(1); }
  .service-row:hover::after  { opacity: 1; right: 2px; }
  .service-row:hover h3 { transform: translateX(5px); }
}

.service-row h3 {
  margin-bottom: 0.6rem;
  transition: transform var(--t-mid) var(--ease);
}

.service-row p {
  margin-bottom: 0;
  font-size: 0.92rem;
  line-height: 1.72;
  color: var(--graphite-500);
  max-width: 46ch;
}

.service-row__link::after { content: ""; position: absolute; inset: 0; }

/* --------------------------------------------------------------------------
   Split + feature list
   -------------------------------------------------------------------------- */

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(3rem, 7vw, 6.5rem);
  align-items: center;
}

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

/* No index markers. A short steel rule above each title carries the rhythm
   instead — quieter than a numeral and it reinforces the hairline language
   used across the rest of the page. */
.feature-list li {
  position: relative;
  margin: 0;
  padding-block: 1.75rem;
  border-bottom: 1px solid var(--line-soft);
}
.feature-list li:first-child { padding-top: 0; }
.feature-list li:last-child { border-bottom: none; padding-bottom: 0; }

.feature-list h3 {
  position: relative;   /* anchor the rule to the heading, not the <li> —
                           first/last items carry different padding */
  margin-bottom: 0.45rem;
  padding-left: 1.4rem;
  font-size: 1.05rem;
}

.feature-list h3::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 14px;
  height: 1px;
  background: var(--graphite-300);
}

.feature-list p { padding-left: 1.4rem; }

.feature-list p {
  margin-bottom: 0;
  font-size: 0.92rem;
  line-height: 1.7;
  color: var(--graphite-500);
}

/* --------------------------------------------------------------------------
   Process steps — hairline rule with an oversized ghost numeral
   -------------------------------------------------------------------------- */

.steps {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.5rem, 3vw, 2.75rem);
}

/* No step numerals. The top rule plus a short steel tick carries the sequence
   — the copy already reads in order, so a number was redundant decoration. */
.step {
  position: relative;
  padding-top: 1.9rem;
  border-top: 1px solid var(--line);
}

.step::before {
  content: "";
  position: absolute;
  top: -1px; left: 0;
  width: 26px; height: 1px;
  background: var(--graphite-500);
}

/* The rest of the rule lights in left-to-right on hover */
.step::after {
  content: "";
  position: absolute;
  top: -1px; left: 0;
  width: 100%; height: 1px;
  background: var(--graphite-500);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-slow) var(--ease);
}
@media (hover: hover) {
  .step:hover::after { transform: scaleX(1); }
}

.step h3 { margin-bottom: 0.55rem; font-size: 1.02rem; }
.step p { margin-bottom: 0; font-size: 0.9rem; line-height: 1.7; color: var(--graphite-500); }

/* --------------------------------------------------------------------------
   ICBC band — the one place a blue edge is used structurally, because it is
   the page's primary conversion path.
   -------------------------------------------------------------------------- */

.icbc-band {
  position: relative;
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: clamp(2.5rem, 5vw, 5rem);
  /* Was `center`, which floated the shorter checklist column and left a
     ~200px void under it. Both columns now hang from the same top edge. */
  align-items: start;
  padding: clamp(2.5rem, 5vw, 4.25rem);
  /* Flat pure white, deliberately. There was a 5% steel radial bloom from the
     top-left corner, but the official ICBC "Colour-on-white" asset carries a
     baked-in opaque white plate (it is the only variant supplied with the
     brand colours), and that plate sits exactly where the bloom was
     strongest — it read as a pale rectangle around the mark. The plate is
     pure #FFFFFF, so on a flat #FFFFFF card it is invisible.
     Do not reintroduce a gradient here while the lockup is displayed. */
  background: var(--surface-card);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(16,24,40,0.055),
              0 20px 48px -28px rgba(16,24,40,0.20);
}

/* Vertical steel edge, fading out top and bottom */
.icbc-band::before {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 2px; height: 100%;
  background: linear-gradient(180deg, transparent, var(--steel) 22%, var(--steel) 78%, transparent);
}

/* ICBC Repair Network logo — official white-version asset.
   Per ICBC's logo usage standards (v1.0, July 2024):
     • minimum on-screen size is a 30px-high ICBC cube. At 240px wide the cube
       renders 37px, so do not scale this below ~200px wide.
     • safety space is half the cube's width/height on all sides. The supplied
       PNG already carries exactly that padding; the margin below is additional
       clearance, never a substitute.
     • the mark must not be recoloured, outlined, rotated, or given any effect,
       and must appear once per area.
     • Omega's own branding stays larger and more prominent (header lockup). */
/* Co-brand lockup. Two hard constraints pull against each other:
     • the ICBC mark may never render below a 30px cube  -> min width 194px
     • the ICBC lockup must sit at <= 50% of our own mark -> ours >= 2x theirs
   So the ICBC mark is held at its minimum permitted size and our wordmark is
   set deliberately large above it. Changing either number breaks compliance. */
.cobrand {
  display: flex;
  flex-direction: column;      /* participant mark ABOVE, per p.12 */
  align-items: flex-start;
  margin-bottom: 2rem;
}

/* The official Colour-on-white asset carries an opaque white plate, so on any
   surface that is NOT pure white it reads as a rectangle floating behind the
   mark. Rather than modify the artwork — which is not permitted — the plate is
   extended into a deliberate plaque. The negative inline-start margin cancels
   the padding so the wordmark stays optically aligned with the eyebrow and
   heading beneath it, and `fit-content` stops the plaque spanning the column.
   Not needed inside .icbc-band, which is already flat #FFFFFF. */
.section--surface .cobrand {
  width: fit-content;
  padding: 1.75rem 2rem;
  margin-inline-start: -2rem;
  background: var(--surface-card);
  border-radius: var(--radius);
}

.cobrand__own {
  display: block;
  font-size: 2.15rem;
  font-weight: 700;
  font-variation-settings: 'wdth' 108;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--graphite-900);
  white-space: nowrap;
}

.icbc-mark {
  width: 200px;                /* cube renders 31px — just clears the 30px floor */
  height: auto;
  /* Gap >= the width of the proportionate ICBC cube (31px), per p.12 */
  margin: 34px 0 0;
  /* No filter, opacity, transform or blend — the mark renders exactly as supplied. */
}

/* Below ~600px the two rules cannot both be satisfied: a compliant ICBC mark
   needs >=194px, which in turn requires a >=388px participant wordmark, and
   neither fits beside the other on a phone. Rather than render the mark
   undersized or the ratio wrong, the lockup is withheld — the accreditation is
   still stated in the body copy, which is permitted wording on its own. */
@media (max-width: 599px) {
  .cobrand { display: none; }
}

.icbc-band h2 { font-size: clamp(1.65rem, 2.9vw, 2.4rem); }
.icbc-band p { margin-bottom: 0; color: var(--graphite-500); }

.icbc-band__checks { list-style: none; margin: 0; padding: 0; }

.icbc-band__checks li {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  margin-bottom: 1.1rem;
  padding-bottom: 1.1rem;
  border-bottom: 1px solid var(--line-soft);
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--graphite-700);
}
.icbc-band__checks li:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; }

.icbc-band__checks svg {
  width: 15px; height: 15px;
  margin-top: 5px;
  flex-shrink: 0;
  color: var(--graphite-500);   /* silver, not blue */
  stroke-width: 1.6;
}

/* --------------------------------------------------------------------------
   Service area chips
   -------------------------------------------------------------------------- */

.area-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
}

.area-chip {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1.35rem 1.5rem;
  background: var(--surface-band);
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--graphite-500);

  /* Grid items default to min-width:auto, so a chip cannot shrink below its
     longest word plus padding — which pushed the two-column grid past the
     viewport at 320px. */
  min-width: 0;
  transition: background var(--t-mid) var(--ease), color var(--t-mid) var(--ease);
}

.area-chip svg {
  width: 14px; height: 14px;
  flex-shrink: 0;
  color: var(--graphite-300);
  stroke-width: 1.4;
  transition: color var(--t-mid) var(--ease);
}

@media (hover: hover) {
  a.area-chip:hover { background: var(--surface-hover); color: var(--graphite-900); }
  a.area-chip:hover svg { color: var(--steel); }
}

/* --------------------------------------------------------------------------
   Quotes + placeholders
   -------------------------------------------------------------------------- */

/* Deliberately compact. These quotes run one to three lines, so generous card
   padding leaves large dead areas and makes short reviews look padded out. */
.quote-card {
  padding: 1.6rem 1.5rem 1.4rem;
  background: var(--surface-card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}

.quote-card__stars { display: flex; gap: 3px; margin-bottom: 0.95rem; }
.quote-card__stars svg { width: 13px; height: 13px; color: var(--star); }

.quote-card blockquote {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.62;
  color: var(--graphite-900);
}

/* Translation of a non-English review. Kept visually secondary to the
   reviewer's own words, which stay primary. */
.quote-card__translation {
  margin: 1rem 0 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line-soft);
  font-size: 0.9rem;
  line-height: 1.65;
  color: var(--graphite-500);
  font-style: italic;
}

.quote-card__author { font-size: 0.82rem; font-weight: 600; color: var(--graphite-900); }
.quote-card__meta { margin-top: 1px; font-size: 0.75rem; color: var(--graphite-300); }

/* Equal-height cards with the attribution pinned to the bottom, so the names
   line up across the row even though the quotes differ in length. */
.grid .quote-card { display: flex; flex-direction: column; }
.quote-card__author { margin-top: auto; padding-top: 1.15rem; }

/* Honest placeholder — a framed, deliberately quiet panel. Reads as
   "reserved by design", not "unfinished". */
.placeholder-note {
  padding: clamp(2.5rem, 4vw, 3.5rem);
  background:
    repeating-linear-gradient(-45deg, rgba(0,0,0,0.016) 0 2px, transparent 2px 9px),
    var(--surface-band);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-lg);
  text-align: center;
  font-size: 0.93rem;
  line-height: 1.75;
  color: var(--graphite-300);
}

.placeholder-note strong {
  display: block;
  margin-bottom: 0.6rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--graphite-500);
}

/* --------------------------------------------------------------------------
   Final CTA
   -------------------------------------------------------------------------- */

.cta-final {
  position: relative;
  text-align: center;
  background:
    radial-gradient(ellipse 55% 75% at 50% 0%, rgba(184, 196, 214, 0.075), transparent 62%),
    linear-gradient(180deg, var(--surface-sunken), var(--surface-page));
  overflow: hidden;
}
.cta-final::before {
  content: "";
  position: absolute;
  top: 0; left: 15%; right: 15%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--line-strong), transparent);
}

.cta-final h2 { max-width: 18ch; margin-inline: auto; }
.cta-final p {
  max-width: 54ch;
  margin-inline: auto;
  margin-bottom: 2.5rem;
  color: var(--graphite-500);
}
.cta-final .btn-row { justify-content: center; }

.contact-strip {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.5rem, 3vw, 3rem);
  margin-top: clamp(3.5rem, 6vw, 5.5rem);
  padding-top: clamp(2.5rem, 4vw, 3.5rem);
  border-top: 1px solid var(--line-soft);
  text-align: left;
}

.contact-strip__item { display: flex; align-items: flex-start; gap: 1rem; }
.contact-strip__item svg {
  width: 18px; height: 18px;
  margin-top: 4px;
  flex-shrink: 0;
  color: var(--graphite-300);
  stroke-width: 1.3;
}

.contact-strip__label {
  margin-bottom: 0.4rem;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--graphite-300);
}
.contact-strip__value { font-size: 0.94rem; line-height: 1.6; color: var(--graphite-900); }
.contact-strip__value span { display: block; font-size: 0.86rem; color: var(--graphite-500); }
@media (hover: hover) { .contact-strip__value a:hover { color: var(--graphite-900); } }

/* --------------------------------------------------------------------------
   Forms — underline fields. Lighter and more editorial than boxed inputs.
   -------------------------------------------------------------------------- */

.form-wrap {
  padding: clamp(2rem, 4vw, 3.25rem);
  background: var(--surface-card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: 0 1px 2px rgba(16,24,40,0.055),
              0 20px 48px -28px rgba(16,24,40,0.20);
}

.form-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.75rem 1.5rem; }

.field { display: flex; flex-direction: column; }
.field--full { grid-column: 1 / -1; }

.field label {
  margin-bottom: 0.65rem;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--graphite-500);
}
.field label .req { color: var(--steel); }

.field .hint {
  margin-top: 0.6rem;
  font-size: 0.79rem;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--graphite-300);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 0.75rem 0;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--graphite-100);
  border-radius: 0;
  color: var(--graphite-900);
  font-family: var(--font-sans);

  /* Must stay at 16px. iOS Safari force-zooms the whole page when a text
     field under 16px receives focus, which throws the layout sideways
     mid-form. The difference from 0.97rem is imperceptible; the bug is not. */
  font-size: 16px;
  transition: border-color var(--t-mid) var(--ease);
}

.field textarea { min-height: 120px; resize: vertical; }

/* Placeholders are sample content and must be readable — they were previously
   on the borders-only token at 1.4:1, which made the form look empty.
   opacity:1 is required or Firefox dims them again on top of the colour. */
.field input::placeholder,
.field textarea::placeholder {
  color: var(--graphite-300);
  opacity: 1;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-bottom-color: var(--steel);
}

.field select {
  appearance: none;
  padding-right: 2rem;
  color: var(--graphite-900);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2383868B' stroke-width='1.5'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0 center;
  background-size: 16px;
}
.field select option { background: var(--surface-card); color: var(--graphite-900); }

.field input[type="file"] {
  padding: 0.9rem 0;
  font-size: 16px;   /* same iOS zoom rule as the text fields */
  color: var(--graphite-300);
  cursor: pointer;
}
.field input[type="file"]::file-selector-button {
  margin-right: 1rem;
  padding: 0.6rem 1.15rem;
  background: transparent;
  border: 1px solid var(--graphite-100);
  border-radius: var(--radius);
  color: var(--graphite-900);
  font-family: var(--font-sans);
  font-size: 0.66rem;
  font-weight: 650;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
@media (hover: hover) {
  .field input[type="file"]::file-selector-button:hover {
    border-color: var(--line-strong);
    background: rgba(0,0,0,0.045);
  }
}

.hp-field { position: absolute; left: -9999px; height: 0; opacity: 0; overflow: hidden; }

.form-consent {
  margin-top: 1.5rem;
  font-size: 0.8rem;
  line-height: 1.65;
  color: var(--graphite-300);
}
.form-consent a { color: var(--graphite-500); border-bottom: 1px solid var(--graphite-100); }
@media (hover: hover) { .form-consent a:hover { color: var(--graphite-900); } }

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

.faq-item { border-bottom: 1px solid var(--line); }

.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  padding: 1.65rem 0;
  list-style: none;
  cursor: pointer;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.008em;
  color: var(--graphite-900);
  transition: color var(--t-fast) var(--ease);
}
.faq-item summary::-webkit-details-marker { display: none; }

/* Thin plus that rotates to a minus */
.faq-item summary::after {
  content: "";
  position: relative;
  width: 12px; height: 12px;
  flex-shrink: 0;
  background:
    linear-gradient(var(--graphite-500), var(--graphite-500)) center/12px 1px no-repeat,
    linear-gradient(var(--graphite-500), var(--graphite-500)) center/1px 12px no-repeat;
  transition: transform var(--t-mid) var(--ease), background-size var(--t-mid) var(--ease);
}
.faq-item[open] summary::after { transform: rotate(90deg); background-size: 12px 1px, 0 0; }

@media (hover: hover) { .faq-item summary:hover { color: var(--graphite-900); } }

.faq-item__body {
  max-width: 72ch;
  padding-bottom: 1.75rem;
  font-size: 0.94rem;
  line-height: 1.78;
  color: var(--graphite-500);
}

/* --------------------------------------------------------------------------
   Prose
   -------------------------------------------------------------------------- */

.prose { max-width: 68ch; }
.prose h2 { margin-top: 3.25rem; font-size: 1.4rem; }
.prose h3 { margin-top: 2.25rem; font-size: 1.05rem; }
.prose h2:first-child { margin-top: 0; }
.prose p, .prose li { color: var(--graphite-500); }
/* Links were graphite and only turned steel on hover, so they were not
   identifiable as links until pointed at — and unreachable as a signal on
   touch, where there is no hover at all. Steel is the documented treatment
   for a true interactive affordance, so this is the rule being applied
   rather than bent. 5.13:1 on white. */
.prose a { color: var(--steel); border-bottom: 1px solid rgba(11, 95, 255, 0.35); }
@media (hover: hover) { .prose a:hover { border-bottom-color: var(--steel); } }

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

   A real Google Maps embed. Deliberately NOT greyscaled to match the palette:
   Google's Maps Platform terms restrict modifying their content, and the
   officially supported route to a styled map is the Maps JavaScript API with
   a custom style, which needs an API key and a billing account. The plain
   embed needs neither.

   It also happens to be the right call visually. A map is CONTENT, so its
   colour is earned — the same reason photography will be welcome here and
   tinted background panels were not.

   `loading="lazy"` matters: the embed pulls well over a megabyte, and this
   sits near the bottom of a long page.
   -------------------------------------------------------------------------- */

.map {
  position: relative;
  margin-top: 1.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(16,24,40,0.055),
              0 12px 28px -18px rgba(16,24,40,0.18);
}

.map iframe {
  display: block;
  width: 100%;
  height: clamp(280px, 38vw, 420px);
  border: 0;
}

/* Address plaque, echoing the reference site's overlay card. Sits bottom-left
   so it never covers Google's own attribution (bottom-left of the map is
   actually the logo, so this is offset above it) or the zoom controls. */
.map__card {
  position: absolute;
  left: clamp(0.75rem, 2vw, 1.25rem);
  bottom: clamp(0.75rem, 2vw, 1.25rem);
  max-width: min(20rem, calc(100% - 2.5rem));
  padding: 1.15rem 1.35rem 1.25rem;
  background: var(--surface-card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 2px 6px rgba(16,24,40,0.10),
              0 18px 40px -22px rgba(16,24,40,0.30);
}

.map__label {
  display: block;
  margin-bottom: 0.5rem;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--graphite-300);
}

.map__addr {
  margin: 0 0 0.9rem;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--graphite-900);
}
.map__addr span { display: block; color: var(--graphite-500); font-size: 0.88rem; }

/* Wide variant, used on the homepage service-area section. Cancels the
   container's gutter so the map runs to the container edges — which is
   edge-to-edge on any viewport narrower than --maxw, and a contained 1320px
   band above that. It reads as a destination rather than as a widget dropped
   into a column.

   Deliberately NOT `calc(50% - 50vw)`. That is the usual full-bleed trick and
   it is wrong here: 100vw includes the scrollbar width, so it overhangs by
   ~15px and gives every page a phantom horizontal scrollbar — the same class
   of bug the mobile nav overlay had. narrow_viewport_test.py measures real
   layout vs scroll width and will catch it if anyone swaps it back. */
.map--wide {
  margin-inline: calc(-1 * var(--gutter));
  border-inline: 0;
  border-radius: 0;
}
.map--wide iframe { height: clamp(320px, 44vw, 520px); }

/* Once the container stops touching the viewport edges, a squared-off edge
   looks like an accident rather than a decision. Give it its border back. */
@media (min-width: 1400px) {
  .map--wide {
    margin-inline: 0;
    border-inline: 1px solid var(--line);
    border-radius: var(--radius-lg);
  }
}

/* Below ~560px the plaque would cover most of the map. Drop it under instead
   of shrinking it into unreadability. */
@media (max-width: 560px) {
  .map__card {
    position: static;
    max-width: none;
    border: 0;
    border-top: 1px solid var(--line);
    border-radius: 0;
    box-shadow: none;
  }
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.footer {
  padding-top: clamp(4rem, 7vw, 6rem);
  background: var(--surface-sunken);
  border-top: 1px solid var(--line-soft);
}

.footer__grid {
  display: grid;
  grid-template-columns: 1.55fr 0.9fr 0.9fr 0.9fr 1.15fr;
  gap: clamp(2.25rem, 3.5vw, 3.25rem);
  padding-bottom: clamp(3rem, 5vw, 4.5rem);
}

.footer__about { max-width: 340px; }
.footer__about p {
  margin: 1.75rem 0 0;
  font-size: 0.88rem;
  line-height: 1.75;
  color: var(--graphite-300);
}

.footer__tagline {
  margin-top: 1.75rem !important;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--graphite-300) !important;
}

.footer h4 {
  margin-bottom: 1.65rem;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--graphite-500);
}

.footer__links { list-style: none; margin: 0; padding: 0; }
.footer__links li { margin-bottom: 0.85rem; }
.footer__links a {
  font-size: 0.88rem;
  color: var(--graphite-300);
  transition: color var(--t-fast) var(--ease);
}
@media (hover: hover) { .footer__links a:hover { color: var(--graphite-900); } }

.footer__contact { list-style: none; margin: 0; padding: 0; font-size: 0.88rem; }
.footer__contact li {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  margin-bottom: 1.1rem;
  line-height: 1.65;
  color: var(--graphite-300);
}
.footer__contact svg {
  width: 15px; height: 15px;
  margin-top: 5px;
  flex-shrink: 0;
  color: var(--graphite-300);
  stroke-width: 1.3;
}
@media (hover: hover) { .footer__contact a:hover { color: var(--graphite-900); } }

/* Three columns rather than space-between: with the copyright and the link
   list being different widths, space-between would push the DSB tag off
   centre. 1fr / auto / 1fr keeps it optically centred on the page. */
/* ICBC-mandated attribution + disclaimer. Required wording — do not reword,
   abbreviate or remove while the Repair Network logo appears on the site. */
.icbc-attribution {
  padding-block: 1.5rem;
  border-top: 1px solid var(--line-soft);
  max-width: 80ch;
}

/* These two statements are REQUIRED while the ICBC logo is displayed and may
   not be removed (LAUNCH.md guardrail 7). They were set in --silver-900,
   which is the borders-only token at ~1.7:1 — effectively invisible, on text
   that exists for compliance reasons. Raised to the tertiary tone (~5.5:1).
   Small legal type may be quiet; it may not be unreadable. */
.icbc-attribution p {
  margin: 0 0 0.5rem;
  font-size: 0.72rem;
  line-height: 1.6;
  color: var(--graphite-300);
}
.icbc-attribution p:last-child { margin-bottom: 0; }

.footer__bottom {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1.5rem;
  padding-block: 2rem;
  border-top: 1px solid var(--line-soft);
  font-size: 0.78rem;
  color: var(--graphite-300);
}

.footer__bottom > :first-child { justify-self: start; }
.footer__bottom .dsb-tag      { justify-self: center; }
.footer__bottom nav {
  justify-self: end;
  display: flex;
  flex-wrap: wrap;
  gap: 2rem;
}

@media (hover: hover) { .footer__bottom a:hover { color: var(--graphite-700); } }

/* --------------------------------------------------------------------------
   DSB credit — house convention across DSB-built sites.
   Sits centred in the legal row, between the copyright and the policy links.
   Deliberately the quietest thing there: findable, never competing with the
   client's own footer.
   -------------------------------------------------------------------------- */

.dsb-tag { line-height: 1; }

.dsb-tag a {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--graphite-300);
  transition: color var(--t-fast) var(--ease);
}

.dsb-tag img {
  width: auto;
  height: 18px;
  max-width: 120px;
  opacity: 0.72;
  transition: opacity var(--t-fast) var(--ease);
}

@media (hover: hover) {
  .dsb-tag a:hover { color: var(--graphite-700); }
  .dsb-tag a:hover img { opacity: 1; }
}

/* Three items in one row need ~660px. Below that, stack and centre the whole
   legal row rather than letting the columns collide. */
@media (max-width: 900px) {
  .footer__bottom {
    grid-template-columns: 1fr;
    justify-items: center;
    gap: 1.35rem;
    text-align: center;
  }
  .footer__bottom > :first-child,
  .footer__bottom .dsb-tag,
  .footer__bottom nav { justify-self: center; }
}

/* --------------------------------------------------------------------------
   Mobile call bar
   -------------------------------------------------------------------------- */

.callbar {
  display: none;
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 90;
  gap: 0.75rem;
  padding: 0.75rem var(--gutter) calc(0.75rem + env(safe-area-inset-bottom));
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  border-top: 1px solid var(--line);
}
.callbar .btn { flex: 1; padding-inline: 0.5rem; }

/* --------------------------------------------------------------------------
   Utilities
   -------------------------------------------------------------------------- */

.text-center { text-align: center; }
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }
.mt-lg { margin-top: clamp(3rem, 5vw, 4.5rem); }

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

/* ---- Scroll reveal — a soft rise with a clip wipe. Cinematic, not bouncy. */
.reveal {
  opacity: 0;
  transform: translateY(26px);
  clip-path: inset(0 0 8% 0);
  transition: opacity 1s var(--ease),
              transform 1s var(--ease),
              clip-path 1.15s var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}
.reveal.is-visible { opacity: 1; transform: none; clip-path: inset(0 0 0 0); }

/* Cascade siblings inside a group so a section lands as a sequence rather than
   all at once. An inline --reveal-delay on the element overrides this. */
.grid > .reveal:nth-child(2),
.steps > .reveal:nth-child(2),
.area-grid > .reveal:nth-child(2),
.service-index > .reveal:nth-child(2)  { --reveal-delay: 70ms; }

.grid > .reveal:nth-child(3),
.steps > .reveal:nth-child(3),
.area-grid > .reveal:nth-child(3),
.service-index > .reveal:nth-child(3)  { --reveal-delay: 140ms; }

.grid > .reveal:nth-child(4),
.steps > .reveal:nth-child(4),
.area-grid > .reveal:nth-child(4),
.service-index > .reveal:nth-child(4)  { --reveal-delay: 210ms; }

.grid > .reveal:nth-child(5),
.area-grid > .reveal:nth-child(5),
.service-index > .reveal:nth-child(5)  { --reveal-delay: 280ms; }

.grid > .reveal:nth-child(n + 6),
.area-grid > .reveal:nth-child(n + 6),
.service-index > .reveal:nth-child(n + 6) { --reveal-delay: 350ms; }






/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 1180px) {
  .nav { gap: 1.8rem; }
  .nav__link { font-size: 0.7rem; letter-spacing: 0.13em; }
  /* Five columns stop fitting — the about block takes the full first row. */
  .footer__grid { grid-template-columns: repeat(4, 1fr); }
  .footer__about { grid-column: 1 / -1; max-width: 460px; }
}

@media (max-width: 980px) {
  :root { --header-h: 72px; }

  .nav-toggle { display: grid; }
  .header__cta { display: none; }

  .nav {
    position: fixed;
    inset: var(--header-h) 0 0;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0;
    margin: 0;
    padding: 2rem var(--gutter) 3rem;
    background: var(--surface-sunken);
    border-top: 1px solid var(--line);
    overflow-y: auto;

    /* Fades in place. A translateX(100%) slide would park this fixed panel a
       full viewport to the right and give every page a phantom horizontal
       scrollbar (body overflow-x cannot clip a fixed element). */
    opacity: 0;
    visibility: hidden;
    transform: translateY(-10px);
    transition: opacity var(--t-mid) var(--ease),
                transform var(--t-mid) var(--ease),
                visibility var(--t-mid) linear;
  }
  .nav.is-open { opacity: 1; visibility: visible; transform: none; }

  .nav__link {
    padding: 1.35rem 0;
    border-bottom: 1px solid var(--line-soft);
    font-size: 0.95rem;
    letter-spacing: 0.14em;
    color: var(--graphite-900);
  }
  .nav__link::after { display: none; }
  .nav > .btn { display: inline-flex; margin-top: 2.25rem; }

  body.nav-open { overflow: hidden; }

  /* Layout collapse */
  .trustbar__grid { grid-template-columns: repeat(2, 1fr); gap: 1.75rem; }
  .trustbar__item:nth-child(odd) { padding-left: 0; border-left: none; }
  .grid--3, .grid--4 { grid-template-columns: repeat(2, 1fr); }
  .service-index { grid-template-columns: 1fr; }
  .steps { grid-template-columns: repeat(2, 1fr); gap: 2.5rem 2rem; }
  .split { grid-template-columns: 1fr; gap: 3rem; }
  .icbc-band { grid-template-columns: 1fr; }
  .area-grid { grid-template-columns: repeat(3, 1fr); }
  .footer__grid { grid-template-columns: 1fr 1fr; }
  .footer__about { grid-column: 1 / -1; max-width: none; }
  .contact-strip { grid-template-columns: 1fr; gap: 2rem; }

  .callbar { display: flex; }
  /* Bar measures ~80px with its padding; 78px left the last 2px of content
     clipped underneath it. Extra allowance covers the safe-area inset too. */
  body { padding-bottom: 96px; }

  .hero { min-height: auto; }

  /* ---- Touch targets ---------------------------------------------------
     Inline links in the contact lists are phone numbers and email addresses —
     the most conversion-critical taps on the site — and they rendered only
     16-17px tall. Give every standalone link a 44px touch area. */
  .footer__contact a,
  .contact-strip__value a,
  .footer__bottom nav a,
  .breadcrumb a,
  .dsb-tag a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  .footer__links a {
    display: inline-block;
    padding-block: 0.7rem;   /* clears 44px total with the 14px line box */
  }

  /* Logo sat at 30px tall inside a 72px header — plenty of room to grow it. */
  .logo { min-height: 44px; }

  /* Selects were 42px; nudge over the 44px threshold. */
  .field select,
  .field input,
  .field textarea { padding-block: 0.85rem; }

  /* 10.6px field labels are too small to scan on a phone. */
  .field label { font-size: 0.75rem; letter-spacing: 0.16em; }
}

@media (max-width: 640px) {
  /* Slightly tighter display tracking at small sizes so big type doesn't
     fall apart on a phone. */
  h1 { font-size: clamp(2.35rem, 11vw, 3.25rem); letter-spacing: -0.03em; }
  h2 { font-size: clamp(1.75rem, 7.5vw, 2.25rem); }

  .grid--2, .grid--3, .grid--4 { grid-template-columns: 1fr; }
  .steps { grid-template-columns: 1fr; gap: 2rem; }
  .trustbar__grid { grid-template-columns: 1fr; gap: 1.35rem; }
  .trustbar__item { padding-left: 0; border-left: none; }
  .area-grid { grid-template-columns: repeat(2, 1fr); }
  .form-grid { grid-template-columns: 1fr; gap: 1.6rem; }
  .footer__grid { grid-template-columns: 1fr; gap: 2.75rem; }
  .footer__bottom nav { gap: 1.5rem; }
  .dsb-tag a { font-size: 0.7rem; }

  .btn { width: 100%; padding: 1.05rem 1.5rem; }
  .btn-row { flex-direction: column; gap: 0.75rem; }
  .callbar { flex-direction: row; }
  .callbar .btn { width: auto; }

  .hero__watermark { right: -30%; opacity: 0.028; }

  /* Tighten the area chips so two columns still fit a 320px phone */
  .area-chip {
    padding: 1.15rem 0.9rem;
    gap: 0.5rem;
    font-size: 0.8rem;
  }
  .hero .btn-row { margin-bottom: 2.5rem; }
  .logo__name { font-size: 1rem; letter-spacing: 0.16em; }
  .logo__sub { font-size: 0.45rem; letter-spacing: 0.34em; }

  .service-row { grid-template-columns: auto 1fr; gap: 1.15rem; }
  .service-row__num { font-size: 1.35rem; }
}

/* --------------------------------------------------------------------------
   Reduced motion + print
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .reveal { opacity: 1; transform: none; clip-path: none; }
  .hero::after { animation: none; }
}

@media print {
  body::before, .header, .callbar, .cta-final, .footer__bottom nav { display: none; }
  body { background: #fff; color: #000; padding-bottom: 0; }
  h1, h2, h3, h4 { color: #000; }
}
