/* ==========================================================================
   PRESTIGE RESIN — site.css
   Perth WA garage transformation specialists.

   Design system — v6
   -------------------
   Palette   Cool near-white base, deep navy as the primary colour (safe as
             both text and fill at once, so it does more work with less
             fuss), electric cyan as the vivid second voice reserved for
             fills. Colour direction taken from a reference site the client
             pointed to (structure and copy are original, only the colour
             family carries over), with green and orange deliberately
             excluded.
   Type      Geist (display and body, one family carrying both roles by
             weight) · Geist Mono (specs, figures, small labels only)
   Signature The hexagon — from the hex lights you install, and from the
             shape of a flake chip. Used structurally, not as decoration.
   Layout    The homepage hero runs dark navy with light text, the one bold
             room in an otherwise light, clean house. Everywhere else stays
             restrained so that moment keeps its impact.
   Motion    Enter 300-500ms ease-out · exit ~65% of enter · stagger 40-60ms
             transform/opacity only · fully disabled under reduced-motion
   ========================================================================== */

/* ---------- 1. Tokens ---------------------------------------------------- */

:root {
  /* Surfaces — cool near-white, not warm paper */
  --s-0: #F3F5F7;   /* page */
  --s-1: #FFFFFF;   /* card — lifts clean off the page */
  --s-2: #E4E8EC;   /* deeper band, alternates with --s-0 for scroll rhythm */
  --s-3: #E9EDF0;   /* input / well */

  /* Text — cool near-black, all checked against --s-0 for WCAG AA */
  --t-1: #14181B;   /* 17.5:1 — primary */
  --t-2: #3A4147;   /* 9.5:1 — secondary / lede body copy */
  --t-3: #5A636A;   /* 5.6:1 — small mono labels only, never body */

  /* Primary accent — deep navy. Unlike a bright hue, navy is dark enough
     to double as safe TEXT directly on the page and as a FILL with white
     text on top, so --ac and --ac-text are the same colour on purpose. */
  --ac:         #0B2A4A; /* 13.3:1 on --s-0 as text · 14.5:1 white-on-fill */
  --ac-hover:   #2C5478; /* lighter, hover state for text, fill and icons */
  --ac-on-fill: #F4F8FB; /* text that sits ON an --ac fill */
  --ac-text:    #0B2A4A; /* same as --ac — navy needs no separate safe variant */
  --ac-soft:    #A9BCCB; /* light, decorative borders/badges only, never text */

  /* Secondary accent — electric cyan. The opposite problem to navy: vivid
     enough to need DARK text on top when used as a fill, and too light to
     use as small text on the page at all, hence --cy-text stays a deeper,
     safe variant. This is the one vivid "pop" colour on the site. */
  --tl:         #00A8E8; /* fill — needs dark text on top, see --tl-on-fill */
  --tl-hover:   #0A6E92; /* deeper, hover fill · safe as text/icons (5.3:1) */
  --tl-on-fill: #0B1216; /* dark text that sits ON a --tl fill */
  --tl-text:    #0A6E92; /* 5.3:1 on --s-0 — safe cyan for text on bare page */
  --tl-soft:    #7FD1EF; /* light, decorative borders/badges only, never text */

  /* Dark hero — its own small token set, scoped inside .hero-dark only */
  --nv-deep:  #081B30;

  /* Pour partners — only ever inside metallic gradients, never flat UI fills */
  --pearl:  #F2E7DA;
  --copper: #C97B45;

  --line:      rgba(20, 24, 27, .10);
  --line-firm: rgba(20, 24, 27, .20);

  /* Type */
  --f-display: "Geist", "Arial Black", "Helvetica Neue", sans-serif;
  --f-body:    "Geist", ui-sans-serif, system-ui, "Segoe UI", sans-serif;
  --f-mono:    "Geist Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

  /* Spacing — 4/8 rhythm */
  --sp-1: .25rem;  --sp-2: .5rem;   --sp-3: .75rem;  --sp-4: 1rem;
  --sp-5: 1.25rem; --sp-6: 1.5rem;  --sp-8: 2rem;    --sp-12: 3rem;   --sp-16: 4rem;
  --sp-24: 6rem;   --sp-32: 8rem;

  --maxw: 1240px;
  --r-sm: 6px;
  --r-md: 12px;
  --r-lg: 20px;

  /* Motion */
  --e-out: cubic-bezier(.16, .84, .44, 1);
  --e-in:  cubic-bezier(.55, 0, 1, .45);
  --d-fast: 180ms;
  --d-base: 300ms;
  --d-slow: 520ms;

  /* Layered z-scale */
  --z-base: 0; --z-raise: 10; --z-sticky: 40; --z-nav: 100; --z-modal: 1000;

  /* Sticky nav's real rendered height (bar + 1px border), single source of
     truth for everything sized relative to it — the hero offset, the
     mobile dropdown position, and the anchor-scroll offset all read this
     instead of a hardcoded number. Redefined smaller inside the mobile
     breakpoint below; nothing that reads it needs to change when it does. */
  --nav-h: 141px;
}

/* ---------- 2. Reset ----------------------------------------------------- */

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

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

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--s-0);
  color: var(--t-1);
  font-family: var(--f-body);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
body.no-scroll { overflow: hidden; }

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

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

a { color: var(--ac-text); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--ac-hover); }

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

::selection { background: var(--ac); color: var(--ac-on-fill); }

/* ---------- 3. Typography ------------------------------------------------ */

h1, h2, h3, h4 {
  font-family: var(--f-display);
  font-weight: 700;
  line-height: .98;
  letter-spacing: -.028em;
  margin: 0 0 var(--sp-4);
  text-wrap: balance;
}

.display {
  font-size: clamp(2.7rem, 8vw, 6rem);
  text-transform: uppercase;
  letter-spacing: -.035em;
}

h2 { font-size: clamp(1.9rem, 4.4vw, 3.1rem); }
h3 { font-size: 1.18rem; letter-spacing: -.015em; }

p { margin: 0 0 var(--sp-4); }
p:last-child { margin-bottom: 0; }

.lede {
  font-size: 1.14rem;
  color: var(--t-2);
  max-width: 60ch;
  line-height: 1.7;
}

/* Mono utility face — eyebrows, specs, figures */
.eyebrow {
  font-family: var(--f-mono);
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ac-text);
  margin: 0 0 var(--sp-4);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}
.eyebrow::before {
  content: "";
  width: 22px;
  height: 1px;
  background: var(--ac-hover);
  flex: none;
}
.eyebrow.is-plain::before { display: none; }

.mono { font-family: var(--f-mono); font-variant-numeric: tabular-nums; }

/* ---------- 4. Layout ---------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--sp-6);
}
@media (min-width: 768px)  { .wrap { padding-inline: var(--sp-8); } }
@media (min-width: 1280px) { .wrap { padding-inline: var(--sp-12); } }

/* Single source of section rhythm — do not add padding on other section
   selectors or the two will fight (see .band, .section-tight below). */
.section { padding-block: clamp(4rem, 9vw, 7.5rem); }
.section-tight { padding-block: clamp(2.5rem, 5vw, 4rem); }
.section-flush-top { padding-top: 0; }

.section-line { border-top: 1px solid var(--line); }

/* Alternating surface bands so the page has real depth as you scroll,
   instead of one flat tone from header to footer. */
.section-cream { background: var(--s-1); }
.section-deep  { background: var(--s-2); }

.grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
@media (max-width: 900px) { .grid-2 { grid-template-columns: 1fr; } }

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

/* ---------- 5. Buttons --------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 48px;              /* touch target */
  padding: var(--sp-3) var(--sp-6);
  border-radius: var(--r-sm);
  font-family: var(--f-mono);
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid transparent;
  transition: background var(--d-fast) var(--e-out),
              border-color var(--d-fast) var(--e-out),
              color var(--d-fast) var(--e-out),
              transform var(--d-fast) var(--e-out);
  touch-action: manipulation;
}
.btn:active { transform: scale(.97); }

.btn-primary { background: var(--ac); color: var(--ac-on-fill); border-color: var(--ac); }
.btn-primary:hover { background: var(--ac-hover); border-color: var(--ac-hover); color: var(--ac-on-fill); }

.btn-line { border-color: var(--line-firm); color: var(--t-1); }
.btn-line:hover { border-color: var(--ac-hover); color: var(--ac-text); background: rgba(178, 85, 31, .10); }

.btn-block { width: 100%; }

/* ---------- 6. Header / nav ---------------------------------------------- */

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: var(--z-modal);
  background: var(--ac);
  color: var(--ac-on-fill);
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-sm);
  font-family: var(--f-mono);
  font-size: .8rem;
}
.skip:focus { left: var(--sp-4); top: var(--sp-4); }

.site-head {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  background: rgba(243, 245, 247, .86);
  backdrop-filter: blur(14px) saturate(1.4);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  border-bottom: 1px solid var(--line);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  height: calc(var(--nav-h) - 1px);
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  text-decoration: none;
  color: var(--t-1);
  flex: none;
}
.brand:hover { color: var(--t-1); }
.brand-mark { width: 76px; height: 76px; flex: none; border-radius: 50%; object-fit: cover; }
.brand-text {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: 1.32rem;
  letter-spacing: .01em;
  text-transform: uppercase;
  line-height: 1;
}
.brand-text small {
  display: block;
  font-family: var(--f-mono);
  font-size: .68rem;
  font-weight: 400;
  letter-spacing: .22em;
  color: var(--t-3);
  margin-top: 4px;
}

.nav-links { display: flex; align-items: center; gap: var(--sp-8); }
.nav-links a {
  font-family: var(--f-mono);
  font-size: .95rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--t-2);
  padding-block: var(--sp-2);
  position: relative;
}
.nav-links a:hover { color: var(--t-1); }
.nav-links a[aria-current="page"] { color: var(--ac-text); }
.nav-links a[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -2px;
  height: 1px;
  background: var(--ac-hover);
}

.nav-cta { display: flex; align-items: center; gap: var(--sp-3); flex: none; }
.nav-phone {
  font-family: var(--f-mono);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: .04em;
  text-decoration: none;
  color: var(--t-1);
  white-space: nowrap;
}
.nav-phone:hover { color: var(--ac-text); }

.nav-toggle {
  display: none;
  width: 46px; height: 46px;
  border: 1px solid var(--line-firm);
  border-radius: var(--r-sm);
  align-items: center;
  justify-content: center;
  color: var(--t-1);
}

@media (max-width: 1024px) {
  .nav-toggle { display: inline-flex; }
  .nav-links {
    position: absolute;
    top: var(--nav-h); left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--s-1);
    border-bottom: 1px solid var(--line);
    padding: var(--sp-2) var(--sp-6) var(--sp-6);
  }
  .nav-links[hidden] { display: none; }
  .nav-links a {
    padding-block: var(--sp-4);
    border-bottom: 1px solid var(--line);
    font-size: .92rem;
  }
  .nav-links a[aria-current="page"]::after { display: none; }
  .nav-cta .nav-phone { display: none; }
}
@media (max-width: 560px) {
  .nav-cta .btn { display: none; }
}

/* The full-size bar/logo (set further up, and confirmed at that size)
   stays as-is through tablet and small-laptop widths — 1024px was too
   wide a cutoff for shrinking it and ended up firing on ordinary desktop
   windows, not just phones. Only genuinely narrow phones get the
   tighter bar. */
@media (max-width: 480px) {
  :root { --nav-h: 85px; }
  .brand-mark { width: 44px; height: 44px; }
  .brand-text { font-size: 1.05rem; }
  .brand-text small { font-size: .6rem; }
}

/* ---------- 7. Hero + hex signature -------------------------------------- */

.hero {
  position: relative;
  padding-block: clamp(3rem, 7vw, 6rem) clamp(4rem, 9vw, 7rem);
  overflow: hidden;
}

/* The one dark room in the house. Redefining the text tokens here means
   every child that already reads var(--t-1)/(--t-2)/(--t-3)/(--ac-text)
   re-themes to light-on-navy automatically, no selector duplication. */
.hero-dark {
  background: var(--nv-deep);
  --t-1: #F4F8FB;
  --t-2: #B9CBDA;
  --t-3: #8FA6B8;
  --ac-text: #6FD1F0;
  --line: rgba(244, 248, 251, .14);
  --line-firm: rgba(244, 248, 251, .26);
  color: var(--t-1);
}
.hero-dark .btn-line { border-color: var(--line-firm); color: var(--t-1); }
.hero-dark .btn-line:hover { border-color: var(--tl); color: var(--tl-soft); background: rgba(0, 168, 232, .12); }
.hero-dark .eyebrow::before { background: var(--tl); }
/* The primary CTA switches to the vivid cyan here so it reads as a clear
   shape against the navy, not another dark rectangle on a dark room. */
.hero-dark .btn-primary { background: var(--tl); border-color: var(--tl); color: var(--tl-on-fill); }
.hero-dark .btn-primary:hover { background: var(--tl); border-color: var(--tl); color: var(--tl-on-fill); filter: brightness(1.12); }

.hero-grid {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  gap: clamp(2.5rem, 5vw, 5rem);
  align-items: center;
}
@media (max-width: 980px) {
  .hero-grid { grid-template-columns: 1fr; }
  .hero-art { order: -1; }
}

.hero h1 { margin-bottom: var(--sp-6); }
.hero h1 .cu {
  /* This text lives inside .hero-dark, so every stop needs to read bright
     against navy — nothing from the "safe on light bg" darkened tokens. */
  background: linear-gradient(96deg, var(--tl) 0%, #EAF6FB 32%, var(--tl-soft) 64%, var(--tl) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero-cta { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin-top: var(--sp-8); }

.hero-strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-6);
  margin-top: var(--sp-8);
  padding-top: var(--sp-6);
  border-top: 1px solid var(--line);
}
.hero-strip div { flex: 1 1 130px; }
.hero-strip dt {
  font-family: var(--f-mono);
  font-size: .66rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--t-3);
  margin-bottom: var(--sp-2);
}
.hero-strip dd {
  margin: 0;
  font-family: var(--f-display);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -.01em;
}

/* ---------- 8. Cards ----------------------------------------------------- */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--sp-4);
  margin-top: var(--sp-12);
}

.card {
  position: relative;
  overflow: hidden;
  background: var(--s-1);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--sp-8);
  transition: border-color var(--d-base) var(--e-out),
              transform var(--d-base) var(--e-out),
              background var(--d-base) var(--e-out);
}
.card:hover {
  border-color: var(--ac-soft);
  transform: translateY(-4px);
  box-shadow: 0 14px 32px -18px rgba(33, 27, 20, .35);
}
/* Soft glow that tracks the pointer, set via --mx/--my in site.js.
   Falls back to a centred glow with no JS, so it's a progressive
   enhancement, not a dependency. */
.card::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(220px circle at var(--mx, 50%) var(--my, 30%), rgba(0, 168, 232, .12), transparent 70%);
  opacity: 0;
  transition: opacity var(--d-base) var(--e-out);
  pointer-events: none;
}
.card:hover::before { opacity: 1; }

/* Photo-led variant — the finish cards on the homepage. The photo replaces
   the line icon (redundant once there's a real image) and bleeds to the
   card's edges via a negative margin equal to the card's own padding. */
.card-photo { padding-top: 0; }
.card-photo-frame {
  margin: 0 calc(var(--sp-8) * -1) var(--sp-6);
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--s-2);
}
.card-photo-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 600ms var(--e-out);
}
.card-photo:hover .card-photo-frame img { transform: scale(1.05); }
.card h3 { margin-bottom: var(--sp-3); }
.card p { color: var(--t-2); font-size: .97rem; margin: 0; }

/* A question list that reads as interactive on hover — a small marker
   brightens and the line nudges right, encouraging a read-through rather
   than sitting as flat text. Used for the "ask any contractor" checklist. */
.ask-list {
  margin: 1.5rem 0 0;
  padding: 0;
  list-style: none;
  color: var(--t-2);
  display: grid;
  gap: .9rem;
  font-size: .97rem;
}
.ask-list li {
  position: relative;
  padding-left: 1.35rem;
  transition: color var(--d-base) var(--e-out), padding-left var(--d-base) var(--e-out);
}
.ask-list li::before {
  content: "";
  position: absolute;
  left: 0; top: .55em;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--ac-soft);
  transition: background var(--d-base) var(--e-out), transform var(--d-base) var(--e-out);
}
.ask-list li:hover { color: var(--t-1); padding-left: 1.6rem; }
.ask-list li:hover::before { background: var(--ac-hover); transform: scale(1.4); }

.card-no {
  font-family: var(--f-mono);
  font-size: .68rem;
  letter-spacing: .14em;
  color: var(--ac-text);
  display: block;
  margin-bottom: var(--sp-6);
}

.card-meta {
  margin-top: var(--sp-6);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line);
  font-family: var(--f-mono);
  font-size: .74rem;
  letter-spacing: .08em;
  color: var(--t-3);
  text-transform: uppercase;
}

/* Feature card — used for bundles.
   The badge only renders if you add a data-badge attribute, e.g.
   <article class="card card-feature" data-badge="Most booked">
   Leave it off unless the claim is actually true — see README. */
.card-feature { border-color: var(--tl-soft); background: #E7F1EF; }
.card-feature .card-no { color: var(--tl-text); }
.card-feature[data-badge]::after {
  content: attr(data-badge);
  position: absolute;
  top: var(--sp-6); right: var(--sp-6);
  font-family: var(--f-mono);
  font-size: .6rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--tl-text);
  border: 1px solid var(--tl-soft);
  border-radius: 999px;
  padding: 3px 9px;
  background: var(--s-1);
}

/* ---------- 9. Before / after slider ------------------------------------- */

.ba {
  position: relative;
  border-radius: var(--r-md);
  overflow: hidden;
  border: 1px solid var(--line);
  aspect-ratio: 16 / 10;
  background: var(--s-1);
  touch-action: pan-y;         /* let the page scroll vertically over it */
  --ba-pos: 50%;
}
.ba-layer { position: absolute; inset: 0; }
.ba-layer img, .ba-layer svg { width: 100%; height: 100%; object-fit: cover; }

/* Top layer is clipped — clip-path is GPU-friendly and causes no reflow */
.ba-after { clip-path: inset(0 0 0 var(--ba-pos)); }

.ba-tag {
  position: absolute;
  bottom: var(--sp-4);
  font-family: var(--f-mono);
  font-size: .64rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  background: rgba(8, 15, 14, .78);
  backdrop-filter: blur(6px);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 5px 12px;
  color: #C7D1D6; /* fixed light colour — this pill sits on a photo, not the page, regardless of site theme */
  pointer-events: none;
}
.ba-tag-before { left: var(--sp-4); }
.ba-tag-after  { right: var(--sp-4); color: var(--ac-soft); border-color: var(--ac-soft); }

.ba-divider {
  position: absolute;
  top: 0; bottom: 0;
  left: var(--ba-pos);
  width: 2px;
  background: var(--ac);
  transform: translateX(-1px);
  pointer-events: none;
  box-shadow: 0 0 18px rgba(178, 85, 31, .55);
}
.ba-knob {
  position: absolute;
  top: 50%; left: var(--ba-pos);
  width: 52px; height: 52px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--ac);
  color: var(--ac-on-fill);
  display: grid;
  place-items: center;
  pointer-events: none;
  box-shadow: 0 4px 22px rgba(0, 0, 0, .5);
}

/* The real control: a range input, so it is keyboard + screen-reader usable */
.ba-range {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: ew-resize;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
}
.ba-range:focus-visible { outline: none; }
.ba-range:focus-visible ~ .ba-knob {
  outline: 3px solid var(--ac-hover);
  outline-offset: 4px;
}

/* ---------- 9b. Flake finish gallery ---------------------------------------- */
/* Cards are .card.card-photo (section 8) so they inherit the cursor glow
   and hover lift for free. Everything below is what's specific to this
   gallery: the empty state, the "View gallery" button, and the lightbox. */

.flake-gallery-section { margin-top: var(--sp-12); }
.flake-gallery-section > a { text-decoration-thickness: 1px; text-underline-offset: 3px; }

.finish-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--sp-6);
  margin-top: var(--sp-8);
}

.card-photo-frame.is-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--s-2);
  color: var(--t-3);
  font-family: var(--f-mono);
  font-size: .8rem;
  letter-spacing: .06em;
  text-align: center;
  padding: var(--sp-4);
}

.finish-view-btn { margin-top: var(--sp-5); width: 100%; }
.finish-view-btn:disabled {
  opacity: .5;
  cursor: default;
  pointer-events: none;
}

/* ---------- 9c. Lightbox --------------------------------------------------- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-6);
}
.lightbox[hidden] { display: none; }

.lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(6, 12, 18, .88);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.lightbox-panel {
  position: relative;
  z-index: 1;
  width: min(1080px, 100%);
  max-height: 92vh;
  background: var(--s-1);
  border-radius: var(--r-md);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 40px 90px -24px rgba(0, 0, 0, .55);
  animation: lightboxIn 260ms var(--e-out);
}
@keyframes lightboxIn {
  from { opacity: 0; transform: translateY(12px) scale(.98); }
  to   { opacity: 1; transform: none; }
}

.lightbox-close {
  position: absolute;
  top: var(--sp-4); right: var(--sp-4);
  z-index: 2;
  width: 40px; height: 40px;
  border-radius: 50%;
  background: rgba(6, 12, 18, .55);
  color: #F4F8FB;
  display: grid;
  place-items: center;
  transition: background var(--d-fast) var(--e-out);
}
.lightbox-close:hover { background: var(--ac-hover); }

.lightbox-header { padding: var(--sp-6) var(--sp-6) 0; flex: none; }
.lightbox-header h3 { margin-bottom: 2px; }
.lightbox-count { font-family: var(--f-mono); font-size: .8rem; color: var(--t-3); margin: 0; }

.lightbox-stage {
  position: relative;
  flex: 1;
  min-height: 280px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0B1622;
  margin-top: var(--sp-4);
}
.lightbox-image {
  max-width: 100%;
  max-height: min(58vh, 560px);
  object-fit: contain;
  display: block;
}

.lightbox-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 44px; height: 44px;
  border-radius: 50%;
  background: rgba(6, 12, 18, .55);
  color: #F4F8FB;
  display: grid;
  place-items: center;
  transition: background var(--d-fast) var(--e-out);
}
.lightbox-nav:hover { background: var(--ac-hover); }
.lightbox-prev { left: var(--sp-4); }
.lightbox-next { right: var(--sp-4); }
.lightbox-nav:disabled { opacity: .3; pointer-events: none; }

.lightbox-thumbs {
  flex: none;
  max-height: 132px;
  overflow-y: auto;
  padding: var(--sp-4) var(--sp-6);
  columns: 96px;
  column-gap: var(--sp-2);
}
.lightbox-thumbs button {
  display: block;
  width: 100%;
  padding: 0;
  margin-bottom: var(--sp-2);
  break-inside: avoid;
  border-radius: var(--r-sm);
  overflow: hidden;
  border: 2px solid transparent;
  cursor: pointer;
  line-height: 0;
}
.lightbox-thumbs img { width: 100%; display: block; opacity: .6; transition: opacity var(--d-fast) var(--e-out); }
.lightbox-thumbs button:hover img { opacity: .9; }
.lightbox-thumbs button.is-active { border-color: var(--ac-hover); }
.lightbox-thumbs button.is-active img { opacity: 1; }

.lightbox-cta {
  flex: none;
  padding: var(--sp-4) var(--sp-6) var(--sp-6);
  text-align: center;
  border-top: 1px solid var(--line);
}

@media (max-width: 640px) {
  .lightbox { padding: 0; }
  .lightbox-panel { width: 100%; height: 100%; max-height: none; border-radius: 0; }
  .lightbox-nav { width: 38px; height: 38px; }
}

/* ---------- 10. Gallery -------------------------------------------------- */

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
  gap: var(--sp-4);
  margin-top: var(--sp-12);
}

.shot {
  position: relative;
  border-radius: var(--r-md);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--s-1);
  aspect-ratio: 4 / 3;
}
.shot > img, .shot > svg { width: 100%; height: 100%; object-fit: cover; transition: transform 600ms var(--e-out); }
.shot:hover > img, .shot:hover > svg { transform: scale(1.04); }
.shot-tall { aspect-ratio: 3 / 4; }
.shot-wide { grid-column: span 2; aspect-ratio: 16 / 9; }
@media (max-width: 700px) { .shot-wide { grid-column: span 1; aspect-ratio: 4 / 3; } }

.shot-cap {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: var(--sp-8) var(--sp-4) var(--sp-4);
  background: linear-gradient(to top, rgba(8, 15, 14, .92), transparent);
  font-family: var(--f-mono);
  font-size: .7rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #C7D1D6; /* fixed light colour — this sits on a photo, not the page */
}
.shot-cap b { color: #F4F8FB; font-weight: 600; }

/* ---------- 11. Process / steps ------------------------------------------ */

.steps { counter-reset: step; margin-top: var(--sp-12); display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }
.step {
  background: var(--s-0);
  padding: var(--sp-8);
  display: grid;
  grid-template-columns: 76px 1fr;
  gap: var(--sp-6);
  align-items: start;
}
@media (max-width: 640px) { .step { grid-template-columns: 1fr; gap: var(--sp-3); padding: var(--sp-6); } }
.step-no {
  font-family: var(--f-mono);
  font-size: .72rem;
  letter-spacing: .12em;
  color: var(--ac-text);
  padding-top: 5px;
}
.step h3 { margin-bottom: var(--sp-2); }
.step p { color: var(--t-2); font-size: .97rem; margin: 0; }

/* ---------- 12. Trust bar ------------------------------------------------ */

.trust {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1px;
  background: var(--line);
  border-block: 1px solid var(--line);
}
.trust-item {
  background: var(--s-0);
  padding: var(--sp-8) var(--sp-6);
  display: flex;
  gap: var(--sp-4);
  align-items: flex-start;
  transition: background var(--d-base) var(--e-out);
}
.trust-item:hover { background: var(--s-1); }
.trust-item svg {
  color: var(--ac-hover);
  flex: none;
  margin-top: 2px;
  transition: transform var(--d-base) var(--e-out);
}
.trust-item:hover svg { transform: scale(1.12) rotate(-4deg); }
.trust-item b { display: block; font-family: var(--f-display); font-size: .98rem; letter-spacing: -.01em; margin-bottom: 3px; }
.trust-item span { font-size: .88rem; color: var(--t-2); line-height: 1.5; }

/* ---------- 12b. Stats --------------------------------------------------- */
/* Unused until you have real figures. See README — do not populate these
   with invented numbers. Pair with data-count to animate on scroll:
   <div class="stat"><b data-count="147" data-suffix="+"></b><span>Garages</span></div> */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  margin-top: var(--sp-8);
}
.stat { background: var(--s-1); padding: var(--sp-8) var(--sp-4); text-align: center; }
.stat b {
  display: block;
  font-family: var(--f-display);
  font-size: clamp(1.9rem, 4vw, 2.6rem);
  font-weight: 700;
  letter-spacing: -.03em;
  line-height: 1;
  color: var(--ac);
  font-variant-numeric: tabular-nums;
  margin-bottom: var(--sp-2);
}
.stat span {
  font-family: var(--f-mono);
  font-size: .68rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--t-3);
}

/* ---------- 13. Band (CTA) ----------------------------------------------- */

.band {
  position: relative;
  background:
    radial-gradient(120% 140% at 50% 0%, rgba(0, 168, 232, .12) 0%, transparent 62%),
    var(--s-1);
  border-block: 1px solid var(--line);
  text-align: center;
  overflow: hidden;
}
/* Second colour for variety across pages: <section class="section band is-tl"> */
.band.is-tl {
  background:
    radial-gradient(120% 140% at 50% 0%, rgba(11, 42, 74, .10) 0%, transparent 62%),
    var(--s-1);
}
.band .lede { margin-inline: auto; }
.band-actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); justify-content: center; margin-top: var(--sp-8); }

/* ---------- 13b. Warranty teaser ------------------------------------------ */
/* Dark anchor moment between the process steps and the final CTA band —
   same dark-navy treatment as the hero caption, not a new colour. */

.warranty-teaser { background: #0B1622; text-align: center; }
.warranty-teaser .wrap { max-width: 720px; }
.warranty-icon { width: 42px; height: 42px; margin: 0 auto var(--sp-6); color: #6FD1F0; }
.warranty-teaser .eyebrow { color: #6FD1F0; justify-content: center; }
.warranty-teaser .eyebrow::before { background: #6FD1F0; }
.warranty-teaser h2 { color: #F4F8FB; }
.warranty-teaser .lede { color: #C6D5DE; margin-inline: auto; }

.warranty-stats {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-8);
  margin-top: var(--sp-8);
  padding-top: var(--sp-8);
  border-top: 1px solid rgba(244, 248, 251, .14);
}
.warranty-stat { min-width: 160px; }
.warranty-stat b {
  display: block;
  font-family: var(--f-display);
  font-size: clamp(2.1rem, 5vw, 2.9rem);
  color: #F4F8FB;
  line-height: 1;
}
.warranty-stat span {
  display: block;
  margin-top: var(--sp-2);
  font-family: var(--f-mono);
  font-size: .8rem;
  letter-spacing: .06em;
  color: #8FA6B8;
}
.warranty-teaser .band-actions { margin-top: var(--sp-10, 2.75rem); }
.warranty-teaser .btn-line { border-color: rgba(244, 248, 251, .35); color: #F4F8FB; }
.warranty-teaser .btn-line:hover { border-color: #00A8E8; color: #7FD1EF; background: rgba(0, 168, 232, .12); }

/* Small trust line near a primary CTA, e.g. under the hero buttons */
.trust-note {
  margin-top: var(--sp-4);
  font-family: var(--f-mono);
  font-size: .78rem;
  letter-spacing: .03em;
}
.trust-note a { color: #8FA6B8; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.trust-note a:hover { color: #F4F8FB; }
/* Light-page variant, used outside the dark hero caption */
.trust-note.is-on-light a { color: var(--t-3); }
.trust-note.is-on-light a:hover { color: var(--ac-hover); }

/* ---------- 14. Forms ---------------------------------------------------- */

.form { display: grid; gap: var(--sp-5); margin-top: var(--sp-8); }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-5); }
@media (max-width: 640px) { .form-row { grid-template-columns: 1fr; } }

.field label {
  display: block;
  font-family: var(--f-mono);
  font-size: .7rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--t-2);
  margin-bottom: var(--sp-2);
}
.field label .req { color: var(--ac); }

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 50px;                /* >=44px touch target */
  background: var(--s-3);
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  padding: var(--sp-3) var(--sp-4);
  font-size: 1rem;                 /* 16px+ stops iOS auto-zoom */
  transition: border-color var(--d-fast) var(--e-out), background var(--d-fast) var(--e-out);
}
.field textarea { min-height: 132px; resize: vertical; line-height: 1.6; }
.field input::placeholder, .field textarea::placeholder { color: var(--t-3); }
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--line-firm); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--ac);
  background: var(--s-2);
}

.field-help { font-size: .82rem; color: var(--t-3); margin: var(--sp-2) 0 0; }

/* Error state carries an icon + text, never colour alone */
.field-error {
  display: none;
  align-items: center;
  gap: var(--sp-2);
  font-size: .84rem;
  color: #B3261E;                  /* 6.0:1 on --s-0 */
  margin-top: var(--sp-2);
}
.field.is-invalid .field-error { display: flex; }
.field.is-invalid input,
.field.is-invalid select,
.field.is-invalid textarea { border-color: #B3261E; }
.field-checkbox.is-invalid .field-error { display: flex; }

.form-status {
  display: none;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-4);
  border-radius: var(--r-sm);
  border: 1px solid var(--line-firm);
  background: var(--s-2);
  font-size: .93rem;
}
.form-status.is-shown { display: flex; }
.form-status svg { flex: none; margin-top: 2px; color: var(--ac); }

.field-checkbox { display: flex; align-items: flex-start; gap: var(--sp-3); }
.field-checkbox label { font-size: .9rem; color: var(--t-2); line-height: 1.5; }
.field-checkbox input[type="checkbox"] { margin-top: 3px; width: 18px; height: 18px; flex: none; accent-color: var(--ac); }

/* ---------- 14b. Warranty page -------------------------------------------- */

.warranty-list { list-style: none; margin: 1.5rem 0 0; padding: 0; display: grid; gap: .85rem; }
.warranty-list li { position: relative; padding-left: 1.7rem; color: var(--t-2); font-size: .97rem; line-height: 1.55; }
.warranty-list li::before {
  position: absolute; left: 0; top: 0;
  font-family: var(--f-mono); font-weight: 700;
}
.warranty-list.is-covered li::before { content: "\2713"; color: var(--tl-text); }
.warranty-list.is-excluded li::before { content: "\2013"; color: var(--t-3); font-size: 1.1rem; }

.warranty-faq { display: grid; gap: var(--sp-6); margin-top: 2.5rem; }
.warranty-faq > div { padding-bottom: var(--sp-6); border-bottom: 1px solid var(--line); }
.warranty-faq > div:last-child { border-bottom: 0; padding-bottom: 0; }
.warranty-faq dt { font-family: var(--f-display); font-weight: 700; font-size: 1.05rem; margin: 0 0 .5rem; }
.warranty-faq dd { margin: 0; color: var(--t-2); line-height: 1.6; }
.warranty-faq dd.is-pending { color: var(--t-3); font-style: italic; }

/* ---------- 15. Contact list --------------------------------------------- */

.contact-list { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--sp-6); }
.contact-list li { display: flex; gap: var(--sp-4); align-items: flex-start; }
.contact-list svg { color: var(--ac-hover); flex: none; margin-top: 3px; }
.contact-list dt {
  font-family: var(--f-mono);
  font-size: .66rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--t-3);
  margin-bottom: 3px;
}
.contact-list dd { margin: 0; font-size: 1.02rem; }
.contact-list dd a { text-decoration: none; }
.contact-list dd a:hover { text-decoration: underline; }
.contact-list small { display: block; color: var(--t-3); font-size: .84rem; margin-top: 3px; }

/* ---------- 16. Footer --------------------------------------------------- */

.site-foot {
  border-top: 1px solid var(--line);
  padding-block: var(--sp-16) var(--sp-8);
  font-size: .92rem;
  color: var(--t-2);
}
.foot-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1.2fr;
  gap: var(--sp-8);
  margin-bottom: var(--sp-16);
}
@media (max-width: 900px) { .foot-grid { grid-template-columns: 1fr 1fr; gap: var(--sp-12) var(--sp-8); } }
@media (max-width: 520px) { .foot-grid { grid-template-columns: 1fr; } }

.foot-grid h4 {
  font-family: var(--f-mono);
  font-size: .68rem;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--t-3);
  margin: 0 0 var(--sp-4);
}
.foot-grid ul { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--sp-3); }
.foot-grid a { color: var(--t-2); text-decoration: none; }
.foot-grid a:hover { color: var(--ac-text); }

.socials { display: flex; gap: var(--sp-3); margin-top: var(--sp-4); }
.socials a {
  width: 42px; height: 42px;
  border: 1px solid var(--line-firm);
  border-radius: var(--r-sm);
  display: grid;
  place-items: center;
  color: var(--t-2);
  transition: color var(--d-fast) var(--e-out), border-color var(--d-fast) var(--e-out);
}
.socials a:hover { color: var(--ac-hover); border-color: var(--ac-hover); }

.foot-base {
  border-top: 1px solid var(--line);
  padding-top: var(--sp-6);
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-8);
  justify-content: space-between;
  font-family: var(--f-mono);
  font-size: .72rem;
  letter-spacing: .06em;
  color: var(--t-3);
  text-transform: uppercase;
}

/* ---------- 16b. Hero photo ------------------------------------------------ */
/* A full-bleed photo with the headline overlaid on a bottom scrim. Static —
   no scroll-jacking, no JS, no frame sequence — see the "Mobile hero photo"
   rule in section 19 for how this stacks on a phone instead of overlaying.
   Target height is 100dvh minus the sticky nav's own height (100px bar +
   1px border — keep this in sync with .nav's height above, it's a real
   bug magnet) — .site-head sits in normal flow above this, not overlaid
   on top of it, so without the subtraction the caption sits partly below
   the fold on load. This is min-height, not height, on purpose: the
   caption content (headline, lede, two CTAs, a trust line, a three-item
   stat row) has grown before and clipped against the top of a
   *fixed*-height container more than once. min-height lets the section
   grow taller than the viewport instead, if the content ever needs more
   room than that — costs nothing on a normal viewport where content
   already fits, and can't clip again if more gets added later. */

.hero-photo { position: relative; min-height: max(560px, calc(100dvh - var(--nav-h))); overflow: hidden; background: #0B1622; }
.hero-photo-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Biased down from centre on purpose. The section is taller now (see the
     min-height note above), and a plain, washed-out band near the top of
     this specific photo was landing right at the seam with the nav once
     more of the image's vertical extent came into view — this crops that
     part out instead of showing it. */
  object-position: center 75%;
}
.hero-photo-caption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 1;
  width: 100%;
  padding: clamp(3rem, 9vw, 6rem) 0 clamp(3rem, 8vw, 6rem);
  /* Two layers: a bottom-up scrim so the caption always has a dark floor to
     sit on, plus a left-side scrim so the text (pinned left, see .wrap
     below) reads clearly even over the bright, sunset-lit part of the
     photo — the car and the rest of the garage stay visible on the right. */
  background:
    linear-gradient(to right, rgba(6, 16, 26, .82) 0%, rgba(6, 16, 26, .55) 42%, transparent 68%),
    linear-gradient(to top, rgba(8, 22, 34, .92) 0%, rgba(8, 22, 34, .55) 45%, transparent 100%);
}
.hero-photo-caption .wrap { max-width: 640px; margin-inline: 0; }
.hero-photo-caption .eyebrow { color: #6FD1F0; }
.hero-photo-caption .eyebrow::before { background: #6FD1F0; }
.hero-photo-caption h1,
.hero-photo-caption h2 { color: #F4F8FB; }
.hero-photo-caption h1 .cu {
  background: linear-gradient(96deg, #2E7F79 0%, #EAF6FB 32%, #7FD1EF 64%, #00A8E8 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.hero-photo-caption p { color: #C6D5DE; }
.hero-photo-caption .hero-strip { border-top-color: rgba(244, 248, 251, .2); }
.hero-photo-caption .hero-strip dt { color: #8FA6B8; }
.hero-photo-caption .hero-strip dd { color: #F4F8FB; }
.hero-photo-caption .btn-line { border-color: rgba(244, 248, 251, .35); color: #F4F8FB; }
.hero-photo-caption .btn-line:hover { border-color: #00A8E8; color: #7FD1EF; background: rgba(0, 168, 232, .12); }

/* A quiet cue that there's more below — not navigation, just a nudge.
   Bobs gently; the reduced-motion rule in section 19 already zeroes
   animation-duration globally, so it just sits still there instead of
   needing its own override. */
.hero-scroll-cue {
  position: absolute;
  left: 50%; bottom: var(--sp-6);
  z-index: 2;
  display: flex;
  color: rgba(244, 248, 251, .75);
  animation: heroCueBob 2.4s var(--e-out) infinite;
}
.hero-scroll-cue:hover { color: #F4F8FB; }
@keyframes heroCueBob {
  0%, 100% { transform: translate(-50%, 0); }
  50%      { transform: translate(-50%, 7px); }
}

/* ---------- 17. Sticky mobile call bar ----------------------------------- */

.callbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: var(--z-sticky);
  display: none;
  gap: 1px;
  background: var(--line-firm);
  border-top: 1px solid var(--line-firm);
  padding-bottom: env(safe-area-inset-bottom);
}
.callbar a {
  flex: 1;
  background: var(--s-1);
  color: var(--t-1);
  text-decoration: none;
  min-height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  font-family: var(--f-mono);
  font-size: .76rem;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.callbar a.is-primary { background: var(--ac); color: var(--ac-on-fill); }
@media (max-width: 720px) {
  .callbar { display: flex; }
  body { padding-bottom: 56px; }
}

/* ---------- 18. Scroll reveal -------------------------------------------- */

.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--d-slow) var(--e-out), transform var(--d-slow) var(--e-out);
  transition-delay: var(--reveal-delay, 0ms);
}
.reveal.is-in { opacity: 1; transform: none; }

/* ---------- 19. Reduced motion ------------------------------------------- */
/* Everything lands in its final state; nothing moves. */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { opacity: 1; transform: none; }
  .card:hover, .btn:active { transform: none; }
  .shot:hover > img, .shot:hover > svg { transform: none; }
}

/* ---------- 19b. Mobile hero photo ----------------------------------------- */
/* The full hero content (headline, lede, two CTAs, a three-item stat row)
   overlaid on a fixed-height photo risks clipping on a short phone viewport
   with nowhere for the overflow to go. Below this width the photo drops to
   its natural aspect ratio in normal flow and the caption sits below it on
   a solid background instead of overlaying. */
@media (max-width: 760px) {
  .hero-photo { position: static; height: auto; min-height: 0; }
  .hero-photo-img { position: static; width: 100%; height: auto; aspect-ratio: 1080 / 607; object-fit: cover; }
  .hero-photo-caption { position: static; padding-top: var(--sp-8); background: #0B1622; }
  .hero-scroll-cue { display: none; }
}

/* ---------- 20. Print ---------------------------------------------------- */

@media print {
  .site-head, .callbar, .band, .ba-range { display: none; }
  body { background: #fff; color: #000; }
}
