/* ==========================================================================
   Falcon Diesel — shared design system
   --------------------------------------------------------------------------
   Every visual decision resolves through a token. Themes in themes.css
   redefine the tokens only; no component rule below hard-codes a colour,
   a font family, or a radius. That is what makes the bottom-of-page theme
   switcher work without touching markup.
   ========================================================================== */

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

:root {
  /* ── Brand palette (Falcon Diesel, sampled from falcondiesel.com.au) ── */
  --brand-gold: #f5cb5c;
  --brand-gold-deep: #e0b23c;

  /* ── Semantic tokens — themes override these ── */
  --accent: var(--brand-gold);
  --accent-strong: var(--brand-gold-deep);
  --on-accent: #1a1614;
  --accent-soft: rgba(245, 203, 92, 0.14);
  --accent-line: rgba(245, 203, 92, 0.38);

  /* Accent as it appears against a DARK surface. Gold reads fine on charcoal,
     but a deep accent (Steel's mid-blue, Heritage's oxblood) drops under 3:1
     on a dark band and stops registering as a shape. Every accent used inside
     .hero, .band-inverse, .cta-band, the topbar, the nav and the footer goes
     through these two instead, so each theme can nominate a lifted variant
     without a pile of per-element overrides. */
  --accent-dk: var(--accent);
  --on-accent-dk: var(--on-accent);

  /* Accent as readable TEXT on a light surface. Separate from --accent-strong
     because that one is a darker *fill* for the primary button's hover, and the
     two pull in opposite directions: Falcon's gold needs to go to a deep bronze
     to clear 4.5:1 as 11px text, but a bronze button fill with dark on-accent
     text would be unreadable. Small accent text (.eyebrow, .tag, .link-arrow,
     .cell-yes) uses this; fills keep --accent-strong. */
  --accent-text: #7d5a0e;

  --ink: #242021;            /* darkest surface / heading colour on light */
  --ink-2: #33302f;
  --ink-3: #45403f;          /* completes the ink scale; no consumer yet */

  --surface: #ffffff;         /* page background */
  --surface-2: #f6f5f3;       /* alternating band */
  --surface-3: #ecebe7;       /* cards on the alternating band; no consumer yet */
  --surface-inverse: #242021; /* dark bands */
  --surface-inverse-2: #2e2a2b;

  --text: #242021;
  --text-muted: #5f5b5a;
  --text-faint: #8b8785;
  --text-on-dark: #ffffff;
  --text-on-dark-muted: #b3aeac;

  --border: #e2e0dc;
  --border-strong: #cfccc6;
  --border-on-dark: rgba(255, 255, 255, 0.12);

  /* ── Type ── */
  --font-body: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-head: var(--font-body);
  --head-weight: 700;
  --head-tracking: -0.02em;
  --head-transform: none;
  --eyebrow-tracking: 0.14em;
  --body-size: 1rem;
  --lede-size: 1.0625rem;

  /* ── Shape & depth ── */
  --r-sm: 6px;
  --r-md: 12px;
  --r-lg: 18px;
  --r-pill: 100px;
  --r-btn: 100px;
  --shadow-sm: 0 1px 3px rgba(20, 18, 18, 0.07), 0 1px 2px rgba(20, 18, 18, 0.04);
  --shadow-md: 0 6px 24px rgba(20, 18, 18, 0.09);
  --shadow-lg: 0 18px 50px rgba(20, 18, 18, 0.14);  /* no consumer yet */
  /* Keyboard focus — an `outline` shorthand, not a box-shadow. The offset leaves
     a gap of background between control and ring, so the ring never merges into
     a fill of its own colour (Steel's blue button, any --accent-dk button on a
     dark band); outlines survive forced-colors mode, which drops box-shadows; and
     no component's own box-shadow can cancel it. The colour is --accent-text, not
     --accent: Falcon's gold is 1.55:1 on white (High-Vis 1.23:1), under the 3:1 a
     focus indicator needs. --ring is for light surfaces; every dark one takes
     --ring-dk (see :focus-visible below). */
  --ring-width: 2px;
  --ring-offset: 2px;
  --ring: var(--ring-width) solid var(--accent-text);
  --ring-dk: var(--ring-width) solid var(--accent-dk);

  /* ── Rhythm ── */
  --shell: 1180px;
  --gutter: 24px;
  --section-y: 88px;
  --hero-y: 108px;

  /* ── Motion ── */
  --t-fast: 0.15s cubic-bezier(0.4, 0, 0.2, 1);
  --t: 0.24s cubic-bezier(0.4, 0, 0.2, 1);
}

@media (max-width: 720px) {
  :root { --section-y: 60px; --hero-y: 72px; --gutter: 18px; }
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* overflow-x: clip (not hidden) contains any stray horizontal overflow
     WITHOUT turning the element into a scroll container. `hidden` on body was
     making body the scroller, which breaks window scrolling, scrollIntoView
     and in-page #anchor jumps. clip + visible is the one legal mixed pair. */
  overflow-x: clip;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

body {
  font-family: var(--font-body);
  font-size: var(--body-size);
  color: var(--text);
  background: var(--surface);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  padding-bottom: 0;
}

a { color: inherit; text-decoration: none; }
img, svg, video { display: block; max-width: 100%; }
img { height: auto; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
ul { list-style: none; }

:focus-visible {
  outline: var(--ring);
  outline-offset: var(--ring-offset);
  border-radius: var(--r-sm);
}
/* --ring's --accent-text is tuned for a light surface; on a dark one it is too
   dark to see in every theme but Midnight. The lightbox and the theme dock (both
   injected by site.js) are dark in every theme but sit inside none of the bands,
   so they are listed too. A new dark surface joins this list. */
.band-inverse :focus-visible, .hero :focus-visible, .cta-band :focus-visible,
.site-header :focus-visible, .site-footer :focus-visible, .topbar :focus-visible,
.lightbox :focus-visible, .theme-dock :focus-visible {
  outline: var(--ring-dk);
}
/* On an accent fill neither accent token separates from the band (Steel's
   --accent-text is 1.4:1 on its own --accent), so the ring takes the band's
   text colour, which every theme already holds at 4.5:1 or better. */
.band-accent :focus-visible, .emergency :focus-visible { outline-color: var(--on-accent); }
/* Controls that float over whatever happens to be behind them — the skip link
   (over the topbar, flush to the viewport corner), the theme re-open pill and
   the full-bleed call bar — cannot count on what surrounds them, and an outer
   ring at a viewport edge is cut off. Their ring goes inside, on their own fill,
   in their own text colour, which that fill already holds at 4.5:1. */
.skip:focus-visible, .theme-reopen:focus-visible, .call-bar a:focus-visible {
  outline-color: currentColor;
  outline-offset: calc(-1 * (var(--ring-width) + var(--ring-offset)));
}

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

/* ── Skip link ── */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--accent); color: var(--on-accent);
  padding: 12px 20px; font-weight: 700; border-radius: 0 0 var(--r-sm) 0;
}
.skip:focus { left: 0; }

/* ==========================================================================
   Layout primitives
   ========================================================================== */

.shell { max-width: var(--shell); margin: 0 auto; padding: 0 var(--gutter); width: 100%; }
.shell-narrow { max-width: 820px; margin: 0 auto; padding: 0 var(--gutter); }

.section { padding: var(--section-y) 0; }
.section-tight { padding: calc(var(--section-y) * 0.62) 0; }
.band-2 { background: var(--surface-2); }
.band-inverse { background: var(--surface-inverse); color: var(--text-on-dark); }
.band-inverse h1, .band-inverse h2, .band-inverse h3, .band-inverse h4 { color: var(--text-on-dark); }
.band-inverse .lede, .band-inverse .section-sub { color: var(--text-on-dark-muted); }
.band-accent { background: var(--accent); color: var(--on-accent); }
.band-accent h2, .band-accent h3 { color: var(--on-accent); }

.grid { display: grid; gap: 24px; }
.g-2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.g-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
.g-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }

.split { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 56px; align-items: center; }
.split-wide { grid-template-columns: 1fr 1fr; }
@media (max-width: 880px) { .split, .split-wide { grid-template-columns: 1fr; gap: 32px; } }

.stack > * + * { margin-top: 16px; }
.center { text-align: center; }
.center .section-head, .section-head.center { margin-left: auto; margin-right: auto; }

/* ==========================================================================
   Type scale
   ========================================================================== */

h1, h2, h3, h4, h5 {
  font-family: var(--font-head);
  font-weight: var(--head-weight);
  letter-spacing: var(--head-tracking);
  text-transform: var(--head-transform);
  line-height: 1.12;
  color: var(--ink);
  text-wrap: balance;
}
h1 { font-size: clamp(2.2rem, 5.2vw, 3.55rem); }
h2 { font-size: clamp(1.75rem, 3.4vw, 2.5rem); }
h3 { font-size: clamp(1.15rem, 1.7vw, 1.35rem); line-height: 1.25; }
h4 { font-size: 1.0125rem; line-height: 1.35; letter-spacing: -0.01em; }

p { text-wrap: pretty; }

.eyebrow {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--font-head);
  font-size: 0.7rem; font-weight: 800;
  letter-spacing: var(--eyebrow-tracking); text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: 16px;
}
.eyebrow::before {
  content: ''; width: 22px; height: 2px; background: var(--accent); flex: none;
}
/* ── Accent text on dark surfaces ────────────────────────────────────────
   --accent-text is tuned for readability on a LIGHT surface, so on every dark
   surface these components switch to --accent-dk. Declared once here rather
   than scattered through the component blocks: .hero, .cta-band, .site-footer
   and .topbar are dark in every theme but are not .band-inverse. */
.band-inverse .eyebrow, .hero .eyebrow, .cta-band .eyebrow, .site-footer .eyebrow,
.band-inverse .link-arrow, .hero .link-arrow, .cta-band .link-arrow, .site-footer .link-arrow,
.band-inverse .cell-yes, .band-inverse .accent-text, .hero .accent-text, .cta-band .accent-text,
.band-inverse .icon-badge, .hero .icon-badge, .cta-band .icon-badge,
.band-inverse .checklist svg, .hero .checklist svg, .cta-band .checklist svg, .site-footer .checklist svg {
  color: var(--accent-dk);
}
.band-inverse .eyebrow::before, .hero .eyebrow::before,
.cta-band .eyebrow::before, .site-footer .eyebrow::before { background: var(--accent-dk); }
.band-inverse .tag, .hero .tag, .cta-band .tag, .site-footer .tag {
  color: var(--accent-dk);
  border-color: color-mix(in srgb, var(--accent-dk) 40%, transparent);
  background: color-mix(in srgb, var(--accent-dk) 13%, transparent);
}
.center .eyebrow { justify-content: center; }

.lede { font-size: var(--lede-size); color: var(--text-muted); line-height: 1.72; }
.section-head { max-width: 680px; margin-bottom: 44px; }
.section-sub { font-size: var(--lede-size); color: var(--text-muted); margin-top: 14px; line-height: 1.7; }
.rule { height: 1px; background: var(--border); border: 0; margin: 0; }
.band-inverse .rule { background: var(--border-on-dark); }

/* ── Links in running text ───────────────────────────────────────────────
   The base `a` rule strips the underline and inherits colour, so a link in a
   sentence was indistinguishable from the words around it (WCAG 1.4.1). The
   permanent underline is the cue; the text also steps up to full-strength
   --text, so a link in muted copy (.lede, FAQ answers, .form-note) reads a
   shade stronger, never weaker.
   Scoped by convention, not a class list: every component link carries a class
   (.btn, .link-arrow, .contact-value, .card, .partner-mark…) and prose links
   never do — and some .link-arrows sit inside a <p>, so the container alone
   could not tell them apart. The header, topbar, footer and call bar sit
   outside main/.cta-band, so their links are untouched. :where() holds this at
   0-1-1 so a component rule always wins.
   The line is --accent-text, not --accent: a 1.5px rule is as thin as a text
   stroke, and Falcon's gold is 1.55:1 on white (High-Vis 1.23:1). The focus
   ring is the shared --ring / --ring-dk; nothing here restates it. */
:where(main, .cta-band) :where(p, li, td, dd) a:not([class]) {
  color: var(--text);
  text-decoration: underline;
  text-decoration-color: var(--accent-text);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 0.2em;
  transition: color var(--t-fast), text-decoration-color var(--t-fast), text-decoration-thickness var(--t-fast);
}
:where(main, .cta-band) :where(p, li, td, dd) a:not([class]):is(:hover, :focus-visible) {
  color: var(--accent-text);
  text-decoration-color: currentColor;
  text-decoration-thickness: 2.5px;
}
/* Dark surfaces. Same weight as the light rules and declared after them, so
   they win inside .hero (which is in <main>) and .cta-band. */
:where(.band-inverse, .hero, .cta-band) :where(p, li, td, dd) a:not([class]) {
  color: var(--text-on-dark);
  text-decoration-color: var(--accent-dk);
}
:where(.band-inverse, .hero, .cta-band) :where(p, li, td, dd) a:not([class]):is(:hover, :focus-visible) {
  color: var(--accent-dk);
  text-decoration-color: currentColor;
}

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

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  font-family: var(--font-head);
  font-size: 0.9375rem; font-weight: 700; letter-spacing: 0.005em;
  padding: 13px 30px; border-radius: var(--r-btn);
  transition: transform var(--t-fast), background var(--t), color var(--t), border-color var(--t), box-shadow var(--t);
  white-space: nowrap; cursor: pointer; border: 1.5px solid transparent;
  text-align: center;
}
.btn:active { transform: translateY(1px); }

.btn-primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.hero .btn-primary, .cta-band .btn-primary, .band-inverse .btn-primary,
.site-header .btn-primary, .site-footer .btn-primary {
  background: var(--accent-dk); color: var(--on-accent-dk); border-color: var(--accent-dk);
}
.hero .btn-primary:hover, .cta-band .btn-primary:hover, .band-inverse .btn-primary:hover,
.site-header .btn-primary:hover, .site-footer .btn-primary:hover {
  background: color-mix(in srgb, var(--accent-dk) 86%, #000); border-color: transparent;
}
.btn-primary:hover { background: var(--accent-strong); border-color: var(--accent-strong); box-shadow: var(--shadow-md); }

.btn-ghost { border-color: var(--border-strong); color: var(--text); }
.btn-ghost:hover { border-color: var(--accent); color: var(--accent-text); background: var(--accent-soft); }

.btn-outline-accent { border-color: var(--accent); color: var(--accent); background: transparent; }
.btn-outline-accent:hover { background: var(--accent); color: var(--on-accent); }

.btn-solid-ink { background: var(--ink); color: var(--text-on-dark); border-color: var(--ink); }
.btn-solid-ink:hover { background: var(--ink-2); border-color: var(--ink-2); }

/* Any dark surface, not just .band-inverse: the hero, the sticky header, the
   CTA band and the footer all sit on --surface-inverse, and the default ghost
   button paints its label in --text, which is near-black. Without this the
   button renders as an empty outlined pill. */
.band-inverse .btn-ghost, .hero .btn-ghost, .site-header .btn-ghost,
.cta-band .btn-ghost, .site-footer .btn-ghost {
  border-color: var(--border-on-dark); color: var(--text-on-dark);
}
.band-inverse .btn-ghost:hover, .hero .btn-ghost:hover, .site-header .btn-ghost:hover,
.cta-band .btn-ghost:hover, .site-footer .btn-ghost:hover {
  border-color: var(--accent-dk); color: var(--accent-dk);
  background: color-mix(in srgb, var(--accent-dk) 14%, transparent);
}
/* Same trap for the ink-filled button — on a dark band it is invisible. */
.band-inverse .btn-solid-ink, .hero .btn-solid-ink, .cta-band .btn-solid-ink {
  background: var(--text-on-dark); color: var(--surface-inverse); border-color: var(--text-on-dark);
}

.btn-sm { padding: 9px 20px; font-size: 0.8375rem; }
/* ── Genuine Parts (FS Equipment cross-link) ───────────────────────────────
   A link to a *different business*, so it is deliberately not another gold
   pill competing with "Get a quote": a light chip on the dark chrome reads as
   prominent and clearly separate. The FS mark carries its own brand colours
   (dark + red + white lettering) and cannot be recoloured, so it needs the
   light ground to stay legible. */
/* Scoped to .header-cta / .nav so these beat `.nav a { color: … }`, which is
   also 0-2-0 and would otherwise paint the label the same colour as the pill. */
.header-cta .btn-parts, .nav .btn-parts {
  background: var(--text-on-dark); color: var(--surface-inverse);
  border-color: var(--text-on-dark);
  gap: 9px; padding-left: 11px;
}
.header-cta .btn-parts:hover, .nav .btn-parts:hover {
  background: var(--accent-dk); border-color: var(--accent-dk); color: var(--on-accent-dk);
  box-shadow: var(--shadow-md);
}
/* The FS mark carries fixed brand colours and cannot be recoloured, so it only
   works on the light pill — which is exactly what .btn-parts is. Sized at 24px
   so the FS glyph actually reads; the pill grows to suit. */
.btn-parts img { height: 24px; width: auto; flex: none; }
.btn-parts .ext { width: 12px; height: 12px; opacity: 0.5; flex: none; }

/* Partner mark on its own light chip. DELIBERATE TOKEN EXCEPTION: the FS
   Equipment logo carries fixed brand colours (dark, red, white lettering) and
   must not be recoloured per theme, so the chip is a fixed white ground with a
   fixed dark label in every theme. The colour is set on the <a> itself, not
   just the inner <span> — the anchor otherwise inherits the footer's light
   --text-on-dark-muted and any text added directly to it would be invisible
   on the white chip. */
.partner-mark {
  display: inline-flex; align-items: center; gap: 10px;
  background: #fff; color: #1a1614; border-radius: var(--r-sm);
  padding: 7px 12px; margin-top: 4px;
  transition: box-shadow var(--t), transform var(--t-fast);
}
.partner-mark:hover { box-shadow: 0 0 0 2px var(--accent-dk); transform: translateY(-1px); }
.partner-mark img { height: 30px; width: auto; }
.partner-mark span {
  font-family: var(--font-head); font-size: 0.8rem; font-weight: 700;
  white-space: nowrap;
}
.partner-mark .ext { width: 11px; height: 11px; opacity: 0.5; }
.header-parts-sep {
  width: 1px; align-self: stretch; margin: 12px 4px;
  background: var(--border-on-dark); flex: none;
}
/* Default: the copy inside the slide-out panel is hidden — the header one
   shows. Declared BEFORE the media query so the query's override wins at
   equal specificity. */
.nav .btn-parts { display: none; }
@media (max-width: 1200px) {
  .header-cta .btn-parts, .header-parts-sep { display: none; }
  /* Below the nav breakpoint the panel copy takes over, full width. */
  .nav .btn-parts { display: inline-flex; margin-top: 18px; width: 100%; justify-content: center; }
}

.btn-lg { padding: 16px 38px; font-size: 1rem; }
.btn-block { width: 100%; }
.btn-row { display: flex; gap: 12px; flex-wrap: wrap; min-width: 0; }
.btn-row > .btn { max-width: 100%; }
/* Buttons carry white-space:nowrap, so on a narrow screen two of them cannot
   share a line — stack them full width rather than letting one hang off the
   edge (html has overflow-x:clip, so an overflow is silently cut, not scrollable). */
@media (max-width: 560px) {
  .hero .btn-row, .cta-band .btn-row, .band-inverse .btn-row { width: 100%; }
  .hero .btn-row > .btn, .cta-band .btn-row > .btn { flex: 1 1 100%; }
}
.center .btn-row { justify-content: center; }

.link-arrow {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-head); font-size: 0.875rem; font-weight: 700;
  color: var(--accent-text);
  border-bottom: 1.5px solid transparent; padding-bottom: 1px;
  transition: gap var(--t-fast), border-color var(--t), color var(--t);
}
.link-arrow::after { content: '→'; transition: transform var(--t-fast); }
.link-arrow:hover { gap: 11px; border-color: currentColor; }

/* ==========================================================================
   Top bar / header / nav
   ========================================================================== */

.topbar {
  background: var(--surface-inverse);
  color: var(--text-on-dark-muted);
  font-size: 0.7875rem;
  border-bottom: 1px solid var(--border-on-dark);
}
.topbar .shell { display: flex; align-items: center; justify-content: space-between; gap: 12px 16px; min-height: 46px; flex-wrap: wrap; padding-block: 5px; }
.topbar-links { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.topbar a:not(.btn) { display: inline-flex; align-items: center; gap: 7px; transition: color var(--t-fast); }
.topbar a:not(.btn):hover { color: var(--accent-dk); }
.topbar a:not(.btn) svg { width: 13px; height: 13px; flex: none; opacity: 0.8; }
.topbar-note { display: inline-flex; align-items: center; gap: 8px; color: var(--accent-dk); font-weight: 700; }
.pulse { width: 7px; height: 7px; border-radius: 50%; background: var(--accent-dk); flex: none; box-shadow: 0 0 0 0 var(--accent-line); animation: pulse 2.4s ease-out infinite; }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 var(--accent-line); } 70% { box-shadow: 0 0 0 8px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }
/* ── Tap-to-call button ───────────────────────────────────────────────────
   The phone number is the primary action for this business, so it is a button
   rather than one more dim text link. It keeps a 44px tap target on a phone. */
.topbar-right { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; justify-content: flex-end; }
.topbar-call { gap: 8px; padding: 8px 18px; font-size: 0.875rem; letter-spacing: 0.01em; }
.topbar-call svg { width: 15px; height: 15px; flex: none; }

/* The address is the longest item and the least useful as plain text on a
   small screen — you tap for directions, you do not read it. Hide it before
   the row is forced to wrap. The selector must out-rank `.topbar a`
   (0-2-0), which is why the original `.topbar-address` rule never applied. */
@media (max-width: 1000px) {
  /* Must match the weight of `.topbar a:not(.btn)` (0-2-1) or it loses — a
     bare `.topbar .topbar-address` (0-2-0) is silently overridden. */
  .topbar a.topbar-address { display: none; }
}
/* Email is the next-longest item; drop it once the row would otherwise wrap. */
@media (max-width: 860px) {
  .topbar a.topbar-email { display: none; }
}
/* On a phone the fixed call bar already carries "Call 1300 202 272" and
   "Get a quote", so the utility bar stops repeating them and becomes one
   tidy centred line instead of three rows of dim 12px text. Full contact
   details remain in the footer and on /contact. */
@media (max-width: 720px) {
  .topbar .shell { justify-content: center; gap: 10px; min-height: 52px; }
  .topbar .topbar-links { display: none; }
  .topbar-right { width: 100%; justify-content: center; gap: 10px 14px; }
  .topbar-note { font-size: 0.75rem; letter-spacing: 0.01em; order: 2; }
  .topbar-call { order: 1; min-height: 44px; padding: 10px 22px; font-size: 0.9375rem; }
}
/* Below ~430px the button and the note cannot share a line without one of them
   wrapping, so the button takes the row and the note steps down. The same
   availability line still appears in the hero stats and the emergency band. */
@media (max-width: 430px) {
  .topbar-call { width: 100%; max-width: 320px; }
  .topbar-note { display: none; }
}

.site-header {
  position: sticky; top: 0; z-index: 90;
  /* NOTE: this z-index makes the header a stacking context, so .nav's z-index
     is resolved INSIDE it. The scrim is a <body> child at 94, which is above
     90, so the whole header — nav included — would paint under the scrim and
     become unclickable. site.js sets body.nav-open to lift it; see below. */
  background: var(--surface-inverse);
  border-bottom: 1px solid var(--border-on-dark);
  transition: box-shadow var(--t);
}
.site-header.is-stuck { box-shadow: var(--shadow-md); }
/* The header carries more than any other row (logo + 7 nav links + Genuine
   Parts + Get a quote), so it gets a wider container than the 1180 content
   shell. Without this the CTA group overflows and "Get a quote" is clipped. */
.site-header .shell {
  display: flex; align-items: center; justify-content: space-between;
  gap: 18px; min-height: 74px; max-width: 1460px;
}

.brand { display: flex; align-items: center; flex: none; }
.brand img { height: 42px; width: auto; }
.brand .logo-on-dark { display: block; }
.brand .logo-on-light { display: none; }

.nav { display: flex; align-items: center; gap: 2px; min-width: 0; }
.nav a {
  font-family: var(--font-head);
  font-size: 0.875rem; font-weight: 600;
  color: var(--text-on-dark);
  padding: 9px 10px; border-radius: var(--r-sm);
  transition: color var(--t-fast), background var(--t-fast);
  white-space: nowrap;
}
.nav a:hover { color: var(--accent-dk); background: rgba(255, 255, 255, 0.06); }
.nav a[aria-current='page'] { color: var(--accent-dk); }
.nav a[aria-current='page']::after {
  content: ''; display: block; height: 2px; background: var(--accent-dk);
  border-radius: 2px; margin-top: 5px;
}
.header-cta { display: flex; align-items: center; gap: 10px; flex: none; }
.brand { flex: none; }

.nav-toggle { display: none; width: 42px; height: 42px; align-items: center; justify-content: center; border-radius: var(--r-sm); border: 1px solid var(--border-on-dark); color: var(--text-on-dark); }
.nav-toggle svg { width: 20px; height: 20px; }
.nav-toggle:hover { border-color: var(--accent-dk); color: var(--accent-dk); }

@media (max-width: 1200px) {
  .nav-toggle { display: inline-flex; }
  .nav {
    position: fixed; inset: 0 0 0 auto; width: min(320px, 84vw);
    background: var(--surface-inverse-2);
    flex-direction: column; align-items: stretch; gap: 4px;
    padding: 88px 20px 32px; z-index: 95;
    transform: translateX(100%); transition: transform var(--t);
    overflow-y: auto; border-left: 1px solid var(--border-on-dark);
  }
  .nav[data-open='true'] { transform: translateX(0); }
  .nav a { padding: 13px 14px; font-size: 0.9375rem; }
  .nav a[aria-current='page']::after { display: none; }
  /* The panel is inset:0 on the right, so it covers the toggle that opened it.
     The panel's 88px top padding leaves that corner empty, so lifting the
     toggle above the panel (both inside the header's stacking context) keeps
     it reachable to close the menu. */
  .nav-toggle { position: relative; z-index: 96; }
  .nav-scrim { position: fixed; inset: 0; background: rgba(10, 9, 9, 0.6); z-index: 94; opacity: 0; pointer-events: none; transition: opacity var(--t); }
  .nav-scrim[data-open='true'] { opacity: 1; pointer-events: auto; }
  /* Lift the header (and therefore the nav panel inside it) above the scrim
     while the menu is open, so the links are visible and clickable and the
     toggle stays reachable to close it. */
  body.nav-open .site-header { z-index: 96; }
  .header-cta .btn-quote { display: none; }
}

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

.hero {
  position: relative;
  padding: var(--hero-y) 0 calc(var(--hero-y) * 0.85);
  background: var(--surface-inverse);
  color: var(--text-on-dark);
  overflow: hidden;
  isolation: isolate;
}
.hero-media { position: absolute; inset: 0; z-index: -2; }
.hero-media img { width: 100%; height: 100%; object-fit: cover; }
.hero-media::after {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(20, 18, 18, 0.78) 0%, rgba(20, 18, 18, 0.62) 45%, rgba(20, 18, 18, 0.9) 100%),
    linear-gradient(100deg, rgba(20, 18, 18, 0.72) 20%, transparent 85%);
}
.hero h1 { color: var(--text-on-dark); }
.hero h1 em { font-style: normal; color: var(--accent-dk); }
.hero-lede { font-size: clamp(1rem, 1.6vw, 1.1875rem); color: var(--text-on-dark-muted); max-width: 620px; margin-top: 20px; line-height: 1.7; }
/* The 760px reading measure belongs on the PROSE, not on the wrapper: when it
   sat on .hero-inner the stat strip inherited it, so four stats only got three
   columns and the fourth orphaned onto its own row. The strip is data and
   spans the full shell. */
.hero-inner { max-width: none; }
.hero-inner > h1 { max-width: 760px; }
.hero .btn-row { margin-top: 34px; }

.crumbs { display: flex; align-items: center; gap: 8px; font-size: 0.8125rem; color: var(--text-on-dark-muted); margin-bottom: 22px; flex-wrap: wrap; }
.crumbs a:hover { color: var(--accent-dk); }
.crumbs span[aria-hidden] { opacity: 0.45; }
.crumbs [aria-current] { color: var(--accent-dk); font-weight: 600; }

.hero-strip {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 18px 32px; margin-top: 52px; padding-top: 32px;
  border-top: 1px solid var(--border-on-dark);
}
.hero-stat-n { font-family: var(--font-head); font-size: clamp(1.6rem, 3vw, 2.2rem); font-weight: 800; color: var(--accent-dk); letter-spacing: -0.02em; line-height: 1; }
.hero-stat-l { font-size: 0.8125rem; color: var(--text-on-dark-muted); margin-top: 8px; }
/* Never nowrap here: a long stat ("After-hours") then overflows its grid cell
   and collides with the next stat. Wrapping at the hyphen is fine; what must
   not happen is overflow. min-width:0 lets the grid cell actually shrink. */
.hero-stat { min-width: 0; }
.hero-stat-n { hyphens: none; overflow-wrap: break-word; }
/* Between roughly 730px and 985px auto-fit lands on three columns, orphaning
   the fourth stat on its own row. A fixed 2x2 reads better in that band. */
@media (min-width: 700px) and (max-width: 1010px) {
  .hero-strip { grid-template-columns: repeat(2, 1fr); }
}

/* ==========================================================================
   Cards
   ========================================================================== */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 28px;
  transition: transform var(--t), border-color var(--t), box-shadow var(--t);
  height: 100%;
  display: flex; flex-direction: column;
}
.card:hover { border-color: var(--accent-line); box-shadow: var(--shadow-md); transform: translateY(-3px); }
.card h3, .card h4 { margin-bottom: 9px; }
.card p { font-size: 0.9125rem; color: var(--text-muted); }
.card .link-arrow { margin-top: auto; padding-top: 18px; align-self: flex-start; }
.band-2 .card { background: var(--surface); }
.band-inverse .card {
  background: var(--surface-inverse-2);
  border-color: var(--border-on-dark);
}
.band-inverse .card p { color: var(--text-on-dark-muted); }
.card-flat:hover { transform: none; }

/* ── Note / callout panel ──────────────────────────────────────────────
   An accent-tinted aside — used for capability caveats and "confirm this"
   detail. On a dark band the accent tint sits too close to the band itself
   in several themes, so it takes the dark-surface treatment instead. */
.note {
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-md);
  padding: 24px 28px;
}
.note h3, .note h4 { margin-bottom: 10px; }
.note p { font-size: 0.9375rem; }
.note p + p { margin-top: 10px; }
.band-inverse .note {
  background: var(--surface-inverse-2);
  border-color: var(--border-on-dark);
}
.band-inverse .note p { color: var(--text-on-dark-muted); }

.icon-badge {
  width: 46px; height: 46px; border-radius: var(--r-sm);
  display: grid; place-items: center; flex: none;
  background: var(--accent-soft); border: 1px solid var(--accent-line);
  color: var(--accent-text); margin-bottom: 18px;
}
.icon-badge svg { width: 22px; height: 22px; }

.numbered { counter-reset: step; }
.num-badge {
  width: 38px; height: 38px; border-radius: var(--r-pill);
  display: grid; place-items: center; flex: none;
  background: var(--accent); color: var(--on-accent);
  font-family: var(--font-head); font-weight: 800; font-size: 0.9375rem;
  margin-bottom: 18px;
}

/* Feature row (icon beside copy) */
.feature { display: flex; gap: 16px; align-items: flex-start; }
.feature .icon-badge { margin-bottom: 0; }
.feature h3, .feature h4 { margin-bottom: 5px; }
.feature p { font-size: 0.9rem; color: var(--text-muted); }
.feature-body { min-width: 0; }
.band-inverse .feature p { color: var(--text-on-dark-muted); }

/* ── Checklist ── */
.checklist { display: grid; gap: 13px; }
.checklist li { display: flex; gap: 12px; align-items: flex-start; font-size: 0.95rem; }
.checklist svg { width: 19px; height: 19px; flex: none; margin-top: 3px; color: var(--accent-text); }
.checklist-2 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 13px 32px; }

/* ── Media frames ── */
.frame {
  border-radius: var(--r-md); overflow: hidden;
  border: 1px solid var(--border); background: var(--surface-2);
}
.frame img { width: 100%; height: 100%; object-fit: cover; }
.frame-tall { aspect-ratio: 4 / 5; }
.frame-wide { aspect-ratio: 16 / 10; }
.frame-square { aspect-ratio: 1; }
.band-inverse .frame { border-color: var(--border-on-dark); }

.figure-stat {
  position: relative;
}
.figure-stat .stat-chip {
  position: absolute; bottom: 18px; left: 18px; right: 18px;
  background: var(--accent); color: var(--on-accent);
  border-radius: var(--r-sm); padding: 14px 18px;
  font-family: var(--font-head); font-weight: 700; font-size: 0.875rem;
  box-shadow: var(--shadow-md);
}

/* ==========================================================================
   Tables
   ========================================================================== */

.table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface); }
.band-inverse .table-wrap { border-color: var(--border-on-dark); background: var(--surface-inverse-2); }
table.data { width: 100%; border-collapse: collapse; min-width: 620px; font-size: 0.9rem; }
table.data th, table.data td { padding: 14px 18px; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
.band-inverse table.data th, .band-inverse table.data td { border-color: var(--border-on-dark); }
table.data thead th {
  font-family: var(--font-head); font-size: 0.7rem; font-weight: 800;
  letter-spacing: var(--eyebrow-tracking); text-transform: uppercase;
  color: var(--text-faint); background: var(--surface-2); white-space: nowrap;
}
.band-inverse table.data thead th { background: rgba(255,255,255,0.04); color: var(--text-on-dark-muted); }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data tbody tr:hover { background: var(--accent-soft); }
table.data td strong { font-weight: 700; }
.cell-yes { color: var(--accent-text); font-weight: 700; }

/* ==========================================================================
   Tags / chips / pills
   ========================================================================== */

.tag {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-head); font-size: 0.7rem; font-weight: 800;
  letter-spacing: 0.09em; text-transform: uppercase;
  padding: 5px 12px; border-radius: var(--r-pill);
  background: var(--accent-soft); color: var(--accent-text);
  border: 1px solid var(--accent-line);
}
.tag-row { display: flex; gap: 8px; flex-wrap: wrap; }
.tag-neutral { background: var(--surface-2); color: var(--text-muted); border-color: var(--border); }

/* ==========================================================================
   Accordion (FAQ)
   ========================================================================== */

.acc { border-top: 1px solid var(--border); }
.acc-item { border-bottom: 1px solid var(--border); }
.acc-btn {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 22px 4px; text-align: left;
  font-family: var(--font-head); font-size: 1.0125rem; font-weight: 700; color: var(--ink);
  transition: color var(--t-fast);
}
.acc-btn:hover { color: var(--accent-text); }
.acc-sign { width: 26px; height: 26px; flex: none; position: relative; border-radius: 50%; border: 1.5px solid var(--border-strong); transition: border-color var(--t), transform var(--t); }
.acc-sign::before, .acc-sign::after {
  content: ''; position: absolute; inset: 50% auto auto 50%;
  background: currentColor; border-radius: 2px;
  transform: translate(-50%, -50%);
}
.acc-sign::before { width: 11px; height: 1.5px; }
.acc-sign::after { width: 1.5px; height: 11px; transition: opacity var(--t), transform var(--t); }
.acc-btn[aria-expanded='true'] { color: var(--accent-text); }
.acc-btn[aria-expanded='true'] .acc-sign { border-color: var(--accent); }
.acc-btn[aria-expanded='true'] .acc-sign::after { opacity: 0; transform: translate(-50%, -50%) rotate(90deg); }
.acc-panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--t); }
.acc-panel[data-open='true'] { grid-template-rows: 1fr; }
.acc-panel > div { overflow: hidden; visibility: hidden; transition: visibility var(--t); }
.acc-panel[data-open='true'] > div { visibility: visible; }
.acc-panel p { padding: 0 4px 24px; font-size: 0.95rem; color: var(--text-muted); max-width: 74ch; }
.acc-panel p + p { padding-top: 0; margin-top: -10px; }
.band-inverse .acc, .band-inverse .acc-item { border-color: var(--border-on-dark); }
.band-inverse .acc-btn { color: var(--text-on-dark); }
.band-inverse .acc-panel p { color: var(--text-on-dark-muted); }

/* ==========================================================================
   Forms
   ========================================================================== */

.form-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: 32px; box-shadow: var(--shadow-md);
}
.band-inverse .form-card { background: var(--surface-inverse-2); border-color: var(--border-on-dark); }
.field { display: grid; gap: 7px; margin-bottom: 16px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 560px) { .field-row { grid-template-columns: 1fr; gap: 0; } }
label, .field-label {
  font-family: var(--font-head); font-size: 0.78rem; font-weight: 700;
  letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-muted);
}
.field-label { display: block; }
.band-inverse label, .band-inverse .field-label { color: var(--text-on-dark-muted); }
input, select, textarea {
  font: inherit; font-size: 0.9375rem;
  width: 100%; padding: 12px 14px;
  color: var(--text); background: var(--surface);
  border: 1.5px solid var(--border-strong); border-radius: var(--r-sm);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.band-inverse input, .band-inverse select, .band-inverse textarea {
  background: rgba(255,255,255,0.04); color: var(--text-on-dark); border-color: var(--border-on-dark);
}
/* The ring comes from the shared :focus-visible rule; this only tints the
   border. Never set `outline` here — at 0-1-1 it would out-rank the ring. The
   border alone is not an indicator: High-Vis's resting --border-strong is
   already its --accent-text black, so only the ring shows the change there. */
input:focus, select:focus, textarea:focus { border-color: var(--accent-text); }
.band-inverse :is(input, select, textarea):focus { border-color: var(--accent-dk); }
textarea { resize: vertical; min-height: 108px; }
select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%); background-position: calc(100% - 19px) 51%, calc(100% - 14px) 51%; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 40px; }
.field-hint { font-size: 0.8rem; color: var(--text-faint); text-transform: none; letter-spacing: 0; font-weight: 500; }
/* The quote form sits in a .band-inverse on most pages, so its hint and note
   text must switch to the dark-surface muted token or it is ~2.5:1. */
.band-inverse .field-hint, .band-inverse .form-note { color: var(--text-on-dark-muted); }
.urgency { display: flex; gap: 8px; flex-wrap: wrap; }
.urgency input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.urgency label {
  padding: 9px 16px; border-radius: var(--r-pill);
  /* --border-strong is a divider tone (1.6:1 on white) — too faint to be the
     boundary of an interactive control. 52% of --text clears 3:1 in all five
     themes, on light cards and dark ones. */
  border: 1.5px solid color-mix(in srgb, var(--text) 52%, transparent);
  cursor: pointer; text-transform: none; letter-spacing: 0; font-size: 0.85rem;
  color: var(--text); transition: all var(--t-fast);
}
.urgency label:hover { border-color: var(--accent-text); color: var(--accent-text); }
/* The accent FILL alone is not a usable selected state on a light card: gold
   on white is 1.55:1 and High-Vis yellow is 1.23:1, so you cannot see which
   pill is chosen. The --accent-text border gives the shape a real edge
   (6.3 / 14.0 / 7.6 / 19.1 / 8.9 across the themes). */
.urgency input:checked + label {
  background: var(--accent); border-color: var(--accent-text); color: var(--on-accent);
  font-weight: 700;
}
.urgency input:focus-visible + label { outline: var(--ring); outline-offset: var(--ring-offset); }

/* The quote form sits on a dark band on most pages. Two things break there:
   the UNSELECTED pill inherits --text (near-black) and drops to ~1.15:1, and
   the SELECTED pill's --accent fill only clears 2.6:1 (Steel) / 1.8:1
   (Heritage) against the dark card, so it stops reading as a filled shape. */
.band-inverse .urgency label {
  color: var(--text-on-dark);
  border-color: color-mix(in srgb, var(--text-on-dark) 40%, transparent);
}
.band-inverse .urgency label:hover {
  border-color: var(--accent-dk); color: var(--accent-dk);
  background: color-mix(in srgb, var(--accent-dk) 12%, transparent);
}
/* On a dark card the --accent-dk fill is already a 9:1 boundary, so it doubles
   as its own border. */
.band-inverse .urgency input:checked + label {
  background: var(--accent-dk); border-color: var(--accent-dk); color: var(--on-accent-dk);
}
/* The ring is on the label, not the focused input, so the shared
   `.band-inverse :focus-visible` swap never reaches it. */
.band-inverse .urgency input:focus-visible + label { outline: var(--ring-dk); }
.form-note { font-size: 0.8125rem; color: var(--text-faint); margin-top: 14px; }
.form-status { margin-top: 16px; padding: 14px 16px; border-radius: var(--r-sm); background: var(--accent-soft); border: 1px solid var(--accent-line); font-size: 0.9rem; font-weight: 600; }
.form-status[hidden] { display: none; }

/* ==========================================================================
   Testimonials
   ========================================================================== */

.quote {
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-md); padding: 26px 28px; height: 100%;
  display: flex; flex-direction: column; gap: 16px;
}
.band-inverse .quote { background: var(--surface-inverse-2); border-color: var(--border-on-dark); border-left-color: var(--accent-dk); }
.stars { display: flex; gap: 3px; color: var(--accent); }
.stars svg { width: 16px; height: 16px; }
.quote blockquote { font-size: 0.95rem; line-height: 1.7; color: var(--text); flex: 1; }
.band-inverse .quote blockquote { color: var(--text-on-dark); }
.quote figcaption { font-size: 0.8375rem; color: var(--text-faint); display: flex; align-items: center; gap: 9px; }
.quote figcaption strong { color: var(--text); font-weight: 700; }
.band-inverse .quote figcaption strong { color: var(--text-on-dark); }

/* ==========================================================================
   Brand logo wall
   ========================================================================== */

.logo-wall { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 12px; align-items: center; }
.logo-wall li {
  display: grid; place-items: center;
  padding: 20px 16px; min-height: 84px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-sm);
  transition: border-color var(--t);
}
.logo-wall li:hover { border-color: var(--accent-line); }
.logo-wall img { max-height: 34px; width: auto; object-fit: contain; filter: grayscale(1); opacity: 0.62; transition: filter var(--t), opacity var(--t); }
.logo-wall li:hover img { filter: grayscale(0); opacity: 1; }
.band-inverse .logo-wall li { background: var(--surface-inverse-2); border-color: var(--border-on-dark); }
.band-inverse .logo-wall img { filter: grayscale(1) invert(1) brightness(1.9); opacity: 0.55; }
.band-inverse .logo-wall li:hover img { opacity: 0.95; }

/* ==========================================================================
   Gallery
   ========================================================================== */

.gallery { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; }
.gallery button {
  position: relative; overflow: hidden; border-radius: var(--r-md);
  aspect-ratio: 4 / 3; border: 1px solid var(--border); display: block; width: 100%;
}
.gallery img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s cubic-bezier(0.2, 0, 0.2, 1); }
.gallery button:hover img { transform: scale(1.06); }
.gallery button::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 42%, rgba(16, 14, 14, 0.86));
  opacity: 0; transition: opacity var(--t);
}
.gallery button:hover::after { opacity: 1; }
.gallery .g-cap {
  position: absolute; bottom: 12px; left: 14px; right: 14px; z-index: 2;
  color: #fff; font-size: 0.8125rem; font-weight: 600; text-align: left;
  opacity: 0; transform: translateY(6px); transition: all var(--t);
}
.gallery button:hover .g-cap, .gallery button:focus-visible .g-cap { opacity: 1; transform: none; }
.gallery .g-span-2 { grid-column: span 2; aspect-ratio: 8 / 3; }
@media (max-width: 560px) { .gallery .g-span-2 { grid-column: span 1; aspect-ratio: 4 / 3; } }

.lightbox {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(14, 13, 13, 0.94);
  display: grid; place-items: center; padding: 28px;
  /* visibility, not just opacity, so the closed viewer's buttons leave the Tab
     order. It flips to hidden after the fade-out, and back at once on open so
     open() can focus the close button in the same task. */
  opacity: 0; pointer-events: none; visibility: hidden;
  transition: opacity var(--t), visibility 0s linear var(--t);
}
.lightbox[data-open='true'] { opacity: 1; pointer-events: auto; visibility: visible; transition: opacity var(--t); }
.lightbox img { max-width: min(1100px, 94vw); max-height: 82vh; width: auto; border-radius: var(--r-md); object-fit: contain; }
.lightbox-cap { color: #e8e5e3; font-size: 0.875rem; margin-top: 16px; text-align: center; }
.lightbox-close {
  position: absolute; top: 20px; right: 20px;
  width: 44px; height: 44px; border-radius: 50%;
  background: rgba(255,255,255,0.1); color: #fff; display: grid; place-items: center;
}
.lightbox-close:hover { background: var(--accent-dk); color: var(--on-accent-dk); }
.lightbox-nav { position: absolute; top: 50%; transform: translateY(-50%); width: 48px; height: 48px; border-radius: 50%; background: rgba(255,255,255,0.1); color: #fff; display: grid; place-items: center; font-size: 1.3rem; }
.lightbox-nav:hover { background: var(--accent-dk); color: var(--on-accent-dk); }
.lightbox-prev { left: 20px; }
.lightbox-next { right: 20px; }
/* show() hides prev/next for a one-image reel; the display:grid above would
   otherwise out-rank the browser's own [hidden] rule. */
.lightbox-nav[hidden] { display: none; }

/* ==========================================================================
   CTA band
   ========================================================================== */

.cta-band {
  background: var(--surface-inverse); color: var(--text-on-dark);
  padding: calc(var(--section-y) * 0.8) 0;
  position: relative; overflow: hidden; isolation: isolate;
}
.cta-band::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: radial-gradient(ellipse 70% 120% at 85% 50%, color-mix(in srgb, var(--accent-dk) 13%, transparent), transparent 70%);
}
.cta-band .shell { display: flex; align-items: center; justify-content: space-between; gap: 40px; flex-wrap: wrap; }
.cta-band h2 { color: var(--text-on-dark); max-width: 640px; font-size: clamp(1.45rem, 2.6vw, 2rem); }
.cta-band p { color: var(--text-on-dark-muted); margin-top: 12px; max-width: 580px; }
/* flex:none made this size to the min-content of two nowrap buttons (417px),
   which overflows a phone viewport and clipped "Call 1300 202 272". */
.cta-band .btn-row { flex: 0 1 auto; min-width: 0; }

/* ── Emergency strip ── */
.emergency {
  background: var(--accent); color: var(--on-accent);
  padding: 18px 0;
}
.emergency .shell { display: flex; align-items: center; justify-content: center; gap: 10px 24px; flex-wrap: wrap; text-align: center; }
.emergency strong { font-family: var(--font-head); font-weight: 800; font-size: 1.0125rem; letter-spacing: var(--head-tracking); }
.emergency span { font-size: 0.9125rem; opacity: 0.82; }
.emergency a { font-weight: 800; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 3px; }
.emergency a:hover { text-decoration-color: rgba(0,0,0,0.35); }

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

.site-footer { background: var(--surface-inverse); color: var(--text-on-dark-muted); padding: 64px 0 0; font-size: 0.9rem; }
.footer-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr 1.2fr; gap: 40px; }
@media (max-width: 900px) { .footer-grid { grid-template-columns: 1fr 1fr; gap: 34px; } }
@media (max-width: 520px) { .footer-grid { grid-template-columns: 1fr; } }
.site-footer h3 {
  font-size: 0.7rem; font-weight: 800; letter-spacing: var(--eyebrow-tracking);
  text-transform: uppercase; color: var(--text-on-dark); margin-bottom: 18px;
}
.site-footer img.footer-logo { height: 40px; width: auto; margin-bottom: 18px; }
.site-footer p { line-height: 1.7; }
.site-footer ul { display: grid; gap: 11px; }
.site-footer a { transition: color var(--t-fast); }
.site-footer a:hover { color: var(--accent-dk); }
.footer-contact { display: grid; gap: 13px; }
.footer-contact a, .footer-contact div { display: flex; gap: 11px; align-items: flex-start; }
.footer-contact svg { width: 15px; height: 15px; flex: none; margin-top: 4px; color: var(--accent-dk); }
.footer-bottom {
  margin-top: 56px; padding: 22px 0; border-top: 1px solid var(--border-on-dark);
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  font-size: 0.8125rem;
}
.footer-bottom .muted, .site-footer .muted { color: var(--text-on-dark-muted); }

/* ── Mobile sticky call bar ── */
.call-bar {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 88;
  display: none; gap: 1px;
  background: var(--border-on-dark);
  box-shadow: 0 -4px 20px rgba(14, 13, 13, 0.28);
}
.call-bar a {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 14px 10px; font-family: var(--font-head); font-weight: 700; font-size: 0.875rem;
}
.call-bar a:first-child { background: var(--accent-dk); color: var(--on-accent-dk); }
.call-bar a:last-child { background: var(--surface-inverse); color: var(--text-on-dark); }
/* The ring is drawn inside (see :focus-visible); keep the buttons square so the
   shared focus radius does not notch the corners of a full-bleed bar. */
.call-bar a:focus-visible { border-radius: 0; }
.call-bar svg { width: 16px; height: 16px; }
@media (max-width: 720px) {
  .call-bar { display: flex; }
  body { padding-bottom: 52px; }
}

/* ==========================================================================
   Theme switcher dock (bottom of page)
   ========================================================================== */

.theme-dock {
  position: fixed; z-index: 120;
  bottom: 20px; left: 50%; transform: translateX(-50%);
  display: flex; align-items: center; gap: 6px;
  padding: 7px 8px;
  background: color-mix(in srgb, var(--surface-inverse) 88%, transparent);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--r-pill);
  box-shadow: 0 12px 40px rgba(10, 9, 9, 0.4);
  transition: transform var(--t), opacity var(--t);
  max-width: calc(100vw - 24px);
}
@supports not (backdrop-filter: blur(4px)) { .theme-dock { background: var(--surface-inverse); } }
/* Same visibility pattern as .lightbox: the collapsed dock's buttons leave the
   Tab order once the slide-out finishes, and return the instant it reopens. */
.theme-dock[data-collapsed='true'] {
  transform: translateX(-50%) translateY(calc(100% + 24px)); opacity: 0; pointer-events: none;
  visibility: hidden; transition: transform var(--t), opacity var(--t), visibility 0s linear var(--t);
}

.theme-dock-label {
  font-family: var(--font-head); font-size: 0.65rem; font-weight: 800;
  letter-spacing: 0.13em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5); padding: 0 8px 0 10px; white-space: nowrap;
}
.theme-swatches { display: flex; gap: 5px; }
.theme-swatch {
  position: relative; width: 34px; height: 34px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.2);
  overflow: hidden; transition: border-color var(--t), transform var(--t-fast);
  flex: none;
}
.theme-swatch::before, .theme-swatch::after { content: ''; position: absolute; inset: 0; }
.theme-swatch::before { background: var(--sw-bg); }
.theme-swatch::after { background: var(--sw-accent); clip-path: polygon(100% 0, 100% 100%, 0 100%); }
.theme-swatch:hover { transform: scale(1.12); border-color: rgba(255, 255, 255, 0.55); }
.theme-swatch[aria-pressed='true'] { border-color: #fff; transform: scale(1.06); }
.theme-swatch[aria-pressed='true']::after { clip-path: polygon(100% 0, 100% 100%, 0 100%); }
/* Detail toggle — shares the dock with the theme swatches. The dock is dark in
   every theme, so like the swatches above it these use white alphas over
   --surface-inverse rather than the light-surface text tokens. */
.dock-sep {
  width: 1px; align-self: stretch; margin: 2px 4px;
  background: rgba(255, 255, 255, 0.16);
}
.variant-toggle {
  display: flex; gap: 2px; padding: 2px;
  background: rgba(255, 255, 255, 0.08);
  border-radius: var(--r-pill);
}
.variant-btn {
  font-family: var(--font-head); font-size: 0.6875rem; font-weight: 800;
  letter-spacing: 0.08em; text-transform: uppercase;
  padding: 6px 12px; border: 0; border-radius: var(--r-pill);
  background: transparent; color: rgba(255, 255, 255, 0.62);
  cursor: pointer; white-space: nowrap;
  transition: background var(--t), color var(--t);
}
.variant-btn:hover:not(:disabled) { color: #fff; background: rgba(255, 255, 255, 0.12); }
.variant-btn[aria-pressed='true'] { background: var(--accent-dk); color: var(--on-accent-dk); }
.variant-btn:disabled { opacity: 0.4; cursor: default; }
.variant-btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

.theme-dock-x {
  width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center;
  color: rgba(255, 255, 255, 0.5); margin-left: 2px; flex: none;
}
.theme-dock-x:hover { color: #fff; background: rgba(255, 255, 255, 0.1); }
.theme-dock-x svg { width: 14px; height: 14px; }

.theme-reopen {
  position: fixed; z-index: 120; bottom: 20px; left: 50%; transform: translateX(-50%);
  display: none; align-items: center; gap: 8px;
  padding: 10px 18px; border-radius: var(--r-pill);
  background: var(--surface-inverse); color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: 0 10px 30px rgba(10, 9, 9, 0.35);
  font-family: var(--font-head); font-size: 0.75rem; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase;
}
.theme-reopen[data-show='true'] { display: inline-flex; }
.theme-reopen svg { width: 15px; height: 15px; }

.theme-toast {
  position: fixed; z-index: 119; bottom: 74px; left: 50%; transform: translateX(-50%) translateY(8px);
  padding: 9px 18px; border-radius: var(--r-pill);
  background: var(--accent); color: var(--on-accent);
  font-family: var(--font-head); font-size: 0.78rem; font-weight: 800;
  letter-spacing: 0.06em; text-transform: uppercase;
  opacity: 0; pointer-events: none; transition: opacity var(--t), transform var(--t);
  white-space: nowrap;
}
.theme-toast[data-show='true'] { opacity: 1; transform: translateX(-50%) translateY(0); }

@media (max-width: 720px) {
  /* Bottom-centre is where the hero CTA and the call bar live, so on a phone
     the dock moves to the right edge and rides above the call bar instead of
     sitting on top of a primary button. */
  .theme-dock, .theme-reopen {
    bottom: 62px; left: auto; right: 10px; transform: none;
  }
  .theme-dock[data-collapsed='true'] { transform: translateY(calc(100% + 24px)); }
  .theme-toast { bottom: 116px; }
  .theme-dock-label { display: none; }
  .dock-sep { margin: 2px 2px; }
  .variant-btn { padding: 6px 9px; font-size: 0.625rem; letter-spacing: 0.06em; }
  .theme-swatch { width: 30px; height: 30px; }
}

/* ==========================================================================
   Reveal on scroll
   ========================================================================== */

.reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.6s ease, transform 0.6s cubic-bezier(0.2, 0, 0.2, 1); }
.reveal.is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; transform: none; } }
/* Never let the entrance animation be the reason content cannot be seen: if
   scripting is off, site.js fails to load, or the observer never runs, every
   .reveal block would otherwise sit at opacity 0 and the page would read as
   empty. site.js carries a matching runtime failsafe. */
@media (scripting: none) { .reveal { opacity: 1; transform: none; } }

/* ── Utilities ── */
.mt-0 { margin-top: 0; }
.mt-1 { margin-top: 8px; }
.mt-2 { margin-top: 16px; }
.mt-3 { margin-top: 24px; }
.mt-4 { margin-top: 32px; }
.mt-5 { margin-top: 44px; }
.mb-3 { margin-bottom: 24px; }
.muted { color: var(--text-muted); }
.faint { color: var(--text-faint); font-size: 0.8125rem; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.nowrap { white-space: nowrap; }
.accent-text { color: var(--accent-text); }

@media print {
  .theme-dock, .theme-reopen, .theme-toast, .call-bar, .site-header, .topbar, .nav-scrim { display: none !important; }
  body { padding-bottom: 0; }
}
