/* ==========================================================================
   Car Care by Zee — Marketing Site
   Design tokens & components per brand kit.

   DARK THEME. The brand palette is unchanged — its usage is inverted.
   The kit specifies carbon 60 / mist 25 / graphite 10 / polish 5, which is
   a dark-dominant ratio; the light build spent that budget on accents.
   Here carbon actually carries the page, as intended.

   Elevation ladder — surfaces get LIGHTER as they rise. Drop shadows are
   nearly invisible on black, so separation comes from hairline borders and
   a 1px specular edge, not from shadow.

       void       #07080A   the page
       carbon     #0E1116   cards, panels, bands
       graphite   #1B1F26   controls nested inside a card
       slate      #2A2F38   hover / highest
       well       #0A0C10   recessed — form inputs read as cut into the card
   ========================================================================== */

:root {
  color-scheme: dark;

  /* Color — brand kit, unchanged */
  --carbon: #0E1116;
  --graphite: #1B1F26;
  --slate: #2A2F38;
  --mist: #F4F5F7;
  --paper: #FAFAFA;
  --chrome: #C8CDD3;
  --polish: oklch(0.68 0.13 235);
  --polish-deep: oklch(0.52 0.13 235);
  --polish-glow: oklch(0.78 0.13 235);

  /* Surfaces */
  --void: #07080A;
  --bg: var(--void);
  --surface: var(--carbon);
  --surface-2: var(--graphite);
  --surface-3: var(--slate);
  --well: #0A0C10;

  /* Ink — mist at descending emphasis.
     The floor is 0.52: below that, mist on carbon drops under 4.5:1 and 11px
     mono labels stop being readable. The light build could afford fainter
     tints because ink-on-white starts with far more headroom. Measured
     against carbon: 0.78 -> 9.9:1, 0.62 -> 7.0:1, 0.52 -> 5.3:1. */
  --ink: var(--mist);
  --ink-2: rgba(244, 245, 247, 0.78);
  --ink-3: rgba(244, 245, 247, 0.62);
  --ink-4: rgba(244, 245, 247, 0.52);

  /* Accent. --polish-deep is a fill colour only; at L .52 it is too dark to
     set type on black, so anything that READS as accent text uses --accent.
     The wash is the selected-state tint; at the 5-6% that worked over white
     it disappears over carbon, hence 16%. */
  --accent: var(--polish);
  --accent-wash-strong: oklch(0.68 0.13 235 / 0.16);

  /* Lines. --line and --line-strong group and decorate; --line-ui draws the
     boundary of an actual control (input, button, chip). WCAG 1.4.11 wants
     3:1 for that, and measured on carbon 0.20 gives 1.7:1 — legible as a hint,
     not as an edge. 0.42 clears 3:1 on every surface in the ladder. */
  --line: rgba(244, 245, 247, 0.10);
  --line-strong: rgba(244, 245, 247, 0.20);
  --line-ui: rgba(244, 245, 247, 0.42);
  --line-dash: 1px dashed rgba(244, 245, 247, 0.12);
  --line-light: rgba(255, 255, 255, 0.08);

  /* Radii */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 14px;
  --r-xl: 18px;
  /* Buttons sit apart from the surface radii. Once the bands went flush there
     were no rounded containers left, which made a 12px button the roundest
     thing on the page — it read as a leftover from the card language rather
     than a deliberate shape. */
  --r-btn: 4px;

  /* Type */
  --display: 'Space Grotesk', system-ui, sans-serif;
  --body: 'Inter', system-ui, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, monospace;

  /* Layout */
  --container: 1280px;
  --gutter: 56px;
  --section-y: 96px;
  /* How far below the header every page starts. One token, because this had
     drifted: hero pages opened 26px higher than the rest. */
  --page-top: 64px;
}

@media (max-width: 768px) {
  :root {
    --gutter: 24px;
    --section-y: 56px;
    --page-top: 40px;
  }
}

/* ==========================================================================
   Reset / Base
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html {
  scroll-behavior: smooth;
  /* The sticky header is 64px tall: #section links (the nav's Window Tint,
     the footer, the old Wix redirects) land below it, not under it. */
  scroll-padding-top: 64px;
}

body {
  /* Two low-alpha blooms bleeding off the top corners. On a page this dark a
     flat fill reads as "unstyled black"; a little atmosphere reads as paint
     under a light. They scroll away — the rest of the page is true black. */
  background-color: var(--bg);
  background-image:
    radial-gradient(900px 520px at 78% -6%, oklch(0.68 0.13 235 / 0.10), transparent 62%),
    radial-gradient(760px 460px at 4% 2%, oklch(0.52 0.13 235 / 0.09), transparent 58%);
  background-repeat: no-repeat;
  color: var(--ink);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

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

/* The five <b> elements would otherwise render at the UA default of 700 —
   a weight no longer requested, so the browser would synthesise it. 600 is
   loaded and is the right weight for this type anyway. */
b, strong { font-weight: 600; }
button { font: inherit; cursor: pointer; border: 0; background: transparent; color: inherit; }
a { color: inherit; text-decoration: none; }
input, select, textarea { font: inherit; color: inherit; }

::selection { background: oklch(0.68 0.13 235 / 0.30); color: var(--mist); }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Skip link. Seven header stops (logo + five nav items + CTA) stood between
   a keyboard user and the content on every page. Hidden until focused. */
.skip-link {
  position: absolute;
  left: 16px;
  top: -100px;
  z-index: 100;
  padding: 12px 18px;
  border-radius: var(--r-md);
  background: var(--mist);
  color: var(--carbon);
  font-size: 14px;
  font-weight: 500;
  transition: top 160ms ease;
}
.skip-link:focus {
  top: 12px;
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* The skip target is focusable only so focus can land there; it should not
   draw a ring around the whole page when it does. */
main[tabindex="-1"]:focus { outline: none; }

/* Scrollbar — a default light scrollbar against a black page is a bright
   stripe down the edge. `color-scheme: dark` handles Firefox and Safari. */
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb {
  background: var(--surface-3);
  border-radius: 999px;
  border: 3px solid var(--bg);
}
::-webkit-scrollbar-thumb:hover { background: #3A404B; }

/* ==========================================================================
   Type primitives
   ========================================================================== */
.display { font-family: var(--display); font-weight: 600; letter-spacing: -0.02em; }

.h1 {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(40px, 6vw, 64px);
  line-height: 0.95;
  letter-spacing: -0.035em;
  margin: 0;
}
.h2 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 28px;
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 0;
}
.h3 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 18px;
  line-height: 1.3;
  letter-spacing: -0.01em;
  margin: 0;
}
.body-lg {
  font-size: 18px;
  line-height: 1.55;
}
.small { font-size: 14px; line-height: 1.5; }

.mono {
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.4;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.mono.tight { letter-spacing: 0.04em; }
.mono.wide { letter-spacing: 0.18em; }
.mono.x-wide { letter-spacing: 0.32em; }
.mono.dim { color: var(--ink-4); }

/* Everything is "on dark" now, so the -light variants collapse onto the
   base. They stay as aliases rather than being removed — the markup uses
   both spellings in ~140 places and they should never diverge again. */
.mono-light {
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.4;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.mono-light.dim { color: var(--ink-4); }

.accent { color: var(--accent); }
.accent-glow { color: var(--polish-glow); }

/* ==========================================================================
   Layout
   ========================================================================== */
.container {
  max-width: var(--container);
  margin: 0 auto;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

.section {
  padding-top: var(--section-y);
  padding-bottom: var(--section-y);
}

/* SectionHead — `<SectionHead title="..." num="01 / Identity" />` */
.section-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  border-bottom: 1px solid var(--line);
  padding-bottom: 16px;
  margin-bottom: 32px;
  gap: 16px;
}
.section-head .num { color: var(--ink-4); white-space: nowrap; }

/* ==========================================================================
   Wordmark / Logo Lockup
   ========================================================================== */
.wordmark {
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 0.95;
  display: flex;
  flex-direction: column;
}
.wordmark > span {
  display: block;
  line-height: 0.95;
}
.wordmark.dark,
.wordmark.light { color: var(--mist); }
.wordmark.dark .accent,
.wordmark.light .accent { color: var(--polish-glow); }

/* Logo lockup — horizontal */
.lockup-h {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  min-height: 44px;   /* it is the "home" link; it needs a real tap target */
}

/* ==========================================================================
   Header / Nav
   ========================================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(7, 8, 10, 0.72);
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--line);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 64px;
  gap: 32px;
}
.site-nav {
  display: flex;
  align-items: center;
  gap: 28px;
}
.site-nav a {
  font-size: 14px;
  font-weight: 500;
  color: var(--ink-2);
  transition: color 180ms ease;
}
.site-nav a:hover,
.site-nav a[aria-current="page"] { color: var(--ink); }

.btn.header-cta { display: none; }
@media (min-width: 768px) {
  .btn.header-cta { display: inline-flex; }
}

/* ==========================================================================
   Mobile navigation

   Below 960px the desktop nav is hidden. Until now nothing replaced it, so a
   phone could reach the logo and the booking CTA and nothing else — five of
   the six pages were unreachable from the header.

   The cut-off was 768px until Window Tint joined the nav (2026-10-09). Six
   links, the logo and the CTA need about 920px on one line; below that the
   links wrapped, so tablets get the panel too.
   ========================================================================== */
.nav-toggle {
  display: none;
  align-items: center;
  gap: 10px;
  padding: 12px 6px;
  margin-right: -6px;
  min-height: 44px;
  color: var(--ink);
}
.nav-toggle__label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
/* Three bars from one element: the middle is the box's own background, the
   outer two are pseudo-elements, so the whole thing animates into an X. */
.nav-toggle__box {
  position: relative;
  width: 22px;
  height: 14px;
  display: block;
}
.nav-toggle__bar,
.nav-toggle__bar::before,
.nav-toggle__bar::after {
  position: absolute;
  left: 0;
  width: 22px;
  height: 1.5px;
  background: currentColor;
  transition: transform 220ms ease, opacity 160ms ease;
}
.nav-toggle__bar { top: 6px; }
.nav-toggle__bar::before { content: ''; top: -6px; }
.nav-toggle__bar::after  { content: ''; top: 6px; }

[aria-expanded="true"] .nav-toggle__bar { background: transparent; }
[aria-expanded="true"] .nav-toggle__bar::before { transform: translateY(6px) rotate(45deg); }
[aria-expanded="true"] .nav-toggle__bar::after  { transform: translateY(-6px) rotate(-45deg); }

.mobile-nav {
  display: none;
  position: fixed;
  inset: 64px 0 0;            /* starts below the header bar */
  z-index: 45;
  background: var(--bg);
  padding: 8px var(--gutter) calc(24px + env(safe-area-inset-bottom));
  overflow-y: auto;
  overscroll-behavior: contain;
  flex-direction: column;
}
.mobile-nav[hidden] { display: none; }

.mobile-nav__links {
  display: flex;
  flex-direction: column;
}
.mobile-nav__links a {
  padding: 18px 0;            /* comfortably past 44px */
  font-family: var(--display);
  font-weight: 500;
  font-size: 24px;
  letter-spacing: -0.02em;
  color: var(--ink);
  border-bottom: 1px solid var(--line);
}
.mobile-nav__links a[aria-current="page"] { color: var(--accent); }

.mobile-nav__foot {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 28px;
}
.mobile-nav__foot .btn { width: 100%; }

/* Stops the page behind the panel from scrolling while it is open. */
body.nav-open { overflow: hidden; }

@media (max-width: 959px) {
  .site-nav { display: none; }
  .nav-toggle { display: inline-flex; }
  /* From 768px the header CTA shows too; keep it beside the toggle rather
     than floating mid-bar. */
  .btn.header-cta { margin-left: auto; }
  .mobile-nav:not([hidden]) { display: flex; }
  /* The panel already carries a booking CTA — no need to float a second one
     over it, and the sticky button would sit above the overlay anyway. */
  body.nav-open .sticky-cta { display: none; }
}

/* ==========================================================================
   Buttons
   ========================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--body);
  font-weight: 500;
  font-size: 14px;
  line-height: 1;
  padding: 14px 24px;
  border-radius: var(--r-btn);
  cursor: pointer;
  transition: transform 180ms ease, background-color 180ms ease,
              border-color 180ms ease, color 180ms ease;
  white-space: nowrap;
}
/* Primary inverts: on a black page the loudest button is a light one.
   A carbon fill would be a black rectangle on black. */
.btn--primary {
  background: var(--mist);
  color: var(--carbon);
}
.btn--primary:hover {
  background: #FFFFFF;
  transform: translateY(-1px);
  box-shadow: 0 6px 22px rgba(244, 245, 247, 0.14);
}
.btn--accent {
  background: var(--polish-deep);
  color: var(--mist);
}
.btn--accent:hover {
  background: var(--polish);
  transform: translateY(-1px);
  box-shadow: 0 6px 24px oklch(0.68 0.13 235 / 0.32);
}
/* Ghost and ghost-light were opposites; on dark they are the same button. */
.btn--ghost,
.btn--ghost-light {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line-ui);
}
.btn--ghost:hover,
.btn--ghost-light:hover {
  background: var(--mist);
  color: var(--carbon);
  border-color: var(--mist);
}
.btn--lg { padding: 16px 28px; font-size: 15px; }

.btn .arrow { transition: transform 200ms ease; }
.btn:hover .arrow { transform: translateX(2px); }

/* Sticky mobile booking CTA */
.sticky-cta {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 60;
  background: var(--polish-deep);
  color: var(--mist);
  padding: 14px 22px;
  border-radius: var(--r-btn);
  font-size: 14px;
  font-weight: 500;
  box-shadow: 0 8px 28px oklch(0.52 0.13 235 / 0.45);
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
@media (min-width: 768px) {
  .sticky-cta { display: none; }
}

/* ==========================================================================
   Bands (DarkBand / LightBand)
   ========================================================================== */
.band {
  border-radius: var(--r-xl);
  padding: clamp(40px, 5vw, 64px);
  position: relative;
  overflow: hidden;
}
.band--dark {
  background: var(--surface);
  color: var(--mist);
  border: 1px solid var(--line);
}
/* Specular edge — a 1px highlight raked across the top, the way a light
   source catches the crown of a body panel. This is what separates a card
   from the page now that shadows are useless. */
.band--dark::before,
.band--light::before {
  content: '';
  position: absolute;
  top: 0;
  left: 12%;
  right: 12%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(244, 245, 247, 0.22), transparent);
  pointer-events: none;
  z-index: 2;
}
/* Glow follows the cursor when there is one; falls back to a fixed
   top-right bloom for touch, keyboard, and reduced-motion users. */
.band--dark.has-glow::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(
    620px circle at var(--glow-x, 82%) var(--glow-y, 12%),
    oklch(0.68 0.13 235 / 0.20),
    transparent 62%
  );
  pointer-events: none;
  z-index: 0;
}
.band--dark > * { position: relative; z-index: 1; }
/* Was the light counterpart to band--dark. It still needs to contrast with
   its sibling, so it becomes the LIFTED band — graphite over carbon. */
.band--light {
  background: var(--surface-2);
  border: 1px solid var(--line);
  color: var(--ink);
  position: relative;
  overflow: hidden;
}

/* Flush — keeps the band's rhythm and colour inheritance but drops the card.
   Composes with band--dark / band--light and must therefore come after both.
   On a black page a carbon panel buys an edge without buying much contrast;
   removing it lets the type carry the layout instead of a container. */
.band--flush {
  background: none;
  border: 0;
  border-radius: 0;
  padding-left: 0;
  padding-right: 0;
  overflow: visible;
}
/* No edge means nothing for the specular highlight or the bloom to sit in. */
.band--flush::before,
.band--flush.has-glow::after { content: none; }

/* Stacked flush rows have no card edges left, so a rule does the separating. */
.section > .band--flush {
  padding-top: 52px;
  padding-bottom: 52px;
}
.band--flush + .band--flush { border-top: 1px solid var(--line); }

/* --page-top already spaces the hero off the header; the band should not add
   to it, or hero pages open tighter than the rest. */
.hero .band--flush {
  padding-top: 0;
  padding-bottom: 8px;
}


/* ==========================================================================
   Two-column splits

   These lived as inline `grid-template-columns` on nine elements. An inline
   style outranks a media query, so those layouts could never collapse — the
   columns just squeezed until the page scrolled sideways (contact.html came
   out 492px wide inside a 390px phone). As classes they can stack.
   ========================================================================== */
.split-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px;
  align-items: center;
}
.split-2--lead { grid-template-columns: 1.2fr 1fr; align-items: start; }
.split-2--wide { grid-template-columns: 1.4fr 1fr; }
.split-2--hero { grid-template-columns: 1.15fr 1fr; gap: 48px; }
.split-2--center { align-items: center; }

.service-row__grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 48px;
  align-items: start;
}

/* A grid item defaults to min-width:auto, so it refuses to shrink below its
   longest unbreakable word. One 24px email address was enough to push the
   contact page 29px past the viewport. */
.split-2 > *,
.service-row__grid > * { min-width: 0; }

/* Contact details. These were inline font sizes, which a media query cannot
   override — the same trap as the inline grids. */
.contact-line {
  display: block;
  margin-top: 6px;
  font-family: var(--display);
  font-weight: 500;
  font-size: 24px;
  letter-spacing: -0.02em;
  color: var(--mist);
  overflow-wrap: anywhere;      /* an email address is one long "word" */
}
.contact-line--lg { font-size: 32px; }
.contact-line--accent { color: var(--polish-glow); }

@media (max-width: 480px) {
  .contact-line { font-size: 19px; }
  .contact-line--lg { font-size: 26px; }
}

@media (max-width: 860px) {
  .split-2,
  .split-2--lead,
  .split-2--wide,
  .split-2--hero,
  .service-row__grid {
    grid-template-columns: 1fr;
    gap: 28px;
    align-items: start;
  }
}

/* The opening block on a page without a hero. Was an inline
   `padding-top: 64px` on six pages; the bottom padding is load-bearing — with
   none, the last paragraph's margin collapses straight out of the section and
   opened an 18px gap on some pages but not others. */
.page-intro {
  padding-top: var(--page-top);
  padding-bottom: 8px;
}

/* ==========================================================================
   Hero
   ========================================================================== */
.hero {
  margin-top: var(--page-top);
}
.hero__band {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: 48px;
  align-items: end;
  min-height: clamp(420px, 60vh, 600px);
}
@media (max-width: 768px) {
  .hero__band {
    grid-template-columns: 1fr;
    align-items: start;
  }
}
.hero__meta {
  display: flex;
  flex-direction: column;
  gap: 10px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.hero__meta b { color: var(--mist); font-weight: 500; }

.hero__head .eyebrow { margin-bottom: 24px; color: var(--ink-3); }
.hero h1 em {
  font-style: normal;
  color: var(--polish-glow);
}
.hero__sub {
  margin-top: 24px;
  max-width: 36ch;
  color: var(--ink-2);
  font-size: 16px;
  line-height: 1.55;
}
.hero__actions {
  margin-top: 32px;
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}
.hero__sidecard {
  border-top: 1px solid rgba(244, 245, 247, 0.15);
  padding-top: 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.hero__sidecard .row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  font-size: 14px;
  color: var(--ink-2);
}
.hero__sidecard .row b {
  font-weight: 500;
  color: var(--mist);
}

/* ==========================================================================
   Service cards (`<ServiceCard />`)
   ========================================================================== */
/* 250px minimum puts seven cards at four-then-three across a desktop
   container, where 218px fit five and stranded two on a mostly empty row. */
.service-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 16px;
}
@media (max-width: 540px) {
  .service-grid { grid-template-columns: 1fr; }
}

.service-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 24px;
  min-height: 200px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  position: relative;
  overflow: hidden;
  transition: transform 200ms ease, border-color 200ms ease,
              box-shadow 200ms ease, background-color 200ms ease;
}
.service-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 18%;
  right: 18%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(244, 245, 247, 0.18), transparent);
  pointer-events: none;
}
/* Hover reads as a glow, not a drop shadow — a shadow cast onto black is
   invisible, so the card emits light instead of blocking it. */
.service-card:hover {
  transform: translateY(-2px);
  background: var(--surface-2);
  border-color: oklch(0.68 0.13 235 / 0.55);
  box-shadow: 0 10px 34px oklch(0.68 0.13 235 / 0.14);
}
.service-card__icon {
  width: 48px;
  height: 48px;
  border-radius: 999px;
  border: 1.5px solid var(--line-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
}
.service-card.signature .service-card__icon {
  background: var(--polish-deep);
  border-color: var(--accent);
}
.service-card.signature .service-card__icon svg path,
.service-card.signature .service-card__icon svg circle {
  stroke: var(--mist);
}
.service-card__body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
}
.service-card__caption {
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-3);
}
.service-card__price {
  margin-top: auto;
  display: flex;
  gap: 6px;
  align-items: baseline;
}
/* A card with a link (home's Most popular): the link's hit area covers the
   whole card, and the card shows the keyboard focus ring. */
.service-card__link {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
}
.service-card__link::after { content: ''; position: absolute; inset: 0; }
.service-card__link:focus-visible { outline: none; }
.service-card:has(.service-card__link:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Text for screen readers only, e.g. what a short link like "Book online"
   refers to. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ==========================================================================
   Google reviews (home). Each card opens the reviews on Zee's Google listing,
   through the reviewer's name, whose hit area covers the card.
   ========================================================================== */
.review-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
}
@media (max-width: 540px) {
  .review-grid { grid-template-columns: 1fr; }
}
.review-card {
  margin: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  position: relative;
  transition: border-color 200ms ease, background-color 200ms ease, box-shadow 200ms ease;
}
.review-card:hover {
  background: var(--surface-2);
  border-color: oklch(0.68 0.13 235 / 0.55);
  box-shadow: 0 10px 34px oklch(0.68 0.13 235 / 0.14);
}
.review-card:has(.review-card__link:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.review-card__stars {
  color: var(--polish-glow);
  font-size: 15px;
  letter-spacing: 0.14em;
  line-height: 1;
}
.review-card__quote { margin: 0; flex: 1; }
.review-card__quote p { margin: 0; color: var(--ink); font-size: 16px; line-height: 1.6; }
.review-card__by { display: flex; align-items: center; gap: 12px; }
.review-card__avatar {
  width: 36px;
  height: 36px;
  flex: none;
  border-radius: 999px;
  border: 1.5px solid var(--line-strong);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--display);
  font-weight: 500;
  color: var(--ink);
}
.review-card__name { display: flex; flex-direction: column; gap: 4px; }
.review-card__link { color: var(--ink); font-weight: 600; text-decoration: none; }
.review-card__link::after { content: ''; position: absolute; inset: 0; border-radius: inherit; }
.review-card__link:focus-visible { outline: none; }
.review-card__source { font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.service-card.signature .service-card__price {
  color: var(--accent);
}

/* ==========================================================================
   Price rows (Invoice pattern)
   ========================================================================== */
.price-list {
  display: flex;
  flex-direction: column;
}
.price-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 16px 0;
  border-bottom: var(--line-dash);
  gap: 16px;
}
.price-row:last-child {
  border-bottom: 0;
  padding-top: 20px;
  margin-top: 4px;
  border-top: 1px solid var(--line);
  font-weight: 600;
  color: var(--accent);
  font-size: 18px;
}
.price-row__label { display: flex; flex-direction: column; gap: 2px; }
.price-row__sub { color: var(--ink-3); font-size: 13px; }

/* ==========================================================================
   Mono Label
   ========================================================================== */
.mono-label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  display: inline-block;
}

/* ==========================================================================
   Feature rows
   ========================================================================== */
.feature-row {
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 48px;
  padding: 32px 0;
  border-bottom: 1px solid var(--line);
}
.feature-row:last-child { border-bottom: 0; }
@media (max-width: 768px) {
  .feature-row { grid-template-columns: 1fr; gap: 16px; }
}

/* ==========================================================================
   Testimonials
   ========================================================================== */
.testimonial-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}
@media (max-width: 1024px) { .testimonial-grid { grid-template-columns: 1fr; } }

.testimonial {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.testimonial__quote {
  font-family: var(--display);
  font-weight: 500;
  font-size: 18px;
  line-height: 1.4;
  letter-spacing: -0.01em;
}
.testimonial__attr {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: auto;
}
.testimonial__attr b { font-weight: 500; font-size: 14px; }

/* ==========================================================================
   FAQ
   ========================================================================== */
.faq {
  display: flex;
  flex-direction: column;
}
.faq details {
  border-bottom: 1px solid var(--line);
  padding: 22px 0;
}
.faq details[open] summary { color: var(--accent); }
.faq summary {
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
  font-family: var(--display);
  font-weight: 500;
  font-size: 18px;
  letter-spacing: -0.01em;
  gap: 24px;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary .plus {
  width: 18px;
  height: 18px;
  position: relative;
  flex-shrink: 0;
  transition: transform 200ms ease;
}
.faq summary .plus::before,
.faq summary .plus::after {
  content: '';
  position: absolute;
  background: currentColor;
  inset: 50% auto auto 0;
}
.faq summary .plus::before { width: 100%; height: 1.5px; transform: translateY(-0.75px); }
.faq summary .plus::after { width: 1.5px; height: 100%; left: 50%; top: 0; transform: translateX(-0.75px); }
.faq details[open] summary .plus { transform: rotate(45deg); }
.faq__body {
  margin-top: 14px;
  color: var(--ink-2);
  max-width: 60ch;
  font-size: 15px;
  line-height: 1.6;
}

/* ==========================================================================
   Footer
   ========================================================================== */
.site-footer {
  background: var(--surface);
  color: var(--mist);
  margin-top: var(--section-y);
  border-top: 1px solid var(--line);
}
.site-footer__inner {
  /* Vertical padding only. These elements also carry .container, and a
     `padding: 64px 0 40px` shorthand here zeroed its side gutter — the footer
     sat flush against the screen edge on every page, phones included. */
  padding-top: 64px;
  padding-bottom: 40px;
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: 48px;
}
@media (max-width: 1024px) {
  .site-footer__inner { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 540px) {
  .site-footer__inner { grid-template-columns: 1fr; }
}
/* Ranked h2 (the footer is its own landmark) but styled as a small label —
   heading rank is structure, not size. */
.site-footer .footer-head {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin: 0 0 16px;
  font-weight: 400;
}
.site-footer ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }
.site-footer a { color: var(--ink-2); font-size: 14px; transition: color 180ms; }
.site-footer a:hover { color: var(--mist); }

/* Form bot trap. Off-screen rather than display:none, which some bots skip;
   aria-hidden and tabindex=-1 in the markup keep people from ever reaching it. */
.hp-field {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
/* Hours sit in the Reach Zee column as plain text, sized to match the links
   around them (and padded to match them on mobile, below). */
.site-footer .footer-hours { color: var(--ink-3); font-size: 14px; }

/* "Specials by email" — the Join box the Wix site had. Each signup reaches
   Zee as an email (/api/inquiry, type subscribe). */
.footer-signup { margin-top: 28px; }
.footer-signup .footer-head { display: block; }
.footer-signup__row { display: flex; gap: 8px; }
.footer-signup input {
  flex: 1;
  min-width: 0;
  padding: 10px 12px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-ui);
  background: var(--well);
  color: var(--ink);
  font-size: 16px;            /* 16px keeps iOS from zooming in on focus */
}
.footer-signup input::placeholder { color: var(--ink-4); }
.footer-signup input:focus {
  outline: 0;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px oklch(0.68 0.13 235 / 0.22);
}
.footer-signup .btn { padding: 10px 18px; }
.footer-signup__msg { margin: 10px 0 0; font-size: 13px; color: var(--ink-3); }
.site-footer__bottom {
  padding-top: 24px;       /* vertical only — see .site-footer__inner */
  padding-bottom: 40px;
  /* The divider is drawn at content width. A border-top would run through
     the .container gutters and overshoot the text on both sides. */
  background: linear-gradient(rgba(244, 245, 247, 0.08), rgba(244, 245, 247, 0.08))
    center top / calc(100% - 2 * var(--gutter)) 1px no-repeat;
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

/* ==========================================================================
   Misc utilities
   ========================================================================== */
.divider { height: 1px; background: var(--line); border: 0; }
.text-center { text-align: center; }
.flex-col { display: flex; flex-direction: column; }
.gap-8 { gap: 8px; } .gap-12 { gap: 12px; } .gap-16 { gap: 16px; } .gap-24 { gap: 24px; }
.mt-16 { margin-top: 16px; } .mt-24 { margin-top: 24px; } .mt-32 { margin-top: 32px; }

/* Scroll reveal */
.reveal {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 400ms ease-out, transform 400ms ease-out;
}
.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* ==========================================================================
   Gallery
   ========================================================================== */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* Every row the height of a 4:3 tile. A tall tile has no height of its
     own (its media is absolutely positioned), so it takes whatever its two
     rows add up to — and a row holding nothing but tall tiles had no tile to
     size it. It collapsed to the caption, and the tall tiles in it read as
     thin strips. Equal rows make the tile order matter only for gaps. */
  grid-auto-rows: 1fr;
  gap: 12px;
}
@media (max-width: 1024px) { .gallery-grid { grid-template-columns: repeat(2, 1fr); } }
/* One column: tall tiles stop spanning and size themselves at 4:5, so rows
   go back to fitting their own tile. Equal rows here would stretch every
   4:3 tile's row to 4:5 and leave a band of empty space under each. */
@media (max-width: 540px) { .gallery-grid { grid-template-columns: 1fr; grid-auto-rows: auto; } }

/* The tonal ladder shifts up one rung. These were carbon/graphite/slate on a
   white page, where carbon read as the deepest cell; against the void they
   would read as holes in the grid instead of tiles on it. */
.gallery-cell {
  aspect-ratio: 4 / 3;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  padding: 16px;
  color: var(--mist);
}
.gallery-cell::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(244, 245, 247, 0.04) 0 8px,
    transparent 8px 16px
  );
}
.gallery-cell.tone-graphite { background: var(--slate); }
.gallery-cell.tone-slate { background: #363C47; }
.gallery-cell.tone-blue {
  background: var(--polish-deep);
  background-image: linear-gradient(135deg, oklch(0.45 0.13 235), oklch(0.58 0.13 235));
}
/* Captions sit on the tile tone today and on real photographs later, so they
   carry their own scrim instead of trusting whatever is behind them. The
   blue tile in particular is light enough that a dimmed tint fell to 2.8:1. */
.gallery-cell::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 50%;
  background: linear-gradient(180deg, transparent, rgba(7, 8, 10, 0.85));
  pointer-events: none;
}
.gallery-cell .caption {
  position: relative;
  z-index: 1;
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   Real media in a tile
   --------------------------------------------------------------------------
   A tile holding no <img>/<video> renders as the placeholder above — tone
   wash plus hatch. Adding a photo is one line inside the tile; nothing has
   to be switched off, because paint order handles the hand-off.

   ::before (the hatch) paints before an element's children and ::after (the
   caption scrim) paints after them. Media landing between the two therefore
   covers the hatch and sits under the scrim automatically, and the caption's
   own z-index keeps it above both. The tile's tone shows through until the
   file decodes, so there is no white flash on a dark page.

   `cover` crops to fill. When it crops away the part that matters — a wheel
   sitting low in frame, a roofline high in it — steer the crop per tile:
       <img ... style="--focal: 50% 25%">
   -------------------------------------------------------------------------- */
.gallery-cell > img,
.gallery-cell > video {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focal, 50% 50%);
}

/* figure carries a UA margin that would break the grid. */
figure.gallery-cell { margin: 0; }

/* Under reduced motion the ambient loop is replaced with real video controls
   (see interactions.js §5). Those occupy the bottom strip of the tile, which
   is where the caption lives — so the caption steps up over them. */
.gallery-cell.has-video-controls .caption { margin-bottom: 40px; }

/* Portrait stills and vertical phone video lose too much of the subject to a
   4/3 crop, so this spans two grid rows and keeps the full frame. Use it in
   pairs — one tall tile leaves a hole in the row beneath it, two fill it. */
.gallery-cell--tall {
  grid-row: span 2;
  aspect-ratio: auto;
}
@media (max-width: 540px) {
  /* Single column: spanning two rows would just yield one enormous tile. */
  .gallery-cell--tall { grid-row: auto; aspect-ratio: 4 / 5; }
}

/* ==========================================================================
   Forms (booking)
   ========================================================================== */
.form-step {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(24px, 4vw, 40px);
  /* The steps are <fieldset>s, which default to min-width: min-content (and a
     2px side margin): a row of buttons wider than a small phone widened the
     whole column, and the page scrolled sideways on step 4 at 320–390px. */
  min-width: 0;
  margin-inline: 0;
}
/* Each step's heading takes focus when the step opens, to announce it; it
   isn't something to click, so no ring. */
.form-step > h2:focus,
[data-success] h2:focus { outline: none; }
.form-progress {
  display: flex;
  gap: 10px;
  margin-bottom: 24px;
}
.form-progress__dot {
  flex: 1;
  height: 4px;
  background: rgba(244, 245, 247, 0.12);
  border-radius: 2px;
}
.form-progress__dot.is-active { background: var(--accent); }
/* Was carbon — a completed step would have been an invisible gap on black. */
.form-progress__dot.is-done { background: rgba(244, 245, 247, 0.40); }

.field-group {
  display: grid;
  /* Pairs by the width of the form, not the viewport. The contact page's form
     sits in a narrow column, where two inputs at their natural ~200px width
     overflowed it and scrolled the whole page sideways at 900–1024px. Two
     fields sit side by side from 376px of form width; below that they stack. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr));
  gap: 16px;
}
/* The display above outranks the browser's own [hidden] rule, so the booking
   form's two time pickers (requested vs live) both showed at once. */
.field-group[hidden] { display: none; }
.field-group--3 { grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 640px) { .field-group, .field-group--3 { grid-template-columns: 1fr; } }

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 16px;
}
.field label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.field input,
.field select,
.field textarea {
  padding: 12px 14px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-ui);
  background: var(--well);
  color: var(--ink);
  font-size: 15px;
  transition: border-color 180ms ease, box-shadow 180ms ease,
              background-color 180ms ease;
}
.field input::placeholder,
.field textarea::placeholder { color: var(--ink-4); }
.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: 0;
  border-color: var(--accent);
  background: var(--void);
  /* The focus ring has to carry further on black than it did on white. */
  box-shadow: 0 0 0 3px oklch(0.68 0.13 235 / 0.22);
}
/* Chrome paints autofilled fields a hard pastel yellow, which is violent on
   a black page. Nothing but an inset shadow can override that fill. */
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus,
.field textarea:-webkit-autofill,
.field select:-webkit-autofill {
  -webkit-text-fill-color: var(--ink);
  -webkit-box-shadow: 0 0 0 1000px var(--well) inset;
  caret-color: var(--ink);
}
.field .error {
  color: var(--accent);
  font-size: 12px;
  font-family: var(--mono);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.field input.has-error,
.field select.has-error,
.field textarea.has-error {
  border-color: var(--accent);
}

.choice-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}
@media (max-width: 540px) { .choice-grid { grid-template-columns: 1fr; } }
.choice {
  display: block;
  padding: 20px 22px;
  border: 1px solid var(--line-ui);
  border-radius: var(--r-md);
  background: var(--surface-2);
  cursor: pointer;
  transition: border-color 180ms ease, background 180ms ease;
  position: relative;
}
.choice input { position: absolute; opacity: 0; pointer-events: none; }
/* The radio is invisible, so its focus ring was too: tabbing through the
   service cards showed nothing. The card carries the ring instead. */
.choice:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.choice:hover { border-color: var(--accent); background: var(--surface-3); }
.choice.is-checked {
  border-color: var(--accent);
  background: var(--accent-wash-strong);
}
.choice__title { font-family: var(--display); font-weight: 500; font-size: 18px; margin: 0 0 4px; letter-spacing: -0.01em; }
.choice__desc { font-size: 13px; color: var(--ink-3); }
.choice__price { margin-top: 8px; }

.form-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  margin-top: 24px;
  gap: 12px;
}
.form-actions .spacer { flex: 1; }
/* On a phone the buttons share the row instead of sitting at its ends, and
   wrap to full width where "← Back" and "Confirm booking →" don't both fit. */
@media (max-width: 480px) {
  .form-actions .spacer { display: none; }
  .form-actions .btn { flex: 1 1 auto; padding-inline: 16px; }
}
/* A send in flight (script.js setSubmitting). */
.btn[aria-disabled="true"] { opacity: 0.7; cursor: progress; transform: none; }

.summary-card {
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--mist);
  border-radius: var(--r-lg);
  padding: 32px;
  position: sticky;
  top: 88px;
}
.summary-card h3 { color: var(--mist); }
.summary-card .price-row { border-bottom-color: rgba(244, 245, 247, 0.10); }
.summary-card .price-row:last-child {
  border-top-color: rgba(244, 245, 247, 0.15);
  color: var(--polish-glow);
}
.summary-card .price-row__sub { color: var(--ink-3); }

/* Booking layout */
.booking-layout {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 32px;
  align-items: start;
}
/* Grid items default to min-width: auto, so anything wide inside a column
   would widen the page rather than stay in its card (the same trap as
   .service-row__grid). */
.booking-layout > * { min-width: 0; }
@media (max-width: 1024px) {
  .booking-layout { grid-template-columns: 1fr; }
  .summary-card { position: static; }
}

/* ==========================================================================
   About / map block
   ========================================================================== */
.area-map {
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--mist);
  border-radius: var(--r-lg);
  padding: clamp(32px, 4vw, 56px);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px;
}
@media (max-width: 768px) { .area-map { grid-template-columns: 1fr; } }

.area-map__visual {
  /* Nashville (36.1627°N, 86.7816°W) projected into the map below. These are
     outputs of the map build, not design choices — if the map is rebuilt with
     a different frame, they change with it. */
  --pin-x: 39.64%;
  --pin-y: 35.13%;
  background: var(--graphite);
  border-radius: var(--r-md);
  aspect-ratio: 4 / 3;
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
/* Middle Tennessee's 41 counties from US Census boundaries, with the rest of
   the state faint for context. The SVG is exactly 4:3, like this box, so it
   fills it with no letterboxing — which is what lets plain percentages put
   the pin on real coordinates. */
.area-map__map {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
/* The glow sits over the map, centred on the pin. */
.area-map__visual::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(circle at var(--pin-x) var(--pin-y),
    oklch(0.78 0.13 235 / 0.22), transparent 28%);
}
.area-map__label {
  position: absolute;
  z-index: 2;
  bottom: 12px;
  left: 12px;
  /* The Alabama state line runs along the bottom of the map; at phone size it
     passed straight through the text without this backdrop. */
  padding: 4px 8px;
  border-radius: 4px;
  background: rgba(27, 31, 38, 0.85);
}
.area-map__pin {
  position: absolute;
  z-index: 2;
  top: var(--pin-y); left: var(--pin-x);
  transform: translate(-50%, -50%);
  width: 14px; height: 14px;
  background: var(--polish-glow);
  border-radius: 50%;
  box-shadow: 0 0 0 6px oklch(0.78 0.13 235 / 0.25);
}
/* list-style/padding are reset explicitly: a flex container blockifies its
   children but `display: list-item` survives, so the UA disc kept rendering
   next to the authored "·" prefix — and the UA's 40px padding-left pushed the
   list out of alignment with the paragraph above it. */
.area-map__list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  list-style: none;
  padding-left: 0;
  margin: 0;
}
.area-map__list li { font-size: 15px; color: var(--ink-2); }

/* ==========================================================================
   About — story block
   ========================================================================== */
.story {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: 48px;
  align-items: start;
}
@media (max-width: 768px) { .story { grid-template-columns: 1fr; } }

.story__portrait {
  aspect-ratio: 3 / 4;
  background: var(--graphite);
  border-radius: var(--r-lg);
  position: relative;
  overflow: hidden;
}
.story__portrait img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.story__portrait::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 55%, rgba(7, 8, 10, 0.72) 100%);
  pointer-events: none;
}
.story__portrait .caption {
  position: absolute;
  left: 16px;
  bottom: 16px;
  z-index: 1;
  color: var(--ink-2);
}
.story__copy p {
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 56ch;
}

.crew {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-top: 32px;
}
@media (max-width: 768px) { .crew { grid-template-columns: 1fr; } }
.crew-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.crew-card .who { font-family: var(--display); font-weight: 500; font-size: 18px; letter-spacing: -0.01em; }
.crew-card .role { font-size: 13px; color: var(--ink-3); }

/* ==========================================================================
   Marquee strip — a slow ticker under the home hero
   One line that scrolls right to left, so a phone sees every item instead of
   the first one and a word cut off at the screen's edge. script.js adds the
   copy it loops on (.marquee__dupe) and the pause button, then .is-scrolling.
   With reduced motion, or no JavaScript, the items wrap and nothing moves.
   ========================================================================== */
.marquee {
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
  padding: 18px 0;
}
.marquee__inner { position: relative; }
.marquee__row {
  display: flex;
  width: max-content;        /* so -50% is one copy of the items, not half the screen */
  white-space: nowrap;
}
.marquee__dupe { display: contents; }
.marquee__item {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-3);
}
/* The dot sits centred between items and the row has no gap, so each item
   carries its own spacing and the two copies line up with no seam. */
.marquee__item .dot {
  display: inline-block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
  margin: 0 40px;
  vertical-align: middle;
}

.marquee.is-scrolling .marquee__track {
  /* Soft ends, and the right end kept clear for the pause button. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 32px, #000 calc(100% - 96px), transparent calc(100% - 44px));
          mask-image: linear-gradient(90deg, transparent, #000 32px, #000 calc(100% - 96px), transparent calc(100% - 44px));
}
.marquee.is-scrolling .marquee__row { animation: marquee-scroll 64s linear infinite; }
.marquee.is-paused .marquee__row,
.marquee.is-offscreen .marquee__row { animation-play-state: paused; }
@media (hover: hover) {
  .marquee.is-scrolling:hover .marquee__row { animation-play-state: paused; }
}
@keyframes marquee-scroll { to { transform: translateX(-50%); } }

.marquee__toggle {
  position: absolute;
  top: 50%;
  right: var(--gutter);
  transform: translateY(-50%);
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--line-ui);
  background: var(--bg);
  color: var(--ink-3);
  cursor: pointer;
  transition: color 180ms, border-color 180ms;
}
.marquee__toggle::before { content: ''; position: absolute; inset: -8px; }  /* a 44px tap target */
.marquee__toggle:hover { color: var(--mist); border-color: var(--accent); }
.marquee__toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.marquee__toggle svg { display: block; }
.marquee__toggle .icon-play,
.marquee.is-paused .marquee__toggle .icon-pause { display: none; }
.marquee.is-paused .marquee__toggle .icon-play { display: block; }

/* No motion wanted, or no JavaScript: the items wrap, centred, all in view. */
@media (prefers-reduced-motion: reduce), (scripting: none) {
  .marquee__row { width: auto; flex-wrap: wrap; justify-content: center; gap: 8px 32px; white-space: normal; }
  .marquee__item { text-align: center; }
  .marquee__item .dot,
  .marquee__dupe,
  .marquee__toggle { display: none; }
  .marquee.is-scrolling .marquee__track { -webkit-mask-image: none; mask-image: none; }
  .marquee.is-scrolling .marquee__row { animation: none; }
}

/* ==========================================================================
   Hero path split — routes the routine-care customer and the
   protection customer to different journeys from the first screen.
   ========================================================================== */
.hero__intro { max-width: 62ch; }

.path-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-top: 48px;
}
@media (max-width: 768px) {
  .path-split { grid-template-columns: 1fr; margin-top: 32px; }
}

.path-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 28px;
  border-radius: var(--r-md);
  border: 1px solid rgba(244, 245, 247, 0.14);
  background: rgba(244, 245, 247, 0.03);
  transition: border-color 200ms ease, background 200ms ease, transform 200ms ease;
}
.path-card:hover {
  border-color: rgba(244, 245, 247, 0.35);
  background: rgba(244, 245, 247, 0.06);
  transform: translateY(-2px);
}
.path-card--accent {
  border-color: oklch(0.68 0.13 235 / 0.45);
  background: oklch(0.68 0.13 235 / 0.08);
}
.path-card--accent:hover {
  border-color: var(--polish-glow);
  background: oklch(0.68 0.13 235 / 0.14);
}

.path-card__tag {
  color: var(--ink-3);
  font-size: 10px;
  letter-spacing: 0.08em;
}
.path-card--accent .path-card__tag { color: var(--polish-glow); }

.path-card__title {
  font-family: var(--display);
  font-weight: 600;
  font-size: 28px;
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--mist);
}
.path-card__desc {
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-2);
  max-width: 38ch;
}
.path-card__meta {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-top: 6px;
  padding-top: 14px;
  border-top: 1px solid rgba(244, 245, 247, 0.10);
}
.path-card__price {
  font-family: var(--display);
  font-weight: 500;
  font-size: 16px;
  color: var(--mist);
}
.path-card__note {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.path-card__cta {
  margin-top: 8px;
  font-size: 14px;
  font-weight: 500;
  color: var(--mist);
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.path-card--accent .path-card__cta { color: var(--polish-glow); }
.path-card .arrow { transition: transform 200ms ease; }
.path-card:hover .arrow { transform: translateX(3px); }

/* ==========================================================================
   PPF Coverage Configurator
   ========================================================================== */
.configurator {
  display: grid;
  grid-template-columns: 1fr 1.05fr;
  gap: 32px;
  align-items: start;
}
@media (max-width: 900px) {
  .configurator { grid-template-columns: 1fr; }
}

/* ---- stage (car diagram) ---- */
.configurator__stage {
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  padding: 24px;
  position: sticky;
  top: 88px;
}
@media (max-width: 900px) {
  .configurator__stage { position: static; }
}
.configurator__stage-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  margin-bottom: 8px;
}
.configurator__stage-head .mono-label { color: var(--ink-3); }
.configurator__clear {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding: 6px 10px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-ui);
  transition: color 160ms ease, border-color 160ms ease;
}
.configurator__clear:hover {
  color: var(--mist);
  border-color: rgba(244, 245, 247, 0.4);
}
.configurator__hint {
  color: var(--ink-4);
  text-align: center;
  display: block;
  margin-top: 4px;
}

.car-diagram {
  width: 100%;
  max-width: 320px;
  height: auto;
  margin: 0 auto;
  display: block;
  overflow: visible;
}

/* The diagram used to sit on a carbon stage floating in a white page, which
   gave it plenty of edge contrast for free. On a black page the whole
   assembly darkens, so the car has to be lifted deliberately or the primary
   interaction on this page reads as an empty rectangle. */
.car-base { fill: #171C24; }
.car-outline {
  fill: none;
  stroke: rgba(244, 245, 247, 0.34);
  stroke-width: 1.5;
  pointer-events: none;
}
.car-glass {
  fill: rgba(244, 245, 247, 0.09);
  stroke: rgba(244, 245, 247, 0.18);
  stroke-width: 1;
  pointer-events: none;
}

.car-panel {
  fill: #333A46;
  stroke: rgba(244, 245, 247, 0.22);
  stroke-width: 1;
  cursor: pointer;
  transition: fill 180ms ease, stroke 180ms ease;
}
.car-panel:hover {
  fill: #454D5C;
  stroke: rgba(244, 245, 247, 0.45);
}
.car-panel:focus-visible {
  outline: none;
  stroke: var(--polish-glow);
  stroke-width: 2;
}
.car-panel.is-selected {
  fill: var(--polish-deep);
  stroke: var(--polish-glow);
}
.car-panel.is-selected:hover { fill: var(--polish); }

.car-indicator {
  fill: var(--polish-deep);
  stroke: var(--polish-glow);
  stroke-width: 1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 180ms ease;
}
.car-indicator.is-selected { opacity: 1; }

/* ---- controls ---- */
.configurator__controls {
  display: flex;
  flex-direction: column;
  gap: 28px;
}
.control-block {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* vehicle tier chips */
.tier-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}
@media (max-width: 540px) {
  .tier-grid { grid-template-columns: 1fr; }
}
.tier-chip {
  display: flex;
  flex-direction: column;
  gap: 4px;
  text-align: left;
  padding: 12px 14px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-ui);
  background: var(--surface);
  transition: border-color 160ms ease, background 160ms ease;
}
.tier-chip:hover { border-color: var(--accent); }
.tier-chip.is-active {
  border-color: var(--accent);
  background: var(--accent-wash-strong);
}
.tier-chip__label {
  font-weight: 500;
  font-size: 13px;
  line-height: 1.3;
}
.tier-chip__eg {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-4);
  line-height: 1.4;
}

/* preset cards */
.preset-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}
@media (max-width: 540px) {
  .preset-grid { grid-template-columns: 1fr; }
}
.preset-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 4px;
  text-align: left;
  padding: 14px 16px;
  border-radius: var(--r-md);
  border: 1px solid var(--line-ui);
  background: var(--surface);
  transition: border-color 160ms ease, background 160ms ease, transform 160ms ease;
}
.preset-card:hover {
  border-color: var(--accent);
  transform: translateY(-1px);
}
.preset-card.is-active {
  border-color: var(--accent);
  background: var(--accent-wash-strong);
}
.preset-card__flag {
  position: absolute;
  top: -7px;
  right: 12px;
  font-family: var(--mono);
  font-size: 8px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: var(--polish-deep);
  color: var(--mist);
  padding: 2px 7px;
  border-radius: 999px;
}
.preset-card__label {
  font-family: var(--display);
  font-weight: 500;
  font-size: 15px;
  letter-spacing: -0.01em;
}
.preset-card__blurb {
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink-3);
}
/* Zee's range for the chosen vehicle size, on the card itself, so packages
   compare at a glance instead of being clicked through one at a time. */
.preset-card__price {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--polish-glow);
}
/* A package Zee doesn't offer at this size (Track Pack on SUVs/pickups).
   Dimmed as an inactive control, but it still names why. */
.preset-card:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}
.preset-card:disabled:hover {
  border-color: var(--line-ui);
  transform: none;
}
.preset-card:disabled .preset-card__price { color: var(--ink-3); }
/* Five packages in two columns would strand the last one; an odd last card
   spans the row so the grid reads as deliberate. */
.preset-card:last-child:nth-child(odd) { grid-column: 1 / -1; }

/* selected panel list */
.panel-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.panel-list__empty {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-4);
  padding: 6px 0;
}
.panel-list__item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  padding: 6px 8px 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface-2);
}
.panel-list__remove {
  font-size: 15px;
  line-height: 1;
  color: var(--ink-4);
  padding: 0 2px;
  transition: color 160ms ease;
}
.panel-list__remove:hover { color: var(--accent); }
.panel-list__free {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--polish-glow);
}

/* Panel picker — the list alternative to tapping the diagram. */
.panel-picker { margin-top: 14px; }
.panel-picker__summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 0;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  transition: color 160ms ease;
}
.panel-picker__summary::-webkit-details-marker { display: none; }
.panel-picker__summary::before {
  content: '+';
  font-size: 14px;
  line-height: 1;
}
.panel-picker[open] .panel-picker__summary::before { content: '\2212'; }
.panel-picker__summary:hover { color: var(--ink); }

.panel-picker__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  margin-top: 6px;
}
@media (max-width: 540px) { .panel-picker__grid { grid-template-columns: 1fr; } }

.panel-picker__item {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 8px 12px;
  /* --line-ui, not --line: this border is the edge of a tap target, and the
     decorative tint measured 1.23:1 against the card behind it. */
  border: 1px solid var(--line-ui);
  border-radius: var(--r-sm);
  background: var(--surface);
  font-size: 14px;
  cursor: pointer;
  transition: border-color 160ms ease, background 160ms ease;
}
.panel-picker__item:hover { border-color: var(--line-ui); }
.panel-picker__item:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-wash-strong);
}
.panel-picker__item input {
  width: 18px;
  height: 18px;
  flex: none;
  accent-color: var(--polish);
  margin: 0;
}

/* quote box */
.quote-box {
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--mist);
  border-radius: var(--r-lg);
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.quote-box__label {
  min-height: 1em;
  letter-spacing: 0.08em;
}
.quote-box__empty {
  font-size: 13px;
  color: var(--ink-4);
  margin: 8px 0;
}
/* Custom and not-offered states carry real information, not a prompt, so
   they sit at body ink rather than the dim placeholder tone. */
.quote-box__empty.is-info {
  color: var(--ink-2);
  line-height: 1.55;
}
.quote-box__note {
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-2);
  margin: 0;
}
.quote-box__figures {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}
/* The display above outranks the browser's own [hidden] rule, so a custom
   mix kept showing the last package's price beside "Custom coverage is
   priced per vehicle". */
.quote-box__figures[hidden] { display: none; }
.quote-box__num {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(28px, 4vw, 38px);
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--polish-glow);
}
.quote-box__dash {
  color: var(--ink-4);
  font-size: 20px;
}
.quote-box__fine {
  font-size: 12px;
  line-height: 1.55;
  color: var(--ink-3);
  margin: 0;
  padding-top: 12px;
  border-top: 1px solid rgba(244, 245, 247, 0.10);
}

/* ==========================================================================
   INTERACTIONS
   Motion is a garnish. Everything below degrades to a static, legible
   state under `prefers-reduced-motion` or with JS disabled.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Before / After drag slider
   -------------------------------------------------------------------------- */
.ba {
  --pos: 50%;
  position: relative;
  aspect-ratio: 16 / 10;
  border-radius: var(--r-md);
  overflow: hidden;
  cursor: ew-resize;
  user-select: none;
  background: var(--surface);
  touch-action: pan-y;
}
.ba__layer {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  padding: 16px;
}
.ba__layer img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ba__layer--after {
  clip-path: inset(0 0 0 var(--pos));
}

/* Placeholder surfaces — swapped for real photos later.
   'Before': matte, hazed, swirl-marked. 'After': deep gloss with a
   specular sweep. Designed so the drag reads even without photography. */
.ba__surface { position: absolute; inset: 0; }
.ba__surface--dull {
  background:
    repeating-conic-gradient(from 0deg at 30% 40%,
      rgba(255,255,255,0.035) 0deg 6deg, transparent 6deg 12deg),
    repeating-conic-gradient(from 0deg at 72% 65%,
      rgba(255,255,255,0.03) 0deg 5deg, transparent 5deg 11deg),
    linear-gradient(155deg, #43474d 0%, #35383e 45%, #2b2e33 100%);
  filter: saturate(0.55);
}
.ba__surface--gloss {
  background:
    linear-gradient(112deg,
      transparent 28%,
      rgba(244,245,247,0.42) 42%,
      rgba(122,179,232,0.30) 49%,
      transparent 61%),
    radial-gradient(120% 90% at 25% 15%, oklch(0.68 0.13 235 / 0.30), transparent 55%),
    linear-gradient(155deg, #1d2937 0%, #131a24 55%, #0E1116 100%);
}

.ba__tag {
  position: relative;
  z-index: 2;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--mist);
  background: rgba(14, 17, 22, 0.6);
  backdrop-filter: blur(6px);
  padding: 6px 10px;
  border-radius: 999px;
}
.ba__layer--after .ba__tag { margin-left: auto; }

.ba__handle {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--pos);
  width: 44px;
  transform: translateX(-50%);
  background: transparent;
  cursor: ew-resize;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ba__handle::before {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  width: 2px;
  background: var(--mist);
  box-shadow: 0 0 14px rgba(14, 17, 22, 0.5);
}
.ba__grip {
  position: relative;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  background: var(--mist);
  box-shadow: 0 4px 16px rgba(14, 17, 22, 0.35);
  transition: transform 180ms ease;
}
.ba__grip::before,
.ba__grip::after {
  content: '';
  position: absolute;
  top: 50%;
  width: 0; height: 0;
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  transform: translateY(-50%);
}
.ba__grip::before { left: 10px;  border-right: 6px solid var(--carbon); }
.ba__grip::after  { right: 10px; border-left: 6px solid var(--carbon); }
.ba__handle:hover .ba__grip { transform: scale(1.1); }
.ba__handle:focus-visible { outline: none; }
.ba__handle:focus-visible .ba__grip {
  outline: 2px solid var(--polish-glow);
  outline-offset: 3px;
}
.ba.is-dragging .ba__grip { transform: scale(0.94); }

/* --------------------------------------------------------------------------
   2. Water-beading demo
   -------------------------------------------------------------------------- */
.beading {
  display: grid;
  grid-template-columns: 1.25fr 1fr;
  gap: 32px;
  align-items: center;
}
@media (max-width: 900px) { .beading { grid-template-columns: 1fr; } }

.beading__stage {
  position: relative;
  aspect-ratio: 16 / 11;
  border-radius: var(--r-md);
  overflow: hidden;
  background:
    radial-gradient(130% 100% at 20% 0%, #223142 0%, transparent 55%),
    linear-gradient(158deg, #18212c 0%, #0E1116 70%);
  cursor: crosshair;
  transition: background 400ms ease, filter 400ms ease;
}
.beading__stage.is-uncoated {
  background:
    radial-gradient(130% 100% at 20% 0%, #3a3f46 0%, transparent 55%),
    linear-gradient(158deg, #34383e 0%, #24272c 70%);
  filter: saturate(0.6);
}
.beading__stage canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.beading__hint {
  position: absolute;
  left: 16px; bottom: 14px;
  z-index: 2;
  pointer-events: none;
  color: var(--ink-4);
}
.beading__switch { display: inline-flex; gap: 6px; padding: 4px; border-radius: 999px;
  background: rgba(244, 245, 247, 0.05); border: 1px solid var(--line); }
.beading__btn {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 9px 16px;
  border-radius: 999px;
  color: var(--ink-3);
  transition: background 180ms ease, color 180ms ease;
}
.beading__btn:hover { color: var(--ink); }
/* Active state was a carbon pill — on a black page that is the same as
   having no active state at all. It inverts instead. */
.beading__btn.is-active { background: var(--mist); color: var(--carbon); }

/* --------------------------------------------------------------------------
   3. Scroll-pinned PPF sequence
   -------------------------------------------------------------------------- */
.seq__track { position: relative; height: 340vh; }
.seq__pin {
  position: sticky;
  top: 0;
  height: 100vh;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: 48px;
  padding: 64px 0;
}
@media (max-width: 900px) {
  .seq__track { height: auto; }
  .seq__pin { position: static; height: auto; grid-template-columns: 1fr; padding: 32px 0; }
}
.seq__stage {
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  padding: 24px;
  height: 100%;
  max-height: 72vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.seq__stage .car-diagram { max-width: 250px; }
.seq__title {
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(28px, 4vw, 44px);
  letter-spacing: -0.03em;
  line-height: 1.05;
  margin: 12px 0 16px;
}
.seq__caption {
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 46ch;
  min-height: 5.5em;
}
/* Manual stage controls. The sequence is scroll-scrubbed on desktop, but the
   pin is disabled below 900px — without these the stages were unreachable on
   a phone, which is where most of this traffic will land. */
.seq__nav {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 24px;
  flex-wrap: wrap;
}
.seq__step {
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: 999px;
  border: 1px solid var(--line-ui);
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  line-height: 1;
  transition: background 180ms ease, border-color 180ms ease, color 180ms ease;
}
.seq__step:hover:not(:disabled) {
  background: var(--mist);
  border-color: var(--mist);
  color: var(--carbon);
}
.seq__count {
  color: var(--ink-4);
  letter-spacing: 0.08em;
  min-width: 6ch;
}
.seq__nav .btn:disabled,
.seq__step:disabled {
  opacity: 0.32;
  cursor: not-allowed;
}
/* The base .btn lifts on hover; a disabled one must not. */
.seq__nav .btn:disabled:hover {
  transform: none;
  box-shadow: none;
  background: transparent;
  color: var(--ink);
  border-color: var(--line-strong);
}

.seq__progress { display: flex; gap: 8px; margin-top: 28px; }
.seq__dot {
  width: 34px; height: 3px;
  border-radius: 2px;
  background: rgba(244, 245, 247, 0.14);
  transition: background 260ms ease, transform 260ms ease;
}
.seq__dot.is-done { background: rgba(244, 245, 247, 0.38); }
.seq__dot.is-active { background: var(--accent); transform: scaleY(1.8); }

/* --------------------------------------------------------------------------
   4. Micro-interactions
   -------------------------------------------------------------------------- */
.split__word { display: inline-block; white-space: nowrap; }
.split__char {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.42em);
  transition: opacity 520ms cubic-bezier(0.22, 1, 0.36, 1),
              transform 520ms cubic-bezier(0.22, 1, 0.36, 1);
}
.is-revealed .split__char { opacity: 1; transform: translateY(0); }

[data-magnetic] { transition: transform 260ms cubic-bezier(0.22, 1, 0.36, 1); }
[data-magnetic]:active { transition-duration: 60ms; }

/* ==========================================================================
   Touch and small screens
   ========================================================================== */
@media (max-width: 768px) {
  /* iOS Safari zooms the viewport when a control smaller than 16px takes
     focus, and does not zoom back out — the rest of the form is then off
     screen. 17 controls across the booking and contact forms were under it. */
  .field input,
  .field select,
  .field textarea {
    font-size: 16px;
  }

  /* Footer and nav links were ~17px tall. Padding gives them a real target
     without changing how they look. */
  .site-footer ul a,
  .mobile-nav__links a { display: block; }
  .site-footer ul { gap: 2px; }
  .site-footer ul a,
  .site-footer .footer-hours { padding: 11px 0; }
  .site-footer__bottom { gap: 8px; }

  /* Buttons and the switch, up to a comfortable minimum. */
  .btn { padding: 15px 24px; min-height: 48px; }
  .btn--lg { padding: 17px 26px; min-height: 52px; }
  .beading__btn { padding: 13px 18px; min-height: 44px; }
  .seq__step { width: 48px; height: 48px; }
  .configurator__clear { padding: 13px 16px; min-height: 44px; }
  /* Block links in the contact card — full width, but they were only 29px
     tall, which is a thin ribbon to hit with a thumb. */
  .contact-line { padding: 8px 0; }
  .panel-list__remove { padding: 6px 8px; margin: -6px -4px; }

  /* Stacks the booking form's side-by-side fields — two inputs across a
     360px screen leaves neither usable. */
  .field-group,
  .field-group--3 { grid-template-columns: 1fr; }

  /* The floating CTA and the footer were colliding at the end of the page. */
  .site-footer { padding-bottom: 72px; }
}

/* Coarse pointers get the same minimums regardless of viewport width —
   a tablet in landscape is still a finger. */
@media (pointer: coarse) {
  .car-panel { stroke-width: 1.5; }
  .faq summary { padding: 6px 0; }
}

@media (prefers-reduced-motion: reduce) {
  .split__char { opacity: 1 !important; transform: none !important; transition: none !important; }
  [data-magnetic] { transform: none !important; }
  .ba__grip, .seq__dot { transition: none !important; }
  /* The reveal still needs to END visible — only the travel is dropped. */
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
  .service-card:hover, .path-card:hover, .preset-card:hover { transform: none !important; }
  .btn:hover { transform: none !important; }
  html { scroll-behavior: auto; }
}

/* ==========================================================================
   Manage a booking (manage.html) — the page behind the link in every
   booking's invite. Move to another open time, or cancel, without an account.
   ========================================================================== */
.manage { display: grid; gap: 24px; }
.manage > * { max-width: 720px; }   /* left-aligned with the intro above */
.manage-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: clamp(20px, 4vw, 32px);
  display: grid;
  gap: 16px;
}
.manage-card[hidden],
.manage .form-actions[hidden] { display: none; }   /* their display beats [hidden] */
.manage-card .form-actions { margin-top: 8px; }
.manage-facts { display: grid; gap: 12px; margin: 0; }
.manage-facts div { display: grid; grid-template-columns: 7rem 1fr; gap: 12px; }
.manage-facts dt {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding-top: 4px;
}
.manage-facts dd { margin: 0; color: var(--ink); }
@media (max-width: 540px) {
  .manage-facts div { grid-template-columns: 1fr; gap: 2px; }
}
