/* XN Car Detailing — site-wide theme (PandaHub-inspired light + brand dark).
   Loaded AFTER each page's inline <style> so it wins on cascade without
   having to edit ~70 individual stylesheets.

   Theme resolution (set on <html data-theme>) is done by the inline snippet
   in each page's <head>, so there is no flash of the wrong theme:
     data-theme="light" | "dark"   — explicit user choice from the menu
     (absent)                      — follow the OS via prefers-color-scheme
*/

/* ═══════════════ LAYOUT STABILITY ═══════════════
   Opening the menu or a modal sets overflow:hidden, which removes the
   scrollbar and used to shove the whole page sideways by its width.
   Reserving the gutter permanently means nothing shifts. */
html{scrollbar-gutter:stable}

/* ═══════════════ TOKENS ═══════════════ */

:root{
  /* rgb triples so translucent colours can flip with the theme */
  --fg:255,255,255;
  --accent-rgb:201,162,39;
  /* text that sits *on* the accent fill; near-black reads on gold */
  --on-gold:#1a1400;
  --on-gold-rgb:26,20,0;
  /* hover fill for cards; the pages only declare --card, not --card2 */
  --card2:#222222;

  --nav-bg:rgba(10,10,10,.92);
  /* the slide-out menu needs to stay opaque even where --nav-bg is see-through */
  --drawer-bg:#0d0d0f;
  --hero-bg:linear-gradient(135deg,#1c1c1e 0%,#0d0d0f 55%,#000 100%);
  --band-bg:linear-gradient(160deg,#0e0e10 0%,#15130c 55%,#0a0a0a 100%);
  --article-hero-bg:linear-gradient(135deg,#0a0a0a 0%,#1a1508 60%,#0a0a0a 100%);
  --page-hero-bg:linear-gradient(135deg,#0a0a0a 0%,#0f1a35 60%,#0a0a0a 100%);
  --footer-bg:#050505;
  --modal-bg:linear-gradient(160deg,#15151a,#0c0c0f);
  --scrim:rgba(0,0,0,.72);

  --shadow-sm:none;
  --shadow-md:none;
  --logo-filter:invert(1);
  --radius:10px;
  --radius-lg:16px;

  /* Dark is the baseline, so it also covers "no explicit choice + OS is dark".
     The light blocks below re-declare this, and html[data-theme="dark"] repeats
     it for the explicit case. Without it, form controls and scrollbars render
     light on a dark page for OS-dark visitors who never touched the toggle. */
  color-scheme:dark;
}

html[data-theme="light"]{
  /* PandaHub blue. Deep enough that white button text and accent-coloured
     links both clear 4.5:1 on a white page. */
  --orange:#0369a1;         /* 5.9:1 under white button text */
  --orange-dark:#075985;
  --orange-light:#0369a1;   /* used as link/text colour — needs contrast */
  --gold:#0369a1;
  --on-gold:#ffffff;--on-gold-rgb:255,255,255;

  --black:#ffffff;          /* page background */
  --dark:#f5f9fc;           /* alternating section background */
  --card:#ffffff;
  --card2:#eef4f9;
  --border:rgba(15,23,42,.11);

  --white:#0f172a;          /* NOTE: --white is a *text* token */
  --gray:#4d5b6e;
  --light-gray:#334155;

  --fg:15,23,42;
  --accent-rgb:14,165,233;

  /* opaque: the logo PNG has a baked-in white background, which shows as a
   visible patch against a translucent nav */
  --nav-bg:#ffffff;
  --drawer-bg:#ffffff;
  --hero-bg:linear-gradient(135deg,#f2f8fd 0%,#e3eefb 55%,#f2f8fd 100%);
  --band-bg:linear-gradient(160deg,#f0f7fd 0%,#e2eefb 55%,#f0f7fd 100%);
  --article-hero-bg:linear-gradient(135deg,#f4f9fd 0%,#e6f1fb 60%,#f4f9fd 100%);
  --page-hero-bg:linear-gradient(135deg,#f4f9fd 0%,#e6f1fb 60%,#f4f9fd 100%);
  --footer-bg:#f2f6fa;
  --modal-bg:#ffffff;
  --scrim:rgba(15,23,42,.45);

  --shadow-sm:0 1px 2px rgba(15,23,42,.05),0 1px 3px rgba(15,23,42,.06);
  --shadow-md:0 4px 12px rgba(15,23,42,.07),0 12px 32px rgba(15,23,42,.06);
  --logo-filter:none;

  color-scheme:light;
}

/* Same palette, applied when the visitor has no explicit choice and their OS
   is set to light. Kept as a duplicate block because CSS cannot alias. */
@media(prefers-color-scheme:light){
  html:not([data-theme]){
    --orange:#0369a1;--orange-dark:#075985;--orange-light:#0369a1;
    --gold:#0369a1;--on-gold:#ffffff;--on-gold-rgb:255,255,255;
    --black:#ffffff;--dark:#f5f9fc;--card:#ffffff;--card2:#eef4f9;
    --border:rgba(15,23,42,.11);
    --white:#0f172a;--gray:#4d5b6e;--light-gray:#334155;
    --fg:15,23,42;--accent-rgb:14,165,233;
    /* opaque: the logo PNG has a baked-in white background, which shows as a
   visible patch against a translucent nav */
  --nav-bg:#ffffff;
  --drawer-bg:#ffffff;
    --hero-bg:linear-gradient(135deg,#f2f8fd 0%,#e3eefb 55%,#f2f8fd 100%);
    --band-bg:linear-gradient(160deg,#f0f7fd 0%,#e2eefb 55%,#f0f7fd 100%);
    --article-hero-bg:linear-gradient(135deg,#f4f9fd 0%,#e6f1fb 60%,#f4f9fd 100%);
    --page-hero-bg:linear-gradient(135deg,#f4f9fd 0%,#e6f1fb 60%,#f4f9fd 100%);
    --footer-bg:#f2f6fa;--modal-bg:#ffffff;--scrim:rgba(15,23,42,.45);
    --shadow-sm:0 1px 2px rgba(15,23,42,.05),0 1px 3px rgba(15,23,42,.06);
    --shadow-md:0 4px 12px rgba(15,23,42,.07),0 12px 32px rgba(15,23,42,.06);
    --logo-filter:none;
    color-scheme:light;
  }
}

html[data-theme="dark"]{ color-scheme:dark }


/* ═══════════════ HARDCODED BACKGROUNDS → TOKENS ═══════════════
   These rules exist verbatim in every page's inline <style> with a baked-in
   dark colour. Re-declaring them here (later in the cascade, same specificity)
   is what lets one file re-theme the whole site. */

/* The pages supply their own backdrop-filter on <nav>; we only retint it.
   (That blur is switched off at mobile widths — see the drawer rules below.) */
nav{
  background:var(--nav-bg)!important;
  /* Chrome re-rasterises a backdrop-filter in tiles as the page scrolls, which
     showed up as the bar blurring in and out with a seam down the middle.
     Promoting nav to its own compositing layer makes the filter resolve once. */
  transform:translateZ(0);
  will-change:backdrop-filter;
  /* breathing room between the grouped actions on the right */
  gap:.6rem;
}
.sticky-cta{background:var(--nav-bg)}
.hero-bg{background:var(--hero-bg)}
.page-hero{background:var(--page-hero-bg)}
.article-hero{background:var(--article-hero-bg)}
.cta-banner,.cta-strip,.article-cta{background:var(--band-bg)}
footer{background:var(--footer-bg)}
.quote-modal,.xnq-modal{background:var(--modal-bg)}
#xn-preloader{background:var(--black)}
#xnQuoteOverlay{background:var(--scrim)}

/* City pages bake these colours in. The rgba(--fg) form keeps the dark look
   pixel-identical while flipping to dark-on-white in light mode. */
.local-context-inner h2{color:var(--white)}
.local-context-inner p{color:rgba(var(--fg),.63)}
.hood-chip{
  background:rgba(var(--accent-rgb),.12);
  border-color:rgba(var(--accent-rgb),.28);
  color:var(--orange-light);
}

/* Remaining light-on-dark text baked into individual pages. Each of these sits
   on a themed surface, so it has to follow the palette rather than stay white. */
.xn-pre-logo{color:var(--white)}
.xn-pre-sub{color:var(--gray)}
.xn-spinner{border-top-color:var(--orange)}
.article-body h3,.quote-modal h3,.cta-banner h2,.um-title,.addon-check,.upsell-chk-mark{color:var(--white)}
.hc-list li,.q-tos{color:var(--light-gray)}
form label,.um-footer-note{color:var(--gray)}

/* The hero pill hardcodes gold. It sits on the photo, so it picks up the
   brightened accent that the overlay scope already supplies. */
.limited-pill{background:rgba(var(--accent-rgb),.12);border-color:rgba(var(--accent-rgb),.4);color:var(--orange-light)}
.limited-pill .dot{background:var(--orange-light)}

/* The city-page services banner is filled with the accent and hardcodes the
   near-black text that only reads on gold. */
.services-header,.services-header a,.strip,.rev-av,.featured-tag{color:var(--on-gold)}

/* Same story on the featured price card, which is filled with the accent. */
.price-card.featured .price-amount,.price-card.featured .price-name,
.price-card.featured .price-list li::before,
.price-card.featured details.pkg-details>summary{color:var(--on-gold)}
.price-card.featured .price-desc{color:rgba(var(--on-gold-rgb),.85)}
.price-card.featured .price-list li{color:rgba(var(--on-gold-rgb),.85);border-bottom-color:rgba(var(--on-gold-rgb),.18)}

/* Accent icons carry the gold as a fill="" presentation attribute, which CSS
   outranks. Review stars are text glyphs, so they are not caught by this.
   Each falls back to its own hex, so /book/ and /quote/ — which have no
   --orange and re-tint these icons themselves — are left untouched. */
svg path[fill="#d4af37"]{fill:var(--orange,#d4af37)}
svg path[fill="#c9a227"]{fill:var(--orange,#c9a227)}
svg path[fill="#e3c15c"]{fill:var(--orange,#e3c15c)}
/* same name as the page's keyframes, declared later, so this one wins */
@keyframes pulseDot{0%{box-shadow:0 0 0 0 rgba(var(--accent-rgb),.55)}70%{box-shadow:0 0 0 8px rgba(var(--accent-rgb),0)}100%{box-shadow:0 0 0 0 rgba(var(--accent-rgb),0)}}


/* ═══════════════ PANDAHUB-STYLE SURFACES ═══════════════ */

/* Cards get a real border + soft shadow in light mode instead of relying on a
   lighter-than-background fill, which does not exist on white. */
.service-card,.price-card,.review-card,.area-card,.blog-card,.feat-card,
.step-card,.faq-item,.city-card,.post-card,.cmp,.chart{
  border-radius:var(--radius-lg);
  box-shadow:var(--shadow-sm);
}
.service-card:hover,.price-card:hover,.blog-card:hover,.area-card:hover,.post-card:hover{
  box-shadow:var(--shadow-md);
}

/* Brand logos are white PNG/SVG art — un-invert them on light backgrounds. */
.logo-strip img,.brand-logos img,.nav-logo img{filter:var(--logo-filter,none)}


/* ═══════════════ PANDAHUB-STYLE BUTTONS ═══════════════ */

.btn-orange,.nav-book,.cta-quote,.btn-primary,.submit-btn,.hero-flash-btn{
  border-radius:var(--radius);
  font-weight:800;
  letter-spacing:.02em;
  transition:background .18s ease,transform .15s ease,box-shadow .18s ease;
}
.btn-orange,.nav-book,.btn-primary{
  background:var(--orange);
  color:var(--on-gold,#1a1400);
  box-shadow:var(--shadow-sm);
}
.btn-orange:hover,.nav-book:hover,.btn-primary:hover{
  background:var(--orange-dark);
  transform:translateY(-1px);
  box-shadow:var(--shadow-md);
}
.btn-orange:active,.nav-book:active{transform:none}

/* The package cards hardcode a near-black hover fill, which turned them black
   on the light theme. */
.price-card:hover{background:var(--card2)}
/* Same story on the other hover states that bake in the brand gold or a white
   outline — both of which disappear or clash on a white page. */
details.pkg-details>summary:hover{background:rgba(var(--accent-rgb),.08)}
.blog-card:hover,.featured a:hover{border-color:rgba(var(--accent-rgb),.5)}

.btn-outline{
  border-radius:var(--radius);
  border:2px solid var(--orange);
  color:var(--orange);
  background:transparent;
  transition:background .18s,color .18s;
}
.btn-outline:hover{background:var(--orange);color:var(--on-gold,#1a1400);border-color:var(--orange)}

/* The article CTA button. A literal white fill vanished on the light band and a
   card-coloured fill vanished on the dark one, so it is the filled accent button
   in both themes — the same treatment as BOOK NOW. The html prefix outranks the
   copy of .btn-white that the article pages declare inline. */
html .btn-white{
  border-radius:var(--radius);
  background:var(--orange);
  color:var(--on-gold);
  border:1px solid transparent;
  box-shadow:var(--shadow-sm);
}
html .btn-white:hover{background:var(--orange-dark);box-shadow:var(--shadow-md);transform:translateY(-1px)}


/* ═══════════════ NAV: call button + hamburger ═══════════════ */

/* the hamburger is the only menu affordance, at every width */
.nav-call,.nav-toggle{display:flex}

/* <nav> is justify-content:space-between, so its three or four children spread
   across the whole bar and the buttons drifted into the middle. Packing them to
   the start and letting the logo absorb the slack keeps the logo hard left and
   the actions together as one tidy group, whatever the child count.
   Targeting the first child rather than a logo class because the pages disagree
   on that class (.nav-logo on the city pages, .nav-logo-text on the blog). */
nav{justify-content:flex-start}
nav>:first-child{margin-right:auto}

/* On anything wider than a phone the Book Now button is the only CTA the bar
   needs; the tap-to-call shortcut only earns its space on a handset. */
@media(min-width:701px){
  .nav-call{display:none}
}

.nav-call{
  align-items:center;gap:.4rem;
  padding:.55rem .95rem;border-radius:var(--radius);
  font-weight:800;font-size:.8rem;letter-spacing:.03em;text-transform:uppercase;
  border:2px solid currentColor;color:var(--orange,#c9a227);
  background:transparent;transition:background .2s;
}
.nav-call svg{width:15px;height:15px;flex-shrink:0;fill:currentColor}

.nav-toggle{
  flex-direction:column;justify-content:center;gap:5px;
  width:42px;height:42px;padding:0 9px;margin-left:.15rem;
  background:transparent;border:1px solid var(--border);border-radius:var(--radius);
  cursor:pointer;flex-shrink:0;color:var(--white);
  z-index:1002;
}
.nav-toggle span{
  display:block;height:2px;width:100%;border-radius:2px;
  background:currentColor;
  transition:transform .25s ease,opacity .2s ease;
}
.nav-toggle.open span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.nav-toggle.open span:nth-child(2){opacity:0}
.nav-toggle.open span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* dim the page behind the open drawer */
.nav-scrim{
  position:fixed;inset:0;z-index:998;
  background:var(--scrim);
  opacity:0;visibility:hidden;transition:opacity .25s ease,visibility .25s;
}
.nav-scrim.open{opacity:1;visibility:visible}

/* slide-in side drawer, at every width. site.js reparents .nav-links to <body>
   so it is no longer a descendant of <nav>. */
body>.nav-links{
  display:flex!important;flex-direction:column;align-items:stretch;gap:0;
  position:fixed;top:0;right:0;bottom:0;left:auto;
  width:min(340px,86vw);
  padding:5.25rem 1.5rem 2rem;
  background:var(--drawer-bg,#0d0d0f);
  border-left:1px solid var(--border);
  box-shadow:-18px 0 46px rgba(0,0,0,.28);
  overflow-y:auto;z-index:1001;
  transform:translateX(100%);
  visibility:hidden;pointer-events:none;
  transition:transform .28s cubic-bezier(.4,0,.2,1),visibility .28s;
}
body>.nav-links.open{transform:translateX(0);visibility:visible;pointer-events:auto}
body>.nav-links a{
  padding:.95rem .2rem;font-size:1rem;font-weight:600;
  color:var(--white);
  border-bottom:1px solid var(--border);
}

@media(max-width:768px){
  .nav-book{padding:.55rem 1rem!important;font-size:.8rem!important}
}

@media(max-width:400px){
  .nav-call{padding:.5rem .7rem;font-size:.72rem}
  .nav-call .nav-call-txt{display:none}
  .nav-logo img{width:34px!important;height:34px!important}
  .nav-logo-text{font-size:.95rem!important}
}


/* ═══════════════ DARK MODE SWITCH (inside the drawer) ═══════════════ */

.xn-theme{
  margin-top:1.25rem;padding-top:1.1rem;
  border-top:1px solid var(--border);
}
.xn-switch{
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  width:100%;padding:.6rem .2rem;
  background:none;border:none;cursor:pointer;
  font-family:inherit;font-size:1rem;font-weight:600;color:var(--white);
}
.xn-switch-track{
  position:relative;flex:0 0 auto;
  width:46px;height:26px;border-radius:999px;
  /* not var(--dark) — the homepage glass palette sets that to transparent */
  background:rgba(var(--fg),.15);border:1px solid var(--border);
  transition:background .2s,border-color .2s;
}
.xn-switch-thumb{
  position:absolute;top:2px;left:2px;
  width:20px;height:20px;border-radius:50%;
  background:var(--white);
  transition:transform .2s ease,background .2s;
}
.xn-switch[aria-checked="true"] .xn-switch-track{background:var(--orange);border-color:var(--orange)}
.xn-switch[aria-checked="true"] .xn-switch-thumb{transform:translateX(20px);background:var(--on-gold,#fff)}
.xn-switch:focus-visible{outline:2px solid var(--orange);outline-offset:3px;border-radius:var(--radius)}


/* ═══════════════ TEXT OVER PHOTOGRAPHY ═══════════════
   These blocks sit on a photo behind a dark scrim, so their text has to stay
   light in *every* theme. Redefining the tokens on the container re-themes
   everything inside it, because custom properties inherit. */
.hero:has(.hero-bg),.hero-content,.svc-overlay,.gal-card,.work-card{
  /* re-assert colour here: headings inherit body's *computed* colour, so
     redefining --white alone would never reach them */
  color:var(--white);
  --white:#ffffff;
  --gray:rgba(255,255,255,.74);
  --light-gray:rgba(255,255,255,.9);
  --fg:255,255,255;
  --border:rgba(255,255,255,.14);
  --card:rgba(255,255,255,.06);
  --dark:rgba(255,255,255,.08);
}
/* on a dark photo the light-mode accent is too dark to read — brighten it */
html[data-theme="light"] .hero:has(.hero-bg),html[data-theme="light"] .hero-content,
html[data-theme="light"] .svc-overlay,html[data-theme="light"] .gal-card{
  /* the brightened accent is now too light for white button text — flip the
     on-accent colour to a deep blue so buttons over the photo still read */
  --orange-light:#7dd3fc;--orange:#38bdf8;--on-gold:#05314a;
}
@media(prefers-color-scheme:light){
  html:not([data-theme]) .hero:has(.hero-bg),html:not([data-theme]) .hero-content,
  html:not([data-theme]) .svc-overlay,html:not([data-theme]) .gal-card{
    --orange-light:#7dd3fc;--orange:#38bdf8;--on-gold:#05314a;
  }
}
/* the scrim itself must not be re-tinted by the light palette */
.hero-overlay{background:linear-gradient(to bottom,rgba(0,0,0,.55) 0%,rgba(0,0,0,.65) 60%,rgba(0,0,0,.9) 100%)}

/* Anything sitting directly on the accent colour keeps readable contrast. */
.btn-orange,.nav-book,.btn-primary,.hero-flash-btn,.cta-quote{color:var(--on-gold,#1a1400)}

/* ── Homepage light-mode frosted-glass try-out ────────────────────────────────
   Solid white panels on a white page read flat, so on the homepage (body
   .home-glass) the light palette swaps them for one translucent white over one
   flat tinted wash. Every white surface uses --glass, so they all render the
   same white. Remove the body class to revert. */
html[data-theme="light"] body.home-glass{
  --glass:rgba(255,255,255,.55);
  /* the page wash is a single flat tint, so --glass composites to the same
     colour no matter which section it sits in */
  --black:transparent;
  --dark:transparent;
  --card:var(--glass);
  /* the bar is the one glass surface with fast-moving content behind it, so at
     --glass's alpha it visibly pulsed light/dark on every scroll. A denser white
     keeps the frosted look but holds a steady colour (and keeps the navy logo
     legible when a dark photo passes underneath). */
  --nav-bg:rgba(255,255,255,.88);
  /* hover needs to differ from --glass or it would read as no change at all */
  --card2:rgba(255,255,255,.8);
  --border:rgba(15,23,42,.1);
  background:#dbe7f4;
}
/* the frosting, plus the panels whose token went transparent above and so need
   --glass applied directly. .svc-card is skipped — a photo covers it, so
   blurring it would only cost paint time. */
html[data-theme="light"] .home-glass .step{background:var(--glass)}
html[data-theme="light"] .home-glass .why-slide,
html[data-theme="light"] .home-glass .area-card,
html[data-theme="light"] .home-glass .city-chip,
html[data-theme="light"] .home-glass .review-card,
html[data-theme="light"] .home-glass .price-card,
html[data-theme="light"] .home-glass .step,
html[data-theme="light"] .home-glass .blog-card{
  backdrop-filter:blur(18px) saturate(1.4);
  -webkit-backdrop-filter:blur(18px) saturate(1.4);
}
/* Same treatment for the visitor who never touched the toggle and whose OS is
   set to light. Without this pair the homepage was the one page that looked
   different depending on HOW you got into light mode: the toggle gave the blue
   frosted wash, the OS setting gave flat white. Duplicated because CSS cannot
   alias a selector across a media query. */
@media(prefers-color-scheme:light){
  html:not([data-theme]) body.home-glass{
    --glass:rgba(255,255,255,.55);
    --black:transparent;
    --dark:transparent;
    --card:var(--glass);
    --nav-bg:rgba(255,255,255,.88);
    --card2:rgba(255,255,255,.8);
    --border:rgba(15,23,42,.1);
    background:#dbe7f4;
  }
  html:not([data-theme]) .home-glass .step{background:var(--glass)}
  html:not([data-theme]) .home-glass .why-slide,
  html:not([data-theme]) .home-glass .area-card,
  html:not([data-theme]) .home-glass .city-chip,
  html:not([data-theme]) .home-glass .review-card,
  html:not([data-theme]) .home-glass .price-card,
  html:not([data-theme]) .home-glass .step,
  html:not([data-theme]) .home-glass .blog-card{
    backdrop-filter:blur(18px) saturate(1.4);
    -webkit-backdrop-filter:blur(18px) saturate(1.4);
  }
}

/* ═══════════════ STACKED HERO ═══════════════
   Shared by the homepage and the 31 city pages. Each of those pages carries its
   own inline copy of the base hero rules; this file loads after all of them, so
   equal specificity here wins and one edit covers all 32. */

/* Accent for copy that sits ON the hero photo. The photo scrim is always dark,
   so this cannot be --orange: the light palette turns that into a navy blue that
   vanishes against the photo. Values are the same on-photo sky blue site.css
   already uses for .hero-content and .gal-card above. */
.hero-stacked{--on-photo-accent:#e0bd4a}
html[data-theme="light"] .hero-stacked{--on-photo-accent:#7dd3fc}
@media(prefers-color-scheme:light){
  html:not([data-theme]) .hero-stacked{--on-photo-accent:#7dd3fc}
}

@media(min-width:901px){
  /* DESKTOP HERO — the badge, eyebrow and headline sit on the photo and the two
     CTAs sit directly under it, so the car and both actions are visible without
     scrolling. Previously the photo was a full 3:2 block (~747px tall at 1120px
     wide on the city pages) with every word stacked beneath it, which pushed the
     buttons far below the fold.

     .hero-copy is display:contents so its children become grid items of the
     section itself. That is what allows the first three to overlap the photo
     while the rest flow underneath, without editing the HTML on 32 pages. */
  .hero-stacked{
    display:grid;
    grid-template-columns:min(1120px,92vw);
    /* row 1 is slack — it soaks up whatever height the photo has beyond the
       three text rows, which pins them to the bottom of the photo */
    grid-template-rows:1fr auto auto auto;
    justify-content:center;
    text-align:center;
  }
  .hero-stacked .hero-copy{display:contents}

  .hero-stacked .hero-photo{
    grid-column:1;grid-row:1/5;z-index:0;position:relative;
    margin:0;max-width:none;
    /* Sized off the viewport height, not the image ratio, so the CTAs sitting
       under it stay on the first screen at any window size. The ceiling is what
       keeps the car looking like a car — much shorter than this and a 3:2 shot
       crops into a letterbox strip. */
    min-height:clamp(380px,60vh,600px);
    border-radius:20px;overflow:hidden;
    box-shadow:0 24px 60px rgba(0,0,0,.28);
  }
  /* Absolute, so the box takes its height from the grid rows rather than from
     the image's own 3:2 ratio — that ratio is what made the photo enormous. */
  .hero-stacked .hero-photo img{
    position:absolute;inset:0;
    width:100%;height:100%;
    aspect-ratio:auto;object-fit:cover;
  }
  /* Light at the top so the car reads, deep at the bottom where the headline is. */
  .hero-stacked .hero-photo::after{
    content:"";position:absolute;inset:0;
    background:linear-gradient(180deg,
      rgba(10,10,10,.12) 0%,
      rgba(10,10,10,.28) 40%,
      rgba(10,10,10,.60) 72%,
      rgba(10,10,10,.88) 100%);
  }

  .hero-stacked .limited-pill,
  .hero-stacked .hero-eyebrow{grid-column:1;z-index:1;justify-self:center}
  .hero-stacked .limited-pill{grid-row:2;margin-bottom:.9rem}
  .hero-stacked .hero-eyebrow{grid-row:3;margin-bottom:.7rem}
  .hero-stacked .hero-copy h1{
    grid-column:1;grid-row:4;z-index:1;
    padding:0 1.5rem;margin-bottom:clamp(1.5rem,3.5vh,2.75rem);
  }

  /* On the photo, so fixed light values rather than theme tokens. */
  .hero-stacked .hero-copy h1{
    color:#fff;
    text-shadow:0 2px 20px rgba(0,0,0,.7),0 1px 3px rgba(0,0,0,.85);
  }
  .hero-stacked .hero-copy h1 span,
  .hero-stacked .hero-eyebrow{color:var(--on-photo-accent)}
  /* It sits high on the photo where the scrim is deliberately thin, so it needs
     to carry its own contrast — otherwise it is gold on yellow bodywork. */
  .hero-stacked .hero-eyebrow{text-shadow:0 1px 10px rgba(0,0,0,.95),0 1px 3px rgba(0,0,0,.9)}
  .hero-stacked .hero-eyebrow::before{background:var(--on-photo-accent)}
  /* Its own chip: the top of the scrim is deliberately light so the car shows,
     which left the old translucent gold pill unreadable over bodywork. */
  .hero-stacked .limited-pill{
    background:rgba(10,10,10,.6);
    border-color:rgba(255,255,255,.28);
    color:#fff;
    backdrop-filter:blur(6px);
    -webkit-backdrop-filter:blur(6px);
  }
  .hero-stacked .limited-pill .dot{background:var(--on-photo-accent)}

  /* Everything from here down sits on the page background, below the photo, so
     it keeps the theme tokens. `order` puts the CTAs first; auto-placement then
     fills rows 5+ in that order, since rows 1-4 are already taken. */
  .hero-stacked .hero-btns{order:1;justify-self:center;margin:1.4rem 0 0}
  /* Spacing here is padding, not margin: the city pages give their second
     paragraph an inline margin-top:-.5rem to tighten it against the first. In
     block flow that just trimmed a gap, but every grid item gets its own row, so
     as a margin it would drag the second paragraph up over the first. As padding
     the inline rule still tightens the pair without overlapping them. */
  .hero-stacked .hero-sub{order:2;justify-self:center;margin:0 auto;padding:1.5rem 1.5rem 0}
  /* The only one of these that has a visible box, so it is the only one that
     cannot take its row spacing as padding — padding here inflates the pill
     itself and makes it top-heavy. It has no inline margin to fight, so margin
     is safe. Its own padding is tightened to keep the badge compact. */
  .hero-stacked .hero-rating{order:3;justify-self:center;margin:1.5rem 0 0;padding:.5rem 1.2rem;font-size:.85rem}
  .hero-stacked .hero-points{order:4;justify-self:center;margin:0;padding:1.6rem 1.5rem 0}
  .hero-stacked .hero-trust{order:5;justify-self:center;margin:0;padding:1.6rem 1.5rem 0}
  .hero-stacked .hero-sub,
  .hero-stacked .hero-points,
  .hero-stacked .hero-trust{max-width:760px}

  /* Breathing room before the yellow service strips butt up against the hero.
     The inline base rule on all 32 pages sets this with !important. */
  .hero-stacked{padding-bottom:7rem!important}
}

/* ═══════════════ WHY US (static grid) ═══════════════
   The homepage and the 31 city pages carry a JS carousel version of this, with
   its CSS and script inline-duplicated on each page. The pages added here
   (/about/, /membership/, /blog/) get a static 4-up grid of the same points
   instead: all four are visible at once, it needs no script, and it cannot
   double-bind the #whyCarousel handlers those other pages already run.

   Self-contained on purpose — the three pages use different section wrappers
   (.sec-dark/.inner, .apply/.wrap, bare) so this brings its own layout rather
   than inheriting whichever one it lands in. Colours are theme tokens because
   this sits on the page background, not on a photo. */
.why-us{padding:clamp(3.5rem,8vh,6rem) 1.5rem;background:var(--dark)}
.why-us-inner{max-width:1120px;margin:0 auto;text-align:center}
.why-us .eye{
  font-size:.68rem;font-weight:800;letter-spacing:.24em;text-transform:uppercase;
  color:var(--orange);margin-bottom:.9rem;
}
.why-us h2{font-size:clamp(1.7rem,3.6vw,2.6rem);margin:0 0 3rem;color:var(--white)}
.why-us-grid{
  display:grid;gap:1.25rem;
  grid-template-columns:repeat(4,1fr);
  text-align:left;
}
@media(max-width:900px){.why-us-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){.why-us-grid{grid-template-columns:1fr}}
.why-card{
  background:var(--card);border:1px solid var(--border);border-radius:16px;
  padding:1.75rem 1.5rem;
  transition:transform .2s,border-color .2s;
}
.why-card:hover{transform:translateY(-4px);border-color:var(--orange)}
/* currentColor, not a hardcoded gold — the light palette needs to recolour these
   along with everything else on the page background. */
.why-card svg{width:40px;height:40px;color:var(--orange);display:block;margin-bottom:1rem}
.why-card h3{font-size:1.05rem;margin:0 0 .55rem;color:var(--white)}
.why-card p{font-size:.9rem;line-height:1.6;margin:0;color:var(--gray)}

/* ═══════════════ PLAN COMPARISON TABLE ═══════════════
   Replaces the old single-plan `.anchor` box on /membership/, which compared
   only Signature and did it against a price that was never filled in — the
   literal string "[NON-MEMBER VISIT PRICE]" shipped to visitors.

   This compares the four plans to each other on numbers that are all derived
   from the published prices, so nothing here needs a figure the site does not
   already state. A "vs booking it yourself" column would need a real one-off
   maintenance-visit rate; the full-detail prices ($125/$225/$299) are NOT that,
   because a monthly maintenance visit is a lighter job than a first-time full
   detail, and using them would overstate the saving. */
.plan-compare{
  max-width:940px;margin:2.6rem auto 0;
  background:var(--card);border:1px solid rgba(var(--accent-rgb),.3);
  border-radius:var(--radius-lg);padding:1.7rem 1.8rem;text-align:left;
}
.plan-compare h3{font-size:1.05rem;font-weight:900;margin:0 0 1.1rem;color:var(--white)}
/* Six columns will not fit a narrow window; the table scrolls inside its own
   box rather than pushing the page sideways. */
.pc-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.plan-compare table{width:100%;border-collapse:collapse;font-size:.92rem}
.plan-compare th{
  text-align:left;font-size:.68rem;font-weight:800;letter-spacing:.12em;
  text-transform:uppercase;color:var(--gray);
  padding:0 .85rem .7rem 0;border-bottom:1px solid var(--border);white-space:nowrap;
}
.plan-compare td{
  padding:.85rem .85rem .85rem 0;border-bottom:1px solid var(--border);
  color:var(--light-gray);vertical-align:middle;
}
.plan-compare tbody tr:last-child td{border-bottom:none}
.plan-compare td b{color:var(--white);font-weight:800}
/* qualified with td: the `.plan-compare td` rule above is (0,1,1) and would
   otherwise outrank a bare .pc-unit (0,1,0) and grey the price out. */
.plan-compare td.pc-unit{color:var(--orange);font-weight:800;white-space:nowrap}
.pc-tag{
  display:inline-block;margin-left:.45rem;padding:.16rem .5rem;border-radius:999px;
  background:rgba(var(--accent-rgb),.14);border:1px solid rgba(var(--accent-rgb),.32);
  color:var(--orange);font-size:.6rem;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;white-space:nowrap;vertical-align:middle;
}
.plan-compare tr.pc-pop,.plan-compare tr.pc-best{background:rgba(var(--accent-rgb),.06)}
.plan-compare .foot{font-size:.86rem;color:var(--gray);margin:1rem 0 0}

/* Phones: six columns cannot read as a table, so each row becomes its own card
   and the header label moves inline via data-l. */
@media(max-width:700px){
  .plan-compare{padding:1.4rem 1.2rem}
  .pc-scroll{overflow-x:visible}
  .plan-compare thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
  .plan-compare tr{
    display:block;border:1px solid var(--border);border-radius:12px;
    padding:.5rem .9rem;margin-bottom:.8rem;
  }
  .plan-compare tbody tr:last-child{margin-bottom:0}
  .plan-compare td{
    display:flex;justify-content:space-between;align-items:baseline;gap:1rem;
    padding:.42rem 0;border-bottom:1px solid var(--border);
  }
  .plan-compare tbody tr td:last-child{border-bottom:none}
  .plan-compare td::before{
    content:attr(data-l);color:var(--gray);font-size:.72rem;font-weight:800;
    letter-spacing:.08em;text-transform:uppercase;flex:0 0 auto;
  }
  /* the plan name is the card's title, so it keeps the full width */
  .plan-compare td:first-child{justify-content:flex-start;font-size:1.02rem}
  .plan-compare td:first-child::before{display:none}
}
