/* Don's Garage Automotive and Transmission — public marketing site.
 *
 * Visual system: chunky-bordered, hard-offset-shadow, condensed-display
 * neo-brutalist. Four colors only — black, white, accent blue, steel gray.
 * Anton (heavy condensed) for display headlines, Inter for body.
 * Edit one custom property and the whole site recolors.
 */

:root {
  /* ── Palette (lock — adding a fifth color is a breaking change) ── */
  --color-bg:          #FFFFFF;
  --color-ink:         #0A0A0A;
  --color-accent:      #42A5F5;
  --color-steel:       #C7CDD3;

  /* Aliases. Same hex; named for the role they play. */
  --color-bg-dark:     #0A0A0A;
  --color-ink-on-dark: #FFFFFF;
  --color-rule:        #0A0A0A;

  /* ── Type ── */
  --font-display: "Anton", "Bebas Neue", "Oswald", Impact, sans-serif;
  --font-body:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
                  Roboto, sans-serif;

  /* ── Layout ── */
  --content-w-wide:  1140px;
  --content-w-prose: 720px;

  /* ── The chunky-shadow primitives. Used by cards, stat-panels, buttons.
        2px border + hard offset shadow is the entire design language. ── */
  --border-chunky:   2px solid var(--color-ink);
  --shadow-chunky:   6px 6px 0 var(--color-ink);
  --shadow-chunky-sm: 4px 4px 0 var(--color-ink);
}

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background-color: var(--color-bg);
  /* Subtle grid pattern. 4% alpha = barely-visible texture; reads as
     paper-engineered, not tiled-wallpaper. Remove the two background-image
     lines if it ever fights the foreground. */
  background-image:
    linear-gradient(rgba(10, 10, 10, 0.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(10, 10, 10, 0.04) 1px, transparent 1px);
  background-size: 40px 40px;
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

a { color: inherit; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 3px; }
a:hover { color: var(--color-accent); }

/* ── Type scale ───────────────────────────────────────────────────────────
   Anton is single-weight (400 only) but reads heavy because it's condensed.
   All-caps via CSS, not markup, so SEO sees natural-cased copy. */
h1, h2, h3, h4 {
  color: var(--color-ink);
  margin: 0 0 0.4em;
}

h1 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(48px, 7vw, 72px);
  line-height: 0.95;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}
h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(36px, 5vw, 48px);
  line-height: 1.0;
  letter-spacing: -0.01em;
  text-transform: uppercase;
}
h3 {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 28px;
  line-height: 1.15;
  letter-spacing: -0.01em;
}
h4 {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 18px;
  line-height: 1.3;
}

p { margin: 0 0 1.05em; }
p:last-child { margin-bottom: 0; }

ul, ol { padding-left: 1.4em; margin: 0 0 1.05em; }
li { margin-bottom: 0.4em; }

/* ── Headline word-highlight ─────────────────────────────────────────────
   Wraps a single word inside an h1/h2 for accent treatment. Light blue with
   a 1px black offset shadow so the word reads as "punched out" of the
   page. The 1px offset is the smallest unit of the chunky-shadow language;
   bigger would compete with the cards. */
.hl-accent {
  color: var(--color-accent);
  text-shadow: 1px 1px 0 var(--color-ink);
}

/* ── Eyebrow / meta labels ───────────────────────────────────────────── */
.eyebrow {
  display: inline-block;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-ink);
  margin-bottom: 12px;
}

.meta {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-ink);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* ── Layout primitives ── */
.container        { max-width: var(--content-w-wide); margin: 0 auto; padding: 0 24px; }
.container--prose { max-width: var(--content-w-prose); margin: 0 auto; padding: 0 24px; }

.section { padding: 88px 0; }
.section--alt   { background: var(--color-steel); }

/* ── Dark-section invert ─────────────────────────────────────────────────
   Full black bg, white type. Blue accent stays the same hue (it's bright
   enough to read on either side); its outline switches to white so the
   "punched out" effect inverts correctly against dark. */
.section--dark {
  background: var(--color-bg-dark);
  color: var(--color-ink-on-dark);
}
.section--dark h1,
.section--dark h2,
.section--dark h3,
.section--dark h4 { color: var(--color-ink-on-dark); }
.section--dark .hl-accent {
  color: var(--color-accent);
  text-shadow: 1px 1px 0 var(--color-ink-on-dark);
}
.section--dark a { color: var(--color-ink-on-dark); }
.section--dark a:hover { color: var(--color-accent); }

/* ── Header ──────────────────────────────────────────────────────────────
   Logo block + nav. Sticky so the phone CTA is always one tap away. */
.site-header {
  background: var(--color-bg);
  border-bottom: var(--border-chunky);
  position: sticky;
  top: 0;
  z-index: 100;
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 16px 0;
  /* Hard rule: the header row never wraps. If something doesn't fit, the
     brand truncates (see .brand below) — the actions cluster stays one
     row, and the toggle/hamburger stay side by side. */
  flex-wrap: nowrap;
}
/* Right-side cluster: theme toggle + hamburger. Heavy-hammer treatment
   because Samsung Internet was still stacking the buttons vertically
   after the C.4.2 defensive rules. Every property is locked with
   !important to override whatever browser-specific quirk is in play.
   Once a real-browser repro identifies the actual offending rule, the
   !importants can be pared down — for now, correct rendering wins
   over stylistic purity. */
.site-header__actions {
  display: inline-flex !important;
  flex-direction: row !important;
  flex-wrap: nowrap !important;
  align-items: center !important;
  gap: 10px !important;
  flex-shrink: 0 !important;
  white-space: nowrap !important;
  min-width: max-content !important;
}
.site-header__actions > * {
  flex-shrink: 0 !important;
  flex-grow: 0 !important;
  flex-basis: auto !important;
  vertical-align: middle !important;
}
/* Both children use inline-flex so they sit horizontally as siblings of
   the actions cluster — but the hamburger needs flex-direction:column
   internally so its three bars stack vertically. The C.4.3 catch-all
   collapsed the bars onto one row; this split rule preserves the
   side-by-side parent layout while giving the hamburger back its
   column-stacked icon. */
.site-header__actions > .theme-toggle {
  display: inline-flex !important;
}
.site-header__actions > .nav-toggle {
  display: inline-flex !important;
  flex-direction: column !important;
  justify-content: space-between !important;
}
/* Hide the hamburger above the mobile breakpoint. The C.4.3/C.4.4
   inline-flex !important rule above leaks into desktop without this
   guard — and an !important is required to overpower it. */
@media (min-width: 821px) {
  .site-header__actions > .nav-toggle {
    display: none !important;
  }
}
.brand {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 22px;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--color-ink);
  text-decoration: none;
  padding: 10px 14px;
  border: var(--border-chunky);
  background: var(--color-bg);
  box-shadow: var(--shadow-chunky-sm);
  /* min-width:0 + flex-shrink:1 lets the brand absorb any narrow-viewport
     squeeze before the actions cluster does. Combined with flex-shrink:0
     on the actions cluster, this guarantees the toggle+hamburger pair
     never wraps. The brand may visually compress; that's the trade. */
  flex-shrink: 1;
  min-width: 0;
}

/* ── Business-name disambiguation strip ────────────────────────────────
   Full-width band directly below the site header. Permanently displays
   the full legal business name "Don's Garage Automotive and Transmission"
   so visitors don't confuse the shop with the unrelated "Don's Garage
   Doors" business. Replaces the in-header tagline attempt from Waves
   D.1 / D.1.1 / D.1.2 (which couldn't fit cleanly across all viewport
   widths). The strip never competes for horizontal space — it gets the
   full row to itself. */
.biz-strip {
  background: var(--color-accent);
  border-top: var(--border-chunky);
  border-bottom: var(--border-chunky);
  padding: 10px 16px;
  text-align: center;
  line-height: 1;
}
.biz-strip__name {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 400;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-ink);
}
@media (max-width: 600px) {
  .biz-strip { padding: 8px 12px; }
  .biz-strip__name {
    font-size: 14px;
    letter-spacing: 0.04em;
  }
}
/* Dark-mode contrast: --color-ink inverts to white in dark mode, but
   white-on-accent-blue fails WCAG (matches the existing precedent for
   .btn--primary and .stat-panel--blue). Pin the strip text to
   --color-ink-on-dark in dark mode so it stays black on the blue band. */
[data-theme="dark"] .biz-strip__name {
  color: var(--color-ink-on-dark);
}

.nav {
  display: flex;
  gap: 24px;
  align-items: center;
  font-size: 14px;
}
.nav a {
  text-decoration: none;
  color: var(--color-ink);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.nav a:hover, .nav a[aria-current="page"] {
  color: var(--color-accent);
}
.nav .btn--primary {
  /* Smaller header variant. The mobile menu drops it to full-width.
     white-space:nowrap prevents the phone number from wrapping across
     two lines on narrow desktop viewports (regression caught after the
     D.1 tagline made the header content compete for horizontal room). */
  font-size: 14px;
  padding: 10px 18px;
  box-shadow: var(--shadow-chunky-sm);
  white-space: nowrap;
}

/* Mobile nav toggle. Same chunky-pill physics as .theme-toggle so the
   two buttons read as a matched pair in the .site-header__actions
   cluster. Padding 13px/11px is calibrated to make the box exactly
   48×48 on mobile, matching the toggle's mobile dimensions:
     width:  11 + 22(bar) + 11 + 4(border) = 48
     height: 13 + 18(3×2 bars + 4×2 margins between bars*) + 13 + 4 = 48
   *bar margin reduced from 4px to 2px so three bars + four 2px gaps
    add up to 18px content height. */
.nav-toggle {
  display: none;
  background: var(--color-bg);
  color: var(--color-ink);
  border: var(--border-chunky);
  border-radius: 6px;
  cursor: pointer;
  padding: 13px 11px;
  box-shadow: var(--shadow-chunky-sm);
  transition: transform 80ms ease, box-shadow 80ms ease;
}
.nav-toggle:hover {
  transform: translate(1px, 1px);
  box-shadow: 2px 2px 0 var(--color-ink);
}
.nav-toggle__bar { display: block; width: 22px; height: 2px; background: var(--color-ink); margin: 2px 0; }

@media (max-width: 820px) {
  .nav { display: none; }
  .nav-toggle { display: block; }
  .nav.is-open {
    display: flex;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    gap: 0;
    padding: 0;
    background: var(--color-bg);
    border-bottom: var(--border-chunky);
  }
  .nav.is-open a {
    padding: 16px 24px;
    border-top: 2px solid var(--color-ink);
    width: 100%;
  }
  .nav.is-open .btn--primary { margin: 16px 24px; }
}

/* ── Buttons ─────────────────────────────────────────────────────────────
   Three variants. Primary is the default phone CTA. Secondary is a chunky
   outline for low-emphasis-but-still-prominent calls. Ghost is a text-link
   chevron for tertiary "browse more" affordances — no shadow, no fill. */
.btn {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 18px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 14px 28px;
  border: var(--border-chunky);
  border-radius: 6px;
  text-decoration: none;
  cursor: pointer;
  line-height: 1.1;
  transition: transform 80ms ease, box-shadow 80ms ease, background-color 80ms ease;
}
.btn:hover {
  /* "Press in" — the box translates into where its shadow was, the shadow
     shrinks. Mimics the press-the-button physical metaphor without bouncy
     SaaS animations. */
  transform: translate(2px, 2px);
  box-shadow: var(--shadow-chunky-sm);
}

.btn--primary {
  background: var(--color-accent);
  color: var(--color-ink);
  box-shadow: var(--shadow-chunky-sm);
}
.btn--primary:hover {
  background: var(--color-accent);
  color: var(--color-ink);
  box-shadow: 2px 2px 0 var(--color-ink);
}

.btn--secondary {
  background: var(--color-bg);
  color: var(--color-ink);
  box-shadow: var(--shadow-chunky-sm);
}
.btn--secondary:hover {
  background: var(--color-bg);
  color: var(--color-ink);
  box-shadow: 2px 2px 0 var(--color-ink);
}

.btn--ghost {
  /* Tertiary text-link style. No shadow, no fill — just a chunky outline
     and the chevron. For "see all services →" / "browse coverage →"
     contexts where a full pill would over-shout. */
  background: transparent;
  color: var(--color-ink);
  border-color: var(--color-ink);
  box-shadow: none;
  padding: 12px 22px;
  font-size: 16px;
}
.btn--ghost:hover {
  background: var(--color-ink);
  color: var(--color-bg);
  transform: none;
  box-shadow: none;
}

.btn--ghost-on-dark {
  background: transparent;
  color: var(--color-ink-on-dark);
  border-color: var(--color-ink-on-dark);
  box-shadow: 4px 4px 0 var(--color-accent);
}
.btn--ghost-on-dark:hover {
  background: var(--color-ink-on-dark);
  color: var(--color-ink);
  box-shadow: 2px 2px 0 var(--color-accent);
}

/* Focus state — visible against the chunky shadow. Accent-blue outline
   offset 4px so it sits clearly outside both the border and the shadow. */
.btn:focus-visible,
.nav a:focus-visible,
.brand:focus-visible,
.nav-toggle:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 4px;
}
.section--dark .btn--ghost-on-dark:focus-visible {
  outline-color: var(--color-ink-on-dark);
}

/* ── Hero ──────────────────────────────────────────────────────────────── */
.hero {
  padding: 96px 0 80px;
}
.hero__eyebrow { color: var(--color-ink); }
.hero__headline {
  max-width: 920px;
}
.hero__sub {
  font-size: 19px;
  font-weight: 400;
  color: var(--color-ink);
  max-width: 620px;
  margin: 24px 0 36px;
  line-height: 1.5;
}
.hero__ctas { display: flex; gap: 16px; flex-wrap: wrap; }

@media (max-width: 520px) {
  .hero { padding: 64px 0 48px; }
  .hero__ctas .btn { width: 100%; text-align: center; }
}

/* ── Stat panels (trust signals on home, scope-of-work blocks elsewhere)
   Bordered + drop-shadowed panel with a big number on top and a short
   uppercase label underneath. Variants for color blocking. ── */
.stat-panel {
  border: var(--border-chunky);
  border-radius: 8px;
  box-shadow: var(--shadow-chunky);
  padding: 32px;
  background: var(--color-bg);
}
.stat-panel--blue  { background: var(--color-accent);  color: var(--color-ink); }
.stat-panel--steel { background: var(--color-steel);   color: var(--color-ink); }
.stat-panel--dark  { background: var(--color-bg-dark); color: var(--color-ink-on-dark); }
.stat-panel--dark .stat-panel__label { color: var(--color-ink-on-dark); }
.stat-panel--white { background: var(--color-bg);      color: var(--color-ink); }

.stat-panel__number {
  display: block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 56px;
  line-height: 1;
  letter-spacing: -0.01em;
}
.stat-panel__label {
  display: block;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 14px;
  margin-top: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  line-height: 1.3;
}

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 24px;
}

/* ── Card grids (services hub, area hub, home services teaser) ──────────
   The chunky-bordered card with hard offset shadow. Block-level link so
   the entire card is the click target. Hover "presses in." */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 32px;
}
.card {
  background: var(--color-bg);
  border: var(--border-chunky);
  border-radius: 8px;
  box-shadow: var(--shadow-chunky);
  padding: 24px;
  text-decoration: none;
  color: inherit;
  display: block;
  transition: transform 80ms ease, box-shadow 80ms ease;
}
a.card:hover {
  transform: translate(3px, 3px);
  box-shadow: 3px 3px 0 var(--color-ink);
  color: inherit;
}
a.card:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 4px;
}
.card h3 { margin: 0 0 12px; }
.card p { color: var(--color-ink); font-size: 16px; opacity: 0.85; }
.card__cta {
  display: inline-block;
  margin-top: 16px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-accent);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}

/* ── Reviews ──────────────────────────────────────────────────────────── */
.review {
  background: var(--color-bg);
  border: var(--border-chunky);
  border-radius: 8px;
  box-shadow: var(--shadow-chunky);
  padding: 24px;
  margin-bottom: 24px;
}
.review__stars {
  color: var(--color-accent);
  letter-spacing: 0.1em;
  margin-bottom: 12px;
  font-size: 18px;
}
.review__body { font-size: 17px; margin-bottom: 12px; color: var(--color-ink); }
.review__byline {
  font-size: 12px;
  font-weight: 700;
  color: var(--color-ink);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  opacity: 0.7;
}

.reviews-empty {
  border: var(--border-chunky);
  background: var(--color-steel);
  padding: 32px;
  text-align: center;
  color: var(--color-ink);
  font-size: 15px;
  border-radius: 8px;
  box-shadow: var(--shadow-chunky);
}

/* ── Footer ─────────────────────────────────────────────────────────────
   Dark-section treatment. White type, blue hover, blue-shadow ghost button
   for the directions link. */
.site-footer {
  background: var(--color-bg-dark);
  color: var(--color-ink-on-dark);
  border-top: var(--border-chunky);
  padding: 64px 0 32px;
  margin-top: 96px;
}
.site-footer__cols {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 32px;
  margin-bottom: 32px;
}
@media (max-width: 720px) {
  .site-footer__cols { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 480px) {
  .site-footer__cols { grid-template-columns: 1fr; }
}
.site-footer h4 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 16px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-ink-on-dark);
  margin: 0 0 16px;
}
.site-footer p { color: var(--color-ink-on-dark); opacity: 0.8; font-size: 15px; }
.site-footer ul { list-style: none; padding: 0; margin: 0; }
.site-footer li { margin-bottom: 8px; font-size: 15px; }
.site-footer a {
  text-decoration: none;
  color: var(--color-ink-on-dark);
  opacity: 0.8;
  font-weight: 500;
}
.site-footer a:hover { color: var(--color-accent); opacity: 1; }
.site-footer__phone {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 24px;
  letter-spacing: 0.02em;
  color: var(--color-accent);
  text-decoration: none;
  display: inline-block;
  margin-top: 8px;
}
.site-footer__phone:hover { color: var(--color-accent); text-decoration: underline; }
.site-footer__legal {
  border-top: 1px solid rgba(255, 255, 255, 0.2);
  padding-top: 20px;
  font-size: 11px;
  font-weight: 500;
  color: var(--color-ink-on-dark);
  opacity: 0.6;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  letter-spacing: 0.04em;
}

/* ── Page intros (used by every non-home page) ───────────────────────── */
.page-intro {
  padding: 64px 0 32px;
  border-bottom: var(--border-chunky);
}

/* ── Embedded map placeholder + iframe (Wave 1.22 partials) ──────────── */
.embedded-map {
  border: var(--border-chunky);
  border-radius: 8px;
  box-shadow: var(--shadow-chunky);
  padding: 0;
  overflow: hidden;
  background: var(--color-bg);
}
.embedded-map--placeholder {
  padding: 56px 32px;
  text-align: center;
  background: var(--color-steel);
  color: var(--color-ink);
}

/* ── Service-area inline links (homepage "Where we work" list) ───────── */
.area-links {
  display: flex;
  flex-wrap: wrap;
  gap: 20px 28px;
  margin-top: 24px;
}
.area-links a {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 22px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--color-accent);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
.area-links a:hover { color: var(--color-ink); }

/* ── Skip link / a11y ── */
.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  background: var(--color-ink);
  color: var(--color-bg);
  padding: 10px 14px;
  border: var(--border-chunky);
  text-decoration: none;
  font-weight: 700;
  z-index: 1000;
}
.skip-link:focus { top: 8px; left: 8px; }

/* ── Cinematic accent (transmission service page only) ───────────────────
   Atmospheric break between the page's prose intro and the social-proof
   sections. NOT a hero — the page's standard .page-intro hero leads. The
   outer .cinematic-accent is 300vh tall to give scroll runway. The inner
   .cinematic-accent__inner is sticky-pinned to the viewport while the outer
   scrolls past — JS reads scroll progress and drives a crossfade between
   the assembled and exploded transmission images, plus pops in clickable
   service labels at scroll thresholds. The chunky-card pattern is
   deliberately broken here: the photoreal images ARE the marquee, no
   surrounding frame. */
.cinematic-accent {
  position: relative;
  height: 300vh;
  background: var(--color-bg);
}
.cinematic-accent__inner {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 64px 24px;
  overflow: hidden;
  max-width: 1280px;
  margin: 0 auto;
}
.cinematic-accent__stage {
  position: relative;
  width: 100%;
  height: 80vh;
  max-width: 1100px;
}
.cinematic-accent__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  user-select: none;
  -webkit-user-drag: none;
  will-change: opacity, transform, filter;
}
.cinematic-accent__img--assembled {
  opacity: 1;
  transform: scale(1);
  filter: blur(0);
}
.cinematic-accent__img--exploded {
  opacity: 0;
  transform: scale(0.88);
}
/* Service labels — chunky pill that matches the rest of the site's button
   physics. JS toggles .is-visible at scroll thresholds; the CSS transition
   smooths the pop. */
.cinematic-accent__label {
  position: absolute;
  background: var(--color-accent);
  color: var(--color-ink);
  border: var(--border-chunky);
  border-radius: 4px;
  box-shadow: 3px 3px 0 var(--color-ink);
  padding: 6px 10px;
  font-family: var(--font-display);
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(0.9);
  transition: opacity 200ms ease, transform 200ms ease;
  will-change: opacity, transform;
  z-index: 6;
}
.cinematic-accent__label.is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translate(-50%, -50%) scale(1);
}
/* Static-fallback breakpoint: collapse to natural height, exploded-only
   static image. The assembled image gets display:none here AND its src is
   stripped in site.js so the network never even fetches it.

   900px (not 720px) — tablet portrait orientation (768–820px) doesn't have
   enough horizontal room for the desktop two-column layout to read well,
   so the 300vh sticky-pinned runway turns into mostly empty whitespace
   around a small image. JS guard in site.js uses the same 900px threshold;
   keep them in sync. */
@media (max-width: 900px) {
  .cinematic-accent { height: auto; }
  .cinematic-accent__inner {
    position: static;
    height: auto;
    padding: 32px 24px;
  }
  /* Stage flows naturally — no fixed height, no min-height. The exploded
     image's intrinsic aspect ratio determines the slot dimensions, which
     keeps the section tight against the image instead of leaving runway
     above and below. */
  .cinematic-accent__stage {
    height: auto;
    min-height: 0;
    aspect-ratio: 16 / 9;
  }
  .cinematic-accent__img--assembled { display: none; }
  .cinematic-accent__img--exploded {
    position: static;
    opacity: 1;
    transform: none;
    width: 100%;
    height: auto;
  }
  .cinematic-accent__label {
    opacity: 1;
    transform: translate(-50%, -50%);
    pointer-events: auto;
    font-size: 11px;
    padding: 4px 8px;
  }
}

/* ── Video accent (engine service page only) ─────────────────────────────
   Atmospheric V8 loop, transparent background — sits in the same slot as
   the transmission cinematic. No controls, no audio; the partial sets
   autoplay/loop/muted/playsinline. The transparent video shows whichever
   canvas color is active (white in light mode, near-black in dark) so
   no per-mode background overrides are needed. */
.video-accent {
  background: var(--color-bg);
  padding: 64px 24px;
}
.video-accent__inner {
  max-width: 1140px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
}
.video-accent__media {
  width: 100%;
  max-width: 800px;
  height: auto;
  display: block;
}
@media (max-width: 900px) {
  .video-accent { padding: 32px 16px; }
  .video-accent__media { max-width: 100%; }
}

/* ── Repair-or-replace calculator widget ────────────────────────────────
   Component overrides for the .rfc-* widget partial. Inherits typography
   and base button physics from site.css; only structural layout, fieldset
   chunky frames, and verdict color states need their own rules. Verdict
   colors mapped to the four-color palette (blue / steel / dark) instead
   of the source's traffic-light green/orange/red so we stay inside the
   site's palette discipline. */
.rfc-widget {
  max-width: 720px;
  margin: 0 auto;
}
.rfc-header { margin-bottom: 32px; }
.rfc-header h2 { margin: 0 0 8px; }
.rfc-header p { margin: 0; opacity: 0.85; }

.rfc-fieldset {
  background: var(--color-bg);
  border: var(--border-chunky);
  border-radius: 8px;
  box-shadow: var(--shadow-chunky-sm);
  padding: 24px 24px 28px;
  margin: 0 0 24px;
}
.rfc-fieldset legend {
  padding: 0 8px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-ink);
}

.rfc-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}
.rfc-full { grid-column: 1 / -1; }
@media (max-width: 540px) {
  .rfc-grid { grid-template-columns: 1fr; }
}

.rfc-field { display: flex; flex-direction: column; }
.rfc-field label {
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-bottom: 8px;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}
.rfc-help {
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--color-accent);
}

.rfc-field input,
.rfc-field select {
  font-family: var(--font-body);
  font-size: 16px;  /* avoid iOS auto-zoom on focus */
  color: var(--color-ink);
  background: var(--color-bg);
  border: 2px solid var(--color-ink);
  border-radius: 6px;
  padding: 10px 12px;
  width: 100%;
}
.rfc-field input:focus-visible,
.rfc-field select:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 2px;
  border-color: var(--color-accent);
}

.rfc-actions {
  text-align: right;
  margin-top: 16px;
}

.rfc-result { margin-top: 32px; }
.rfc-result:empty { display: none; }

/* Verdict cards. Border + tinted background communicate state; the
   verdict headline color reinforces. Four-color palette: fix=blue,
   tossup=steel, replace=dark/inverted. Rationale: position + intensity
   carry meaning, traffic-light semantics aren't required when each card
   has an explicit "Recommendation" label and a clear headline. */
.rfc-verdict {
  border: var(--border-chunky);
  border-radius: 8px;
  box-shadow: var(--shadow-chunky-sm);
  padding: 24px;
  margin-bottom: 20px;
}
.rfc-verdict-fix {
  border-color: var(--color-accent);
  background: rgba(66, 165, 245, 0.08);
}
.rfc-verdict-tossup {
  border-color: var(--color-ink);
  background: var(--color-steel);
}
.rfc-verdict-replace {
  border-color: var(--color-ink);
  background: var(--color-bg-dark);
  color: var(--color-ink-on-dark);
}
.rfc-verdict-label {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  opacity: 0.75;
  margin-bottom: 4px;
}
.rfc-verdict-headline {
  font-family: var(--font-display);
  font-size: clamp(28px, 4vw, 36px);
  font-weight: 400;
  line-height: 1;
  text-transform: uppercase;
  margin: 0 0 12px;
}
.rfc-verdict-fix    .rfc-verdict-headline { color: var(--color-accent); }
.rfc-verdict-tossup .rfc-verdict-headline { color: var(--color-ink); }
.rfc-verdict-replace .rfc-verdict-headline { color: var(--color-ink-on-dark); }

.rfc-confidence {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 4px 10px;
  border: 2px solid currentColor;
  border-radius: 4px;
  margin-bottom: 12px;
}
.rfc-summary { font-size: 17px; line-height: 1.5; margin: 0; }

/* Math breakdown — chunky framed list of computed values. */
.rfc-math {
  background: var(--color-bg);
  border: var(--border-chunky);
  border-radius: 8px;
  box-shadow: var(--shadow-chunky-sm);
  padding: 20px 24px;
  margin-bottom: 20px;
}
.rfc-math h4 {
  margin: 0 0 12px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.rfc-math-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 8px 0;
  border-bottom: 1px solid rgba(10, 10, 10, 0.12);
  gap: 16px;
}
.rfc-math-row:last-child { border-bottom: none; }
.rfc-math-label { font-size: 15px; }
.rfc-math-value {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

.rfc-considerations { margin-bottom: 20px; }
.rfc-considerations h4 {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin: 0 0 12px;
}
.rfc-considerations ul { margin: 0; padding-left: 20px; }
.rfc-considerations li { margin-bottom: 8px; line-height: 1.5; }

/* Replaces the original lead-capture form. Phone CTA only. */
.rfc-second-opinion {
  background: var(--color-bg);
  border: var(--border-chunky);
  border-radius: 8px;
  box-shadow: var(--shadow-chunky);
  padding: 28px;
  margin-top: 20px;
}
.rfc-second-opinion h4 {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 400;
  line-height: 1.15;
  text-transform: uppercase;
  margin: 0 0 12px;
}
.rfc-second-opinion p { margin: 0 0 20px; }

/* In-widget FAQ. The disclosure summaries map to the page-level FAQPage
   schema, but the user-visible disclosures are intentionally a subset. */
.rfc-faq {
  margin-top: 48px;
  padding-top: 32px;
  border-top: var(--border-chunky);
}
.rfc-faq h3 {
  margin: 32px 0 12px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: -0.01em;
}
.rfc-faq h3:first-child { margin-top: 0; }
.rfc-faq p, .rfc-faq ul { margin: 0 0 12px; }
.rfc-faq-item {
  border-bottom: 1px solid rgba(10, 10, 10, 0.15);
  padding: 12px 0;
}
.rfc-faq-item summary {
  cursor: pointer;
  font-weight: 700;
  padding: 8px 0;
  list-style: none;
}
.rfc-faq-item summary::-webkit-details-marker { display: none; }
.rfc-faq-item summary::after {
  content: " +";
  float: right;
  font-weight: 700;
  color: var(--color-accent);
}
.rfc-faq-item[open] summary::after { content: " −"; }
.rfc-faq-item[open] summary { margin-bottom: 8px; }

.rfc-error {
  color: var(--color-ink);
  font-weight: 700;
  font-size: 14px;
  margin-top: 4px;
}

/* Dark-mode tints for the verdict cards. The canvas inverts via tokens,
   but the rgba blue tint and the ink-on-dark contrast need explicit
   overrides because rgba doesn't follow tokens. */
[data-theme="dark"] .rfc-verdict-fix {
  background: rgba(90, 182, 248, 0.12);
}
[data-theme="dark"] .rfc-verdict-tossup {
  background: var(--color-steel);  /* gunmetal in dark */
  color: var(--color-ink);  /* white text on gunmetal */
}
[data-theme="dark"] .rfc-verdict-tossup .rfc-verdict-headline {
  color: var(--color-ink);  /* white in dark */
}
/* rfc-verdict-replace: --color-bg-dark inverts to white in dark mode,
   so the "dark" verdict card becomes a white card on the dark canvas.
   Border and shadow inherit white via --color-ink, which makes the
   chunky frame disappear into the white panel — restore it explicitly. */
[data-theme="dark"] .rfc-verdict-replace {
  background: var(--color-bg-dark);  /* white in dark */
  color: var(--color-ink-on-dark);   /* black in dark */
  border-color: var(--color-ink-on-dark);  /* black border on white */
  box-shadow: 4px 4px 0 var(--color-ink-on-dark);
}
[data-theme="dark"] .rfc-verdict-replace .rfc-verdict-headline {
  color: var(--color-ink-on-dark);
}
[data-theme="dark"] .rfc-math-row {
  border-bottom-color: rgba(255, 255, 255, 0.15);
}
[data-theme="dark"] .rfc-faq-item {
  border-bottom-color: rgba(255, 255, 255, 0.15);
}

/* Card placeholder variant — used on the resources hub for "coming soon"
   cards that aren't clickable. Sits as a passive sibling of the live .card. */
.card--placeholder {
  opacity: 0.5;
  pointer-events: none;
}

/* ── Transmission diagnostic quiz widget ──────────────────────────────────
   Same architectural pattern as the .rfc-* calculator: chunky question
   cards, four-color palette across the four confidence variants, dark-mode
   token-aware. Native radio inputs left as default so accessibility (focus
   ring, keyboard nav, screen-reader announcement) isn't broken by custom
   styling. */
.tq-widget {
  max-width: 720px;
  margin: 0 auto;
}

.tq-question {
  background: var(--color-bg);
  border: var(--border-chunky);
  border-radius: 8px;
  box-shadow: var(--shadow-chunky-sm);
  padding: 24px 24px 28px;
  margin: 0 0 24px;
}
.tq-question legend {
  padding: 0 8px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 17px;
  line-height: 1.3;
  color: var(--color-ink);
  display: inline-flex;
  align-items: baseline;
  gap: 12px;
}
.tq-q-number {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 24px;
  line-height: 1;
  color: var(--color-accent);
}
.tq-options {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 16px;
}
.tq-option {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 10px 14px;
  border: 2px solid transparent;
  border-radius: 6px;
  cursor: pointer;
  transition: background-color 80ms ease, border-color 80ms ease;
  line-height: 1.5;
}
.tq-option:hover {
  background: rgba(66, 165, 245, 0.06);
}
.tq-option input[type="radio"] {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  margin: 2px 0 0;
  accent-color: var(--color-accent);
  cursor: pointer;
}
.tq-option input[type="radio"]:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 3px;
}
/* Selected-state highlight: when the input is :checked, shift the
   wrapping label to the accent border. Uses :has() for the nice path
   in modern browsers; falls back gracefully (no highlight) where :has()
   isn't supported. */
.tq-option:has(input[type="radio"]:checked) {
  background: rgba(66, 165, 245, 0.10);
  border-color: var(--color-accent);
}

.tq-actions {
  text-align: right;
  margin-top: 8px;
}

.tq-result { margin-top: 32px; }
.tq-result:empty { display: none; }

/* Verdict cards — four confidence variants mapped to the four-color palette. */
.tq-verdict {
  border: var(--border-chunky);
  border-radius: 8px;
  box-shadow: var(--shadow-chunky-sm);
  padding: 28px;
  margin-bottom: 20px;
}
.tq-verdict--most-likely {
  border-color: var(--color-accent);
  background: rgba(66, 165, 245, 0.08);
}
.tq-verdict--likely {
  border-color: var(--color-ink);
  background: var(--color-steel);
}
.tq-verdict--possible {
  border-color: var(--color-ink);
  background: var(--color-bg);
}
.tq-verdict--unclear {
  border-color: var(--color-ink);
  background: var(--color-bg-dark);
  color: var(--color-ink-on-dark);
}
.tq-verdict--unclear a {
  color: var(--color-ink-on-dark);
  text-decoration: underline;
}
.tq-verdict--unclear a:hover { color: var(--color-accent); }

.tq-confidence {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 4px 10px;
  border: 2px solid currentColor;
  border-radius: 4px;
  margin-bottom: 12px;
}
.tq-verdict-headline {
  font-family: var(--font-display);
  font-size: clamp(26px, 3.4vw, 34px);
  font-weight: 400;
  line-height: 1.05;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  margin: 0 0 16px;
}
.tq-verdict--most-likely .tq-verdict-headline { color: var(--color-accent); }
.tq-verdict--likely      .tq-verdict-headline { color: var(--color-ink); }
.tq-verdict--possible    .tq-verdict-headline { color: var(--color-ink); }
.tq-verdict--unclear     .tq-verdict-headline { color: var(--color-ink-on-dark); }

.tq-verdict-why,
.tq-verdict-recommendation { font-size: 17px; line-height: 1.5; margin: 0 0 14px; }
.tq-verdict-why:last-child,
.tq-verdict-recommendation:last-child { margin-bottom: 0; }
.tq-runner-note {
  font-size: 15px;
  line-height: 1.5;
  margin: 14px 0 0;
  opacity: 0.85;
}

.tq-second-opinion {
  background: var(--color-bg);
  border: var(--border-chunky);
  border-radius: 8px;
  box-shadow: var(--shadow-chunky);
  padding: 28px;
}
.tq-second-opinion h4 {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 400;
  line-height: 1.15;
  text-transform: uppercase;
  margin: 0 0 12px;
}
.tq-second-opinion p { margin: 0 0 20px; }

/* Dark-mode tints — same logic as .rfc-verdict-* dark overrides. */
[data-theme="dark"] .tq-option:hover {
  background: rgba(90, 182, 248, 0.10);
}
[data-theme="dark"] .tq-option:has(input[type="radio"]:checked) {
  background: rgba(90, 182, 248, 0.16);
}
[data-theme="dark"] .tq-verdict--most-likely {
  background: rgba(90, 182, 248, 0.12);
}
[data-theme="dark"] .tq-verdict--likely {
  background: var(--color-steel);  /* gunmetal in dark */
  color: var(--color-ink);
}
[data-theme="dark"] .tq-verdict--likely .tq-verdict-headline {
  color: var(--color-ink);
}
[data-theme="dark"] .tq-verdict--possible {
  background: var(--color-bg);
}
[data-theme="dark"] .tq-verdict--unclear {
  /* --color-bg-dark inverts to white in dark mode → unclear panel
     becomes white-on-black-canvas. Restore the chunky frame with explicit
     ink-on-dark border + shadow so it doesn't disappear into the panel. */
  background: var(--color-bg-dark);
  color: var(--color-ink-on-dark);
  border-color: var(--color-ink-on-dark);
  box-shadow: 4px 4px 0 var(--color-ink-on-dark);
}
[data-theme="dark"] .tq-verdict--unclear .tq-verdict-headline {
  color: var(--color-ink-on-dark);
}
[data-theme="dark"] .tq-verdict--unclear a {
  color: var(--color-ink-on-dark);
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition: none !important; animation: none !important; }
  .btn:hover, a.card:hover { transform: none; }
  /* Cinematic accent: collapse the scroll runway, hold the exploded view
     visible from the start. No crossfade. */
  .cinematic-accent { height: auto; }
  .cinematic-accent__inner { position: static; height: auto; }
  .cinematic-accent__img--assembled { opacity: 0; }
  .cinematic-accent__img--exploded { opacity: 1; transform: scale(1); }
  .cinematic-accent__label { opacity: 1; transform: translate(-50%, -50%); pointer-events: auto; }
  /* Video accent: modern browsers honour reduced-motion for autoplay.
     Pause and freeze on the poster frame so the page is still legible
     for users with vestibular sensitivity. */
  .video-accent__media { animation-play-state: paused; }
}

/* ── Dark mode ────────────────────────────────────────────────────────────
   Token swap on [data-theme="dark"]. Set by the inline no-flash script in
   base.html (and by the toggle handler in site.js). NOT gated by
   @media (prefers-color-scheme: dark) — OS preference is translated into
   the data-theme attribute by the no-flash script, so light/dark/toggle
   all flow through one mechanism.

   Inversion semantics: --color-bg-dark and --color-ink-on-dark flip too.
   In light mode .section--dark is a black panel with white type. In dark
   mode it becomes a white panel with black type — same role (high-contrast
   band that breaks page rhythm), opposite hues. */
[data-theme="dark"] {
  --color-bg:          #0A0A0A;
  --color-ink:         #FFFFFF;
  --color-accent:      #5AB6F8;   /* slightly brighter for pop on dark */
  --color-steel:       #3A4148;   /* gunmetal — fills the "neutral support" role */
  --color-bg-dark:     #FFFFFF;   /* INVERT: section--dark becomes white */
  --color-ink-on-dark: #0A0A0A;   /* INVERT: black type on the now-white "dark" panel */
  --color-rule:        #FFFFFF;
}

/* Body background grid: faint white lines on the dark canvas instead of
   faint black lines on the light canvas. */
[data-theme="dark"] body {
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.04) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.04) 1px, transparent 1px);
}

/* Cards on a dark canvas need a slightly elevated surface so the chunky
   border has something visibly different to outline. Without this, the
   card and the canvas are the same hex and the card vanishes. */
[data-theme="dark"] .card {
  background: #1A1D22;
}

/* Buttons + panels that sit on the bright accent: keep BLACK text in dark
   mode for contrast (white on #5AB6F8 is only ~3:1; black on #5AB6F8 is
   ~10:1). Border + shadow inherit white from --color-ink, which preserves
   the chunky-shadow language against the dark canvas. */
[data-theme="dark"] .btn--primary {
  color: var(--color-ink-on-dark);
}
[data-theme="dark"] .stat-panel--blue {
  color: var(--color-ink-on-dark);
}

/* btn--ghost-on-dark sits inside .section--dark, which inverts to a white
   panel in dark mode. Button inverts with it: black border + black text on
   the white panel, blue shadow stays as the contrast pop. */
[data-theme="dark"] .btn--ghost-on-dark {
  color: var(--color-ink-on-dark);
  border-color: var(--color-ink-on-dark);
  box-shadow: 4px 4px 0 var(--color-accent);
}
[data-theme="dark"] .btn--ghost-on-dark:hover {
  background: var(--color-ink-on-dark);
  color: var(--color-bg-dark);
  box-shadow: 2px 2px 0 var(--color-accent);
}

/* Footer in dark mode flips to a white panel (because --color-bg-dark
   inverts to white). The legal hairline was rgba(white, .2) for the
   dark-on-light footer; on a now-white footer it's invisible. */
[data-theme="dark"] .site-footer__legal {
  border-top-color: rgba(0, 0, 0, 0.2);
}

/* ── Theme toggle button ───────────────────────────────────────────────
   Same chunky-pill physics as the rest of the site. Lives between the
   last nav link and the phone CTA. Shows the icon for the *destination*
   state — moon in light mode (click to go dark), sun in dark mode. */
.theme-toggle {
  background: var(--color-bg);
  color: var(--color-ink);
  border: var(--border-chunky);
  border-radius: 6px;
  box-shadow: 3px 3px 0 var(--color-ink);
  padding: 8px 10px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform 80ms ease, box-shadow 80ms ease;
}
.theme-toggle:hover {
  transform: translate(1px, 1px);
  box-shadow: 2px 2px 0 var(--color-ink);
}
.theme-toggle:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 4px;
}
/* Default (no [data-theme] attribute, e.g. JS off): show the moon so the
   button isn't blank. The button does nothing without JS, but at least
   reads as a button. */
.theme-toggle__icon { display: none; }
.theme-toggle__icon--moon { display: block; }
[data-theme="dark"] .theme-toggle__icon--moon { display: none; }
[data-theme="dark"] .theme-toggle__icon--sun  { display: block; }

@media (max-width: 820px) {
  /* The toggle now lives outside .nav so it stays visible regardless of
     menu state. Bump the padding so the tap target hits the 44×44 minimum
     (the desktop 8/10 padding lands at ~38×34, too small for thumbs). */
  .theme-toggle { padding: 13px; }
  /* Belt-and-suspenders: keep both buttons in the actions cluster
     guaranteed-inline at every viewport. */
  .theme-toggle,
  .nav-toggle { flex-shrink: 0; }
}

/* Very narrow phones (~≤380px): shrink the brand block to free width
   for the actions cluster. Main brand text remains; aria-label on the
   link still announces the full legal name to screen readers. */
@media (max-width: 380px) {
  .brand { font-size: 18px; padding: 8px 12px; }
}
