/* ==========================================================================
   Mo's Valeting — shared stylesheet
   Brand: black / red / white, premium automotive
   Used by every page. Edit once, changes everywhere.
   ========================================================================== */

:root{
  /* colour */
  --black:#0A0A0B;
  --surface:#111113;
  --elev:#18181C;
  --line:rgba(255,255,255,.09);
  --line-2:rgba(255,255,255,.18);
  --white:#FFFFFF;
  --text:#F2F2F4;
  --muted:#A2A2AA;
  --muted-2:#71717B;
  --red:#E11B22;
  --red-dark:#A9131A;
  --red-soft:rgba(225,27,34,.14);
  --star:#FFB400;

  /* type */
  --display:"Archivo","Helvetica Neue",Arial,sans-serif;
  --body:"Inter",system-ui,-apple-system,sans-serif;

  /* system */
  --r:4px;
  --r-lg:8px;
  --maxw:1200px;
  --gut:24px;
  --hdr-h:78px;          /* fixed header height; 64px on phones (see responsive) */
  --shadow:0 30px 70px -28px rgba(0,0,0,.85);

  /* shared motion system — used across the flagship PPF sections */
  --ease-premium:cubic-bezier(.16,1,.3,1);
  --dur-fast:.3s;
  --dur-med:.6s;
  --dur-slow:1.1s;
}

*{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;scroll-padding-top:calc(var(--hdr-h) + 16px)}
/* Horizontal safeguard. `clip` on BOTH html and body is deliberate: the value
   on html propagates to the viewport (where it just means "scroll"), but it
   stops body's own value propagating too, so body genuinely clips its content
   without ever becoming a scroll container. That is what keeps position:sticky
   working (an overflow:hidden body would break it) and it holds on iOS, where
   overflow-x:hidden alone still lets the page pan sideways. The `hidden` line
   is the fallback for browsers without `clip`. Every real overflow source has
   also been fixed at source; this is a belt, not the braces. */
html{overflow-x:clip}
body{
  margin:0;background:var(--black);color:var(--text);
  font-family:var(--body);font-size:16.5px;line-height:1.65;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;overflow-x:clip;
}
h1,h2,h3,h4{font-family:var(--display);font-weight:700;line-height:1.06;letter-spacing:-.02em;margin:0}
p{margin:0 0 1em}
a{color:inherit;text-decoration:none}
img{max-width:100%;display:block;height:auto}
ul{margin:0;padding:0}

/* accessibility ---------------------------------------------------------- */
.skip{position:absolute;left:-9999px;top:0;background:var(--red);color:#fff;padding:12px 18px;z-index:999}
.skip:focus{left:12px;top:12px}
:focus-visible{outline:2px solid var(--red);outline-offset:3px;border-radius:2px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* layout ----------------------------------------------------------------- */
.wrap{width:100%;max-width:var(--maxw);margin:0 auto;padding:0 var(--gut)}
.section{padding:100px 0}
.section-sm{padding:72px 0}
.surface{background:var(--surface);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}

.eyebrow{
  font-family:var(--display);font-size:12px;font-weight:700;letter-spacing:.2em;
  text-transform:uppercase;color:var(--red);margin:0 0 16px;display:flex;align-items:center;gap:10px
}
.eyebrow::before{content:"";width:22px;height:2px;background:var(--red);flex:none}
.eyebrow.center{justify-content:center}

.sec-head{max-width:660px;margin-bottom:52px}
.sec-head.center{margin-left:auto;margin-right:auto;text-align:center}
.sec-head.center .eyebrow{justify-content:center}
.sec-head h2{font-size:clamp(2rem,4.4vw,3.05rem)}
.sec-head p{color:var(--muted);margin:18px 0 0;font-size:1.06rem}

/* buttons ---------------------------------------------------------------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  font-family:var(--display);font-weight:700;font-size:14.5px;letter-spacing:.04em;text-transform:uppercase;
  padding:15px 28px;border-radius:var(--r);border:1px solid transparent;cursor:pointer;
  transition:background .2s ease,color .2s ease,border-color .2s ease;
}
/* hover = colour and border only. No lift, no glow: the motion budget on this
   site goes to photography, not to buttons. Arrows inside links move 3px. */
.btn-primary{background:var(--red);color:#fff}
.btn-primary:hover{background:var(--red-dark)}
.btn-ghost{border-color:var(--line-2);color:var(--text);background:transparent}   /* a <button> would otherwise show the UA grey */
.btn-ghost:hover{border-color:var(--white);background:rgba(255,255,255,.06)}
.btn-light{background:var(--white);color:var(--black)}
.btn-light:hover{background:#e6e6e8}
.more-link{display:inline-flex;align-items:center;gap:8px;font-family:var(--display);font-weight:700;font-size:13.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--text);min-height:44px}
.more-link span{color:var(--red);transition:transform .2s}
.more-link:hover span{transform:translateX(3px)}

/* header ----------------------------------------------------------------- */
.site-header{
  position:fixed;top:0;left:0;right:0;z-index:100;
  border-bottom:1px solid transparent;transition:background .3s,border-color .3s,backdrop-filter .3s;
}
.site-header.scrolled{background:rgba(10,10,11,.9);backdrop-filter:blur(14px);border-bottom-color:var(--line)}
.nav{display:flex;align-items:center;justify-content:space-between;height:var(--hdr-h);gap:20px}
.logo{display:flex;align-items:center;gap:11px;flex:none}
.logo img{display:block;height:52px;width:auto}
.site-header .logo img{height:40px}
.logo .logo-sub{
  font-family:var(--body);font-weight:500;font-size:10px;letter-spacing:.22em;
  text-transform:uppercase;color:var(--muted-2)
}
.nav-links{display:flex;align-items:center;gap:30px;list-style:none}
.nav-links a{font-size:14.5px;font-weight:500;color:var(--muted);transition:color .2s}
.nav-links a:hover,.nav-links a[aria-current="page"]{color:var(--white)}
.nav-right{display:flex;align-items:center;gap:16px}
.nav-tel{display:none;font-family:var(--display);font-weight:700;font-size:15px}
.nav-tel:hover{color:var(--red)}
/* 44x44 target, lines centred inside it */
.burger{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;width:44px;height:44px;margin-right:-8px;background:none;border:0;padding:0;cursor:pointer;color:var(--white)}
.burger span{width:22px;height:2px;background:currentColor;border-radius:2px;transition:transform .25s,opacity .25s}
.burger[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0}
.burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
.nav-quote{white-space:nowrap;gap:0}   /* two text nodes inside a flex button: no flex gap between them */

/* Closed: slid up behind the header AND visibility:hidden, so its links are
   out of the tab order and out of the accessibility tree. The visibility
   change is delayed on close so the slide-up is still seen. */
.mobile-nav{
  position:fixed;top:var(--hdr-h);left:0;right:0;z-index:95;background:rgba(10,10,11,.98);
  backdrop-filter:blur(14px);border-bottom:1px solid var(--line);padding:6px var(--gut) 22px;
  max-height:calc(100dvh - var(--hdr-h));overflow-y:auto;overscroll-behavior:contain;
  transform:translateY(-110%);visibility:hidden;list-style:none;
  transition:transform .3s cubic-bezier(.2,.7,.2,1),visibility 0s linear .3s
}
.mobile-nav.open{transform:none;visibility:visible;transition:transform .3s cubic-bezier(.2,.7,.2,1),visibility 0s}
.mobile-nav li{border-bottom:1px solid var(--line)}
.mobile-nav li:last-child{border-bottom:0}
.mobile-nav a{display:block;padding:15px 2px;font-family:var(--display);font-weight:600;font-size:17px}
.mobile-nav .btn{width:100%;margin-top:18px}

/* hero ------------------------------------------------------------------- */
.hero{position:relative;min-height:92svh;display:flex;align-items:center;padding:140px 0 80px;overflow:hidden}
.hero-media{
  position:absolute;inset:0;z-index:0;background-color:var(--elev);
  background-image:url('/images/hero.jpg?v=10');
  background-repeat:no-repeat;background-position:center 35%;background-size:cover;
}
.hero-media::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(10,10,11,.94) 0%,rgba(10,10,11,.72) 45%,rgba(10,10,11,.45) 100%);
}
/* signature: specular sweep, like light travelling over polished paint */
/* One pass after the entrance, then still. Same geometry as .hh-sheen above:
   the band starts and finishes entirely outside the hero, and .hero's
   overflow:hidden keeps it from widening the page. */
.hero-sheen{
  --sheen-clear:26vh;
  position:absolute;top:-8%;bottom:-8%;left:0;width:30%;z-index:1;pointer-events:none;opacity:0;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.05) 42%,rgba(255,255,255,.1) 50%,rgba(255,255,255,.05) 58%,transparent);
  transform:translateX(calc(-140% - var(--sheen-clear))) skewX(-14deg);
  animation:sweep 3s cubic-bezier(.4,0,.25,1) 1.3s 1 both
}
@keyframes sweep{
  0%{transform:translateX(calc(-140% - var(--sheen-clear))) skewX(-14deg);opacity:0}
  10%{opacity:1}
  90%{opacity:1}
  100%{transform:translateX(calc(460% + var(--sheen-clear))) skewX(-14deg);opacity:0}
}
.hero .wrap{position:relative;z-index:2;width:100%}
.hero-inner{max-width:720px}
.hero h1{font-size:clamp(2.5rem,6.4vw,4.5rem);text-transform:uppercase}
.hero h1 em{font-style:normal;color:var(--red)}
.hero .lead{font-size:clamp(1.05rem,2.1vw,1.25rem);color:var(--muted);max-width:580px;margin:24px 0 34px}
.hero-actions{display:flex;gap:14px;flex-wrap:wrap}
.hero-rating{display:flex;align-items:center;gap:12px;margin-top:32px;font-size:14px;color:var(--muted)}
.hero-rating .stars{color:var(--star);letter-spacing:2px}

/* homepage hero (.hh) ------------------------------------------------------
   Asymmetric on desktop: type in the left ~40%, the car in the right ~60%,
   with the photo box itself starting part-way across so the car is not
   parked under the headline. On phones the photo takes the top half and the
   type sits beneath it on solid black. The trust strip is the hero's last
   row, so one set of credentials replaces the two bars that used to follow. */
.hh{position:relative;display:flex;flex-direction:column;min-height:min(92svh,880px);padding:calc(var(--hdr-h) + 40px) 0 34px;background:var(--black);overflow:hidden}
.hh-media{position:absolute;top:0;right:0;bottom:0;left:0;z-index:0;overflow:hidden;background:var(--elev)}
.hh-media picture,.hh-media img{position:absolute;inset:0;width:100%;height:100%}
.hh-media img{object-fit:cover;object-position:58% 50%}
/* directional: opaque behind the type, open over the car, a little weight at
   the foot for the trust strip */
.hh-scrim{position:absolute;inset:0;z-index:1;background:
  linear-gradient(90deg,rgba(10,10,11,.97) 0%,rgba(10,10,11,.88) 28%,rgba(10,10,11,.46) 54%,rgba(10,10,11,.12) 76%,rgba(10,10,11,.06) 100%),
  linear-gradient(180deg,rgba(10,10,11,.3) 0%,rgba(10,10,11,0) 26%,rgba(10,10,11,0) 62%,rgba(10,10,11,.72) 100%)}
/* One specular pass, ~1.5s after load. It is a child of .hh (full hero width),
   NOT of .hh-media: the media box is inset from the left on wide screens and
   clips its own overflow, so a sweep inside it could only ever appear from
   that inset edge onwards. Travel is expressed as a multiple of the band's
   own width, so it scales with the hero at every breakpoint:
     band width 30% of the hero, so travel scales with the hero
     start  translateX(-140%) -> band spans -42%..-12% of the hero
     end    translateX(460%)  -> band spans 138%..168%
   The -14deg skew also pushes the band sideways by about 0.14 x the hero's
   height at each end. On a phone the hero is ~780px tall but only 375px wide,
   so that overhang alone is ~113px: percentage clearance is not enough there
   and the band's leading edge would still be inside the hero at 0%. The
   --sheen-clear term adds an absolute margin tied to the viewport height,
   which is what makes the start genuinely off-screen at every width.
   .hh has overflow:hidden, so none of this can widen the page. */
.hh-sheen{
  --sheen-clear:26vh;
  position:absolute;top:-8%;bottom:-8%;left:0;width:30%;z-index:2;pointer-events:none;opacity:0;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.04) 42%,rgba(255,255,255,.09) 50%,rgba(255,255,255,.04) 58%,transparent);
  transform:translateX(calc(-140% - var(--sheen-clear))) skewX(-14deg);
  animation:hhSweep 3s cubic-bezier(.4,0,.25,1) 1.5s 1 both}
@keyframes hhSweep{
  0%{transform:translateX(calc(-140% - var(--sheen-clear))) skewX(-14deg);opacity:0}
  10%{opacity:1}
  90%{opacity:1}
  100%{transform:translateX(calc(460% + var(--sheen-clear))) skewX(-14deg);opacity:0}
}
.hh-wrap{position:relative;z-index:3;display:flex;flex-direction:column;flex:1}
.hh-content{max-width:640px;margin:auto 0;padding:20px 0 52px}
.hh-eyebrow{margin-bottom:22px}
.hh-title{font-size:clamp(2.25rem,4.7vw,4.1rem);text-transform:uppercase;line-height:.98;letter-spacing:-.025em}
/* each line is its own mask for the entrance; the padding stops descenders
   and the ampersand being shaved by the clip */
.hh-line{display:block;overflow:hidden;padding-bottom:.1em;margin-bottom:-.1em}
.hh-line > span{display:block}
.hh-title em{font-style:normal;color:var(--red)}
.hh-lead{font-size:clamp(1.02rem,1.6vw,1.2rem);color:var(--muted);max-width:480px;margin:26px 0 32px}
.hh-actions{display:flex;align-items:center;gap:8px 28px;flex-wrap:wrap}
.hh-link{display:inline-flex;align-items:center;gap:8px;font-family:var(--display);font-weight:700;font-size:13.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--text);padding:8px 0;min-height:44px}
.hh-link span{transition:transform .2s;color:var(--red)}
.hh-link:hover span{transform:translateX(3px)}
.hh-trust{list-style:none;display:flex;flex-wrap:wrap;gap:12px 36px;padding-top:20px;border-top:1px solid rgba(255,255,255,.14)}
.hh-trust li{display:flex;align-items:center;gap:10px;font-family:var(--display);font-weight:600;font-size:12.5px;letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.84)}
.hh-trust li::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--red);flex:none}
.hh-trust a{display:inline-flex;align-items:center;gap:8px;color:inherit;transition:color .2s}
.hh-trust a:hover{color:#fff}
.hh-stars{color:var(--star);letter-spacing:1px;font-size:12px}
@media (min-width:1025px){.hh-media{left:10%}}
@media (min-width:1200px){.hh-media{left:18%}}

/* service cards ----------------------------------------------------------
   Name, one sentence, price, destination. One link per card, stretched over
   the whole card with ::after, so it is a single tab stop and the card is
   the target. The featured card is marked by a red rule and a label, not a
   red border around everything. */
.svc-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.svc{
  position:relative;display:flex;flex-direction:column;gap:12px;padding:28px 26px 24px;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-lg);
  transition:border-color .25s,background .25s
}
.svc::before{content:"";position:absolute;left:0;right:0;top:-1px;height:2px;border-radius:var(--r-lg) var(--r-lg) 0 0;background:var(--red);opacity:0;transition:opacity .25s}
.svc:hover{border-color:var(--line-2);background:var(--elev)}
.svc:hover::before,.svc.is-featured::before{opacity:1}
.svc p.svc-flag{margin:0;font-family:var(--display);font-weight:700;font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--red)}
.svc-name{font-size:1.3rem;line-height:1.12}
.svc-desc{color:var(--muted);font-size:15px;margin:0;flex:1}
.svc-foot{display:flex;align-items:flex-end;justify-content:space-between;gap:14px;margin-top:10px;padding-top:16px;border-top:1px solid var(--line)}
.svc-price{font-family:var(--display);font-weight:700;font-size:1.5rem;line-height:1;color:var(--text);white-space:nowrap}
.svc-price small{display:block;font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin-bottom:6px;font-weight:600}
.svc-link{font-family:var(--display);font-weight:700;font-size:12.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--red);display:inline-flex;align-items:center;gap:6px;text-align:right}
.svc-link::after{content:"";position:absolute;inset:0;border-radius:var(--r-lg)}
.svc-link span{transition:transform .2s}
.svc:hover .svc-link span{transform:translateX(3px)}
.svc-link:focus-visible{outline:2px solid var(--red);outline-offset:3px}
@supports selector(:has(a)){
  .svc-link:focus-visible{outline:none}
  .svc:has(.svc-link:focus-visible){outline:2px solid var(--red);outline-offset:3px}
}
.svc-note{margin:22px 0 0;color:var(--muted-2);font-size:13.5px}
/* older card variant still used on the location pages (icon + text link) */
.svc .ic{width:38px;height:38px;border-radius:var(--r);background:var(--red-soft);color:var(--red);display:grid;place-items:center}
.svc .ic svg{width:20px;height:20px}
.svc h3{font-size:1.22rem}
.svc p{color:var(--muted);font-size:14.8px;margin:0}
.svc .more{font-family:var(--display);font-weight:700;font-size:13px;letter-spacing:.06em;text-transform:uppercase;color:var(--red);display:inline-flex;align-items:center;gap:7px;margin-top:auto}
.svc .more span{transition:transform .2s}
.svc:hover .more span{transform:translateX(3px)}

/* before / after slider (signature) --------------------------------------
   Position is one custom property, --ba-x, written by site.js. The CSS
   default of 50% is the no-JS state: a fixed half-and-half split with both
   labels, which is still a useful comparison. The photographs never move;
   only the clip on the "after" layer and the divider do. */
/* the glow sits 40px outside the frame; the section clips it so it can never
   make the page wider than the screen (no sticky inside, so hidden is safe) */
.ba-section{overflow:hidden;overflow:clip}
.ba-head{margin-bottom:36px}
.ba-frame{position:relative;max-width:900px;margin:0 auto;padding:3px}
.ba-frame::before{
  content:"";position:absolute;inset:-40px;z-index:0;pointer-events:none;
  background:radial-gradient(60% 60% at 50% 50%,rgba(225,27,34,.16),transparent 70%)
}
.ba{
  position:relative;width:100%;aspect-ratio:16/9;border-radius:var(--r-lg);overflow:hidden;
  border:1px solid var(--line);box-shadow:var(--shadow);cursor:ew-resize;user-select:none;-webkit-user-select:none;background:var(--elev);
  touch-action:pan-y   /* vertical swipes scroll the page; only a sideways drag moves the divider */
}
.ba.is-dragging{cursor:grabbing}
.ba.is-focus{outline:2px solid var(--red);outline-offset:4px}
/* both comparisons now use real <picture> layers, so the browser can pick
   AVIF and the frame reserves its space from width/height */
.ba-before,.ba-after{position:absolute;inset:0;background-size:cover;background-position:center}
.ba-before img,.ba-after img{width:100%;height:100%;object-fit:cover;object-position:center;display:block}
.ba-after{clip-path:inset(0 0 0 var(--ba-x,50%))}
.ba-tag{
  position:absolute;bottom:16px;z-index:4;font-family:var(--display);font-weight:700;font-size:11.5px;
  letter-spacing:.16em;text-transform:uppercase;background:rgba(10,10,11,.78);padding:7px 13px;border-radius:var(--r);
  backdrop-filter:blur(6px)
}
.ba-tag.before{left:16px;color:var(--muted)}
.ba-tag.after{right:16px;color:#fff;background:var(--red)}
.ba-handle{position:absolute;top:0;bottom:0;width:2px;background:var(--white);z-index:5;left:var(--ba-x,50%);transform:translateX(-50%);pointer-events:none}
.ba-knob{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:48px;height:48px;border-radius:50%;
  background:var(--white);display:grid;place-items:center;box-shadow:0 6px 20px rgba(0,0,0,.5)
}
.ba-knob svg{width:22px;height:22px;color:var(--black)}
/* the real slider for keyboard and assistive tech. Not visible and not a
   pointer target: pointer input goes to the frame (site.js), keyboard focus
   is mirrored onto the frame as .is-focus */
.ba-range{position:absolute;left:0;top:0;width:1px;height:1px;opacity:0;margin:0;pointer-events:none}
.ba-hint{display:flex;align-items:center;justify-content:center;gap:8px;margin:16px 0 0;font-family:var(--display);font-weight:700;font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted-2);transition:opacity .3s}
.ba-hint svg{width:16px;height:16px;color:var(--red)}
.ba.is-used ~ .ba-hint{opacity:.5}

/* gallery ---------------------------------------------------------------- */
.gal{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.gal figure{
  position:relative;margin:0;aspect-ratio:4/3;border-radius:var(--r-lg);overflow:hidden;
  border:1px solid var(--line);background:var(--elev)
}
.gal img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .7s var(--ease-premium)}
.gal figure::after{
  content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(180deg,transparent 48%,rgba(10,10,11,.55) 78%,rgba(10,10,11,.9) 100%)
}
.gal figcaption{
  position:absolute;left:16px;bottom:14px;z-index:2;font-family:var(--display);font-weight:700;
  font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;color:#fff
}
/* a very small scale on hover, fine pointers only. The figure clips it. */
@media (hover:hover) and (pointer:fine){.gal figure:hover img{transform:scale(1.035)}}

/* why us ----------------------------------------------------------------- */
.why{display:grid;grid-template-columns:.9fr 1.1fr;gap:64px;align-items:start}
.why > .reveal:first-child{position:sticky;top:calc(var(--hdr-h) + 40px)}
.why h2{font-size:clamp(1.9rem,4vw,2.8rem)}
.why-lead{color:var(--muted);margin:18px 0 0;max-width:400px}
.why-cta{margin:26px 0 0}
.why-list{list-style:none}
.why-list li{display:flex;gap:16px;padding:18px 0;border-bottom:1px solid var(--line)}
.why-list li:first-child{padding-top:0}
.why-list li:last-child{border-bottom:0;padding-bottom:0}
.why-list .tick{width:32px;height:32px;flex:none;border-radius:50%;background:var(--red-soft);color:var(--red);display:grid;place-items:center;margin-top:1px}
.why-list .tick svg{width:15px;height:15px}
.why-list b{font-family:var(--display);font-size:16.5px;display:block;margin-bottom:4px}
.why-list p{margin:0;color:var(--muted);font-size:14.8px}

/* reviews ----------------------------------------------------------------
   One flat row of cards in a scroll-snap track. --per (3 / 2 / 1 by width)
   sets how many share the row; site.js reads it to page the arrows and the
   counter. Manual only: no timer, nothing moves unless the visitor does. */
.rev-head{display:flex;align-items:flex-end;justify-content:space-between;gap:24px;flex-wrap:wrap;margin-bottom:36px}
.rev-head h2{font-size:clamp(1.9rem,4vw,2.8rem)}
.rev-badge{display:flex;align-items:center;gap:14px;border:1px solid var(--line);background:var(--black);border-radius:var(--r-lg);padding:14px 20px;text-decoration:none;color:inherit;transition:border-color .25s,background .25s}
.rev-badge:hover{border-color:var(--line-2);background:var(--elev)}
.rev-badge svg{width:28px;height:28px;flex:none}
.rev-badge .score{font-family:var(--display);font-weight:700;font-size:1.45rem;line-height:1}
.rev-badge .stars{color:var(--star);letter-spacing:2px;font-size:13px}
.rev-badge small{color:var(--muted);font-size:12px}
.rev-carousel{position:relative}
.rev-track{
  --per:3;--gap:16px;
  /* stretch, not flex-start: every card in the row takes the height of the
     tallest, so collapsed cards match on every page and at any text size.
     An expanded card grows the whole row together; site.js collapses an open
     review when the visitor changes page so that height is never carried. */
  display:flex;gap:var(--gap);align-items:stretch;
  overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;
  -webkit-overflow-scrolling:touch;scrollbar-width:none;-ms-overflow-style:none;overscroll-behavior-x:contain;
}
.rev-track::-webkit-scrollbar{display:none}
.rev{
  flex:0 0 calc((100% - (var(--per) - 1) * var(--gap)) / var(--per));min-width:0;scroll-snap-align:start;
  display:flex;flex-direction:column;gap:14px;padding:26px;background:var(--black);border:1px solid var(--line);border-radius:var(--r-lg);transition:border-color .25s
}
.rev:hover{border-color:var(--line-2)}
.rev .stars{color:var(--star);letter-spacing:2px;font-size:14px}
.rev blockquote{margin:0;font-size:15px;line-height:1.62}
/* long reviews show ~6 lines and a toggle. Clamped only when JS is running,
   because JS is what provides the toggle; without it the full text shows. */
.js .rev.is-clamped:not(.is-open) blockquote{display:-webkit-box;-webkit-line-clamp:6;-webkit-box-orient:vertical;overflow:hidden}
.rev-more{display:none;align-self:flex-start;background:none;border:0;padding:6px 0;margin:-8px 0 -4px;font-family:var(--display);font-weight:700;font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--red);cursor:pointer;transition:color .2s}
.js .rev.is-clamped .rev-more{display:inline-flex}
.rev-more:hover{color:#fff}
/* identity sits at the foot of the card whatever the excerpt length, with a
   little air above it on the shorter reviews */
.rev .who{display:flex;align-items:center;gap:12px;margin-top:auto;padding-top:4px}
.rev .av{width:40px;height:40px;flex:none;border-radius:50%;background:var(--elev);border:1px solid var(--line);color:var(--red);display:grid;place-items:center;font-family:var(--display);font-weight:700}
.rev .who b{font-family:var(--display);font-size:14.5px;display:block;line-height:1.3}
.rev .who small{color:var(--muted-2);font-size:12px}

.rev-controls{display:flex;align-items:center;justify-content:center;gap:18px;margin-top:26px}
.rev-arrow{width:44px;height:44px;border-radius:50%;border:1px solid var(--line);background:var(--surface);color:var(--text);display:grid;place-items:center;cursor:pointer;transition:border-color .2s,color .2s;flex:none;padding:0}
.rev-arrow:hover{border-color:var(--red);color:var(--red)}
.rev-arrow svg{width:18px;height:18px}
.rev-pos{margin:0;font-family:var(--display);font-weight:700;font-size:14px;letter-spacing:.08em;color:var(--muted);min-width:72px;text-align:center;font-variant-numeric:tabular-nums}
.rev-pos b{color:var(--text)}
.rev-pos-sep{margin:0 7px;color:var(--muted-2)}

/* about ------------------------------------------------------------------ */
/* eyebrow and heading sit above the two columns, so the first paragraph can
   start level with the top of the photograph rather than below a heading */
.about-head{max-width:660px;margin-bottom:38px}
.about-head h2{font-size:clamp(1.9rem,4vw,2.8rem)}
.about-grid{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:56px;align-items:start}
.about-copy > :first-child{margin-top:0}
.about-grid .lead-p{color:var(--text);font-size:1.1rem}
.about-grid p{color:var(--muted)}
.about-cta{margin:26px 0 0}
/* one photograph of both brothers. The aspect ratio matches the file, so the
   space is reserved before it loads and nothing is stretched. */
.about-photo{margin:0;border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--line);background:var(--elev)}
.about-photo img{display:block;width:100%;height:auto;aspect-ratio:4/5;object-fit:cover}

/* service areas ---------------------------------------------------------- */
.areas{display:flex;flex-wrap:wrap;gap:10px}
.areas a{
  display:inline-flex;align-items:center;gap:8px;padding:11px 18px;border:1px solid var(--line);
  border-radius:999px;font-size:14.5px;color:var(--muted);transition:.2s;background:var(--surface)
}
.areas a:hover{color:var(--white);border-color:var(--red);background:var(--red-soft)}
.areas a svg{width:14px;height:14px;color:var(--red);flex:none}

/* faq --------------------------------------------------------------------
   Native <details>. With no JS an open answer simply shows (no max-height
   trap). site.js animates height on open/close and keeps the element open
   until the close transition has finished. */
.faq-head{margin-bottom:26px}
.faq{max-width:860px;margin:0 auto;border-top:1px solid var(--line)}
.faq details{border-bottom:1px solid var(--line);position:relative}
.faq details::before{
  content:"";position:absolute;left:-24px;top:0;bottom:0;width:2px;background:var(--red);
  transform:scaleY(0);transform-origin:center;transition:transform .3s var(--ease-premium)
}
.faq details[open]::before{transform:scaleY(1)}
.faq summary{
  display:flex;align-items:center;justify-content:space-between;gap:20px;cursor:pointer;list-style:none;
  padding:22px 0;min-height:44px;font-family:var(--display);font-weight:600;font-size:1.15rem;transition:color .2s
}
.faq summary:hover{color:#fff}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{
  content:"+";color:var(--red);font-size:1.6rem;font-weight:400;line-height:1;flex:none;
  transition:transform .3s var(--ease-premium)
}
.faq details[open] summary::after{transform:rotate(45deg)}
.faq .answer{overflow:hidden;color:var(--muted);max-width:640px}
.js .faq .answer{transition:height .35s var(--ease-premium)}
.faq .answer p{margin:0;padding:0 0 24px}

/* cta banner ------------------------------------------------------------- */
.cta{background:var(--red);text-align:center;position:relative;overflow:hidden}
.cta::before{
  content:"";position:absolute;inset:0;
  background:radial-gradient(60% 100% at 50% 0%,rgba(255,255,255,.16),transparent 65%)
}
.cta .wrap{position:relative;z-index:2;padding-top:70px;padding-bottom:70px}
.cta-ghost{border-color:rgba(255,255,255,.55);color:#fff}
.cta-ghost:hover{border-color:#fff;background:rgba(255,255,255,.08)}
.cta h2{font-size:clamp(1.9rem,4.2vw,2.9rem);text-transform:uppercase;color:#fff;max-width:780px;margin:0 auto}
.cta p{color:rgba(255,255,255,.9);max-width:560px;margin:18px auto 30px}
.cta-actions{display:flex;gap:14px;justify-content:center;flex-wrap:wrap}

/* footer -----------------------------------------------------------------
   Desktop: brand / services / areas / contact. Phones: contact first, then
   the two link groups side by side, then the brand block (CSS order). */
.site-footer{background:var(--black);border-top:1px solid var(--line);padding:56px 0 28px}
.foot-grid{display:grid;grid-template-columns:1.4fr 1fr 1fr 1.2fr;gap:40px;margin-bottom:44px}
.foot-grid h4{font-family:var(--display);font-size:13px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted-2);margin-bottom:16px}
.foot-grid ul{list-style:none}
.foot-grid li{margin-bottom:8px}
.foot-grid a{display:inline-block;padding:2px 0;color:var(--muted);font-size:14.8px;transition:color .2s}
.foot-grid a:hover{color:var(--white)}
.foot-grid address{font-style:normal;color:var(--muted);font-size:14.8px;line-height:1.7;display:flex;flex-direction:column;align-items:flex-start;gap:6px}
.foot-tel{font-family:var(--display);font-weight:700;font-size:1.2rem;color:var(--text)}
.foot-grid a.foot-tel{color:var(--text);font-size:1.2rem}
.foot-addr{display:block;margin-top:4px}
.foot-blurb{color:var(--muted);font-size:14.8px;max-width:300px;margin-top:16px}
.socials{display:flex;gap:10px;margin-top:20px}
.socials a{width:44px;height:44px;border:1px solid var(--line);border-radius:var(--r);display:grid;place-items:center;color:var(--muted);transition:color .2s,border-color .2s;padding:0}
.socials a:hover{color:var(--white);border-color:var(--line-2)}
.socials svg{width:17px;height:17px}
.foot-base{border-top:1px solid var(--line);padding-top:26px;display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;color:var(--muted-2);font-size:13.5px}
.foot-base a{color:var(--muted-2)}
.foot-base a:hover{color:var(--muted)}
.foot-legal{display:flex;gap:20px;flex-wrap:wrap}

/* reveal on scroll -------------------------------------------------------
   Start state only under html.js (set by an inline script in <head>), so a
   page with scripting off, or a script that never runs, shows everything. */
/* `reveal-ready` is added by assets/site.js once its IntersectionObserver is
   actually running. Gating on `.js` instead would hide this content for
   anyone whose copy of site.js never arrived. */
.reveal-ready .reveal{opacity:0;transform:translateY(16px);transition:opacity .55s ease,transform .55s cubic-bezier(.2,.7,.2,1)}
.reveal-ready .reveal.in{opacity:1;transform:none}

/* GSAP-staggered groups — children are visible by default (safe no-JS
   fallback); animations.js hides then reveals them only once GSAP has
   actually loaded, so a blocked/slow CDN never leaves content invisible. */
.reveal-group > *{opacity:1}

/* hero: JS-driven entrance. Only hidden once animations.js confirms GSAP
   is present — see the guard at the top of animations.js. */
.js-gsap .hero-inner .eyebrow,
.js-gsap .hero-inner h1,
.js-gsap .hero-inner .lead,
.js-gsap .hero-inner .hero-actions,
.js-gsap .hero-inner .hero-rating{opacity:0}

/* homepage hero: eyebrow / lead / actions / trust fade up; each headline line
   rises out of its own mask (.hh-line has overflow:hidden) */
.js-gsap .hh-eyebrow,
.js-gsap .hh-lead,
.js-gsap .hh-actions,
.js-gsap .hh-trust{opacity:0}
.js-gsap .hh-line > span{transform:translateY(110%)}

/* inner-page hero: same JS-gated entrance, smaller element set (no eyebrow,
   and .article-meta stands in for .lead on blog posts). */
.js-gsap .page-hero .breadcrumb,
.js-gsap .page-hero h1,
.js-gsap .page-hero .lead,
.js-gsap .page-hero .hero-actions,
.js-gsap .page-hero .article-meta{opacity:0}

/* responsive ------------------------------------------------------------- */
@media (min-width:1025px){ .nav-tel{display:block} .burger{display:none} }
@media (max-width:1024px){
  :root{--hdr-h:64px}
  .nav-links{display:none}
  .nav{gap:12px}
  .site-header .logo img{height:34px}
  .nav-right{gap:8px}
  .nav-quote{padding:10px 14px;font-size:12.5px;letter-spacing:.06em}
  .svc-grid{grid-template-columns:repeat(2,1fr)}
  .svc.is-featured{grid-column:1/-1}
  .why{grid-template-columns:1fr;gap:40px}
  .why > .reveal:first-child{position:static}
  .about-head{margin-bottom:28px}
  .about-grid{grid-template-columns:1fr;gap:28px}
  .rev-track{--per:2}
  .foot-grid{grid-template-columns:1fr 1fr;gap:36px}
  .section{padding:78px 0}
}
/* homepage hero: its own phone composition */
@media (max-width:780px){
  .hh{min-height:min(100svh,780px);padding:0 0 26px}   /* full screen on a phone; capped so a tablet does not get a hollow hero */
  .hh-media{bottom:auto;height:min(54svh,440px);left:0}
  .hh-media img{object-position:44% 62%}
  .hh-scrim{background:linear-gradient(180deg,rgba(10,10,11,.4) 0%,rgba(10,10,11,.06) 26%,rgba(10,10,11,.1) 54%,rgba(10,10,11,.86) 82%,var(--black) 100%)}
  .hh-wrap{padding-top:calc(min(54svh,440px) - 92px)}
  .hh-content{margin:0;padding:0 0 30px;max-width:none}
  .hh-eyebrow{margin-bottom:16px}
  .hh-title{font-size:clamp(1.7rem,8.8vw,3rem)}   /* "PAINT PROTECTION" (the widest line) holds one line down to 320px */
  .hh-lead{margin:18px 0 22px;font-size:1rem;max-width:440px}
  .hh-actions{gap:6px 22px}
  .hh-actions .btn{padding:14px 24px}
  .hh-trust{display:grid;grid-template-columns:1fr 1fr;gap:12px 14px;padding-top:18px;margin-top:auto}
  .hh-trust li{font-size:11.5px;letter-spacing:.1em;gap:8px}
  .hh-trust-long,.hh-stars{display:none}   /* short labels so each fits its half-width cell on one line */
}
@media (max-width:640px){
  .logo .logo-sub{display:none}
  .svc-grid{grid-template-columns:1fr;gap:12px}
  .svc.is-featured{grid-column:auto}
  .svc{padding:22px 20px 20px}
  .gal{grid-template-columns:1fr 1fr;gap:10px}
  .rev-track{--per:1}
  .rev{padding:22px}
  .rev-head{margin-bottom:26px}
  .foot-grid{grid-template-columns:1fr 1fr;gap:30px 20px;margin-bottom:34px}
  .foot-contact{order:-1;grid-column:1/-1;padding-bottom:26px;border-bottom:1px solid var(--line)}
  .foot-brand{order:1;grid-column:1/-1;padding-top:4px}
  .foot-grid li{margin-bottom:4px}
  .foot-grid a{padding:6px 0}
  .foot-blurb{max-width:none}
  .section{padding:64px 0}
  .sec-head{margin-bottom:34px}
  .ba-head{margin-bottom:26px}
  .faq-head{margin-bottom:18px}
  .hero{min-height:auto;padding:120px 0 64px}
  .ba{aspect-ratio:4/3}
  .ba-knob{width:44px;height:44px}
}
@media (max-width:360px){.nav-quote-long{display:none}}

/* motion / print --------------------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
  .reveal-ready .reveal{opacity:1;transform:none}
  .reveal-group > *{opacity:1!important;transform:none!important}
  .hero-sheen,.hh-sheen{display:none}
  .gal figure:hover img{transform:none}
  .rev-track{scroll-behavior:auto}
  .lib-results.is-updating{opacity:1}
}

/* ==========================================================================
   INNER PAGES — service pages, contact page
   ========================================================================== */

/* page hero (smaller than homepage hero) --------------------------------- */
/* ============ PPF flagship bespoke hero ============ */
/* ============================================================================
   PPF HERO — campaign opening frame
   ----------------------------------------------------------------------------
   Asymmetric: copy in the left ~55%, visual weight right. The media slot is
   full-bleed; until real footage/photography lands it renders a dark studio
   surface with a right-biased specular, and the directional overlay is tuned
   for that same composition, so swapping in the asset is a data change only.
   Reveal order (animations.js): eyebrow → service → PROTECTION → PERFECTED →
   lead → CTAs → trust strip, then one specular sweep. Pre-animation hidden
   states are .js-gsap-gated so a blocked CDN never hides the hero.
   ============================================================================ */
.ppf-hero{
  position:relative;min-height:92svh;display:flex;align-items:flex-end;
  overflow:hidden;border-bottom:1px solid var(--line)
}
.ppf-hero-media{position:absolute;inset:0;z-index:0;background:linear-gradient(160deg,#151518 0%,#0A0A0B 62%)}
.ppf-hero-media video,.ppf-hero-media picture,.ppf-hero-media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:70% 50%;display:block}
/* RS5 hero: three crops, each with its own object-position.
   The CROP does the composition, not object-position: the master has the car
   left of centre, the crops drop source from the left so the car sits in the
   right 55-60%, and the right edge lands just past the front bumper so the
   duplicated shelving unit is cut away.
   object-position then only handles the SECONDARY crop the viewport's own
   aspect forces, and it is pinned near 100% on purpose: the front bumper sits
   at 97% of the image, so a low X would push it out of frame on a narrow or
   tall window. At a normal 16:9 desktop it moves the car by about 30px. */
.ppf-hero.has-media .ppf-hero-media img{object-position:88% 58%}
@media (max-width:1100px){
  .ppf-hero.has-media .ppf-hero-media img{object-position:90% 56%}
}
.ppf-hero-texture{
  position:absolute;inset:0;opacity:.5;
  background:repeating-linear-gradient(115deg,rgba(255,255,255,.025) 0 1px,transparent 1px 3px)
}
/* placeholder studio light, weighted to the right where the car will sit */
.ppf-hero-specular{
  position:absolute;inset:-30%;pointer-events:none;z-index:1;
  background:radial-gradient(34% 40% at 66% 44%,rgba(255,255,255,.09),transparent 66%);
  transform:translate(var(--sx,0px),var(--sy,0px));transition:transform 1.1s var(--ease-premium)
}
.has-media .ppf-hero-texture,.has-media .ppf-hero-specular{display:none}
/* one strip-light pass across the media after the reveal, then never again */
.ppf-hero-sweep{
  position:absolute;inset:0;z-index:1;pointer-events:none;opacity:0;
  background:linear-gradient(105deg,transparent 42%,rgba(255,255,255,.07) 50%,transparent 58%);
  background-size:220% 100%;background-position:120% 0
}
.js-gsap .ppf-hero-sweep{animation:ppfHeroSweep 2.2s var(--ease-premium) 1.5s 1 both}
/* 128% -> -38%, not 120% -> -30%: the 105deg band leans, so on a tall narrow
   hero its top corner was still a hair inside the frame at the start. Same
   lesson as the homepage sheen. */
@keyframes ppfHeroSweep{0%{opacity:0;background-position:128% 0}20%{opacity:1}80%{opacity:1}100%{opacity:0;background-position:-38% 0}}
/* directional overlay: dark on the left where the type is, open on the right
   where the vehicle is, plus a lift at the foot for the trust strip */
.ppf-hero-overlay{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    linear-gradient(90deg,rgba(10,10,11,.95) 0%,rgba(10,10,11,.90) 20%,rgba(10,10,11,.72) 38%,
      rgba(10,10,11,.46) 52%,rgba(10,10,11,.28) 62%,rgba(10,10,11,.10) 76%,rgba(10,10,11,.03) 100%),
    linear-gradient(0deg,rgba(10,10,11,.86) 0%,rgba(10,10,11,.26) 30%,transparent 55%)
}

.ppf-hero-content{position:relative;z-index:2;padding:112px var(--gut) 118px}   /* .wrap supplies the 1200px measure */
.ppf-hero-crumbs{margin:0 0 38px;opacity:.4;font-size:11.5px}   /* navigation, not a headline */
.ppf-hero-crumbs a{color:var(--muted)}
.ppf-hero-eyebrow{
  overflow:hidden;margin:0 0 22px;
  font-family:var(--display);font-weight:700;font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--muted)
}
.ppf-hero-eyebrow span{display:inline-flex;align-items:center;gap:12px}
.ppf-hero-eyebrow span::before{content:"";width:22px;height:1px;background:var(--red);flex:none}
.ppf-hero-h1{margin:0 0 28px;font-size:inherit;line-height:1}
.ppf-hero-service{
  display:block;overflow:hidden;margin:0 0 20px;
  font-family:var(--display);font-weight:600;font-size:clamp(.95rem,1.25vw,1.15rem);
  letter-spacing:.18em;text-transform:uppercase;color:var(--text)
}
.ppf-hero-service span{display:block}
/* the statement: campaign type, not a website heading */
.ppf-hero-line{
  display:block;overflow:hidden;
  font-family:var(--display);font-weight:700;text-transform:uppercase;
  font-size:clamp(3.4rem,8.6vw,8.4rem);line-height:.9;letter-spacing:-.035em;color:#fff;
  padding-bottom:.1em;margin-bottom:-.1em   /* the CLIP box, not the span: room for the comma's tail at line-height .9 */
}
.ppf-hero-line span{display:block}
.ppf-hero-lead-wrap{overflow:hidden;margin:0 0 36px}
.ppf-hero-lead-wrap p{color:var(--muted);font-size:clamp(1rem,1.35vw,1.15rem);line-height:1.6;max-width:52ch;margin:0}
.ppf-hero-cta-wrap{overflow:hidden}
.ppf-hero-cta-wrap .hero-actions{display:flex;gap:14px;flex-wrap:wrap}
.ppf-hero .btn-ghost{border-color:rgba(255,255,255,.28)}

/* bottom trust strip, edge to edge, under the copy */
.ppf-hero-trust{
  position:absolute;left:0;right:0;bottom:0;z-index:2;
  list-style:none;margin:0;padding:22px var(--gut);
  display:flex;gap:0;border-top:1px solid rgba(255,255,255,.1);
  font-family:var(--display);font-weight:700;font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)
}
.ppf-hero-trust li{padding:0 28px 0 0;display:flex;align-items:center;gap:10px}
.ppf-hero-trust li::before{content:"";width:5px;height:5px;border-radius:50%;background:var(--red);flex:none}
.ppf-hero-trust li + li{padding-left:28px;border-left:1px solid rgba(255,255,255,.1)}
@media (min-width:1249px){.ppf-hero-trust{padding-left:calc((100% - var(--maxw)) / 2 + var(--gut));padding-right:calc((100% - var(--maxw)) / 2 + var(--gut))}}

/* pre-animation states, .js-gsap-gated */
.js-gsap .ppf-hero-eyebrow span{transform:translateY(22px);opacity:0}
.js-gsap .ppf-hero-service span{transform:translateY(100%);opacity:0}
.js-gsap .ppf-hero-line span{transform:translateY(115%);opacity:0}   /* clip is 1.1 lines tall; 115% fully hides */
.js-gsap .ppf-hero-lead-wrap p{transform:translateY(26px);opacity:0}
.js-gsap .ppf-hero-cta-wrap .hero-actions{transform:translateY(26px);opacity:0}
.js-gsap .ppf-hero-trust{opacity:0;transform:translateY(10px)}

/* ---- mobile: its own composition, not a shrunk desktop ---- */
@media (max-width:780px){
  .ppf-hero{min-height:92svh}
  .ppf-hero-media video,.ppf-hero-media picture,.ppf-hero-media img{object-position:62% 40%}
  .ppf-hero.has-media .ppf-hero-media img{object-position:92% 50%}
  .ppf-hero-specular{background:radial-gradient(60% 34% at 62% 26%,rgba(255,255,255,.08),transparent 68%)}
  /* the copy sits at the foot on phones, so the darkening is bottom-up and
     eases off across the car's roofline and bonnet rather than flattening it */
  .ppf-hero-overlay{
    background:
      linear-gradient(0deg,rgba(10,10,11,.97) 0%,rgba(10,10,11,.92) 26%,rgba(10,10,11,.72) 42%,
        rgba(10,10,11,.46) 58%,rgba(10,10,11,.22) 76%,rgba(10,10,11,.18) 100%)
  }
  /* On a phone the copy and the car want the same band, and no crop of this
     photograph can separate them. Rather than flattening the RS5 under a
     heavier wash, the type carries its own shadow and the lead goes to full
     strength, so the car stays bright and the words stay legible. */
  .ppf-hero.has-media .ppf-hero-service span,
  .ppf-hero.has-media .ppf-hero-line span{text-shadow:0 2px 20px rgba(10,10,11,.9),0 1px 3px rgba(10,10,11,.5)}
  .ppf-hero.has-media .ppf-hero-lead-wrap p{color:var(--text);text-shadow:0 1px 14px rgba(10,10,11,.85)}
  .ppf-hero.has-media .ppf-hero-eyebrow{text-shadow:0 1px 10px rgba(10,10,11,.8)}
  .ppf-hero-content{padding:72px var(--gut) 88px}
  .ppf-hero-crumbs{margin-bottom:20px;font-size:10.5px;opacity:.36}
  .ppf-hero-eyebrow{margin-bottom:13px;font-size:10px}
  .ppf-hero-service{font-size:.8rem;letter-spacing:.16em;margin-bottom:14px}
  .ppf-hero-line{font-size:clamp(2.4rem,12.4vw,4.2rem);letter-spacing:-.03em}   /* PROTECTION, is one unbreakable word: 12.4vw keeps it inside a 375px screen */
  .ppf-hero-lead-wrap{margin-bottom:26px}
  .ppf-hero-lead-wrap p{font-size:.98rem}
  .ppf-hero-cta-wrap .hero-actions{flex-direction:column;gap:10px}
  .ppf-hero-cta-wrap .btn{width:100%}
  .ppf-hero-trust{padding:14px var(--gut);font-size:9.5px;letter-spacing:.14em;justify-content:space-between}
  .ppf-hero-trust li{padding:0;gap:7px}
  .ppf-hero-trust li + li{padding-left:0;border-left:0}
}
@media (max-width:380px){
  .ppf-hero-trust{font-size:9px;letter-spacing:.1em}
  .ppf-hero-trust li{gap:6px}
}
@media (prefers-reduced-motion:reduce){
  .ppf-hero-sweep,.js-gsap .ppf-hero-sweep{animation:none;opacity:0}
  .ppf-hero-specular{transition:none}
}

/* ============================================================================
   FLAGSHIP: "Under the surface" exploded PPF layer diagram
   ----------------------------------------------------------------------------
   Seven photoreal renders plotted from one locked master camera. Every layer
   shares the same canvas, aspect ratio and object-fit, so they stay pixel
   aligned until the scroll sequence pulls them apart. Never give an individual
   layer its own sizing, cropping or aspect rule — the shared geometry is the
   entire illusion.

   Defaults below are the FULLY EXPLODED state with all labels showing. That is
   deliberate: no-JS and reduced-motion visitors get the complete diagram with
   no motion at all. assets/ppf-layers.js adds .ppf-ul--js and then drives the
   sequence, so a failed script degrades to a finished static diagram.
   ============================================================================ */
.ppf-ul{
  position:relative;background:var(--black);overflow-x:clip;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  --ul-w:min(52vw,760px,86vh);                /* stage width; vh cap protects the separation budget */
  /* Vertical separation unit. The floor matters: the gap between adjacent
     layers is 1.45x this, and each floating label is ~58px tall, so dropping
     below ~40px starts colliding labels on short laptop viewports. The ceiling
     keeps panel + full spread inside 100svh at every size checked. */
  --ul-u:clamp(40px,min(6.9vh,4.4vw),66px);
  /* horizontal drift: a real diagonal spread separates the layers without
     costing any vertical room, which is the scarce dimension on short screens */
  --ul-ux:clamp(6px,1.4vw,22px);
  --ul-anchor-y:42%;                          /* where leaders meet the panel */
  --ul-lead:62px;                             /* leader line length */
  --ul-labelw:264px;                          /* also feeds the centring calc below */
  --ul-headroom:clamp(88px,12vh,140px);       /* clears the nav, drops the stage below the copy */
  --ul-copy-top:clamp(84px,10.5vh,118px);       /* copy anchored to the viewport, not the stage */
}
/* Long runway on purpose. The six-layer sequence occupies ~80% of it, so a
   short track makes the whole panel come apart in a flick of the wheel. */
/* 260vh: 100svh pinned + 160vh of runway. The WINDOWS map in
   assets/ppf-layers.js is expressed as fractions of that runway, so the two
   must be changed together - see the note above WINDOWS. Was 360vh, a third
   of which was the completed diagram sitting still. */
.ppf-ul-track{height:260vh}
.ppf-ul-sticky{position:sticky;top:0;height:100svh;min-height:580px;display:block}
/* full-height inner, so .ppf-ul-copy can be anchored to the TOP OF THE VIEWPORT
   rather than to a vertically-centred box — otherwise the heading lands on top
   of the panel, which sits low-left at rest. The padding pushes the stage down
   clear of both the nav and the copy. */
.ppf-ul-inner{
  position:relative;height:100%;display:flex;align-items:center;
  padding-top:var(--ul-headroom)
}

/* restrained studio falloff + very fine grain. No colour, no blobs. */
/* width is 100%, never a vw value: a vw-sized centred element wider than the
   section pushes document scrollWidth out and gives the whole page a
   horizontal scrollbar on narrow viewports */
.ppf-ul-glow{
  position:absolute;left:50%;top:50%;width:100%;max-width:1420px;height:min(82vh,800px);
  transform:translate(-50%,-50%);pointer-events:none;
  background:
    radial-gradient(ellipse at center,rgba(255,255,255,.055) 0%,rgba(255,255,255,.02) 40%,transparent 72%),
    repeating-linear-gradient(0deg,rgba(255,255,255,.012) 0 1px,transparent 1px 3px)
}

/* ---- copy block: sits top-left over the empty upper canvas, then recedes
        as the panel dismantles so the diagram becomes the sole focus ---- */
.ppf-ul-copy{
  position:absolute;left:var(--gut);top:var(--ul-copy-top);max-width:390px;
  z-index:80;pointer-events:none;
  opacity:var(--copy-o,1);transform:translateY(calc(var(--copy-y,0) * 1px))
}
.ppf-ul-copy h2{font-size:clamp(1.85rem,3.2vw,2.7rem);line-height:1.08;margin:10px 0 0}
.ppf-ul-lead{color:var(--muted);margin:12px 0 0;font-size:1rem;max-width:330px}
/* Pinned to the bottom-left of the viewport, not stacked under the lead. The
   panel is a diagonal sweep sitting low on the left at rest, so a cue directly
   beneath the copy lands on top of it; down here the canvas is genuinely empty. */
.ppf-ul-cue{
  position:absolute;left:var(--gut);bottom:clamp(28px,5vh,56px);z-index:80;
  display:flex;align-items:center;gap:10px;margin:0;
  font-family:var(--display);font-size:11px;text-transform:uppercase;
  letter-spacing:.18em;color:var(--muted-2);opacity:var(--cue-o,1)
}
.ppf-ul-cue span{
  width:26px;height:1px;background:var(--red);flex:none;transform-origin:left center;
  animation:ppfUlCue 2.4s var(--ease-premium) infinite
}
@keyframes ppfUlCue{0%,100%{transform:scaleX(.35)}50%{transform:scaleX(1)}}

/* ---- the stage: one shared coordinate system for all seven images ---- */
/* --sep re-centres the composition. The layer offsets run from -5.32u to
   +1.45u, so the stack's midpoint drifts up by 1.935u as it separates; the
   figure eases down by exactly that to stay optically centred. Without full
   compensation the top film clips under the nav on short laptop viewports.
   A global translate does not alter relative spacing, so the body panel still
   reads as the anchor. Driven straight off scroll, so no transition here —
   it must not lag the scrub. All unit maths stays in CSS so ppf-layers.js
   only ever writes unitless numbers. */
/* Horizontal placement is scrubbed, not fixed. At rest the panel is CENTRED in
   the content area, because the label gutter on its right is still empty and a
   left-hugging panel reads as lopsided. As the layers separate and the labels
   arrive, the whole composition slides left to make room for them. Both ends
   are derived from the live widths, so it stays correct at every breakpoint.
   min() guards the slide so it can only ever move left, never drift right. */
.ppf-ul-figure{
  margin:0;display:flex;justify-content:flex-start;align-items:center;width:100%;
  --ul-rest-x:max(0px,calc((100% - var(--ul-w)) / 2));
  --ul-shift:min(0px,calc(
    max(0px,calc(100% - (var(--ul-w) * .97 + var(--ul-lead) + 14px + var(--ul-labelw) + var(--ul-ux) * 3)))
    - max(0px,calc((100% - var(--ul-w)) / 2))));
  transform:translate3d(
    calc(var(--ul-rest-x) + var(--ul-shift) * var(--sep,0)),
    calc(var(--ul-u) * 1.935 * var(--sep,0)),
    0)
}
/* parallax rides on the stage instead, where it can be smoothed without
   making the scroll-scrubbed separation feel mushy */
.ppf-ul-stage{
  position:relative;width:var(--ul-w);aspect-ratio:1672/941;flex:none;
  transform:translate3d(calc(var(--px,0) * 1px),calc(var(--py,0) * 1px),0);
  transition:transform .55s var(--ease-premium)
}
.ppf-ul-master,.ppf-ul-layer{position:absolute;inset:0}
.ppf-ul-master picture,.ppf-ul-layer picture{display:block;width:100%;height:100%}
.ppf-ul-master img,.ppf-ul-layer img{
  display:block;width:100%;height:100%;object-fit:contain;object-position:center;
  -webkit-user-drag:none;user-select:none
}
/* visible by default; only ppf-layers.js, which adds .ppf-ul--js once it has
   initialised and warmed its images, is allowed to fade it */
.ppf-ul-master{z-index:70;opacity:1}
.ppf-ul--js .ppf-ul-master{opacity:var(--master-o,0)}

.ppf-ul-layer{
  --p:1;                       /* 0 = assembled, 1 = fully separated */
  opacity:var(--o,1);
  transform:translate3d(
    calc(var(--tx) * var(--ul-ux) * var(--p)),
    calc(var(--ty) * var(--ul-u)  * var(--p)),
    0)
}
/* No drop-shadow on the moving layers. Safari repaints a filter on every
   frame while the layers translate: measured in real Safari 7 Oct 2026 at
   231ms a frame (about 4fps) with the four shadows, 33ms (its ceiling in
   that window) without. The shadow was 18% black and changed the finished
   diagram by 1.5/255 on average, so it is gone rather than worked around.
   Do not put a filter on .ppf-ul-layer or its img while it is animated. */
.ppf-ul.is-live .ppf-ul-layer,.ppf-ul.is-live .ppf-ul-master{will-change:transform,opacity}

/* one restrained studio strip-light pass over the assembled panel,
   masked to the silhouette so it never bleeds into the black */
.ppf-ul-sweep{
  position:absolute;inset:0;pointer-events:none;opacity:0;mix-blend-mode:screen;
  background:linear-gradient(105deg,transparent 38%,rgba(255,255,255,.26) 50%,transparent 62%);
  background-size:260% 100%;background-position:130% 0;
  -webkit-mask-image:url(/images/00-master-reference.webp);mask-image:url(/images/00-master-reference.webp);
  -webkit-mask-size:100% 100%;mask-size:100% 100%;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat
}
.ppf-ul.is-armed .ppf-ul-sweep{animation:ppfUlSweep 2.4s var(--ease-premium) .3s 1 both}
@keyframes ppfUlSweep{
  0%{opacity:0;background-position:130% 0}
  20%{opacity:1}
  80%{opacity:1}
  100%{opacity:0;background-position:-45% 0}
}

/* ---- technical leader line + label, carried by the layer they describe ---- */
.ppf-ul-leader{
  position:absolute;left:97%;top:var(--ul-anchor-y);
  width:var(--ul-lead);height:10px;margin-top:-5px;pointer-events:none
}
.ppf-ul-leader svg{display:block;width:100%;height:100%;overflow:visible}
.ppf-ul-leader line{
  stroke:rgba(242,242,244,.35);stroke-width:1;stroke-dasharray:120;stroke-dashoffset:0;
  transition:stroke-dashoffset .45s var(--ease-premium)
}
.ppf-ul-dot{
  position:absolute;left:-2px;top:50%;width:5px;height:5px;margin-top:-2.5px;
  border-radius:50%;background:var(--red);transform:scale(1);
  transition:transform .35s var(--ease-premium) .12s
}
/* width is tuned so the longest description wraps to two lines, not three —
   three would make the label taller than the gap between layers */
.ppf-ul-label{
  position:absolute;left:calc(97% + var(--ul-lead) + 14px);top:var(--ul-anchor-y);
  width:var(--ul-labelw);transform:translateY(-50%);opacity:1;pointer-events:none;
  transition:opacity .4s ease
}
.ppf-ul-label b{
  display:flex;align-items:baseline;gap:9px;font-family:var(--display);font-weight:600;
  font-size:12px;text-transform:uppercase;letter-spacing:.14em;color:var(--text)
}
.ppf-ul-label b em{font-style:normal;font-size:11px;color:var(--red);letter-spacing:.1em}
.ppf-ul-label small{display:block;margin-top:6px;color:var(--muted);font-size:12.5px;line-height:1.45}

/* JS-driven states. Only applied once the script confirms it is running. */
.ppf-ul--js .ppf-ul-leader line{stroke-dashoffset:120}
.ppf-ul--js .ppf-ul-dot{transform:scale(0)}
.ppf-ul--js .ppf-ul-label{opacity:0;transform:translateY(-50%) translateX(-8px);transition:opacity .4s ease,transform .4s var(--ease-premium)}
.ppf-ul--js .ppf-ul-layer.is-revealed .ppf-ul-leader line{stroke-dashoffset:0}
.ppf-ul--js .ppf-ul-layer.is-revealed .ppf-ul-dot{transform:scale(1)}
.ppf-ul--js .ppf-ul-layer.is-revealed .ppf-ul-label{opacity:1;transform:translateY(-50%) translateX(0)}
/* hierarchy comes from the text, never from dimming the photography */
.ppf-ul--js .ppf-ul-layer.is-revealed.is-dim .ppf-ul-label{opacity:.5}

/* ---- semantic index. Visually hidden on desktop (the floating labels carry
        the same words there); becomes the readable list on mobile. ---- */
/* the per-item layer image and the 01 / 06 progress belong to the phone
   sequence only; above 860px the exploded stage does the work and these never
   render, so only one set of layer renders is ever fetched */
.ppf-ul-step{display:none}
.ppf-ul-index{
  list-style:none;margin:0;padding:0;
  position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap
}

/* Narrower viewports shrink --ul-u to its floor, so the gap between layers
   stops shrinking while label text does not — labels must get SHORTER here,
   not narrower. There is spare width at this size, so widen them to force the
   longest description onto two lines instead of three. */
@media (max-width:1100px){
  /* the stage is narrower here, so the width-driven term can be more generous
     without the composition outgrowing 100svh — this buys back the label gap */
  .ppf-ul{--ul-w:min(56vw,660px,80vh);--ul-lead:40px;--ul-labelw:280px;
          --ul-u:clamp(46px,min(6.9vh,5.4vw),64px)}
  .ppf-ul-label small{font-size:12px;line-height:1.4}
  .ppf-ul-copy{max-width:300px}
}

/* ---- tablet: keep the sticky idea, shorter runway, tighter composition.
        Separation still must not drop below the label height, so --ul-u keeps
        the same floor as desktop and the labels get narrower instead. ---- */
@media (max-width:1000px) and (min-width:861px){
  .ppf-ul{--ul-w:min(58vw,620px,80vh);--ul-u:clamp(46px,min(6.9vh,6vw),62px);
          --ul-lead:30px;--ul-labelw:250px}
  .ppf-ul-track{height:250vh}
  .ppf-ul-label small{font-size:12px;line-height:1.4}
  .ppf-ul-copy{max-width:260px}
}

/* ---- phones and narrower tablets: ONE compact, explorable diagram ---------
   Replaces the old six-tall vertical list. The six registered renders are
   stacked in a single stage with a fixed step and a slight sideways drift, so
   every layer stays countable on a narrow screen without being a shrunken
   copy of the desktop explosion. No pinning, no scroll-driven motion.

   Geometry is pure CSS, so the static diagram is correct with no JavaScript:
     frame height = 941/1672 of a layer's width; each render's top 19% and
     bottom 15% is empty canvas; layers are 95.5% of the stage wide so the
     drift (4.3% of the stage at most) stays inside it. Stage height is then
     0.5375 x (0.66 + 5 x 0.19) = 0.865 of its width, plus a little room for
     the drop shadow. Change --m-step and the aspect-ratio together. */
@media (max-width:860px){
  .ppf-ul{--m-step:19%;--m-drift:.9%}
  .ppf-ul-track{height:auto}
  .ppf-ul-sticky{position:static;height:auto;min-height:0;padding:44px 0 0;display:block}
  .ppf-ul-inner{height:auto;display:block;padding-top:0}
  .ppf-ul-glow{height:380px}
  .ppf-ul-copy{
    position:static;max-width:none;
    opacity:1;transform:none              /* never fade the heading out on mobile */
  }
  .ppf-ul-copy h2{font-size:clamp(1.7rem,7vw,2.2rem)}
  .ppf-ul-copy h2 br{display:none}
  .ppf-ul-lead{max-width:none}
  .ppf-ul-cue{display:none}

  .ppf-ul-figure{display:block;margin:16px auto 0;max-width:460px;transform:none}
  .ppf-ul-stage{width:100%;aspect-ratio:1000 / 878;transform:none;transition:none}
  .ppf-ul-master,.ppf-ul-leader,.ppf-ul-label{display:none}
  .ppf-ul-layer{
    inset:auto;left:0;top:0;width:95.5%;aspect-ratio:1672 / 941;opacity:1;
    transform:translate3d(calc((5 - var(--i)) * var(--m-drift)), calc(-19% + var(--i) * var(--m-step)), 0)
  }

  /* compact mode: armed by ppf-layers.js once all six renders have decoded */
  .ppf-ul--compact .ppf-ul-layer{transition:opacity .22s ease}
  .ppf-ul--compact .ppf-ul-stage.has-sel .ppf-ul-layer{opacity:.38}
  .ppf-ul--compact .ppf-ul-stage.has-sel .ppf-ul-layer.is-sel{opacity:1}
  .ppf-ul--compact .ppf-ul-layer.is-sel img{
    filter:drop-shadow(0 0 12px rgba(225,27,34,.4)) drop-shadow(0 12px 26px rgba(0,0,0,.3))
  }
  .ppf-ul--compact .ppf-ul-index{display:none}
  .ppf-ul--compact .ppf-ul-inner{padding-bottom:40px}

  .ppf-ul-pick{display:grid;gap:10px;max-width:460px;margin:14px auto 0}
  .ppf-ul-pick-row{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}
  .ppf-ul-pick-k{
    grid-column:1 / -1;margin:0;font-family:var(--display);font-size:10.5px;
    letter-spacing:.16em;text-transform:uppercase;color:var(--muted-2)
  }
  .ppf-ul-btn{
    display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:3px;
    min-width:0;min-height:50px;padding:7px 10px;margin:0;border-radius:10px;cursor:pointer;text-align:left;
    background:var(--surface);border:1px solid var(--line);color:var(--muted);
    font-family:var(--display);font-size:11.5px;font-weight:600;line-height:1.2;
    letter-spacing:.05em;text-transform:uppercase;overflow-wrap:anywhere;
    -webkit-tap-highlight-color:transparent;
    transition:border-color .2s ease,background-color .2s ease,color .2s ease
  }
  .ppf-ul-btn em{font-style:normal;font-size:10.5px;letter-spacing:.1em;color:var(--red)}
  .ppf-ul-btn[aria-pressed="true"]{border-color:var(--red);background:rgba(225,27,34,.1);color:var(--text)}
  .ppf-ul-btn:focus-visible{outline:2px solid var(--red);outline-offset:2px}
  /* 320px screens (and 400% zoom): "INTERFACE" is the longest word and broke
     mid-word at the normal padding; this keeps every word whole */
  @media (max-width:359px){
    .ppf-ul-pick-row{gap:5px}
    .ppf-ul-btn{padding:7px 7px;font-size:11px;letter-spacing:.02em}
  }

  .ppf-ul-info{max-width:460px;margin:14px auto 0;min-height:6.4rem}
  .ppf-ul-info-k{
    display:flex;align-items:baseline;gap:10px;margin:0 0 6px;font-family:var(--display);
    font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted-2)
  }
  .ppf-ul-info-n{color:var(--red)}
  .ppf-ul-info-name{margin:0;font-family:var(--display);font-size:17px;letter-spacing:.1em;text-transform:uppercase;color:var(--text)}
  .ppf-ul-info-desc{margin:6px 0 0;color:var(--muted);font-size:14.5px;line-height:1.55}

  /* no JavaScript, or the renders did not all arrive: the static diagram above
     plus every name and description, compactly */
  /* the list is a .wrap, but the base rule's padding:0 would cancel the
     side gutter, so it is restated here: the text lines up with the diagram */
  .ppf-ul-index{
    position:static;width:auto;height:auto;overflow:visible;clip-path:none;white-space:normal;
    display:block;max-width:calc(460px + var(--gut) * 2);margin:20px auto 0;padding:0 var(--gut) 56px
  }
  /* a render failed to arrive: a stack with a layer missing would misdescribe
     the panel, so phones drop the diagram and the written list stands in */
  .ppf-ul--partial .ppf-ul-figure{display:none}
  .ppf-ul-index li{display:block;padding:14px 0;border-top:1px solid var(--line)}
  .ppf-ul-index li:last-child{border-bottom:1px solid var(--line)}
  .ppf-ul-step{
    display:flex;align-items:baseline;gap:10px;margin:0 0 4px;font-family:var(--display);
    font-size:11px;letter-spacing:.14em;text-transform:uppercase
  }
  .ppf-ul-idx{color:var(--red)}
  .ppf-ul-grp{color:var(--muted-2)}
  .ppf-ul-index h3{
    margin:0;font-family:var(--display);font-size:15px;text-transform:uppercase;
    letter-spacing:.1em;color:var(--text)
  }
  .ppf-ul-desc{margin:4px 0 0;color:var(--muted);font-size:14px;line-height:1.55}
}
.ppf-ul-pick[hidden],.ppf-ul-info[hidden]{display:none}
/* never show the browser's broken-image glyph inside the diagram; on desktop
   the layer's label and leader stay, so all six names are still on screen */
.ppf-ul-layer.is-missing picture{visibility:hidden}

/* short landscape phones: the stack beside its controls, not above them, and
   never taller than the screen. The min-width keeps a 400% zoomed desktop
   (320 x 256) on the single column: two columns there left 37px buttons. */
@media (max-width:860px) and (min-width:560px) and (orientation:landscape) and (max-height:560px){
  .ppf-ul-inner{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);column-gap:28px;align-items:start}
  .ppf-ul-copy{grid-column:1 / -1}
  .ppf-ul-figure{grid-column:1;grid-row:2 / span 2;margin:16px 0 0;max-width:min(100%, calc((100svh - 72px) * 1.08))}
  .ppf-ul-pick{grid-column:2;grid-row:2;margin:16px 0 0;max-width:none}
  .ppf-ul-info{grid-column:2;grid-row:3;margin:14px 0 0;max-width:none}
}

/* ---- reduced motion: the finished diagram, immediately, with no sequence ---- */
@media (prefers-reduced-motion:reduce){
  .ppf-ul-track{height:auto}
  .ppf-ul-sticky{position:static;height:auto;min-height:0;padding:76px 0 0;display:block}
  .ppf-ul-inner{height:auto;display:block;padding-top:0}
  .ppf-ul-copy{position:static;max-width:none;opacity:1;transform:none}
  .ppf-ul-cue{display:none}
  .ppf-ul-figure{margin-top:30px}
  .ppf-ul-master{opacity:0}
  .ppf-ul-sweep{animation:none;opacity:0}
  .ppf-ul-layer{--p:1;opacity:1}
  .ppf-ul-index li{opacity:1}
  .ppf-ul--compact .ppf-ul-layer,.ppf-ul-btn{transition:none}
}

.page-hero{position:relative;padding:170px 0 76px;overflow:hidden;border-bottom:1px solid var(--line)}
.page-hero.has-photo{min-height:100vh;min-height:100svh;display:flex;align-items:center;padding:150px 0 90px}
.page-hero::before{
  content:"";position:absolute;inset:0;z-index:0;
  background:
    radial-gradient(70% 90% at 80% 20%,rgba(225,27,34,.15),transparent 62%),
    linear-gradient(160deg,#151519,#0A0A0B);
}
.page-hero-photo{position:absolute;inset:0;z-index:0;background-size:cover;background-position:center 85%}
.page-hero-video{width:100%;height:100%;object-fit:cover;background-position:center 50%}
.page-hero .eyebrow{position:relative;z-index:2}
.page-hero.has-photo::before{
  background:linear-gradient(100deg,rgba(10,10,11,.98) 0%,rgba(10,10,11,.95) 34%,rgba(10,10,11,.68) 60%,rgba(10,10,11,.28) 100%)
}
/* art-directed hero: the shared scrim does the work, so the flat ::before wash
   is dropped. This photograph is a bright outdoor scene, which is why the
   breadcrumb and lead were hard to read at full strength. */
.page-hero.has-photo:has(.hero-full-media)::before{display:none}
/* 88svh, not 100: a full-viewport hero hides the fact there is a page below it,
   and on phones the browser chrome eats the bottom of it */
.page-hero.has-photo:has(.hero-full-media){min-height:min(88svh,820px)}
.page-hero.has-photo:has(.hero-full-media) .wrap{max-width:var(--maxw)}
.page-hero.has-photo:has(.hero-full-media) h1{max-width:14ch;text-shadow:0 2px 24px rgba(10,10,11,.55)}
.page-hero.has-photo:has(.hero-full-media) h1.h1-service{max-width:40ch}
.page-hero.has-photo:has(.hero-full-media) .lead{color:var(--text);max-width:52ch}
.page-hero.has-photo:has(.hero-full-media) .breadcrumb{color:var(--text);opacity:.8}
.page-hero.has-photo:has(.hero-full-media) .breadcrumb a{color:var(--text)}
.page-hero.has-photo:has(.hero-full-media) .breadcrumb li::after{color:rgba(242,242,244,.5)}
.page-hero.has-photo:has(.hero-full-media) .eyebrow{color:var(--text)}
/* ---- campaign hero: small service H1, large statement ------------------- */
/* The <h1> keeps the local search phrase and stays real, readable text; it is
   simply not the thing the eye lands on. Shrinking it to nothing or pushing it
   offscreen would be cloaking, so neither is done here. */
.page-hero .h1-service{
  font-family:var(--display);font-weight:600;
  font-size:clamp(.82rem,1.18vw,1rem);line-height:1.35;letter-spacing:.15em;
  text-transform:uppercase;color:rgba(242,242,244,.86);
  max-width:34ch;margin:0 0 20px
}
.page-hero .hero-statement{
  font-family:var(--display);font-weight:700;text-transform:uppercase;
  font-size:clamp(2.4rem,4.7vw,4rem);line-height:.94;letter-spacing:-.025em;
  margin:0 0 26px;color:var(--text);
  text-shadow:0 2px 30px rgba(10,10,11,.6),0 1px 4px rgba(10,10,11,.35)
}
.page-hero .hero-statement span{display:block}
.page-hero .hero-statement .is-accent{color:var(--red)}
.page-hero .hero-note{
  margin:18px 0 0;color:var(--muted);font-size:.95rem;
  text-shadow:0 1px 14px rgba(10,10,11,.6)
}
.page-hero .hero-note a{color:var(--text);text-decoration:underline;text-underline-offset:3px}
.page-hero .hero-note a:hover{color:var(--red)}
/* the copy column is held clear of the Ferrari rather than running under it */
.page-hero.has-photo:has(.hero-full-media) .lead{max-width:44ch}
/* navigation, not a headline */
.page-hero.has-photo:has(.hero-full-media) .breadcrumb{opacity:.5;font-size:11.5px}

/* the valeting scrim runs darker and opens sooner than the shared one: the
   Ferrari starts at about 31% of the frame and must not be dimmed */
.page-hero .hero-full-scrim{
  background:
    linear-gradient(90deg,
      rgba(10,10,11,.94) 0%,
      rgba(10,10,11,.90) 16%,
      rgba(10,10,11,.70) 30%,
      rgba(10,10,11,.40) 42%,
      rgba(10,10,11,.18) 55%,
      rgba(10,10,11,.07) 72%,
      rgba(10,10,11,.02) 100%),
    linear-gradient(0deg,
      rgba(10,10,11,.78) 0%,
      rgba(10,10,11,.22) 26%,
      transparent 50%);
}
@media (max-width:767px){
  /* dark across the copy at the top, then opening right up so the Ferrari and
     the van are the brightest things on the screen */
  .page-hero .hero-full-scrim{
    background:
      linear-gradient(180deg,
        rgba(10,10,11,.93) 0%,
        rgba(10,10,11,.87) 28%,
        rgba(10,10,11,.72) 50%,
        rgba(10,10,11,.52) 66%,
        rgba(10,10,11,.28) 80%,
        rgba(10,10,11,.14) 92%,
        rgba(10,10,11,.10) 100%);
  }
  .page-hero .h1-service{font-size:.74rem;letter-spacing:.13em;margin-bottom:14px;max-width:none}
  .page-hero .hero-statement{font-size:clamp(2.2rem,10.6vw,3.2rem);margin-bottom:18px}
  .page-hero .hero-note{font-size:.9rem;margin-top:14px}
  .page-hero.has-photo:has(.hero-full-media) .lead{max-width:none;margin:18px 0 26px;text-shadow:0 1px 16px rgba(10,10,11,.9)}
  .page-hero.has-photo:has(.hero-full-media) .h1-service,
  .page-hero.has-photo:has(.hero-full-media) .eyebrow,
  .page-hero.has-photo:has(.hero-full-media) .hero-note{text-shadow:0 1px 14px rgba(10,10,11,.9)}
}
@media (max-width:767px){
  /* The Ferrari sits along the bottom of this photograph and cannot be moved
     up by any crop, so on phones the copy goes to the TOP, over the sky, and
     the car is left alone underneath it. Bottom-aligning the copy buried the
     one thing the hero is selling. */
  .page-hero.has-photo:has(.hero-full-media){align-items:flex-start;min-height:min(96svh,820px);padding:100px 0 32px}
  .page-hero.has-photo:has(.hero-full-media) h1{max-width:none}
}
.page-hero .wrap{position:relative;z-index:2}
.page-hero h1{font-size:clamp(2.1rem,5.2vw,3.6rem);text-transform:uppercase;max-width:16ch}
.page-hero .lead{color:var(--muted);font-size:clamp(1.02rem,2vw,1.18rem);max-width:600px;margin:22px 0 32px}
.page-hero .hero-actions{display:flex;gap:14px;flex-wrap:wrap}

.breadcrumb{display:flex;flex-wrap:wrap;gap:8px;list-style:none;font-size:13.5px;color:var(--muted-2);margin-bottom:22px}
.breadcrumb li::after{content:"/";margin-left:8px;color:var(--muted-2)}
.breadcrumb li:last-child::after{content:""}
.breadcrumb a{color:var(--muted)}
.breadcrumb a:hover{color:var(--white)}

/* accreditation strip ----------------------------------------------------- */
.accred{background:var(--surface);border-bottom:1px solid var(--line)}
.accred .wrap{display:flex;align-items:center;justify-content:center;gap:12px 44px;flex-wrap:wrap;padding:20px var(--gut);text-align:center}   /* keeps .wrap's side gutters */
@media (max-width:640px){.accred .wrap{gap:8px 22px;padding:16px var(--gut)}.accred span{font-size:11.5px;letter-spacing:.12em}}
.accred span{
  font-family:var(--display);font-weight:700;font-size:12.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted)
}

/* two-column prose intro -------------------------------------------------- */
.intro{display:grid;grid-template-columns:1fr 1.25fr;gap:60px;align-items:start}
/* aligns the first line of copy with the top of the photograph, and only
   means anything while the grid is two columns. See the single-column
   override below, where it becomes 184px of empty page. */
.intro.has-photo .body{margin-top:150px}
.intro .body{max-width:62ch}
.intro h2{font-size:clamp(1.8rem,3.8vw,2.6rem)}
.intro .body p{color:var(--muted)}
.intro .body p:first-child{color:var(--text);font-size:1.1rem}

/* pricing tiers ----------------------------------------------------------- */
.tiers{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;align-items:stretch}
.tier{
  display:flex;flex-direction:column;padding:34px 28px;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r-lg);position:relative;transition:border-color .25s,transform .25s
}
.tier:hover{border-color:var(--line-2);transform:translateY(-4px)}
.tier.featured{border-color:var(--red);background:var(--elev)}
.tier .flag{
  position:absolute;top:-11px;left:28px;z-index:1;background:var(--red);color:#fff;font-family:var(--display);
  font-weight:700;font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;padding:5px 11px;border-radius:var(--r)
}
.tier h3{font-size:1.3rem;margin-bottom:8px}
.tier .sub{color:var(--muted);font-size:14.5px;margin-bottom:22px;min-height:44px}
.tier .price{font-family:var(--display);font-weight:700;font-size:2.1rem;line-height:1;display:block}
.tier .price small{display:block;font-family:var(--body);font-weight:500;font-size:12.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted-2);margin-bottom:6px}
.tier ul{list-style:none;margin:24px 0 26px;flex:1}
.tier li{display:flex;gap:11px;padding:9px 0;font-size:14.6px;color:var(--muted);border-bottom:1px solid var(--line)}
.tier li.tier-group{
  border-bottom:0;padding:16px 0 4px;font-family:var(--display);font-weight:700;font-size:11px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--red)
}
.tier li.tier-group:first-child{padding-top:0}
.tier-best{font-size:13.5px;color:var(--muted);line-height:1.55;margin:18px 0 22px;padding-top:18px;border-top:1px solid var(--line)}
.tier-includes{display:block;color:var(--muted);font-size:12.5px;margin-top:6px}
.tier li.tier-hidden{display:none}
.tier.is-expanded li.tier-hidden{display:flex}
.tier-toggle{
  display:inline-flex;align-items:center;background:none;border:0;padding:12px 0 2px;margin:0;
  color:var(--red);font-family:var(--display);font-weight:700;font-size:12px;letter-spacing:.06em;
  text-transform:uppercase;cursor:pointer
}
.tier-toggle:hover{text-decoration:underline}
.tier-upsell{
  display:flex;align-items:flex-start;gap:10px;margin:16px 0 4px;padding:12px 14px;border-radius:var(--r);
  background:var(--red-soft);font-size:13px;line-height:1.55;color:var(--text)
}
.tier-upsell svg{width:17px;height:17px;color:var(--red);flex:none;margin-top:2px}
.tier-best b{color:var(--text);font-family:var(--display);font-weight:700}
.tier li:last-child{border-bottom:0}
.tier li svg{width:15px;height:15px;flex:none;margin-top:4px;color:var(--red)}
.tier .btn{width:100%}

/* price placeholder — deliberately loud so it cannot ship by accident */
.tbc{
  color:var(--red)!important;background:rgba(225,27,34,.12);
  outline:2px dashed var(--red);outline-offset:3px;border-radius:3px;padding:0 6px
}
.price-note{
  margin-top:26px;padding:18px 22px;border:1px solid var(--line);border-left:3px solid var(--red);
  border-radius:var(--r);background:var(--surface);color:var(--muted);font-size:14.5px
}
.price-note p{margin:0}

/* process steps ----------------------------------------------------------- */
.process{list-style:none;counter-reset:step;display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.process li{counter-increment:step;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:28px 24px}
.process li::before{
  content:"0" counter(step);display:block;font-family:var(--display);font-weight:700;font-size:13px;
  letter-spacing:.14em;color:var(--red);margin-bottom:14px
}
.process b{font-family:var(--display);font-size:1.05rem;display:block;margin-bottom:8px}
.process p{margin:0;color:var(--muted);font-size:14.6px}

/* benefits ---------------------------------------------------------------- */
.benefits{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.benefit{padding:28px;border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface)}
.benefit .ic{width:40px;height:40px;border-radius:var(--r);background:var(--red-soft);color:var(--red);display:grid;place-items:center;margin-bottom:18px}
.benefit .ic svg{width:20px;height:20px}
.benefit b{font-family:var(--display);font-size:1.05rem;display:block;margin-bottom:8px}
.benefit p{margin:0;color:var(--muted);font-size:14.6px}

/* contact page ------------------------------------------------------------ */
.contact-grid{display:grid;grid-template-columns:1fr 1.15fr;gap:56px;align-items:start}
.contact-card{border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface);padding:26px;margin-bottom:14px}
.contact-card small{display:block;font-family:var(--display);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted-2);margin-bottom:9px}
.contact-card b{font-family:var(--display);font-size:1.08rem;line-height:1.5}
.contact-card address{font-style:normal;font-family:var(--display);font-weight:600;font-size:1.05rem;line-height:1.6}

.field{margin-bottom:18px}
.field label{display:block;font-family:var(--display);font-weight:600;font-size:13.5px;letter-spacing:.04em;margin-bottom:8px}
.field-opt{font-family:var(--body);font-weight:400;letter-spacing:0;color:var(--muted)}
.field input,.field select,.field textarea{
  width:100%;padding:14px 16px;background:var(--black);color:var(--text);
  border:1px solid var(--line);border-radius:var(--r);font-family:var(--body);font-size:15.5px;
  transition:border-color .2s
}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--red);outline:none}
.field textarea{min-height:130px;resize:vertical}
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.form-note{color:var(--muted-2);font-size:13px;margin-top:14px}
.form-status{margin-top:16px;padding:14px 18px;border-radius:var(--r);display:none;font-size:14.5px}
.form-status.ok{display:block;background:rgba(46,160,67,.14);border:1px solid rgba(46,160,67,.5);color:#7EE787}
.form-status.err{display:block;background:var(--red-soft);border:1px solid var(--red);color:#FF8A8F}

/* full-bleed map on the contact page — deliberately outside .wrap so it
   spans edge to edge under the details/form grid */
.map-full{width:100%;background:var(--elev);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.map-full iframe{display:block;width:100%;height:450px;border:0}
@media (max-width:640px){.map-full iframe{height:320px}}

@media (max-width:1024px){
  .intro{grid-template-columns:1fr;gap:28px}
  /* single column: the desktop alignment offset would be a blank hole */
  .intro.has-photo .body{margin-top:0}
  .intro .body{max-width:none}
  .tiers{grid-template-columns:1fr}
  .process{grid-template-columns:1fr 1fr}
  .benefits{grid-template-columns:1fr 1fr}
  .contact-grid{grid-template-columns:1fr;gap:44px}
  .page-hero{padding:140px 0 60px}
  .page-hero.has-photo{padding:130px 0 60px}
}
@media (max-width:640px){
  /* PHONES: an integrated numbered sequence, not six stacked cards. Same six
     steps, a thin rail down the left, one rule between each. Roughly half the
     height of the card treatment and far easier to scan. Shared with
     /valeting/, which had the same six-card problem. */
  .process{grid-template-columns:1fr;gap:0;position:relative}
  .process li{
    background:none;border:0;border-radius:0;border-bottom:1px solid var(--line);
    padding:18px 0 18px 46px;position:relative
  }
  .process li:last-child{border-bottom:0;padding-bottom:0}
  .process li::before{
    position:absolute;left:0;top:18px;width:30px;height:30px;
    display:grid;place-items:center;border-radius:50%;
    border:1px solid var(--line-2);background:var(--black);color:var(--red);
    font-size:11px;letter-spacing:.06em;margin:0
  }
  /* the rail: a hairline joining the step markers */
  .process::before{
    content:"";position:absolute;left:15px;top:32px;bottom:14px;width:1px;background:var(--line);z-index:0
  }
  .process li::before{z-index:1}
  .process b{margin-bottom:5px;font-size:1rem}
  .process p{font-size:14.2px;line-height:1.55}
  .benefits{grid-template-columns:1fr}
  .field-row{grid-template-columns:1fr}
}

/* four-package layouts (valeting, paint correction) */
.tiers.four{grid-template-columns:repeat(4,1fr);gap:14px}
.tiers.four .tier{padding:30px 22px}
.tiers.four .tier h3{font-size:1.15rem}
.tiers.four .tier .price{font-size:1.85rem}
@media (max-width:1100px){.tiers.four{grid-template-columns:repeat(2,1fr)}}
@media (max-width:640px){.tiers.four{grid-template-columns:1fr}}

/* ==========================================================================
   DROPDOWN NAV
   ========================================================================== */
.nav-links .has-sub{position:relative}
.nav-links .has-sub > a{display:inline-flex;align-items:center;gap:6px}
.nav-links .chev{width:14px;height:14px;transition:transform .25s}
.nav-links .has-sub:hover .chev,.nav-links .has-sub:focus-within .chev{transform:rotate(180deg)}
.nav-links .sub{
  position:absolute;top:100%;left:-20px;min-width:290px;list-style:none;
  background:rgba(17,17,19,.98);backdrop-filter:blur(14px);
  border:1px solid var(--line);border-radius:var(--r-lg);padding:8px;
  box-shadow:var(--shadow);opacity:0;visibility:hidden;transform:translateY(10px);
  transition:opacity .22s ease,transform .22s ease,visibility .22s;z-index:120
}
/* invisible bridge so the menu doesn't close crossing the gap */
.nav-links .has-sub::after{content:"";position:absolute;top:100%;left:0;right:0;height:18px}
.nav-links .has-sub:hover .sub,.nav-links .has-sub:focus-within .sub{opacity:1;visibility:visible;transform:none}
.nav-links .sub li{margin:0}
.nav-links .sub a{
  display:block;padding:12px 14px;border-radius:var(--r);font-size:14.5px;
  color:var(--muted);transition:background .2s,color .2s
}
.nav-links .sub a:hover{background:var(--red-soft);color:var(--white)}

.mobile-nav .sub-head{
  padding:15px 2px 8px;font-family:var(--display);font-weight:700;font-size:12px;
  letter-spacing:.18em;text-transform:uppercase;color:var(--muted-2);border-bottom:1px solid var(--line)
}
.mobile-nav .sub-item a{padding-left:18px;font-size:15.5px;color:var(--muted)}
.mobile-nav .sub-item a::before{content:"—";margin-right:10px;color:var(--red)}

/* ==========================================================================
   BLOG
   ========================================================================== */
.post-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.post-card{
  display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);overflow:hidden;transition:border-color .25s
}
.post-card:hover{border-color:var(--line-2)}
.blog-all{margin:28px 0 0}
.post-card .thumb{aspect-ratio:16/9;background:linear-gradient(140deg,#1d1d22,#101013);position:relative;overflow:hidden;display:block}
.post-card .thumb img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .7s var(--ease-premium)}
.post-card:hover .thumb img{transform:scale(1.02)}
.post-card .thumb:not(:has(img))::after{content:"";position:absolute;inset:0;background:radial-gradient(60% 70% at 35% 30%,rgba(225,27,34,.18),transparent 65%)}
.post-card .body{padding:22px 24px 24px;display:flex;flex-direction:column;flex:1}
.post-card .cat{font-family:var(--display);font-weight:700;font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--red);margin-bottom:10px}
.post-card h3{font-size:1.18rem;line-height:1.25;margin-bottom:10px}
.post-card h3 a:hover{color:var(--red)}
.post-card p{color:var(--muted);font-size:14.6px;flex:1;margin-bottom:14px}
.post-card .meta{font-size:12.5px;color:var(--muted-2);display:flex;gap:10px;align-items:center}

/* article body */
/* article body: 17.5px / 1.72 on a 720px measure. The opening paragraph
   is the answer, so it reads a step larger and in full-strength text. */
.article{max-width:760px;margin:0 auto;font-size:17.5px;line-height:1.72}
.article > p:first-of-type{font-size:1.1em;color:var(--text);line-height:1.6}
.article p{color:var(--muted);font-size:1em;line-height:inherit;margin:0 0 1.3em}
.article h2{font-size:clamp(1.45rem,2.6vw,1.85rem);line-height:1.15;margin:2.1em 0 .6em;scroll-margin-top:calc(var(--hdr-h) + 24px)}
.article h3{font-size:1.2rem;line-height:1.25;margin:1.7em 0 .5em}
.article ul,.article ol{margin:0 0 1.5em;padding-left:22px;color:var(--muted)}
.article li{margin-bottom:.55em;font-size:1em;line-height:1.65}
.article li::marker{color:var(--red)}
.article strong{color:var(--text);font-weight:600}
/* links: colour and an underline, so they read as links without the red */
.article a{color:var(--red);text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px;transition:color .2s}
.article a:hover{color:var(--white)}
.article figcaption,.article .note{font-size:.88em;color:var(--muted-2);line-height:1.55}
.article figure{margin:1.6em 0}
.article img{border-radius:var(--r);border:1px solid var(--line)}
/* tables: full width, and a wide one scrolls inside .table-wrap (added by
   blog.py), never the page */
.table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:0 0 1.6em;border:1px solid var(--line);border-radius:var(--r)}
.article table{width:100%;border-collapse:collapse;font-size:.92em;color:var(--muted)}   /* a genuinely wide table still scrolls inside .table-wrap */
.article th,.article td{padding:12px 14px;text-align:left;vertical-align:top;border-bottom:1px solid var(--line)}
@media (max-width:640px){.article th,.article td{padding:10px 10px;font-size:.95em}}
.article th{font-family:var(--display);font-weight:700;font-size:.82em;letter-spacing:.08em;text-transform:uppercase;color:var(--text);background:var(--surface)}
.article th[scope=row]{white-space:nowrap}
@media (max-width:640px){.article th[scope=row]{white-space:normal}}
.article .nowrap{white-space:nowrap}
.article th .note{display:block;font-family:var(--body);font-weight:500;letter-spacing:0;text-transform:none;font-size:.9em;color:var(--muted-2);margin-top:2px}
.article .table-wrap + .note{margin-top:-.9em;margin-bottom:1.8em}
.article tr:last-child td{border-bottom:0}
@media (max-width:640px){.article{font-size:17px;line-height:1.7}.article h2{margin-top:1.8em}}
.article-meta{display:flex;gap:14px;align-items:center;color:var(--muted-2);font-size:13.5px;margin-top:18px}
/* a genuinely useful aside: a left rule and a little air, not a box */
.callout{
  border-left:2px solid var(--red);padding:6px 0 6px 22px;margin:1.9em 0
}
.callout p{margin:0 0 .8em}
.callout p:last-child{margin:0}
.callout b{color:var(--text);font-family:var(--display)}

@media (max-width:1024px){.post-grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:640px){.post-grid{grid-template-columns:1fr}}

/* ==========================================================================
   ADVICE LIBRARY — /blog/ landing page only (.lib-*). Article pages and the
   homepage keep .post-card; nothing here reaches them.
   ========================================================================== */
.lib-intro{padding:calc(var(--hdr-h) + 48px) 0 40px;border-bottom:1px solid var(--line)}
.lib-crumbs{margin-bottom:30px}
.lib-head{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,.6fr);gap:28px 56px;align-items:end}
.lib-eyebrow{margin-bottom:18px}
.lib-title{font-size:clamp(2.3rem,4.8vw,4.25rem);text-transform:uppercase;line-height:.96;letter-spacing:-.025em}
.lib-line{display:block;overflow:hidden;padding-bottom:.1em;margin-bottom:-.1em}
.lib-line > span{display:block}
.lib-lead{color:var(--muted);font-size:1.06rem;line-height:1.6;max-width:420px;margin:0 0 .3em}

.lib{padding:34px 0 96px}
.lib [hidden]{display:none!important}

/* search + type filters. Rendered only with scripting: a search box that
   cannot search is worse than no search box. */
.lib-tools{display:none}
.js .lib-tools{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:16px 32px;align-items:end}
.lib-label{display:block;font-family:var(--display);font-weight:700;font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin-bottom:10px}
.lib-field{position:relative;display:flex;align-items:center}
.lib-field-icon{position:absolute;left:16px;width:18px;height:18px;color:var(--muted-2);pointer-events:none;transition:color .2s}
.lib-field:focus-within .lib-field-icon{color:var(--text)}
.lib-input{
  width:100%;min-height:52px;padding:12px 50px 12px 46px;background:var(--surface);
  border:1px solid var(--line-2);border-radius:var(--r);color:var(--text);
  font:500 16px/1.4 var(--body);-webkit-appearance:none;appearance:none;
  transition:border-color .2s,background .2s,box-shadow .2s
}
.lib-input::placeholder{color:var(--muted-2);opacity:1}
.lib-input:hover{border-color:rgba(255,255,255,.32)}
.lib-input:focus{outline:none;border-color:var(--red);background:var(--elev);box-shadow:0 0 0 3px rgba(225,27,34,.22)}
.lib-input::-webkit-search-cancel-button,.lib-input::-webkit-search-decoration{-webkit-appearance:none;display:none}
.lib-clear{position:absolute;right:6px;width:40px;height:40px;display:grid;place-items:center;background:none;border:0;border-radius:var(--r);color:var(--muted);cursor:pointer;transition:color .2s,background .2s}
.lib-clear:hover{color:#fff;background:rgba(255,255,255,.06)}
.lib-clear svg{width:16px;height:16px}
.lib-cats{display:flex;flex-wrap:wrap;gap:0 22px}
.lib-cat{
  position:relative;min-height:44px;padding:10px 2px;background:none;border:0;cursor:pointer;
  font-family:var(--display);font-weight:600;font-size:14px;letter-spacing:.02em;color:var(--muted);transition:color .2s
}
/* active = heavier text AND an underline, never colour alone */
.lib-cat::after{content:"";position:absolute;left:0;right:0;bottom:6px;height:2px;background:var(--red);transform:scaleX(0);transform-origin:left;transition:transform .25s var(--ease-premium)}
.lib-cat:hover{color:var(--text)}
.lib-cat:active{color:#fff}
.lib-cat[aria-pressed="true"]{color:#fff;font-weight:700}
.lib-cat[aria-pressed="true"]::after{transform:scaleX(1)}
.lib-topic label{display:block;font-family:var(--display);font-weight:700;font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin-bottom:10px}
.lib-topic select{min-height:52px;width:100%;padding:12px 40px 12px 16px;background:var(--surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A2A2AA' stroke-width='2.4'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") no-repeat right 14px center/14px;border:1px solid var(--line-2);border-radius:var(--r);color:var(--text);font:500 16px var(--body);-webkit-appearance:none;appearance:none}
.lib-topic select:focus{outline:none;border-color:var(--red);box-shadow:0 0 0 3px rgba(225,27,34,.22)}

.lib-status{display:none}
.js .lib-status{display:flex;align-items:center;gap:18px;margin:22px 0 22px;padding-top:16px;border-top:1px solid var(--line)}
.lib-count{margin:0;font-size:13.5px;color:var(--muted);letter-spacing:.01em}
.lib-reset{background:none;border:0;padding:8px 0;font-family:var(--display);font-weight:700;font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--red);cursor:pointer;transition:color .2s}
.lib-reset:hover{color:#fff}

/* results. Editorial: the featured article takes two thirds and two rows,
   the next two stack beside it, anything further flows in a grid beneath.
   Filtered: a plain, consistent grid, ranked when there is a query. */
.lib-results{display:grid;gap:18px;grid-template-columns:repeat(3,minmax(0,1fr));transition:opacity .18s ease}
.lib-results.is-updating{opacity:.35}
.lib-results.is-editorial .lib-card.is-featured{grid-column:1/3;grid-row:1/3}
.lib-card{position:relative;display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--line);border-radius:var(--r);transition:border-color .25s}
.lib-card:hover{border-color:var(--line-2)}
.lib-card-media{position:relative;aspect-ratio:16/9;overflow:hidden;background:linear-gradient(140deg,#1d1d22,#101013)}
.lib-card-pic{display:block;width:100%;height:100%}
.lib-card-pic img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .7s var(--ease-premium)}
.lib-card:hover .lib-card-pic img{transform:scale(1.02)}
/* TODO: real article photographs land here — replace the gradient with an <img> in library_card() */
.lib-card-media:not(:has(img))::after{content:"";position:absolute;inset:0;background:radial-gradient(60% 70% at 35% 30%,rgba(225,27,34,.16),transparent 65%)}
.lib-card-body{padding:20px 22px 22px;display:flex;flex-direction:column;gap:10px;flex:1}
.lib-card-cat{margin:0;font-family:var(--display);font-weight:700;font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--red)}
.lib-card-title{font-size:1.2rem;line-height:1.22;letter-spacing:-.01em;margin:0}
.lib-card-title a{color:var(--text);transition:color .2s}
/* one link per card, stretched over it: one tab stop, no hidden anchors */
.lib-card-title a::after{content:"";position:absolute;inset:0;border-radius:var(--r)}
.lib-card:hover .lib-card-title a{color:#fff}
.lib-card-sum{margin:0;color:var(--muted);font-size:14.8px;line-height:1.6}
.lib-card-meta{margin:auto 0 0;display:flex;align-items:center;gap:8px;padding-top:8px;font-size:12.5px;color:var(--muted-2)}
.lib-card-cta{margin:2px 0 0;display:inline-flex;align-items:center;gap:6px;font-family:var(--display);font-weight:700;font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--red)}
.lib-card-cta span{transition:transform .2s}
.lib-card:hover .lib-card-cta span{transform:translateX(3px)}
.lib-card-title a:focus-visible{outline:2px solid var(--red);outline-offset:3px}
@supports selector(:has(a)){
  .lib-card-title a:focus-visible{outline:none}
  .lib-card:has(a:focus-visible){outline:2px solid var(--red);outline-offset:3px}
}
/* the featured article, in the editorial arrangement: type on the left,
   media on the right, so the lead reads as a headline rather than a box */
.is-editorial .lib-card.is-featured{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr)}
.is-editorial .lib-card.is-featured .lib-card-media{order:2;aspect-ratio:auto;min-height:100%;border-left:1px solid var(--line)}
.is-editorial .lib-card.is-featured .lib-card-body{order:1;padding:30px 30px 30px;gap:14px;justify-content:center}
.is-editorial .lib-card.is-featured .lib-card-meta{margin-top:4px}
.is-editorial .lib-card.is-featured .lib-card-title{font-size:clamp(1.55rem,2.5vw,2.1rem);line-height:1.1;letter-spacing:-.02em}
.is-editorial .lib-card.is-featured .lib-card-sum{font-size:1.02rem;max-width:600px}
/* The two supporting articles beside the featured one stay text-led above
   1024px. Tried showing their thumbnails once real photographs existed: the
   featured card shares its grid row with this pair, so the extra 2x159px
   stretched the lead photograph's frame to 361x925 and it showed a narrow
   vertical sliver of the car. The pair keeps its images at every other size
   and in every other listing. */
.is-editorial .lib-card:not(.is-featured):nth-child(-n+3) .lib-card-media{display:none}
.is-editorial .lib-card:not(.is-featured):nth-child(-n+3) .lib-card-body{padding:22px 22px 22px}

.lib-empty{padding:44px 24px;border:1px dashed var(--line-2);border-radius:var(--r);text-align:center;color:var(--muted)}
.lib-empty-title{font-family:var(--display);font-weight:700;font-size:1.25rem;color:var(--text);margin:0 0 6px}
.lib-empty p{margin:0}
.lib-empty-reset{margin-top:20px}

/* ==========================================================================
   ARTICLE PAGE — /blog/<slug>/ (.post-*). Header, reading column, contents,
   "at a glance", next step, related. The body itself is .article, below.
   ========================================================================== */
.post-head{padding:calc(var(--hdr-h) + 44px) 0 40px;border-bottom:1px solid var(--line)}
.post-crumbs{margin-bottom:30px}
.post-head-inner{max-width:860px}
.post-cat{margin:0 0 16px;font-family:var(--display);font-weight:700;font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--red)}
/* the title keeps its published case and wraps naturally in a wide column */
.post-title{font-size:clamp(1.9rem,4vw,3.15rem);line-height:1.08;letter-spacing:-.02em;text-wrap:balance}
.post-intro{margin:20px 0 0;color:var(--muted);font-size:clamp(1.05rem,1.5vw,1.2rem);line-height:1.6;max-width:720px}
.post-meta{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;margin:22px 0 0;font-size:13.5px;color:var(--muted)}
.post-meta .post-author{color:var(--text);font-weight:500}
.post-meta-sep{color:var(--muted-2)}

/* reading layout: contents rail + 720px reading column, centred together */
.post-layout{display:grid;grid-template-columns:minmax(0,720px);justify-content:center;gap:0 72px;padding:48px var(--gut) 80px}   /* keeps .wrap's gutters */
.post-layout.has-toc{grid-template-columns:200px minmax(0,720px)}
.post-body{min-width:0}
.post-toc{min-width:0}
.post-toc-desk{position:sticky;top:calc(var(--hdr-h) + 36px);padding-top:6px}
.post-toc-label{margin:0 0 12px;font-family:var(--display);font-weight:700;font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted-2)}
.post-toc ol{list-style:none;margin:0;padding:0;border-left:1px solid var(--line)}
.post-toc li{margin:0}
.post-toc a{
  display:block;padding:7px 0 7px 14px;margin-left:-1px;border-left:2px solid transparent;
  font-size:13.5px;line-height:1.4;color:var(--muted);transition:color .2s,border-color .2s
}
.post-toc a:hover{color:var(--text)}
.post-toc a[aria-current="true"]{color:var(--text);border-left-color:var(--red)}
.post-toc-m{display:none}

/* "At a glance": a ruled passage, not a card */
.post-glance{margin:0 0 36px;padding:4px 0 22px;border-bottom:1px solid var(--line)}
.post-glance-label{margin:0 0 10px;font-family:var(--display);font-weight:700;font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--red)}
.post-glance p:last-child{margin:0;font-size:1.12rem;line-height:1.65;color:var(--text)}

/* the one contextual next step, after the body */
.post-next{margin:52px 0 0;padding:30px 0 0;border-top:1px solid var(--line)}
.post-next .eyebrow{margin-bottom:12px}
.post-next-title{font-size:1.45rem;line-height:1.15;margin:0 0 10px}
.post-next p{color:var(--muted);max-width:560px;margin:0 0 20px}

/* related */
.post-related-head{margin-bottom:34px}
.post-rel-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px}
.post-related-all{margin:30px 0 0}

/* reading progress: a hairline under the fixed header, desktop only,
   scaled with a transform so it never touches layout or width */
.post-progress{position:fixed;top:var(--hdr-h);left:0;width:100%;height:2px;z-index:99;background:var(--red);transform:scaleX(0);transform-origin:left;pointer-events:none;display:none}
@media (min-width:1025px){.js .post-progress{display:block}}

/* entrance pre-states, GSAP-gated */
.js-gsap .post-crumbs,.js-gsap .post-cat,.js-gsap .post-title,.js-gsap .post-intro,.js-gsap .post-meta{opacity:0}

@media (max-width:1024px){
  .post-head{padding:calc(var(--hdr-h) + 34px) 0 32px}
  .post-crumbs{margin-bottom:22px}
  .post-layout,.post-layout.has-toc{grid-template-columns:minmax(0,720px);gap:0;padding:32px var(--gut) 64px}
  .post-toc-desk{display:none}
  /* phones and tablets: a collapsed disclosure near the top of the article */
  .post-toc-m{display:block;margin:0 0 30px;border:1px solid var(--line);border-radius:var(--r);background:var(--surface)}
  .post-toc-m summary{
    display:flex;align-items:center;justify-content:space-between;gap:16px;cursor:pointer;list-style:none;
    padding:14px 18px;min-height:48px;font-family:var(--display);font-weight:700;font-size:13px;letter-spacing:.12em;text-transform:uppercase;color:var(--text)
  }
  .post-toc-m summary::-webkit-details-marker{display:none}
  .post-toc-m summary::after{content:"+";color:var(--red);font-size:1.4rem;font-weight:400;line-height:1;transition:transform .25s var(--ease-premium)}
  .post-toc-m[open] summary::after{transform:rotate(45deg)}
  .post-toc-m ol{border-left:0;padding:0 18px 12px}
  .post-toc-m a{padding:10px 0;border-left:0;margin:0;border-top:1px solid var(--line);font-size:15px}
  .post-toc-m a[aria-current="true"]{color:var(--text)}
  .post-rel-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:640px){
  .post-title{font-size:clamp(1.75rem,7.6vw,2.4rem)}
  .post-intro{font-size:1.02rem}
  .post-glance{margin-bottom:30px}
  .post-glance p:last-child{font-size:1.05rem}
  .post-next{margin-top:40px}
  .post-rel-grid{grid-template-columns:1fr;gap:14px}
}

/* ==========================================================================
   CERAMIC COATING & PAINT CORRECTION — hero only (.cc-*). Scoped to that
   page; the PPF, valeting and location heroes are untouched.
   ========================================================================== */
.cc-hero{position:relative;background:var(--black);border-bottom:1px solid var(--line);overflow:hidden;overflow:clip}
/* full-bleed: the car fills the hero, the type sits in the dark left side */
.cc-hero.has-media{min-height:min(88svh,820px);display:flex;align-items:center}
.cc-hero.has-media .cc-hero-grid{grid-template-columns:minmax(0,.58fr) minmax(0,.42fr);position:relative;z-index:2}
.cc-hero.has-media .cc-hero-lead{color:var(--text);max-width:48ch}
@media (max-width:1024px){
  .cc-hero.has-media{min-height:min(84svh,720px)}
  .cc-hero.has-media .cc-hero-grid{grid-template-columns:minmax(0,.72fr) minmax(0,.28fr)}
}
@media (max-width:767px){
  .cc-hero.has-media{min-height:min(84svh,660px);align-items:flex-end}
  .cc-hero.has-media .cc-hero-grid{grid-template-columns:1fr}
}
/* a soft studio falloff behind the type, so the left column is not flat black */
.cc-hero::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background:radial-gradient(62% 70% at 12% 34%,rgba(225,27,34,.10),transparent 62%),
             linear-gradient(160deg,#141418 0%,var(--black) 58%)}
.cc-hero-grid{position:relative;z-index:1;display:grid;grid-template-columns:minmax(0,1.22fr) minmax(0,.78fr);
  gap:56px;align-items:center;padding-top:calc(var(--hdr-h) + 56px);padding-bottom:64px}
.cc-hero-copy{max-width:700px}
.cc-hero-crumbs{margin:0 0 24px;opacity:.55;font-size:11.5px}
.cc-hero-crumbs a{color:var(--text)}
.cc-hero-crumbs li::after{color:rgba(242,242,244,.45)}
.cc-hero-eyebrow{margin-bottom:20px}
/* the H1 carries service + location and stays legible, but the campaign line
   below it is the larger type */
.cc-hero-h1{font-size:clamp(.92rem,1.25vw,1.06rem);line-height:1.35;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted);font-weight:600;margin:0 0 18px;max-width:30ch}
.cc-hero-statement{font-family:var(--display);font-weight:700;font-size:clamp(2.1rem,4vw,3.35rem);
  line-height:.98;letter-spacing:-.025em;text-transform:uppercase;margin:0;color:var(--text)}
.cc-line{display:block;overflow:hidden;padding-bottom:.08em;margin-bottom:-.08em}
.cc-line > span{display:block}
.cc-line:last-child > span{color:var(--red)}
.cc-hero-lead{color:var(--muted);font-size:clamp(1.02rem,1.5vw,1.16rem);line-height:1.6;max-width:480px;margin:24px 0 32px}
.cc-hero-actions{display:flex;align-items:center;gap:10px 28px;flex-wrap:wrap}
.cc-hero-link{display:inline-flex;align-items:center;gap:8px;min-height:44px;font-family:var(--display);
  font-weight:700;font-size:13.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--text)}
.cc-hero-link span{color:var(--red);transition:transform .2s}
.cc-hero-link:hover span{transform:translateX(3px)}
.cc-hero-rating{margin-top:30px}

/* the car sits in its own frame on the right. The source is portrait, so it
   is presented rather than cropped into a letterbox band. */
.cc-hero-media{position:relative;margin:0;border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--line);background:var(--elev)}
.cc-hero-media img{display:block;width:100%;height:auto;aspect-ratio:3/4;max-height:min(70svh,600px);object-fit:cover;object-position:48% 50%}
/* directional treatment where the photograph meets the type, so the two
   columns read as one composition instead of a pasted-in picture */
.cc-hero-media::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,rgba(10,10,11,.55) 0%,rgba(10,10,11,.12) 26%,transparent 52%)}

@media (max-width:1024px){
  .cc-hero-grid{grid-template-columns:1fr;gap:34px;padding-top:calc(var(--hdr-h) + 36px);padding-bottom:48px}
  .cc-hero-copy{max-width:none;order:2}
  .cc-hero-media{order:1}
  /* landscape band on tablet: the full portrait would push the type off-screen */
  .cc-hero-media img{aspect-ratio:16/10;max-height:min(46svh,380px);object-position:48% 50%}
  .cc-hero-media::after{background:linear-gradient(180deg,transparent 45%,rgba(10,10,11,.5) 100%)}
}
@media (max-width:640px){
  .cc-hero-grid{gap:26px;padding-top:calc(var(--hdr-h) + 24px);padding-bottom:38px}
  .cc-hero-h1{font-size:.84rem;letter-spacing:.12em;margin-bottom:14px;max-width:none}
  /* "LASTING PROTECTION." is the widest line; this keeps it on one line to 320px */
  .cc-hero-statement{font-size:clamp(1.5rem,7.4vw,2.6rem)}
  .cc-hero-lead{margin:18px 0 24px;font-size:1rem}
  .cc-hero-media img{aspect-ratio:4/5;max-height:min(42svh,340px);object-position:48% 50%}
  .cc-hero-rating{margin-top:24px}
}

/* entrance pre-states, GSAP-gated (see animations.js) */
.js-gsap .cc-hero-eyebrow,.js-gsap .cc-hero-h1,.js-gsap .cc-hero-lead,
.js-gsap .cc-hero-actions,.js-gsap .cc-hero-rating,.js-gsap .cc-hero-media{opacity:0}
.js-gsap .cc-line > span{transform:translateY(110%)}

/* --- ceramic page sections (.cc-*) ------------------------------------- */
/* overview: photo and copy on one grid, a normal gap when stacked */
.cc-ov-grid{display:grid;grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);gap:56px;align-items:start}
.cc-ov-photo{margin:0;border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--line);background:var(--elev)}
.cc-ov-photo img{display:block;width:100%;height:auto;aspect-ratio:3/4;max-height:min(64svh,540px);object-fit:cover;object-position:52% 42%}
.cc-ov-copy h2{font-size:clamp(1.7rem,3.2vw,2.5rem);line-height:1.1;max-width:18ch}
.cc-ov-body{margin-top:20px;max-width:600px}
.cc-ov-body p{color:var(--muted);margin:0 0 1.1em}
.cc-ov-body p:last-child{margin:0}
.cc-ov-body b{color:var(--text);font-family:var(--display);font-size:1.02em}

/* transformation: macro evidence + case study, then the comparison */
.cc-trans-head{max-width:640px;margin-bottom:34px}
.cc-trans-head h2{line-height:1.08}
.cc-evidence{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);gap:24px;align-items:stretch}
.cc-macro{margin:0;display:flex;flex-direction:column;border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;background:var(--black)}
.cc-macro img{display:block;width:100%;height:auto;aspect-ratio:4/3;object-fit:cover}
.cc-macro figcaption{padding:16px 20px;color:var(--muted);font-size:13.8px;line-height:1.55}
.cc-case{border:1px solid var(--line);border-radius:var(--r-lg);background:var(--black);padding:28px 30px;display:flex;flex-direction:column;justify-content:center}
/* the three stages of one job: the car, mid-correction, before and after */
.cc-case-step{
  margin:0 0 12px;font-family:var(--display);font-weight:700;font-size:10.5px;
  letter-spacing:.2em;text-transform:uppercase;color:var(--red);
  display:flex;align-items:center;gap:10px
}
.cc-case-step::before{content:"";width:18px;height:1px;background:var(--red);flex:none}
.cc-case-step--center{justify-content:center;margin-bottom:16px}
.cc-macro .cc-case-step{margin-bottom:14px}
.cc-case-title{font-size:1.5rem;margin:0 0 18px}
.cc-case-facts{margin:0}
.cc-case-facts dt{font-family:var(--display);font-weight:700;font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--red);margin-top:16px}
.cc-case-facts dt:first-child{margin-top:0}
.cc-case-facts dd{margin:5px 0 0;color:var(--muted);font-size:15px;line-height:1.55}
.cc-ba{margin-top:26px}
.ba-label{text-align:center}
.cc-ba-note{text-align:center;color:var(--muted-2);font-size:13.5px;margin:14px 0 0}
/* scoped to this page: the 85% vertical bias frames the Porsche's lower body,
   and would crop the homepage's macro panel shots off-centre */
.cc-ba .ba-before img,.cc-ba .ba-after img{object-position:center 85%}

/* packages */
.cc-pkg-head{max-width:640px;margin-bottom:26px}
.cc-shared{border:1px solid var(--line);border-radius:var(--r);background:var(--surface);padding:18px 22px;margin-bottom:22px}
.cc-shared-title{margin:0 0 10px;font-family:var(--display);font-weight:700;font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--red)}
.cc-shared ul{list-style:none;display:flex;flex-wrap:wrap;gap:6px 26px;margin:0}
.cc-shared li{color:var(--muted);font-size:14.5px;display:flex;align-items:center}
.cc-shared li::before{content:"";width:5px;height:5px;border-radius:50%;background:var(--line-2);margin-right:10px;flex:none}
.cc-pkg-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px;align-items:stretch}
.cc-pkg{position:relative;display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:26px 22px 22px;transition:border-color .25s}
.cc-pkg:hover{border-color:var(--line-2)}
/* the featured package is marked by a rule and a label, not a red box */
.cc-pkg.is-popular{background:var(--elev)}
.cc-pkg.is-popular::before{content:"";position:absolute;left:0;right:0;top:-1px;height:2px;border-radius:var(--r-lg) var(--r-lg) 0 0;background:var(--red)}
.cc-pkg-flag{margin:0 0 10px;line-height:1.6;min-height:1.6em;font-family:var(--display);font-weight:700;font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--red)}
.cc-pkg-name{font-size:1.24rem;line-height:1.15;margin:0 0 8px}
.cc-pkg-pos{margin:0 0 16px;color:var(--muted);font-size:14.5px;line-height:1.5;min-height:3em}   /* two lines reserved: the longest positioning wraps to two at every
      breakpoint, so the price below starts level across the row. It is a
      floor, not a fixed height, so larger text still grows the card. */
.cc-pkg-price{margin:0 0 14px;font-family:var(--display);font-weight:700;font-size:1.85rem;line-height:1;color:var(--text)}
.cc-pkg-price small{display:block;font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin-bottom:6px;font-weight:600}
/* correction level: the number customers compare across the row */
.cc-pkg-level{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 8px;padding:12px 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line);margin-bottom:14px}
.cc-pkg-level-v{font-family:var(--display);font-weight:700;font-size:1.05rem;color:var(--red)}
.cc-pkg-level-n{color:var(--muted);font-size:13.5px}
.cc-pkg-level-n--only{font-family:var(--display);font-weight:700;font-size:1.05rem;color:var(--text)}
.cc-pkg-stages{flex-basis:100%;font-family:var(--display);font-weight:700;font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted-2)}
.cc-pkg-steps{list-style:none;margin:0 0 14px;display:flex;flex-direction:column;gap:7px}
.cc-pkg-steps li{color:var(--muted);font-size:14px;line-height:1.45;display:flex}
.cc-pkg-steps li::before{content:"";width:5px;height:5px;border-radius:50%;background:var(--red);margin:7px 10px 0 0;flex:none}
.cc-pkg-why{margin:0 0 14px;padding-left:12px;border-left:2px solid var(--red);color:var(--muted);font-size:13.6px;line-height:1.5}
/* turnaround closes the card and carries the margin:auto that keeps every
   CTA on the same baseline whatever the step count above it */
.cc-pkg-turn{margin:auto 0 16px;padding-top:12px;border-top:1px solid var(--line);
  font-family:var(--display);font-weight:700;font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted-2)}
.cc-pkg-cta{width:100%}
/* coating add-ons: the body is included in every package, wheels and windows
   are priced separately. Three items, so three columns on desktop */
.cc-addons{margin:26px 0 0;padding:22px 24px;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg)}
.cc-addons-title{margin:0 0 14px;font-family:var(--display);font-weight:700;font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}
.cc-addons ul{list-style:none;margin:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px 36px}
.cc-addons li{display:grid;grid-template-columns:1fr auto;gap:2px 16px;align-items:baseline;padding-top:14px;border-top:1px solid var(--line)}
.cc-addon-name{font-family:var(--display);font-weight:600;font-size:15px;color:var(--text)}
.cc-addon-price{font-family:var(--display);font-weight:700;font-size:1.1rem;color:var(--red);text-align:right}
.cc-addon-note{grid-column:1/-1;color:var(--muted);font-size:13.6px;line-height:1.5}
.cc-addons-note{margin:16px 0 0;color:var(--muted-2);font-size:13.4px;line-height:1.55}
@media (max-width:900px){
  .cc-addons{padding:20px}
  .cc-addons ul{grid-template-columns:1fr;gap:14px}
}
.cc-pkg-qualifier{margin:22px 0 0;color:var(--muted-2);font-size:13.5px;line-height:1.6;max-width:820px}

/* process: a connected sequence, not six boxes */
.cc-proc-grid{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,.75fr);gap:56px;align-items:start}
.cc-proc-head{max-width:520px;margin-bottom:28px}
.cc-steps{list-style:none;margin:0;padding:0;position:relative}
/* the thin connecting line. Decorative: every stage reads without it. */
.cc-steps::before{content:"";position:absolute;left:17px;top:10px;bottom:10px;width:1px;background:var(--line)}
.cc-steps::after{content:"";position:absolute;left:17px;top:10px;width:1px;height:calc((100% - 20px) * var(--proc, 0));background:var(--red);transition:height .3s linear}
.cc-step{position:relative;display:flex;gap:20px;padding:14px 0}
.cc-step-n{position:relative;z-index:1;flex:none;width:34px;height:34px;border-radius:50%;background:var(--surface);border:1px solid var(--line);display:grid;place-items:center;font-family:var(--display);font-weight:700;font-size:12px;color:var(--muted)}
.cc-step.is-on .cc-step-n{color:var(--text);border-color:var(--red)}
.cc-step h3{font-size:1.06rem;margin:6px 0 5px}
.cc-step p{margin:0;color:var(--muted);font-size:14.6px;line-height:1.55}
.cc-proc-video{margin:0;position:sticky;top:calc(var(--hdr-h) + 28px)}

/* portrait videos get an intentional width instead of filling the column */
.cc-video{position:relative;width:100%;max-width:340px;margin:0 auto;aspect-ratio:9/16;border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--line);background:var(--elev)}
.cc-video iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.cc-proc-video figcaption,.cc-ben-video figcaption{margin-top:12px;text-align:center;color:var(--muted-2);font-size:13px}

/* benefits */
.cc-ben-grid{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,.75fr);gap:56px;align-items:center}
.cc-ben-head{max-width:520px;margin-bottom:24px}
.cc-ben-list{list-style:none;margin:0;display:flex;flex-direction:column}
.cc-benefit{display:flex;gap:18px;padding:20px 0;border-bottom:1px solid var(--line)}
.cc-benefit:last-child{border-bottom:0;padding-bottom:0}
.cc-benefit .ic{flex:none;width:36px;height:36px;border-radius:50%;background:var(--red-soft);color:var(--red);display:grid;place-items:center}
.cc-benefit .ic svg{width:18px;height:18px}
.cc-benefit b{font-family:var(--display);font-size:16.5px;display:block;margin-bottom:4px}
.cc-benefit p{margin:0;color:var(--muted);font-size:14.8px;line-height:1.55}
.cc-ben-video{margin:0}

/* comparison */
.cc-cmp-head{margin-bottom:30px}
.cc-cmp-tabs{display:none}
.cc-cmp-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface)}
.cc-cmp-table{width:100%;border-collapse:collapse;font-size:14.6px}
.cc-cmp-table th,.cc-cmp-table td{padding:15px 18px;text-align:left;vertical-align:top;border-bottom:1px solid var(--line)}
.cc-cmp-table thead th{font-family:var(--display);font-weight:700;font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--text);background:var(--black)}
.cc-cmp-table tbody th{font-family:var(--display);font-weight:600;font-size:13px;color:var(--text);white-space:nowrap}
.cc-cmp-table td{color:var(--muted)}
.cc-cmp-table tr:last-child th,.cc-cmp-table tr:last-child td{border-bottom:0}
/* the coating column is ours: a thin rule and stronger text, no glow */
.cc-cmp-table .is-feat{color:var(--text);background:rgba(225,27,34,.05)}
.cc-cmp-table thead .is-feat{box-shadow:inset 0 -2px 0 var(--red)}
.cc-cmp-foot{margin:20px 0 0;text-align:center;color:var(--muted);font-size:14.5px}
.cc-cmp-foot a{color:var(--red);text-decoration:underline;text-underline-offset:3px}

/* reviews */
.cc-rev-track{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px;align-items:stretch}
.cc-rev{display:flex;flex-direction:column;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;transition:border-color .25s}
.cc-rev:hover{border-color:var(--line-2)}
.cc-rev-media{position:relative;aspect-ratio:4/3;background:var(--elev)}
.cc-rev-media img{width:100%;height:100%;object-fit:cover;display:block}
/* no genuine photo of this customer's car yet: an honest panel, never a
   borrowed car and never a broken image */
.cc-rev-await{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;
  background:repeating-linear-gradient(135deg,#141418 0 10px,#111113 10px 20px);color:var(--muted-2);text-align:center;padding:16px}
.cc-rev-await svg{width:26px;height:26px}
.cc-rev-await span{font-family:var(--display);font-weight:700;font-size:10.5px;letter-spacing:.14em;text-transform:uppercase}
.cc-rev-body{display:flex;flex-direction:column;gap:10px;padding:22px 22px 20px;flex:1}
/* vehicle and package are visible, never hover-only */
.cc-rev-job{display:flex;flex-wrap:wrap;align-items:center;gap:8px 10px;margin:0}
.cc-rev-car{color:var(--text)}
.cc-rev-car{font-family:var(--display);font-weight:700;font-size:13px;color:var(--text)}
.cc-rev-pkg{
  margin:0 0 6px;font-family:var(--display);font-weight:700;font-size:11px;
  letter-spacing:.18em;text-transform:uppercase;color:var(--red)
}
.cc-rev-work{margin:0 0 2px;color:var(--muted-2);font-size:12.8px;line-height:1.5;letter-spacing:.01em}
.cc-rev .stars{color:var(--star);letter-spacing:2px;font-size:14px}
.cc-rev blockquote{margin:0;font-size:14.6px;line-height:1.62;color:var(--text)}
.js .cc-rev.is-clamped:not(.is-open) blockquote{display:-webkit-box;-webkit-line-clamp:6;-webkit-box-orient:vertical;overflow:hidden}
.cc-rev-more{display:none}
.js .cc-rev.is-clamped .cc-rev-more{display:inline-flex}
.cc-rev-who{display:flex;flex-direction:column;margin:auto 0 0;padding-top:10px}
.cc-rev-who b{font-family:var(--display);font-size:14.5px}
.cc-rev-who small{color:var(--muted-2);font-size:12px}
.cc-rev-controls{display:flex;align-items:center;justify-content:center;gap:18px;margin-top:24px}
/* an author display declaration beats the UA's [hidden]{display:none}, so the
   attribute alone was not enough: the counter and arrows stayed visible on
   desktop where all three cards already fit and there is nothing to page. */
.cc-rev-controls[hidden]{display:none}

@media (max-width:1024px){
  .cc-ov-grid{grid-template-columns:1fr;gap:28px}
  .cc-ov-photo img{aspect-ratio:16/10;max-height:min(42svh,360px);object-position:52% 40%}
  .cc-ov-copy h2{max-width:none}
  .cc-evidence{grid-template-columns:1fr;gap:16px}
  .cc-pkg-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .cc-proc-grid,.cc-ben-grid{grid-template-columns:1fr;gap:34px}
  .cc-proc-video{position:static;max-width:340px}
  .cc-ben-video{max-width:340px;margin:0 auto}
  .cc-rev-track{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:720px){
  /* comparison becomes a selector: one column at a time, readable */
  .cc-cmp.is-tabbed .cc-cmp-tabs{display:flex;gap:0 20px;flex-wrap:wrap;margin-bottom:14px}
  .cc-cmp-tab{position:relative;min-height:44px;padding:10px 2px;background:none;border:0;cursor:pointer;font-family:var(--display);font-weight:600;font-size:13.5px;color:var(--muted)}
  .cc-cmp-tab::after{content:"";position:absolute;left:0;right:0;bottom:6px;height:2px;background:var(--red);transform:scaleX(0);transform-origin:left;transition:transform .25s var(--ease-premium)}
  .cc-cmp-tab[aria-pressed="true"]{color:#fff;font-weight:700}
  .cc-cmp-tab[aria-pressed="true"]::after{transform:scaleX(1)}
  .cc-cmp.is-tabbed .cc-cmp-scroll{overflow-x:visible}
  .cc-cmp.is-tabbed thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
  .cc-cmp.is-tabbed td{display:none}
  .cc-cmp.is-tabbed[data-col="0"] td[data-col="0"],
  .cc-cmp.is-tabbed[data-col="1"] td[data-col="1"],
  .cc-cmp.is-tabbed[data-col="2"] td[data-col="2"]{display:table-cell;text-align:right;background:none;color:var(--text)}
  .cc-cmp.is-tabbed tbody th{white-space:normal;color:var(--muted)}
  /* reviews: one at a time, swipeable, manual controls */
  .cc-rev-track.is-carousel{display:flex;grid-template-columns:none;gap:14px;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;overscroll-behavior-x:contain}
  .cc-rev-track.is-carousel::-webkit-scrollbar{display:none}
  .cc-rev-track.is-carousel .cc-rev{flex:0 0 100%;scroll-snap-align:start}
}
@media (max-width:640px){
  .cc-ov-photo img{aspect-ratio:4/5;max-height:min(40svh,320px)}
  .cc-trans-head{margin-bottom:24px}
  .cc-case{padding:22px 20px}
  .cc-pkg-grid{grid-template-columns:1fr;gap:12px}
  .cc-pkg{padding:22px 20px 20px}
  .cc-shared ul{flex-direction:column;gap:6px}
  .cc-benefit{gap:14px}
  .cc-rev-track{grid-template-columns:1fr}
  .cc-video{max-width:300px}
}

/* entrance pre-states for the package cards (see animations.js) */
.js-gsap .cc-pkg-grid:not(.is-in) .cc-pkg{opacity:0}

/* ==========================================================================
   LOCATION PAGES — /car-detailing-<town>/ (.loc-*). One shared layout from
   towns.py: compact hero, credentials strip, services, overview + studio
   block, mobile coverage list, FAQs. Scoped so no other page changes.
   ========================================================================== */
.loc-hero{padding:calc(var(--hdr-h) + 40px) 0 44px}
.loc-hero h1{max-width:none;font-size:clamp(2rem,4.6vw,3.4rem);line-height:1.02}
.loc-hero .lead{max-width:640px;margin:20px 0 28px}
.loc-hero .breadcrumb{margin-bottom:26px}
.loc-sec-head{margin-bottom:34px}
.loc-services{padding-top:64px}
/* availability label on each card: where the work happens */
.svc p.svc-where{margin:0 0 2px;font-family:var(--display);font-weight:700;font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted-2)}
.svc p.svc-where::before{content:"";display:inline-block;width:6px;height:6px;border-radius:50%;background:var(--red);margin-right:8px;vertical-align:1px}

/* overview + studio block */
.loc-overview-grid{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,.75fr);gap:48px 64px;align-items:start}
.loc-overview h2{font-size:clamp(1.6rem,3vw,2.2rem);line-height:1.12;max-width:20ch}
.loc-overview-body{margin-top:18px;max-width:600px}
.loc-overview-body p{color:var(--muted)}
.loc-overview-body p:last-child{margin-bottom:0}
.loc-studio{border:1px solid var(--line);border-radius:var(--r);background:var(--black);padding:24px 26px 22px}
.loc-studio h3{font-size:1.2rem;margin:0 0 12px}
.loc-studio-addr{font-style:normal;color:var(--text);line-height:1.6;margin:0 0 12px}
.loc-studio-facts{list-style:none;margin:0 0 12px;padding:0;display:flex;flex-direction:column;gap:4px;font-size:14.5px;color:var(--text)}
.loc-studio-facts li::before{content:"";display:inline-block;width:5px;height:5px;border-radius:50%;background:var(--red);margin-right:10px;vertical-align:2px}
.loc-studio-note{color:var(--muted);font-size:14.5px;margin:0 0 16px}
.loc-studio-links{list-style:none;display:flex;flex-direction:column;gap:2px;border-top:1px solid var(--line);padding-top:8px}

/* coverage: a plain text list in columns, not buttons */
.loc-areas{list-style:none;columns:3;column-gap:32px;max-width:760px;margin:0}
.loc-areas li{break-inside:avoid;padding:9px 0;border-bottom:1px solid var(--line);color:var(--text);font-size:15px}
.loc-areas li::before{content:"";display:inline-block;width:5px;height:5px;border-radius:50%;background:var(--red);margin-right:10px;vertical-align:2px}
.loc-coverage{padding:64px 0 72px}
.loc-coverage h2,.loc-services h2{font-size:clamp(1.6rem,3vw,2.3rem)}
.loc-coverage .loc-sec-head{margin-bottom:24px}
.loc-coverage + #faq{padding-top:72px}
.loc-coverage + #faq .sec-head{margin-bottom:24px}

@media (max-width:1024px){
  .loc-hero{padding:calc(var(--hdr-h) + 30px) 0 36px}
  .loc-services{padding-top:56px}
  /* tablet: three horizontal rows instead of two cards and a straggler */
  .loc-svc-grid{grid-template-columns:1fr;gap:12px}
  .loc-svc-grid .svc{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"where foot" "name foot" "desc foot";align-items:center;gap:4px 28px;padding:20px 24px}
  .loc-svc-grid .svc-where{grid-area:where}
  .loc-svc-grid .svc-name{grid-area:name;font-size:1.15rem}
  .loc-svc-grid .svc-desc{grid-area:desc;flex:none}
  .loc-svc-grid .svc-foot{grid-area:foot;flex-direction:column;align-items:flex-end;gap:10px;margin:0;padding:0;border-top:0;border-left:1px solid var(--line);padding-left:28px;align-self:stretch;justify-content:center}
  .loc-svc-grid .svc-price{text-align:right}
  .loc-overview-grid{grid-template-columns:1fr;gap:28px}
  .loc-overview h2{max-width:none}
  .loc-areas{columns:2}
}
@media (max-width:640px){
  .loc-hero{padding:calc(var(--hdr-h) + 26px) 0 32px}
  .loc-hero h1{font-size:clamp(1.9rem,9vw,2.6rem)}
  .loc-hero .lead{margin:16px 0 22px}
  .loc-services{padding-top:48px}
  .loc-sec-head{margin-bottom:24px}
  /* phones: stacked compact cards; the price and link share one row */
  .loc-svc-grid .svc{display:flex;flex-direction:column;gap:8px;padding:18px 18px 16px}
  .loc-svc-grid .svc-foot{flex-direction:row;align-items:flex-end;justify-content:space-between;border-left:0;border-top:1px solid var(--line);padding:12px 0 0;margin-top:6px;align-self:auto}
  .loc-svc-grid .svc-price{text-align:left;font-size:1.35rem}
  .loc-svc-grid .svc-desc{font-size:14.5px}
  .loc-studio{padding:20px 20px 18px}
  .loc-areas{columns:2;column-gap:20px}
  .loc-areas li{font-size:14.5px;padding:8px 0}
}
@media (max-width:360px){.loc-areas{columns:1}}

/* entrance pre-states, GSAP-gated: eyebrow/lead/tools/status fade up, the
   two heading lines rise out of their masks, cards follow. The results box
   gets .is-in when the card tween finishes (or straight away in the
   reduced-motion fallback), which releases the CSS pre-state. */
.js-gsap .lib-eyebrow,.js-gsap .lib-lead,.js-gsap .lib-tools,.js-gsap .lib-status{opacity:0}
.js-gsap .lib-line > span{transform:translateY(110%)}
.js-gsap .lib-results:not(.is-in) .lib-card{opacity:0}

@media (max-width:1024px){
  .lib-head{grid-template-columns:1fr;gap:18px;align-items:start}
  .js .lib-tools{grid-template-columns:1fr;gap:6px}
  .lib-topic{margin-top:6px;max-width:320px}
  .lib-results{grid-template-columns:repeat(2,minmax(0,1fr))}
  /* tablet: the lead spans the row but keeps its type | media split */
  .lib-results.is-editorial .lib-card.is-featured{grid-column:1/-1;grid-row:auto;grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr)}
  .is-editorial .lib-card.is-featured .lib-card-media{min-height:280px}
  .is-editorial .lib-card.is-featured .lib-card-body{padding:26px 26px 26px}
  .is-editorial .lib-card:not(.is-featured):nth-child(-n+3) .lib-card-media{display:block}
}
@media (max-width:640px){
  .lib-intro{padding:calc(var(--hdr-h) + 34px) 0 30px}
  .lib-crumbs{margin-bottom:22px}
  .lib-eyebrow{margin-bottom:14px}
  .lib-title{font-size:clamp(1.6rem,8.5vw,2.7rem)}   /* "BETTER DECISIONS." holds one line down to 320px */
  .lib-lead{font-size:1rem;max-width:none}
  .lib{padding:26px 0 72px}
  .lib-cats{gap:0 18px}
  .js .lib-status{margin:18px 0 18px}
  .lib-results{grid-template-columns:1fr;gap:14px}
  /* phones: stacked, media first, like every other card */
  .lib-results.is-editorial .lib-card.is-featured{display:flex}
  .is-editorial .lib-card.is-featured .lib-card-media{order:0;aspect-ratio:16/9;min-height:0;border-left:0}
  .is-editorial .lib-card.is-featured .lib-card-body{padding:20px 20px 22px}
  .lib-card-body{padding:18px 18px 20px}
  .lib-empty{padding:34px 20px}
}

/* services hub rows */
.svc-rows{display:flex;flex-direction:column;gap:18px}
.svc-row{
  display:grid;grid-template-columns:1.5fr 1fr;gap:40px;padding:38px;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);
  transition:border-color .25s,transform .25s
}
.svc-row:hover{border-color:var(--line-2);transform:translateY(-3px)}
.svc-row h2{font-size:clamp(1.4rem,2.6vw,1.85rem);margin-bottom:14px}
.svc-row h2 a:hover{color:var(--red)}
.svc-row p{color:var(--muted);margin-bottom:22px}
.svc-row-side{border-left:1px solid var(--line);padding-left:34px}
.svc-row-price{font-family:var(--display);font-weight:700;font-size:1.7rem;color:var(--red);display:block;margin-bottom:16px}
.svc-row-side ul{list-style:none}
.svc-row-side li{padding:8px 0;font-size:14.5px;color:var(--muted);border-bottom:1px solid var(--line)}
.svc-row-side li:last-child{border-bottom:0}
@media (max-width:900px){
  .svc-row{grid-template-columns:1fr;gap:26px;padding:28px}
  .svc-row-side{border-left:0;border-top:1px solid var(--line);padding-left:0;padding-top:22px}
}

/* area chips — real links to the six location pages, and also reused as
   plain non-link spans for the sub-area tags within each location page
   (roads/villages that don't have their own page) */
.areas .area-chip{
  display:inline-flex;align-items:center;gap:8px;padding:11px 18px;border:1px solid var(--line);
  border-radius:999px;font-size:14.5px;color:var(--muted);background:var(--surface)
}
.areas .area-chip svg{width:14px;height:14px;color:var(--red);flex:none}

/* ===================================================================
   Ceramic Coating & Paint Correction page — bespoke sections
   =================================================================== */

/* hero review badge, made into a link */
.hero-rating.is-link{text-decoration:none;transition:color .2s}
.hero-rating.is-link:hover{color:var(--text)}

/* overview photo (single portrait shot, under the heading) */
.intro-photo{aspect-ratio:4/5;border-radius:var(--r-lg);margin-top:28px;overflow:hidden;border:1px solid var(--line);position:relative}
.intro-photo picture{display:block;width:100%;height:100%}
.intro-photo img{width:100%;height:100%;object-fit:cover;display:block}
.intro-photo:empty{background:linear-gradient(140deg,#1d1d22,#101013)}
.intro-photo:empty::after{content:"";position:absolute;inset:0;background:radial-gradient(60% 70% at 35% 30%,rgba(225,27,34,.16),transparent 65%)}

/* case study: static split photo + write-up */
.case-study{display:grid;grid-template-columns:1fr 1fr;gap:28px;align-items:stretch}
.case-photo{
  border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--line);min-height:320px;
  background-image:url('/images/paint-correction-case-study.jpg?v=1');
  background-size:cover;background-position:center
}
.case-card{border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface);padding:36px;display:flex;flex-direction:column;justify-content:center}
.case-card h3{font-size:1.5rem;margin-bottom:16px;line-height:1.3}
.case-card h3 em{font-style:normal;color:var(--red)}
.case-card p{color:var(--muted);margin-bottom:14px}
.case-card p:last-child{margin-bottom:0}

/* brand marquee band */
.brand-band{border-top:1px solid var(--line);border-bottom:1px solid var(--line);background:var(--surface);padding:28px 0;margin-top:52px;overflow:hidden}
.brand-band p{text-align:center;color:var(--muted-2);font-size:12px;letter-spacing:.16em;text-transform:uppercase;margin:0 0 20px}
.brand-track{display:flex;gap:64px;width:max-content;animation:brandScroll 26s linear infinite}
.brand-track span{font-family:var(--display);font-weight:700;font-size:1.2rem;letter-spacing:.03em;color:var(--muted);white-space:nowrap;flex:none}
@keyframes brandScroll{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){.brand-track{animation:none}}

/* benefits + video, two columns */
.benefits-av{display:grid;grid-template-columns:1.05fr 1fr;gap:52px;align-items:center}
.benefits-av .bf-video{max-width:none}
.bf-list{display:flex;flex-direction:column;gap:28px}
.bf-row{display:flex;gap:18px;align-items:center}
.bf-row .ic{width:44px;height:44px;border-radius:var(--r);background:var(--red-soft);color:var(--red);display:grid;place-items:center;flex:none}
.bf-row .ic svg{width:22px;height:22px}
.bf-row b{font-family:var(--display);font-size:1.05rem;display:block;margin-bottom:6px}
.bf-row p{margin:0;color:var(--muted);font-size:14.6px}
.bf-video{position:relative;border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--line);aspect-ratio:9/16;max-width:500px;margin:0 auto}
.bf-video video,.bf-video iframe{width:100%;height:100%;object-fit:cover;display:block;border:0;background:var(--elev)}
.bf-video-note{
  position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;
  padding:28px;gap:14px;color:var(--muted);font-size:13.8px;line-height:1.6;
  background:linear-gradient(140deg,#1d1d22,#101013)
}
.bf-video-note .play-ic{
  width:54px;height:54px;border-radius:50%;background:var(--red);display:grid;place-items:center;flex:none;
  box-shadow:0 10px 28px -8px rgba(225,27,34,.65)
}
.bf-video-note .play-ic svg{width:18px;height:18px;color:#fff;margin-left:3px}
.bf-video-note b{display:block;color:var(--text);font-family:var(--display);margin-bottom:8px}
.bf-video.landscape{aspect-ratio:16/9;max-width:none}

/* XPEL accreditation section (PPF page) */
.xpel-block{display:grid;grid-template-columns:1fr 1fr;gap:28px;margin-top:40px}
.xpel-vid{margin:0}
.xpel-vid figcaption{margin-top:14px;color:var(--muted);font-size:13.5px;line-height:1.6}
.xpel-vid figcaption b{display:block;color:var(--text);font-family:var(--display);font-size:15px;margin-bottom:5px}
@media (max-width:900px){.xpel-block{grid-template-columns:1fr}}

/* large editorial statement section */
.statement{padding:70px 0;text-align:center}
.statement h2{font-size:clamp(2.2rem,5.5vw,4rem);line-height:1.08;max-width:15ch;margin:0 auto 24px;text-transform:uppercase}
.statement p{color:var(--muted);font-size:1.1rem;line-height:1.6;max-width:540px;margin:0 auto}

/* honesty / limitations list */
.honesty-list{list-style:none;max-width:760px;margin:0 auto}
.honesty-list li{
  position:relative;padding:22px 0 22px 34px;border-bottom:1px solid var(--line);color:var(--muted);
  font-size:1.02rem;line-height:1.65
}
.honesty-list li::before{content:"";position:absolute;left:0;top:31px;width:14px;height:2px;background:var(--red)}
.honesty-list li:last-child{border-bottom:0}

/* comparison table: wax / ceramic / PPF */
.compare{background:transparent}
.compare-scroll{
  overflow-x:auto;border:1px solid rgba(225,27,34,.3);border-radius:var(--r-lg);background:var(--surface);
  box-shadow:0 0 60px -12px rgba(225,27,34,.4)
}
.compare table{width:100%;border-collapse:collapse;min-width:560px}
.compare th,.compare td{padding:18px 22px;text-align:left;font-size:14.4px;border-bottom:1px solid var(--line)}
.compare thead th{font-family:var(--display);font-weight:700;text-transform:uppercase;font-size:12.5px;letter-spacing:.07em;color:var(--muted-2);background:var(--elev)}
.compare thead th.feat{background:var(--red);color:#fff;border-top-right-radius:0}
.compare thead th.feat img{height:24px;width:auto;display:block;margin-bottom:6px}
.compare tbody th{color:var(--muted);font-weight:600;font-size:14px}
.compare tbody td.feat{background:var(--red-soft);color:var(--text);font-weight:600;border-left:1px solid rgba(225,27,34,.3);border-right:1px solid rgba(225,27,34,.3)}
.compare tbody tr:last-child td,.compare tbody tr:last-child th{border-bottom:0}
.compare-foot{
  display:flex;align-items:center;gap:56px;flex-wrap:wrap;padding:32px 34px;margin-top:24px;
  border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface)
}
.compare-foot p{color:var(--muted);font-size:14.6px;line-height:1.6;margin:0;flex:1 1 380px}
.compare-foot .btn{flex:none}
.compare td.cov{text-align:center}
.cov-yes{color:var(--red);display:inline-flex}
.cov-yes svg{width:18px;height:18px}
.cov-no{color:var(--muted-2)}

/* "watch us work" video section — portrait video, benefit cards flanking it.
   A flex row (not a grid with 1fr side columns) so the whole group hugs
   together at its natural width instead of leaving dead space either side. */
.watch-video{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:28px 48px}
.watch-video .bf-video{max-width:540px}
.watch-specs{display:flex;flex-direction:column;gap:26px}
.watch-spec{
  display:flex;align-items:center;gap:14px;border:1px solid var(--line);border-radius:var(--r-lg);
  padding:16px 22px;background:var(--surface);min-width:230px
}
.watch-specs.right .watch-spec{flex-direction:row-reverse;text-align:right}
.watch-spec .ic{width:38px;height:38px;border-radius:var(--r);background:var(--red-soft);color:var(--red);display:grid;place-items:center;flex:none}
.watch-spec .ic svg{width:19px;height:19px}
.watch-spec b{display:block;font-family:var(--display);font-size:1.05rem;color:var(--text)}
.watch-spec small{display:block;font-size:12px;color:var(--muted);text-transform:uppercase;letter-spacing:.06em;margin-top:2px}
@media (max-width:900px){
  .watch-specs{flex-direction:row;flex-wrap:wrap;justify-content:center}
  .watch-specs.right .watch-spec{flex-direction:row;text-align:left}
}

/* studio vs mobile hover-expand split (valeting page) */
.split{display:flex;height:560px;border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--line)}
.split-half{position:relative;flex:1;min-width:0;overflow:hidden;cursor:pointer;transition:flex .55s cubic-bezier(.4,0,.2,1)}
.split-half:not(:last-child){border-right:1px solid var(--line)}
.split-photo{position:absolute;inset:0;display:block;background:linear-gradient(140deg,#1d1d22,#101013)}
.split-photo img{width:100%;height:100%;object-fit:cover;display:block}
.split-half[data-side="studio"] .split-photo img{object-position:50% 46%}   /* unit, cars inside, van */
.split-half[data-side="mobile"] .split-photo img{object-position:46% 62%}   /* van and the car being washed */
/* the red wash only belongs to the empty placeholder state */
.split-photo:not(:has(img))::after{content:"";position:absolute;inset:0;background:radial-gradient(60% 70% at 35% 30%,rgba(225,27,34,.16),transparent 65%)}
.split-overlay{position:absolute;inset:0;background:linear-gradient(0deg,rgba(10,10,11,.94) 0%,rgba(10,10,11,.6) 42%,rgba(10,10,11,.18) 100%)}
.split-content{position:absolute;left:0;right:0;bottom:0;padding:36px;color:#fff;z-index:1}
.split-tag{display:block;font-family:var(--display);font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--red);margin-bottom:10px}
.split-content h3{font-size:1.5rem;margin-bottom:8px;color:#fff}
.split-teaser{color:rgba(255,255,255,.75);font-size:14.5px;transition:opacity .2s}
.split-details{list-style:none;margin:0;max-height:0;opacity:0;overflow:hidden;transition:max-height .4s ease,opacity .3s ease,margin-top .4s ease}
.split-details li{display:flex;gap:10px;padding:7px 0;font-size:14.2px;color:rgba(255,255,255,.85);line-height:1.5}
.split-details li svg{width:16px;height:16px;flex:none;margin-top:3px;color:var(--red)}
.split.has-active .split-half{flex:.55}
.split.has-active .split-half.is-open{flex:1.9}
.split-half.is-open .split-teaser{display:none}
.split-half.is-open .split-details{max-height:340px;opacity:1;margin-top:16px}
.split-half:focus-visible{outline:2px solid var(--red);outline-offset:-2px}
@media (max-width:780px){
  .split{flex-direction:column;height:auto}
  .split-half{min-height:200px}
  .split-half:not(:last-child){border-right:0;border-bottom:1px solid var(--line)}
  .split.has-active .split-half{flex:none}
  .split.has-active .split-half.is-open{flex:none;min-height:420px}
}

/* interactive flip-card benefits grid (valeting page) */
.flip-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.flip-card{perspective:1400px;height:210px;cursor:pointer}
.flip-inner{position:relative;width:100%;height:100%;transition:transform .6s cubic-bezier(.4,0,.2,1);transform-style:preserve-3d}
.flip-card:hover .flip-inner,.flip-card.is-flipped .flip-inner{transform:rotateY(180deg)}
.flip-face{
  position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;
  border-radius:var(--r-lg);border:1px solid var(--line);padding:28px;display:flex;flex-direction:column;justify-content:center
}
.flip-front{background:var(--surface)}
.flip-front .ic{width:46px;height:46px;border-radius:var(--r);background:var(--red-soft);color:var(--red);display:grid;place-items:center;margin-bottom:16px}
.flip-front .ic svg{width:23px;height:23px}
.flip-front h3{font-size:1.1rem}
.flip-back{background:linear-gradient(150deg,var(--red-dark),var(--red));border-color:transparent;transform:rotateY(180deg)}
.flip-back p{font-size:14px;line-height:1.62;color:rgba(255,255,255,.94);margin:0}
.flip-card:focus-visible .flip-face{outline:2px solid var(--red);outline-offset:-2px}
@media (max-width:900px){.flip-grid{grid-template-columns:1fr 1fr}}
@media (max-width:600px){.flip-grid{grid-template-columns:1fr}.flip-card{height:230px}}

/* add-on services grid (valeting page) */
.addons{display:grid;grid-template-columns:repeat(auto-fill,minmax(270px,1fr));gap:18px}
.addon{
  position:relative;padding:30px 26px;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);
  transition:transform .25s,border-color .25s,background .25s
}
.addon:hover{transform:translateY(-4px);border-color:var(--line-2);background:var(--elev)}
.addon .ic{width:44px;height:44px;border-radius:var(--r);background:var(--red-soft);color:var(--red);display:grid;place-items:center;margin-bottom:18px}
.addon .ic svg{width:22px;height:22px}
.addon h3{font-size:1.1rem;margin-bottom:6px}
.addon .price{display:block;font-family:var(--display);font-weight:700;color:var(--red);font-size:13px;letter-spacing:.02em;margin-bottom:12px}
.addon p{color:var(--muted);font-size:14.2px;line-height:1.6;margin:0}

/* end of lease callout (valeting page) */
.lease-callout{
  display:grid;grid-template-columns:1.1fr 1fr;gap:52px;align-items:center;
  border:1px solid rgba(225,27,34,.3);border-radius:var(--r-lg);background:var(--surface);
  padding:52px;box-shadow:0 0 60px -15px rgba(225,27,34,.35)
}
.lease-callout .checklist{display:flex;flex-direction:column;gap:24px}
@media (max-width:900px){.lease-callout{grid-template-columns:1fr;padding:34px;gap:34px}}

/* PPF benefits: sticky visual + scroll-tracked benefit list, replaces flip-cards on this page */
.benefit-story{display:grid;grid-template-columns:1fr 1.15fr;gap:56px;align-items:start}
/* sticky photo panel: six full-bleed photos stacked, crossfading as the active
   benefit row changes. Driven by assets/ppf-benefits.js. */
.benefit-visual{
  position:sticky;top:110px;height:420px;border-radius:var(--r-lg);border:1px solid var(--line);
  background:#101013;overflow:hidden
}
.benefit-visual-photo{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;
  opacity:0;transform:scale(1.04);
  transition:opacity .7s var(--ease-premium),transform 1.4s var(--ease-premium)
}
.benefit-visual-photo.is-active{opacity:1;transform:scale(1)}
/* keeps the label legible over any photo without dulling the image itself */
.benefit-visual-scrim{
  position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(10,10,11,.28) 0%,transparent 34%,transparent 62%,rgba(10,10,11,.72) 100%)
}
.benefit-visual-num{
  position:absolute;top:14px;right:22px;font-family:var(--display);font-weight:700;font-size:6.5rem;line-height:1;
  color:rgba(255,255,255,.12);user-select:none;pointer-events:none
}
.benefit-visual-label{
  position:absolute;bottom:24px;left:26px;font-family:var(--display);font-weight:700;font-size:12px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--text)
}
.benefit-list{display:flex;flex-direction:column}
.benefit-row{border-bottom:1px solid var(--line)}
.benefit-row:last-child{border-bottom:0}
/* The row header is a real <button> so the mobile accordion is operable. On
   desktop it toggles nothing, so it is taken out of the tab order by the
   script and styled as plain text. */
.benefit-head{
  display:block;width:100%;padding:32px 0;margin:0;border:0;background:none;
  color:inherit;font:inherit;text-align:left;cursor:default
}
.benefit-chev{display:none}
.benefit-panel-in > p{color:var(--muted);margin:0;max-width:480px;line-height:1.65}
.benefit-slot{display:none}
/* inactive rows stay readable: this is emphasis, not concealment */
.benefit-list.js-tracking .benefit-row{opacity:.62;transition:opacity .4s ease}
.benefit-list.js-tracking .benefit-row.is-active{opacity:1}
/* every row carries its own number and benefit name, so the list reads on its
   own without relying on the sticky visual to say which one you are looking at */
.benefit-tag{
  display:flex;align-items:baseline;gap:10px;margin-bottom:10px;
  font-family:var(--display);font-size:11px;font-weight:600;
  text-transform:uppercase;letter-spacing:.16em;color:var(--muted-2)
}
.benefit-tag em{font-style:normal;color:var(--red);letter-spacing:.1em}
.benefit-head b{display:block;font-family:var(--display);font-size:1.35rem;margin-bottom:10px}
.benefit-row p{color:var(--muted);margin:0;max-width:480px;line-height:1.65}

/* No script (or the script failed): the panel loses its fixed height and all
   six photographs stack in order, every explanation open. Nothing is hidden. */
.benefit-story:not(.benefit-story--js) .benefit-visual{
  position:static;height:auto;border:0;background:none;display:flex;flex-direction:column;gap:14px;overflow:visible
}
.benefit-story:not(.benefit-story--js) .benefit-visual-photo{
  position:static;opacity:1;transform:none;height:auto;aspect-ratio:3/2;
  border-radius:var(--r-lg);border:1px solid var(--line)
}
.benefit-story:not(.benefit-story--js) .benefit-visual-scrim,
.benefit-story:not(.benefit-story--js) .benefit-visual-num,
.benefit-story:not(.benefit-story--js) .benefit-visual-label{display:none}

@media (max-width:900px){
  /* MOBILE: six compact disclosures. The photograph moves into the open row,
     so a picture is never stranded above six unrelated descriptions. Thin
     rules, no cards, and the page is never scrolled for the visitor. */
  .benefit-story{grid-template-columns:1fr;gap:0}
  /* position:relative, NOT static. The photographs waiting in this collapsed
     panel are position:absolute; inset:0. With a static panel they had no
     containing block inside the section and escaped to the top of the
     document: five invisible, full-screen images over the hero on every
     phone, which registered as a layout shift of 1.0 (the worst possible
     score) under a throttled lab load. Relative keeps them inside this
     zero-height box, where overflow:hidden actually clips them. */
  .benefit-story.is-accordion .benefit-visual{
    position:relative;height:0;padding:0;margin:0;border:0;background:none;overflow:hidden
  }
  /* photographs waiting in the collapsed panel keep the desktop scale(1.04),
     which on a 390px screen is a 406px box. Clipped, so it never scrolls, but
     there is no reason for it to exist. */
  .benefit-story.is-accordion .benefit-visual .benefit-visual-photo{transform:none;width:100%;height:100%}
  .benefit-story.is-accordion .benefit-head{
    display:flex;align-items:center;gap:14px;padding:18px 0;cursor:pointer;min-height:56px
  }
  .benefit-story.is-accordion .benefit-tag{margin:0;flex:none}
  .benefit-story.is-accordion .benefit-tag em{font-size:12.5px}
  .benefit-story.is-accordion .benefit-head b{margin:0;flex:1;font-size:1.02rem;line-height:1.25}
  .benefit-story.is-accordion .benefit-chev{
    display:grid;place-items:center;flex:none;width:22px;height:22px;color:var(--muted);
    transition:transform .28s var(--ease-premium),color .2s ease
  }
  .benefit-story.is-accordion .benefit-chev svg{width:16px;height:16px}
  .benefit-story.is-accordion .benefit-row.is-open .benefit-chev{transform:rotate(180deg);color:var(--red)}
  .benefit-story.is-accordion .benefit-row.is-open .benefit-head b{color:var(--text)}
  .benefit-story.is-accordion .benefit-panel{
    display:grid;grid-template-rows:0fr;transition:grid-template-rows .3s var(--ease-premium)
  }
  .benefit-story.is-accordion .benefit-row.is-open .benefit-panel{grid-template-rows:1fr}
  .benefit-story.is-accordion .benefit-panel-in{min-height:0;overflow:hidden}
  .benefit-story.is-accordion .benefit-slot{display:block;margin:2px 0 14px}
  .benefit-story.is-accordion .benefit-slot .benefit-visual-photo{
    position:static;opacity:1;transform:none;width:100%;height:auto;aspect-ratio:3/2;
    border-radius:var(--r);border:1px solid var(--line);transition:none
  }
  .benefit-story.is-accordion .benefit-panel-in > p{padding-bottom:20px;max-width:none}
  /* emphasis-by-fading belongs to the desktop tracker only */
  .benefit-story.is-accordion .benefit-list.js-tracking .benefit-row{opacity:1}
  .benefit-story:not(.benefit-story--js) .benefit-visual-num{font-size:4.5rem;top:10px;right:16px}
}
@media (prefers-reduced-motion:reduce){
  .benefit-visual-photo{transition:opacity .2s ease}
  .benefit-story.is-accordion .benefit-panel{transition:none}
  .benefit-story.is-accordion .benefit-chev{transition:none}
}

/* correction & coating reviews, with hover-reveal photo */
.corr-reviews{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}
.corr-review{border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;background:var(--surface)}
.corr-review .photo{
  position:relative;aspect-ratio:4/3;overflow:hidden;background:linear-gradient(140deg,#1d1d22,#101013);cursor:pointer
}
.corr-review .photo::after{content:"";position:absolute;inset:0;background:radial-gradient(60% 70% at 35% 30%,rgba(225,27,34,.18),transparent 65%)}
.corr-review .mask{
  position:absolute;inset:0;background:rgba(10,10,11,.85);display:flex;align-items:center;justify-content:center;
  text-align:center;padding:20px;opacity:0;transition:opacity .25s;color:var(--text);font-size:13.6px;font-weight:600;line-height:1.5
}
.corr-review .photo:hover .mask,.corr-review .photo:focus-within .mask{opacity:1}
.corr-review .body{padding:26px}
.corr-review .stars{color:var(--star);letter-spacing:2px;margin-bottom:14px;font-size:14px}
.corr-review blockquote{margin:0 0 18px;font-size:14.2px;color:var(--text);line-height:1.65}
.corr-review .who b{display:block;font-family:var(--display);font-size:14px}
.corr-review .who small{color:var(--muted-2);font-size:12.5px}

/* slider variant: landscape frame, filled edge to edge (no letterboxing).
   The source photos are portrait with empty ceiling/floor space around the
   car, so this aspect ratio + background-position is tuned to crop that
   empty space away rather than the car itself — see the inline
   background-position on the two panels for the vertical bias. */
.ba-frame.wide-car .ba{aspect-ratio:1.39}
.ba-label{text-align:center;color:var(--muted);font-size:14.5px;margin:0 0 18px}
.ba-label b{color:var(--text)}

@media (max-width:1024px){
  .case-study{grid-template-columns:1fr}
  .benefits-av{grid-template-columns:1fr;gap:34px}
  .corr-reviews{grid-template-columns:1fr}
}

/* ============================================================================
   PPF PACKAGE SELECTOR — "How far do you want to protect?"
   ----------------------------------------------------------------------------
   Three specification cards, each led by a 3-view artwork carousel. The red
   coverage artwork is the strongest thing on the page, so everything around it
   is deliberately restrained: thin borders, small type, one red accent at a
   time. Rendered from PPF_PACKAGES in build.py; behaviour in ppf-packages.js.

   No-JS defaults: first view visible, details open, arrows/dots hidden.
   ============================================================================ */
.pkg-section{background:var(--black);border-top:1px solid var(--line)}
/* This section breaks the standard 1200px measure on purpose. Three uncropped
   1.64:1 cars in a 1200 wrap come out at ~225px tall; at 1400 they reach ~270px
   and start to feel like the sales asset they are. The intro copy keeps the
   site's normal reading measure, so only the artwork gets the extra width. */
.pkg-section > .wrap{max-width:1400px}
.pkg-intro{max-width:720px;margin-bottom:56px}
.pkg-intro h2{font-size:clamp(2.1rem,4.6vw,3.4rem);line-height:1.02}
.pkg-intro p{max-width:560px}

.pkg-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;align-items:start}

.pkg{
  position:relative;display:flex;flex-direction:column;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  transition:border-color .3s ease
}
.pkg:hover,.pkg:focus-within{border-color:var(--line-2)}
/* the featured package: a fine red rule and a warmer border, nothing louder */
.pkg--popular{border-color:rgba(225,27,34,.35)}
.pkg--popular::before{
  content:"";position:absolute;top:-1px;left:-1px;right:-1px;height:2px;
  background:var(--red);border-radius:var(--r) var(--r) 0 0
}
.pkg--popular:hover,.pkg--popular:focus-within{border-color:rgba(225,27,34,.55)}

/* ---- media / carousel ------------------------------------------------- */
/* Aspect is the three-quarter artwork (1604x981). The side profiles are wider,
   so with object-fit:contain they letterbox — bottom-aligned, so the only bar
   is at the top where the artwork is genuinely black and the bar disappears. */
/* Background continues the artwork's own backdrop: the renders are ~(1,1,1) at
   the corners with a soft studio glow towards the centre, so a flat #0A0A0B
   letterbox reads as a faint lighter rectangle above the side-profile views.
   This gradient sits under the image only, never over it. */
.pkg-media{
  position:relative;aspect-ratio:1604/981;overflow:hidden;
  background:linear-gradient(90deg,#020203 0%,#0d0d10 50%,#020203 100%);
  border-bottom:1px solid var(--line);outline:none;touch-action:pan-y
}
.pkg-media:focus-visible{box-shadow:inset 0 0 0 2px var(--red)}
.pkg-slide{
  position:absolute;inset:0;display:block;opacity:0;transform:translateX(0);
  transition:opacity .38s var(--ease-premium),transform .42s var(--ease-premium);
  will-change:opacity,transform
}
.pkg-slide.is-entering{transform:translateX(var(--enter-x,6px));transition:none}
.pkg-slide.is-active{opacity:1;transform:translateX(0);z-index:1}
.pkg-slide img{
  display:block;width:100%;height:100%;object-fit:contain;object-position:center bottom;
  -webkit-user-drag:none;user-select:none;
  transition:transform .8s var(--ease-premium)
}
/* hover: fractional scale on the artwork only, never colour */
@media (hover:hover) and (pointer:fine){
  .pkg:hover .pkg-slide img{transform:scale(1.015)}
}

.pkg-arrow{
  position:absolute;top:50%;z-index:3;width:44px;height:44px;margin-top:-22px;
  display:grid;place-items:center;background:transparent;border:0;color:var(--text);
  cursor:pointer;opacity:.55;transition:opacity .25s ease,color .2s ease
}
.pkg-arrow svg{width:22px;height:22px}
.pkg-arrow--prev{left:6px}
.pkg-arrow--next{right:6px}
.pkg-arrow:hover{opacity:1;color:#fff}
.pkg-arrow:focus-visible{opacity:1;outline:2px solid var(--red);outline-offset:-2px;border-radius:var(--r)}
/* on a mouse, arrows stay quiet until the card is hovered or focused */
@media (hover:hover) and (pointer:fine){
  .pkg-arrow{opacity:0}
  .pkg:hover .pkg-arrow,.pkg:focus-within .pkg-arrow{opacity:.6}
  .pkg:hover .pkg-arrow:hover{opacity:1}
}

.pkg-dots{
  position:absolute;left:0;right:0;bottom:10px;z-index:3;
  display:flex;justify-content:center;gap:2px
}
.pkg-dot{
  width:24px;height:24px;padding:0;background:transparent;border:0;cursor:pointer;
  display:grid;place-items:center
}
.pkg-dot::before{
  content:"";width:6px;height:6px;border-radius:50%;background:rgba(255,255,255,.28);
  transition:background .25s ease,transform .25s var(--ease-premium)
}
.pkg-dot:hover::before{background:rgba(255,255,255,.6)}
.pkg-dot.is-active::before{background:#fff;transform:scale(1.25)}
.pkg-dot:focus-visible{outline:2px solid var(--red);outline-offset:-4px;border-radius:50%}

/* controls only mean something once the script is driving them */
.pkg-arrow,.pkg-dots{visibility:hidden}
.pkg-grid--js .pkg-arrow,.pkg-grid--js .pkg-dots{visibility:visible}

/* ---- body ---------------------------------------------------------------- */
.pkg-body{display:flex;flex-direction:column;padding:24px 26px 26px;flex:1}
.pkg-head{display:flex;align-items:center;gap:14px;height:22px;margin-bottom:10px}  /* fixed height: the popular label must not make one card 1px taller */
.pkg-index{font-family:var(--display);font-weight:700;font-size:12px;letter-spacing:.14em;color:var(--red)}
/* .pkg-popular removed: the red corner tab (.pkg-flag) is now the single,
   accessible "Most popular" treatment. A second red line inside the card head
   repeated the same words and stacked more red onto red vehicle artwork. */
.pkg-name{
  font-family:var(--display);font-weight:700;text-transform:uppercase;letter-spacing:-.01em;
  font-size:clamp(1.7rem,2.1vw,2.5rem);line-height:1;margin:0 0 8px;
  transition:transform .3s var(--ease-premium)
}
.pkg:hover .pkg-name{transform:translateX(1px)}
/* min-height reserves two lines, so a descriptor that wraps on a narrower card
   ("Complete painted exterior protection") cannot make that card taller than
   its neighbours — the closed row stays perfectly level at every 3-col width */
.pkg-descriptor{
  font-family:var(--display);font-weight:600;font-size:11px;letter-spacing:.16em;line-height:1.5;
  text-transform:uppercase;color:var(--muted);margin:0 0 20px;min-height:3em
}

/* full-width details control, a real button, whole row clickable */
.pkg-toggle{
  display:flex;align-items:center;justify-content:space-between;width:100%;
  padding:15px 0;background:transparent;border:0;border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  color:var(--text);cursor:pointer;text-align:left;
  font-family:var(--display);font-weight:700;font-size:11.5px;letter-spacing:.14em;text-transform:uppercase;
  transition:color .2s ease
}
.pkg-toggle:hover{color:#fff}
.pkg-toggle:focus-visible{outline:2px solid var(--red);outline-offset:4px;border-radius:2px}
.pkg-toggle-ic{position:relative;width:12px;height:12px;flex:none;color:var(--muted);transition:color .2s ease}
.pkg-toggle:hover .pkg-toggle-ic,.pkg--popular .pkg-toggle-ic{color:var(--red)}
.pkg-toggle-ic i{position:absolute;background:currentColor;transition:transform .35s var(--ease-premium),opacity .25s ease}
.pkg-toggle-ic i:first-child{left:0;right:0;top:5px;height:2px}
.pkg-toggle-ic i:last-child{top:0;bottom:0;left:5px;width:2px}
.pkg-toggle[aria-expanded="true"] .pkg-toggle-ic i:last-child{transform:scaleY(0)}

/* accessible height animation: 0fr -> 1fr on a grid, inner min-height:0 */
.pkg-details{display:grid;grid-template-rows:1fr;transition:grid-template-rows .42s var(--ease-premium)}
.pkg-grid--js .pkg-details{grid-template-rows:0fr}
.pkg-grid--js .pkg-details.is-open{grid-template-rows:1fr}
.pkg-details-inner{min-height:0;overflow:hidden}
.pkg-details-head{
  font-family:var(--display);font-weight:700;font-size:10.5px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--muted-2);margin:20px 0 12px
}
.pkg-list{list-style:none;margin:0;padding:0}
.pkg-list li{display:flex;align-items:flex-start;gap:10px;padding:5px 0;font-size:14.5px;line-height:1.4;color:var(--text)}
.pkg-list svg{width:16px;height:16px;flex:none;margin-top:3px;color:var(--red)}
.pkg-positioning{color:var(--muted);font-size:13.5px;line-height:1.55;margin:14px 0 0;max-width:34ch}
/* the Full Car exclusion: plain, readable, not buried */
.pkg-note{
  display:flex;align-items:center;gap:10px;margin:14px 0 0;
  font-family:var(--display);font-weight:600;font-size:12px;letter-spacing:.06em;color:var(--text)
}
.pkg-note::before{content:"";width:10px;height:1px;background:var(--red);flex:none}
.pkg-details-inner > :last-child{margin-bottom:22px}

.pkg-foot{margin-top:auto;padding-top:22px}
.pkg-price{display:flex;align-items:baseline;gap:12px;margin:0 0 18px}
.pkg-price span{
  font-family:var(--display);font-weight:700;font-size:11px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--muted)
}
.pkg-price b{font-family:var(--display);font-weight:700;font-size:2.15rem;line-height:1;letter-spacing:-.01em;color:#fff}
/* CTA: the site's primary button, but no lift and no glow beside red artwork */
.pkg-cta{width:100%;padding:16px 22px;font-size:13.5px;gap:12px}
.pkg-cta:hover{transform:none;box-shadow:none}
.pkg-cta.btn-ghost{border-color:var(--line-2);color:var(--text)}
.pkg-cta.btn-ghost:hover{background:var(--red);border-color:var(--red);color:#fff}
.pkg-cta svg{width:18px;height:18px;transition:transform .3s var(--ease-premium)}
.pkg-cta:hover svg{transform:translateX(4px)}

.pkg-disclaimer{color:var(--muted-2);font-size:13px;line-height:1.6;max-width:720px;margin:36px 0 0}

/* ---- staggered entrance via the site's .reveal system ----------------------
   .reveal gives us the IntersectionObserver hook (site.js adds .in); the grid
   itself never hides, only its cards stagger in. */
.pkg-grid.reveal{opacity:1;transform:none;transition:none}
/* The entrance state is gated on .pkg-grid--js, which ppf-packages.js adds on
   its first line. Ungated, a blocked script or a no-JS visitor was left with
   three invisible package cards: the commercial heart of the page, gone. */
.reveal-ready .pkg-grid--js > .pkg{opacity:0;transform:translateY(18px);transition:opacity .7s ease,transform .8s var(--ease-premium),border-color .3s ease}
.reveal-ready .pkg-grid--js.in > .pkg{opacity:1;transform:none}
.pkg-grid.in > .pkg:nth-child(2){transition-delay:.08s}
.pkg-grid.in > .pkg:nth-child(3){transition-delay:.16s}

/* ---- the comparison table: secondary, quieter than the cards ------------- */
.pkg-compare .compare thead th.feat{background:var(--elev);color:var(--red);box-shadow:inset 0 2px 0 var(--red)}
.pkg-compare .compare td.feat{background:rgba(225,27,34,.04)}

/* ---- responsive ------------------------------------------------------------ */
@media (max-width:1180px){
  .pkg-grid{gap:16px}
  .pkg-body{padding:20px 20px 22px}
  .pkg-price b{font-size:1.9rem}
  .pkg-cta{padding:15px 16px;font-size:12.5px}
}
/* One card per row below 1100. Three columns at 1024 put the car at ~190px
   tall, which throws away the strongest asset on the page; a single 640px
   column gives a 390px car and a short, deliberate scroll instead. */
@media (max-width:1100px){
  .pkg-grid{grid-template-columns:1fr;gap:26px;max-width:640px;margin:0 auto}
  .pkg-intro{margin-bottom:40px}
  .pkg-body{padding:24px 24px 26px}
  .pkg-name{font-size:clamp(1.9rem,7vw,2.6rem)}
  .pkg-descriptor{min-height:0}
  .pkg-price b{font-size:2.2rem}
  .pkg-arrow{opacity:.5}
}
@media (max-width:480px){
  .pkg-body{padding:20px 18px 22px}
  .pkg-arrow--prev{left:0}
  .pkg-arrow--next{right:0}
}

@media (prefers-reduced-motion:reduce){
  .pkg-slide{transition:opacity .15s linear}
  .pkg-slide.is-entering{transform:none}
  .pkg-slide img{transition:none}
  .pkg:hover .pkg-slide img{transform:none}
  .pkg-details{transition:none}
  .reveal-ready .pkg-grid--js > .pkg{opacity:1;transform:none;transition:border-color .3s ease}
  .pkg-toggle-ic i,.pkg-cta svg,.pkg-name{transition:none}
}

/* contact form: PPF package field, preselected when arriving from a package CTA */
.field-hint{margin:8px 0 0;font-size:12.5px;color:var(--muted)}
.field.is-prefilled select,.field.is-prefilled input{border-color:var(--red)}

/* ============================================================================
   FLAGSHIP WARRANTY — "10 YEARS"
   ----------------------------------------------------------------------------
   The seventh reason. One enormous number, black space, almost no UI. Facts
   come from PPF_WARRANTY in build.py.

   Base styles = the COMPLETE static composition (no-JS, reduced motion, and
   every viewport at or below 1024px). ppf-warranty.js adds .wty--js on desktop
   only, which switches to a sticky cinematic stage driven by unitless custom
   properties (--rule, --lead, --lead-out, --num, --years, --sub, --kick, --def,
   --copy). Inside .wty--js every var defaults to 0, so the section starts dark
   the instant the class lands and render() takes it from there.
   ============================================================================ */
/* no overflow:hidden here — it would make this box the sticky stage's scroll
   container and the stage would never pin. Nothing inside overflows anyway. */
.wty{position:relative;background:var(--black);border-top:1px solid var(--line)}
.wty-track{position:relative}
.wty-sticky{position:relative;padding:120px 0 110px}
.wty-inner{position:relative;z-index:1}

/* soft studio lift behind the number + a whisper of grain. No colour. */
.wty-bg{
  position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(ellipse 58% 62% at 30% 48%,rgba(255,255,255,.045) 0%,rgba(255,255,255,.015) 45%,transparent 72%),
    repeating-linear-gradient(0deg,rgba(255,255,255,.011) 0 1px,transparent 1px 3px)
}

/* the transition beat from the benefits section: one thin red line */
.wty-rule{display:block;width:64px;height:1px;background:var(--red);margin:0 0 34px;transform-origin:left center}

/* transitional line. In the static composition it is a modest introduction
   above the number; in the cinematic stage it is the large opening frame. */
.wty-lead{
  font-family:var(--display);font-weight:700;text-transform:uppercase;letter-spacing:-.005em;
  font-size:clamp(1.3rem,2.1vw,1.7rem);line-height:1.05;color:var(--muted);margin:0 0 44px
}
.wty-mask{display:block;overflow:hidden}
.wty-mask > span{display:block}

/* ---- the hero: 10 | YEARS / OF MANUFACTURER BACKING. ----------------------- */
.wty-hero{margin:0 0 44px}
.wty-heading{
  display:flex;align-items:flex-end;gap:clamp(20px,3vw,44px);
  margin:0;line-height:1;font-weight:700
}
/* The number. Archivo 700, tracking pulled in hard so the 1 and 0 read as one
   object. Height-capped as well as width-capped so it never outgrows a short
   laptop viewport. Off-white with a faint vertical studio falloff, not red. */
/* --fill is registered so it interpolates: 0 = thin outline, 1 = solid. The
   gradient alpha and the stroke alpha are both derived from it, so one number
   drives the whole outline-to-solid moment on desktop and mobile alike. */
@property --fill{syntax:"<number>";inherits:false;initial-value:1}
.wty-num{
  display:block;font-family:var(--display);font-weight:700;
  font-size:clamp(9rem,min(32vw,50vh),34rem);line-height:.82;letter-spacing:-.06em;
  margin-left:-.04em;   /* optical: the 1's left bearing */
  --fill:1;
  color:#f2f2f4;
  background:linear-gradient(180deg,
    rgba(255,255,255,var(--fill)) 0%,
    rgba(236,236,239,var(--fill)) 55%,
    rgba(201,201,206,var(--fill)) 100%);
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;
  -webkit-text-stroke:1px rgba(242,242,244,calc(.85 * (1 - var(--fill))))
}
.wty-side{display:flex;flex-direction:column;gap:12px;padding-bottom:.08em}
.wty-years{
  display:block;font-family:var(--display);font-weight:700;text-transform:uppercase;
  font-size:clamp(2rem,5.2vw,4.4rem);letter-spacing:.02em;line-height:.95;color:var(--text)
}
.wty-sub{
  display:block;font-family:var(--display);font-weight:600;text-transform:uppercase;
  font-size:clamp(1rem,1.55vw,1.35rem);letter-spacing:.06em;line-height:1.2;color:var(--muted)
}
.wty-kicker{
  display:inline-flex;align-items:center;gap:12px;margin:26px 0 0;
  font-family:var(--display);font-weight:700;font-size:11px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--red)
}
.wty-kicker::before{content:"";width:22px;height:1px;background:var(--red);flex:none}

/* ---- the foot: defects row, statement, terms link -------------------------- */
.wty-foot{border-top:1px solid var(--line);padding-top:30px}
.wty-defects{
  list-style:none;margin:0 0 34px;padding:0;
  display:flex;flex-wrap:wrap;gap:14px 0
}
.wty-defects li{
  position:relative;flex:1 1 0;min-width:0;padding:0 28px 0 0;
  font-family:var(--display);font-weight:700;font-size:clamp(.95rem,1.25vw,1.15rem);
  letter-spacing:.14em;text-transform:uppercase;color:var(--text);white-space:nowrap
}
.wty-defects li + li{padding-left:28px;border-left:1px solid var(--line)}
.wty-idx{display:block;margin-bottom:8px;font-size:11px;letter-spacing:.18em;color:var(--red)}

.wty-copy{display:grid;grid-template-columns:minmax(0,58ch) auto;gap:18px 48px;align-items:end}
.wty-statement{margin:0;color:var(--text);font-size:1.02rem;line-height:1.6}
.wty-small{grid-column:1;margin:0;color:var(--muted-2);font-size:12.5px;line-height:1.55}
.wty-link{
  grid-column:2;grid-row:1 / span 2;justify-self:end;
  display:inline-flex;align-items:center;gap:10px;
  font-family:var(--display);font-weight:700;font-size:12px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--text);text-decoration:none;padding-bottom:6px;border-bottom:1px solid var(--line-2);
  transition:border-color .25s ease,color .25s ease
}
.wty-link svg{width:16px;height:16px;color:var(--red);transition:transform .3s var(--ease-premium)}
.wty-link:hover{color:#fff;border-color:var(--red)}
.wty-link:hover svg{transform:translateX(4px)}
.wty-link:focus-visible{outline:2px solid var(--red);outline-offset:4px}

/* ============================================================================
   CINEMATIC MODE (desktop only, added by ppf-warranty.js)
   ============================================================================ */
/* 190vh: 100svh pinned + 90vh runway. assets/ppf-warranty.js expresses every
   beat as a fraction of that runway, so it rescales with this number rather
   than silently running out of room. */
.wty--js .wty-track{height:190vh}
.wty--js .wty-sticky{
  position:sticky;top:0;height:100svh;min-height:600px;padding:60px 0 0;  /* centre below the nav, not behind it */
  display:flex;align-items:center
}
.wty--js .wty-inner{width:100%}
/* in cinematic mode the script owns the hero; the .reveal observer must not */
.wty--js .wty-hero.reveal{opacity:1;transform:none;transition:none}
.wty--js .wty-rule{
  position:absolute;left:var(--gut);top:calc(50% - 130px);margin:0;
  transform:scaleX(var(--rule,0))
}
/* opening frame: large, centred, masked line reveal, then lifts away */
.wty--js .wty-lead{
  position:absolute;left:var(--gut);right:var(--gut);top:50%;margin:0;
  font-size:clamp(2.2rem,4.6vw,4rem);line-height:1;color:var(--text);
  transform:translateY(calc(-50% - var(--lead-out,0) * 70px));
  opacity:calc(1 - var(--lead-out,0));
  pointer-events:none
}
.wty--js .wty-mask > span{transform:translateY(calc((1 - var(--lead,0)) * 110%))}
.wty--js .wty-mask:nth-child(2) > span{transform:translateY(calc((1 - var(--lead2,0)) * 110%))}

/* the number: outline -> solid as the promise becomes concrete (JS writes --fill) */
.wty--js .wty-num{
  --fill:0;
  opacity:var(--num-o,0);
  transform:translateY(calc((1 - var(--num,0)) * 24px)) scale(calc(1.03 - var(--num,0) * .03))
}
.wty--js .wty-years{opacity:var(--years,0);transform:translateY(calc((1 - var(--years,0)) * 18px))}
.wty--js .wty-sub{opacity:var(--sub,0);transform:translateY(calc((1 - var(--sub,0)) * 14px))}
.wty--js .wty-kicker{opacity:var(--kick,0);transform:translateY(calc((1 - var(--kick,0)) * 10px))}
.wty--js .wty-foot{border-top-color:rgba(255,255,255,calc(.09 * var(--def,0)))}
/* defects stagger off one variable: item n lights up as --def passes n/5 */
.wty--js .wty-defects li{opacity:calc(clamp(0,(var(--def,0) - var(--i)) * 4,1));transform:translateY(calc((1 - clamp(0,(var(--def,0) - var(--i)) * 4,1)) * 12px))}
.wty--js .wty-defects li:nth-child(1){--i:0}
.wty--js .wty-defects li:nth-child(2){--i:.16}
.wty--js .wty-defects li:nth-child(3){--i:.32}
.wty--js .wty-defects li:nth-child(4){--i:.48}
.wty--js .wty-copy{opacity:var(--copy,0);transform:translateY(calc((1 - var(--copy,0)) * 12px))}
/* exit: the whole composition settles and darkens a touch as the next section arrives */
.wty--js .wty-inner{opacity:calc(1 - var(--exit,0) * .55);transform:translateY(calc(var(--exit,0) * -18px))}

/* short laptop viewports: the number is height-capped by 50vh but the rest of
   the stack is not, so trim both a touch to keep the composition off the nav */
@media (min-width:1025px) and (max-height:780px){
  .wty--js .wty-sticky{padding-top:70px}
  .wty--js .wty-num{font-size:clamp(9rem,min(32vw,42vh),34rem)}
  .wty--js .wty-hero{margin-bottom:28px}
  .wty--js .wty-foot{padding-top:22px}
  .wty--js .wty-defects{margin-bottom:22px}
  .wty--js .wty-kicker{margin-top:18px}
}

/* ---- tablet / mobile: static column, number still enormous ---------------- */
@media (max-width:1024px){
  .wty-sticky{padding:96px 0 88px}
  .wty-heading{flex-direction:column;align-items:flex-start;gap:18px}
  .wty-num{font-size:clamp(9rem,min(58vw,40vh),22rem);margin-left:-.05em}
  .wty-side{padding-bottom:0}
  .wty-years{font-size:clamp(2.2rem,8vw,4rem)}
  .wty-defects{display:grid;grid-template-columns:1fr 1fr;gap:22px 24px}
  .wty-defects li{padding:0;white-space:normal}
  .wty-defects li + li{padding-left:0;border-left:0}
  .wty-copy{grid-template-columns:1fr;gap:16px}
  .wty-small{grid-column:auto}
  .wty-link{grid-column:auto;grid-row:auto;justify-self:start;margin-top:6px}
}
@media (max-width:480px){
  .wty-sticky{padding:80px 0 72px}
  .wty-num{font-size:clamp(8rem,78vw,20rem)}
  .wty-lead{font-size:1.25rem}
  .wty-defects{grid-template-columns:1fr 1fr;gap:18px 16px}
  .wty-defects li{font-size:.9rem;letter-spacing:.12em}
}

/* the mobile/tablet number still gets its outline -> solid moment on entry,
   driven by the site's .reveal observer (site.js adds .in) */
@media (max-width:1024px){
  .wty-hero.reveal{opacity:1;transform:none}
  .wty-hero.reveal .wty-num{--fill:0;transition:--fill 1.2s var(--ease-premium) .15s}
  .wty-hero.reveal.in .wty-num{--fill:1}
}

@media (prefers-reduced-motion:reduce){
  .wty-hero.reveal .wty-num,.wty-hero.reveal.in .wty-num{--fill:1;transition:none}
  .wty-link svg{transition:none}
}


/* ============================================================================
   "THE INSTALL MATTERS" — certification, craft, installation quality
   ----------------------------------------------------------------------------
   Rhythm: head -> 96px -> credential plate -> 72px -> trust strip -> 104px ->
   "See the film in action" -> 48px -> videos. Entrance choreography is
   CSS-only, keyed off .reveal/.in from site.js's IntersectionObserver.
   ============================================================================ */
.inst-head{margin-bottom:64px}
.inst-head p{max-width:650px;margin-left:auto;margin-right:auto}

/* ---- credential plate ------------------------------------------------------ */
.cred{
  position:relative;width:min(1100px,100%);margin:0 auto 56px;
  display:grid;grid-template-columns:34fr 1px 66fr;align-items:center;
  background:var(--surface);border:1px solid var(--line);border-radius:6px;
  padding:52px 56px;isolation:isolate   /* so the ::before lift paints above the plate's own background */
}
/* a very soft studio lift behind the plate, nothing more */
.cred::before{
  content:"";position:absolute;inset:-60px -40px;z-index:-1;pointer-events:none;
  background:radial-gradient(ellipse 55% 60% at 50% 50%,rgba(255,255,255,.035),transparent 70%)
}
.cred-mark{position:relative;display:flex;align-items:center;justify-content:center;padding:8px 48px 8px 8px}
.cred-mark img{width:min(100%,230px);height:auto;display:block;opacity:.86}
/* studio light across the wordmark: a soft band, masked to the letters
   themselves, so the light travels over the mark rather than the box */
.cred-sweep{
  position:absolute;inset:8px 48px 8px 8px;pointer-events:none;opacity:0;
  background:linear-gradient(105deg,transparent 40%,rgba(255,255,255,.95) 50%,transparent 60%);
  background-size:260% 100%;background-position:130% 0;
  -webkit-mask:url(/images/XPEL-logo-white.png) center / min(100%,230px) auto no-repeat;
  mask:url(/images/XPEL-logo-white.png) center / min(100%,230px) auto no-repeat
}
.cred-divider{display:block;width:1px;height:100%;min-height:96px;background:var(--line-2);transform-origin:top center}
.cred-body{padding-left:56px}
.cred-eyebrow{
  margin:0 0 14px;font-family:var(--display);font-weight:700;font-size:10.5px;
  letter-spacing:.2em;text-transform:uppercase;color:var(--red)
}
.cred-title{
  margin:0 0 16px;font-family:var(--display);font-weight:700;text-transform:uppercase;
  font-size:clamp(1.5rem,2.3vw,2.1rem);line-height:1.05;letter-spacing:-.005em;color:var(--text)
}
.cred-title span{display:block}
.cred-copy{margin:0;color:var(--muted);font-size:15px;line-height:1.6;max-width:44ch}

/* entrance: plate -> mark -> divider draws -> text -> one light pass */
.cred.reveal{transform:translateY(16px)}
.cred.reveal .cred-mark img{opacity:0;transform:scale(.97);transition:opacity .7s ease .25s,transform .9s var(--ease-premium) .25s}
.cred.reveal .cred-divider{transform:scaleY(0);transition:transform .6s var(--ease-premium) .55s}
.cred.reveal .cred-eyebrow,.cred.reveal .cred-title,.cred.reveal .cred-copy{opacity:0;transform:translateY(10px);transition:opacity .6s ease,transform .7s var(--ease-premium)}
.cred.reveal .cred-eyebrow{transition-delay:.75s}
.cred.reveal .cred-title{transition-delay:.85s}
.cred.reveal .cred-copy{transition-delay:.95s}
.cred.reveal.in .cred-mark img{opacity:.86;transform:none}
.cred.reveal.in .cred-divider{transform:scaleY(1)}
.cred.reveal.in .cred-eyebrow,.cred.reveal.in .cred-title,.cred.reveal.in .cred-copy{opacity:1;transform:none}
.cred.reveal.in .cred-sweep{animation:credSweep 1.6s var(--ease-premium) 1.2s 1 both}
@keyframes credSweep{
  0%{opacity:0;background-position:130% 0}
  15%{opacity:1}
  85%{opacity:1}
  100%{opacity:0;background-position:-40% 0}
}

/* ---- trust strip ------------------------------------------------------------ */
.trust{
  list-style:none;margin:0 0 104px;padding:44px 0 0;border-top:1px solid var(--line);
  display:grid;grid-template-columns:repeat(3,1fr)
}
.trust li{position:relative;padding:0 32px}
.trust li:first-child{padding-left:0}
.trust li + li{border-left:1px solid var(--line)}
.trust-line{display:block;width:22px;height:1px;background:var(--red);margin:0 0 18px}
.trust-idx{display:block;margin:0 0 10px;font-family:var(--display);font-weight:700;font-size:11px;letter-spacing:.18em;color:var(--red)}
.trust b{display:block;font-family:var(--display);font-weight:700;font-size:1rem;letter-spacing:.06em;text-transform:uppercase;margin:0 0 10px;color:var(--text)}
.trust p{margin:0;color:var(--muted);font-size:14px;line-height:1.6;max-width:30ch}
/* items stagger in with the strip */
.trust.reveal li{opacity:0;transform:translateY(12px);transition:opacity .6s ease,transform .7s var(--ease-premium)}
.trust.reveal li:nth-child(2){transition-delay:.1s}
.trust.reveal li:nth-child(3){transition-delay:.2s}
.trust.reveal.in li{opacity:1;transform:none}

/* ---- videos ----------------------------------------------------------------- */
.inst-videos .eyebrow{margin-bottom:34px}
.inst-videos .xpel-block{margin-top:0;gap:36px}
.inst-videos .bf-video{border-color:var(--line-2)}
.inst-videos .xpel-vid figcaption{margin-top:16px}
.inst-videos .xpel-vid figcaption b{font-size:14px;letter-spacing:.06em;text-transform:uppercase;margin-bottom:6px}

/* ---- responsive --------------------------------------------------------------- */
@media (max-width:1024px){
  .cred{padding:44px 40px;grid-template-columns:36fr 1px 64fr}
  .cred-mark{padding-right:32px}
  .cred-body{padding-left:40px}
}
@media (max-width:820px){
  .inst-head{margin-bottom:72px}
  .cred{grid-template-columns:1fr;gap:0;padding:40px 32px;margin-bottom:56px}
  .cred-mark{padding:0 0 32px;justify-content:flex-start}
  .cred-mark img{width:min(100%,180px)}
  .cred-sweep{inset:0 0 32px 0;-webkit-mask-size:min(100%,180px) auto;mask-size:min(100%,180px) auto;-webkit-mask-position:left center;mask-position:left center}
  .cred-divider{width:100%;height:1px;min-height:0;transform-origin:left center}
  .cred.reveal .cred-divider{transform:scaleX(0)}
  .cred.reveal.in .cred-divider{transform:scaleX(1)}
  .cred-body{padding:32px 0 0}
  .trust{grid-template-columns:1fr;padding-top:0;border-top:0;margin-bottom:80px}
  .trust li{padding:28px 0;border-top:1px solid var(--line)}
  .trust li + li{border-left:0}
  .trust li:last-child{border-bottom:1px solid var(--line)}
  .trust p{max-width:none}
  .inst-videos .eyebrow{margin-bottom:32px}
  .inst-videos .xpel-block{gap:40px}
}
@media (max-width:480px){
  .cred{padding:32px 24px}
  .cred-title{font-size:1.6rem}
}

@media (prefers-reduced-motion:reduce){
  .cred.reveal,.cred.reveal .cred-mark img,.cred.reveal .cred-divider,
  .cred.reveal .cred-eyebrow,.cred.reveal .cred-title,.cred.reveal .cred-copy,
  .trust.reveal li{opacity:1;transform:none;transition:none}
  .cred.reveal .cred-mark img{opacity:.86}
  .cred.reveal.in .cred-sweep,.cred-sweep{animation:none;opacity:0}
}

/* ============================================================================
   "BEYOND CLEAR PPF" — STEALTH | COLOR PPF finish selector
   ----------------------------------------------------------------------------
   The photography IS the layout. One frame, two panels, a 1px seam. On
   desktop the hovered/focused side widens to ~59% (grid-template-columns is
   animatable); below 1024px the panels stack as tall immersive blocks.
   Red is limited to the tiny tag indicator and the CTA arrow — the cars are
   blue and the two must not fight.
   ============================================================================ */
.fin{background:var(--black);padding:140px 0 110px}
.fin-intro{max-width:760px;margin-bottom:80px}
.fin-intro h2{font-size:clamp(2.4rem,5.4vw,4.4rem);line-height:.98;letter-spacing:-.01em;text-transform:uppercase;margin:0}
.fin-lead{color:var(--muted);font-size:1.08rem;line-height:1.65;max-width:600px;margin:26px 0 0}

/* ---- the frame ---------------------------------------------------------- */
.fin-frame{width:min(1400px,calc(100% - 2 * var(--gut)));margin:0 auto}
.fin-split{
  position:relative;display:grid;grid-template-columns:1fr 1fr;
  height:clamp(650px,78svh,900px);
  transition:grid-template-columns .75s var(--ease-premium)
}
/* The width transition has to live HERE, not on .fin-split alone: the frame
   also carries .reveal, and `.js .reveal` sets its own shorthand transition
   at a higher specificity, which silently threw the 750ms away and left the
   panels snapping between states. */
.fin-split.reveal{opacity:1;transform:none;   /* the panels reveal themselves; the frame never hides */
  transition:grid-template-columns .75s var(--ease-premium)}
/* 57 / 43. Enough to say which side you are on, not enough for one
   finish to look like it is swallowing the other. */
.fin-split[data-active="stealth"]{grid-template-columns:1.3256fr 1fr}
.fin-split[data-active="color"]{grid-template-columns:1fr 1.3256fr}

.fin-panel{
  position:relative;display:block;overflow:hidden;min-width:0;color:var(--text);text-decoration:none;
  outline:none
}
.fin-panel:focus-visible .fin-text{outline:2px solid var(--red);outline-offset:6px}
.fin-media{display:block;position:absolute;inset:0}
.fin-media img{
  width:100%;height:100%;object-fit:cover;display:block;
  transform:scale(1);filter:brightness(1);
  transition:transform .95s var(--ease-premium),filter .75s ease
}
/* each photograph is framed on its subject, not just centred */
.fin-panel--stealth .fin-media img{object-position:50% 48%}   /* taillight, RS3 badge, rear quarter */
.fin-panel--color .fin-media img{object-position:52% 62%}     /* PORSCHE + GT3 RS lettering, XPEL plate lifted clear of the copy */
/* active side: a whisper of scale; the other side eases back 8% */
.fin-split[data-active] .fin-panel.is-active .fin-media img{transform:scale(1.012)}
.fin-split[data-active] .fin-panel:not(.is-active) .fin-media img{filter:brightness(.94)}

/* readability without a box: a low, dark grade that fades to the page black */
.fin-scrim{
  position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(10,10,11,0) 40%,rgba(10,10,11,.42) 68%,rgba(10,10,11,.86) 100%)
}

/* the 1px seam rides the panel boundary as it moves */
.fin-seam{position:absolute;top:0;bottom:0;left:50%;width:1px;background:rgba(255,255,255,.14);pointer-events:none;transition:left .75s var(--ease-premium)}
.fin-split[data-active="stealth"] .fin-seam{left:57%}
.fin-split[data-active="color"] .fin-seam{left:43%}

/* ---- text over the photograph ------------------------------------------- */
.fin-text{
  position:absolute;left:0;right:0;bottom:0;z-index:2;
  display:flex;flex-direction:column;align-items:flex-start;
  padding:clamp(28px,3.8vw,52px)
}
.fin-tag{
  display:inline-flex;align-items:center;gap:10px;margin:0 0 18px;
  font-family:var(--display);font-weight:700;font-size:11px;letter-spacing:.2em;
  text-transform:uppercase;color:rgba(242,242,244,.72)
}
.fin-tag i{width:6px;height:6px;border-radius:50%;background:var(--red);display:block;flex:none;transform:scale(.8);transition:transform .4s var(--ease-premium)}
.fin-panel.is-active .fin-tag i{transform:scale(1.25)}
.fin-name{
  display:block;font-family:var(--display);font-weight:700;text-transform:uppercase;
  font-size:clamp(2.2rem,3.8vw,4.2rem);line-height:.94;letter-spacing:-.015em;margin:0 0 12px;color:#fff
}
.fin-name span{display:block}
.fin-head{
  display:block;font-family:var(--display);font-weight:600;text-transform:uppercase;
  font-size:clamp(.85rem,1.05vw,1rem);letter-spacing:.14em;color:var(--text);margin:0 0 16px
}
/* description and CTA sit back in the neutral state, resolve when active.
   Never hidden — a touch or keyboard user must still read both options. */
.fin-copy{
  /* readable before anything is hovered: essential copy must not depend on a
     pointer. Activating a panel is now a small lift, not the difference
     between legible and not. */
  display:block;max-width:40ch;color:rgba(242,242,244,.94);font-size:15px;line-height:1.6;
  opacity:.88;transform:translateY(2px);transition:opacity .5s ease,transform .6s var(--ease-premium)
}
.fin-cta{
  display:inline-flex;align-items:center;gap:10px;margin-top:22px;
  font-family:var(--display);font-weight:700;font-size:12px;letter-spacing:.16em;text-transform:uppercase;
  color:#fff;padding-bottom:6px;border-bottom:1px solid rgba(255,255,255,.48);
  opacity:.92;transition:opacity .5s ease,border-color .4s ease
}
.fin-cta svg{width:16px;height:16px;color:var(--red);transition:transform .4s var(--ease-premium)}
.fin-panel.is-active .fin-copy{opacity:1;transform:none}
.fin-panel.is-active .fin-cta{opacity:1;border-color:var(--red)}
.fin-panel.is-active .fin-cta svg{transform:translateX(4px)}

/* ---- entrance: the two photographs reveal outward from the seam ---------- */
/* .js-gated: without scripting nothing adds .in, so an ungated clip-path left
   both finish photographs clipped to zero width and the section looked empty. */
.fin-split--js.reveal .fin-panel--stealth .fin-media{clip-path:inset(0 0 0 100%);transition:clip-path 1.2s var(--ease-premium) .1s}
.fin-split--js.reveal .fin-panel--color   .fin-media{clip-path:inset(0 100% 0 0);transition:clip-path 1.2s var(--ease-premium) .1s}
/* same trap as the frame: this selector beats .fin-seam, so the seam's own
   left transition has to be restated here or it jumps */
.fin-split.reveal .fin-seam{transform:scaleY(0);transform-origin:center;
  transition:transform .7s var(--ease-premium),left .75s var(--ease-premium)}
.fin-split.reveal .fin-text{opacity:0;transform:translateY(12px);transition:opacity .7s ease .7s,transform .8s var(--ease-premium) .7s}
.fin-split--js.reveal.in .fin-panel .fin-media{clip-path:inset(0)}
.fin-split.reveal.in .fin-seam{transform:scaleY(1)}
.fin-split.reveal.in .fin-text{opacity:1;transform:none}

/* ---- foot: the package relationship, one shared CTA ---------------------- */
.fin-foot{
  display:flex;align-items:flex-end;justify-content:space-between;gap:32px 48px;flex-wrap:wrap;
  margin-top:72px;padding-top:32px;border-top:1px solid var(--line)
}
.fin-foot-label{margin:0 0 10px;font-family:var(--display);font-weight:700;font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--red)}
.fin-foot-copy{margin:0;color:var(--muted);font-size:15px;line-height:1.6;max-width:52ch}
.fin-foot-cta{border-color:var(--line-2);gap:12px}
.fin-foot-cta svg{width:16px;height:16px;transition:transform .3s var(--ease-premium)}
.fin-foot-cta:hover{transform:none;background:var(--red);border-color:var(--red);color:#fff}
.fin-foot-cta:hover svg{transform:translateX(4px)}

/* ---- tablet / mobile: two tall immersive panels, no hover dependency ------ */
@media (max-width:1024px){
  .fin{padding:100px 0 90px}
  .fin-intro{margin-bottom:56px}
  .fin-frame{width:calc(100% - 2 * var(--gut))}
  .fin-split{grid-template-columns:1fr;height:auto;gap:14px;transition:none}
  .fin-split[data-active]{grid-template-columns:1fr}
  .fin-panel{height:clamp(520px,74svh,720px)}
  .fin-panel--color .fin-media img{object-position:58% 50%}   /* keep GT3 RS + plate in a tall crop */
  .fin-seam{display:none}
  .fin-text{padding:28px 26px}
  .fin-name{font-size:clamp(2.4rem,11vw,3.6rem)}
  .fin-copy,.fin-cta{opacity:1;transform:none}
  .fin-cta{border-color:rgba(255,255,255,.5)}
  /* entrance per panel: settle from 1.02 and reveal text, no seam wipe */
  .fin-split--js.reveal .fin-panel .fin-media{clip-path:none;transform:scale(1.02);transition:transform 1.1s var(--ease-premium)}
  .fin-split--js.reveal.in .fin-panel .fin-media{transform:scale(1)}
  .fin-split.reveal .fin-panel--color .fin-text{transition-delay:.9s}
  .fin-foot{margin-top:56px}
  .fin-foot-cta{width:100%}
}
@media (max-width:480px){
  .fin{padding:80px 0 72px}
  .fin-intro h2{font-size:clamp(2.1rem,10vw,2.8rem)}
  .fin-panel{height:clamp(480px,72svh,640px)}
  .fin-text{padding:24px 20px}
}

@media (prefers-reduced-motion:reduce){
  .fin-split,.fin-seam,.fin-media img,.fin-copy,.fin-cta,.fin-tag i{transition:opacity .2s ease}
  .fin-split[data-active]{grid-template-columns:1fr 1fr}
  .fin-split[data-active] .fin-seam{left:50%}
  .fin-split[data-active] .fin-panel.is-active .fin-media img{transform:none}
  .fin-split.reveal .fin-panel .fin-media,.fin-split.reveal.in .fin-panel .fin-media{clip-path:none;transform:none;transition:none}
  .fin-split.reveal .fin-seam,.fin-split.reveal .fin-text{transform:none;opacity:1;transition:none}
}


/* ============================================================================
   PACKAGES — Most Popular tab + ceramic add-on panel
   ============================================================================ */
/* the intro row: heading left, add-on in the right-hand space it used to waste */
.pkg-top{display:grid;grid-template-columns:minmax(0,720px) minmax(280px,380px);justify-content:space-between;align-items:end;gap:32px 48px;margin-bottom:56px}
.pkg-top .pkg-intro{margin-bottom:0}
.pkg-addon{
  position:relative;padding:24px 26px 24px 30px;border:1px solid var(--line);border-radius:var(--r);
  background:var(--surface)
}
.pkg-addon::before{content:"";position:absolute;left:-1px;top:18px;bottom:18px;width:2px;background:var(--red)}
.pkg-addon-eyebrow{margin:0 0 8px;font-family:var(--display);font-weight:700;font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--red)}
.pkg-addon h3{margin:0 0 8px;font-family:var(--display);font-weight:700;font-size:1.05rem;text-transform:uppercase;letter-spacing:.02em;color:var(--text)}
.pkg-addon p{margin:0 0 14px;color:var(--muted);font-size:14px;line-height:1.55}
.pkg-addon a{
  display:inline-flex;align-items:center;gap:8px;font-family:var(--display);font-weight:700;font-size:11.5px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--text);text-decoration:none;
  padding-bottom:4px;border-bottom:1px solid var(--line-2);transition:border-color .25s ease
}
.pkg-addon a svg{width:14px;height:14px;color:var(--red);transition:transform .3s var(--ease-premium)}
.pkg-addon a:hover{border-color:var(--red)}
.pkg-addon a:hover svg{transform:translateX(3px)}
@media (max-width:1100px){
  .pkg-top{grid-template-columns:1fr;align-items:start;margin-bottom:40px}
  .pkg-addon{max-width:640px;margin:0 auto;width:100%}
}
/* a real tab on the featured card, so the red rule reads as a decision, not a stray border */
.pkg-flag{
  position:absolute;top:-1px;left:-1px;z-index:4;
  padding:9px 14px;background:var(--red);color:#fff;border-radius:var(--r) 0 var(--r) 0;
  font-family:var(--display);font-weight:700;font-size:10.5px;letter-spacing:.18em;text-transform:uppercase
}
.pkg--popular{border-color:rgba(225,27,34,.34)}
.pkg--popular:hover,.pkg--popular:focus-within{border-color:rgba(225,27,34,.6)}

/* ============================================================================
   BEFORE / AFTER COMPARISON — "Same road. Different outcome."
   ----------------------------------------------------------------------------
   One frame. The PROTECTED layer is the base; the UNPROTECTED layer sits on
   top clipped at --split. Only the clip changes, never the images, so the two
   pixel-matched photographs stay in register. Everything below also works over
   the dark placeholder until the real photography is configured in build.py.
   ============================================================================ */
.cmp{background:var(--black)}
.cmp-intro{display:grid;grid-template-columns:minmax(0,1fr) minmax(280px,420px);align-items:end;gap:28px 64px;margin-bottom:48px}
.cmp-intro h2{font-size:clamp(2.6rem,5vw,5.2rem);line-height:.96;letter-spacing:-.02em;text-transform:uppercase;margin:0}
.cmp-lead{margin:0 0 6px;color:var(--muted);font-size:1.05rem;line-height:1.65}
.cmp-help{max-width:1200px;margin:0 auto 14px;color:var(--text);font-size:.95rem;line-height:1.6}
.cmp-controls{
  display:flex;flex-wrap:wrap;gap:8px;max-width:600px;margin:16px auto 0;
  font-size:.875rem
}
.cmp-controls[hidden]{display:none}
.cmp-controls button{
  flex:1 1 7.5em;min-width:0;min-height:48px;padding:10px 12px;
  border:1px solid var(--line-2);border-radius:3px;background:var(--surface);color:var(--text);
  font:inherit;font-weight:600;line-height:1.4;cursor:pointer;
  transition:border-color .2s ease,background .2s ease
}
.cmp-controls button:hover{border-color:var(--muted)}
.cmp-controls button[aria-pressed="true"]{border-color:var(--red);background:var(--elev)}
.cmp-controls button:focus-visible{outline:2px solid var(--red);outline-offset:3px}

.cmp-frame{
  --split:50;
  position:relative;width:100%;max-width:1200px;margin:0 auto;aspect-ratio:3/2;
  border:1px solid var(--line);border-radius:8px;overflow:hidden;background:var(--surface);
  touch-action:pan-y;user-select:none;-webkit-user-select:none;cursor:ew-resize;
  transition:border-color .3s ease
}
.cmp-frame:hover,.cmp-frame:focus-within{border-color:var(--line-2)}
.cmp-frame.reveal{opacity:1;transform:none}    /* the frame reveals its own way, below */
.cmp-layer{position:absolute;inset:0}
/* the layers are <picture> wrappers now, so the element the CSS positions is
   the <picture> and the <img> fills it */
.cmp-layer picture{position:absolute;inset:0;display:block}
.cmp-layer--top{clip-path:inset(0 calc(100% - var(--split) * 1%) 0 0)}
.cmp-img{position:absolute;inset:0;width:100%;height:100%;display:block;object-fit:cover;object-position:center;
  -webkit-user-drag:none;pointer-events:none}
/* both photographs render with identical geometry — never position one differently */

/* intentional placeholder surface, until the two files exist */
.cmp-ph{
  background:
    repeating-linear-gradient(0deg,rgba(255,255,255,.028) 0 1px,transparent 1px 28px),
    repeating-linear-gradient(90deg,rgba(255,255,255,.028) 0 1px,transparent 1px 28px),
    var(--surface)
}
.cmp-ph--unprotected{background-color:#0e0e10}
.cmp-dev{
  position:absolute;top:50%;transform:translateY(-50%);text-align:center;
  font-family:var(--display);font-weight:700;font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted-2)
}
.cmp-dev b{display:block;color:var(--muted);margin-bottom:6px}
.cmp-ph--unprotected .cmp-dev{left:0;width:calc(var(--split) * 1%)}
.cmp-ph--protected .cmp-dev{right:0;width:calc(100% - var(--split) * 1%)}

/* divider + handle ride the split */
.cmp-divider{
  position:absolute;top:0;bottom:0;left:calc(var(--split) * 1%);width:1px;margin-left:-.5px;z-index:3;
  background:rgba(255,255,255,.55);pointer-events:none;transition:background .25s ease
}
.cmp-handle{
  position:absolute;top:50%;left:50%;width:44px;height:44px;transform:translate(-50%,-50%);
  display:grid;place-items:center;border-radius:50%;
  background:rgba(17,17,19,.86);border:1px solid rgba(255,255,255,.55);color:var(--text);
  transition:border-color .25s ease,background .25s ease
}
.cmp-handle svg{width:18px;height:18px}
.cmp-frame:hover .cmp-divider,.cmp-frame:focus-within .cmp-divider{background:rgba(255,255,255,.85)}
.cmp-frame:hover .cmp-handle,.cmp-frame:focus-within .cmp-handle{border-color:#fff;background:rgba(17,17,19,.95)}
.cmp-frame.is-dragging{cursor:grabbing}

/* labels sit above both layers and are never clipped */
.cmp-label{
  position:absolute;bottom:24px;z-index:3;pointer-events:none;
  display:inline-flex;align-items:center;gap:7px;
  padding:8px 12px;border-radius:3px;
  font-family:var(--display);font-weight:700;font-size:11px;letter-spacing:.16em;text-transform:uppercase
}
.cmp-label--left{left:24px;background:rgba(10,10,11,.62);color:var(--text);backdrop-filter:blur(6px)}
.cmp-label--right{right:24px;background:var(--red);color:#fff}
/* Full-image views keep the handle inside the frame and only identify the
   photograph that is actually visible. The buttons stay outside the image. */
.cmp-frame.is-protected .cmp-label--left,
.cmp-frame.is-unprotected .cmp-label--right,
.cmp-frame.is-unprotected .cmp-edge{visibility:hidden}
.cmp-frame.is-protected .cmp-handle{transform:translate(0,-50%)}
.cmp-frame.is-unprotected .cmp-handle{transform:translate(-100%,-50%)}

/* the protected corner carries a short red rule. No tint, no overlay, nothing
   on the photograph itself. */
.cmp-edge{
  position:absolute;top:0;right:0;z-index:3;pointer-events:none;
  width:clamp(64px,14%,132px);height:2px;background:var(--red)
}

/* the accessible control: visually hidden but focusable; the divider is the focus ring's host */
.cmp-range{
  position:absolute;left:0;top:0;width:1px;height:1px;opacity:0;margin:0;pointer-events:none
}
.cmp-frame:focus-within{outline:2px solid var(--red);outline-offset:4px}

.cmp-disclaimer{max-width:1200px;margin:22px auto 0;color:var(--muted);font-size:13px;line-height:1.6}

/* ---- entrance: the photograph opens from the centre seam outward, then the
        divider draws and the labels resolve. .in comes from site.js's observer;
        .is-ready from ppf-compare.js once both photographs have decoded. ---- */
.cmp-stage{position:absolute;inset:0}
/* .cmp--js is added by ppf-compare.js before anything else it does, so the
   stage is only ever hidden when the script that reveals it is actually running. */
.reveal-ready .cmp-frame.cmp--js.reveal .cmp-stage{clip-path:inset(0 50% 0 50%);opacity:0;transition:clip-path 1.1s var(--ease-premium) .1s,opacity .4s ease .1s}
:where(.reveal-ready) .cmp-frame:where(.cmp--js).reveal .cmp-divider{opacity:0;transform:scaleY(0);transition:opacity .4s ease .7s,transform .7s var(--ease-premium) .7s}
:where(.reveal-ready) .cmp-frame:where(.cmp--js).reveal .cmp-label,:where(.reveal-ready) .cmp-frame:where(.cmp--js).reveal .cmp-edge{opacity:0;transition:opacity .5s ease 1s}
.reveal-ready .cmp-frame.cmp--js.reveal.in.is-ready .cmp-stage{clip-path:inset(0);opacity:1}
.reveal-ready .cmp-frame.cmp--js.reveal.in.is-ready .cmp-divider{opacity:1;transform:none}
.reveal-ready .cmp-frame.cmp--js.reveal.in.is-ready .cmp-label,
.reveal-ready .cmp-frame.cmp--js.reveal.in.is-ready .cmp-edge{opacity:1}

/* The divider follows the pointer with NO easing while dragging. These two
   classes are the only places the split is animated: the one-off entrance
   hint, and a click or tap that jumps the divider. Both are stripped the
   moment a real drag starts.
   They have to sit after the entrance rules above, which target the same
   elements at the same specificity and would otherwise win on source order
   and quietly swallow the easing. */
.cmp-frame.reveal.is-hinting .cmp-divider,.cmp-frame.is-hinting .cmp-divider{
  transition:left .3s var(--ease-premium),opacity .4s ease,transform .7s var(--ease-premium)}
.cmp-frame.reveal.is-hinting .cmp-layer--top,.cmp-frame.is-hinting .cmp-layer--top{
  transition:clip-path .3s var(--ease-premium)}
.cmp-frame.reveal.is-easing .cmp-divider,.cmp-frame.is-easing .cmp-divider{
  transition:left .26s var(--ease-premium),opacity .4s ease,transform .7s var(--ease-premium)}
.cmp-frame.reveal.is-easing .cmp-layer--top,.cmp-frame.is-easing .cmp-layer--top{
  transition:clip-path .26s var(--ease-premium)}
/* and nothing at all once the pointer is actually dragging */
.cmp-frame.is-dragging .cmp-divider,.cmp-frame.is-dragging .cmp-layer--top{transition:none}

/* ---- responsive ---- */
@media (max-width:1024px){
  .cmp-intro{grid-template-columns:1fr;gap:18px;margin-bottom:36px}
  .cmp-intro h2{font-size:clamp(2.4rem,7.5vw,4rem)}
  .cmp-frame{aspect-ratio:4/3}
}
@media (max-width:640px){
  .cmp-frame{aspect-ratio:1/1;border-radius:6px}
  /* the two labels have to share one narrow frame without meeting in the
     middle over the car, so they shed letter-spacing and padding first */
  .cmp-label{bottom:12px;font-size:9px;letter-spacing:.08em;padding:6px 8px;gap:5px}
  .cmp-label--left{left:12px}
  .cmp-label--right{right:12px}
  .cmp-edge{width:clamp(48px,18%,90px)}
  .cmp-dev{font-size:9px;letter-spacing:.14em}
}

@media (prefers-reduced-motion:reduce){
  .cmp-frame.reveal .cmp-stage,.cmp-frame.reveal .cmp-divider,.cmp-frame.reveal .cmp-label{opacity:1;transform:none;clip-path:none;transition:none}
  .cmp-divider,.cmp-handle,.cmp-controls button{transition:none}
  .cmp-frame.is-hinting .cmp-divider,.cmp-frame.is-hinting .cmp-layer--top,
  .cmp-frame.is-easing .cmp-divider,.cmp-frame.is-easing .cmp-layer--top{transition:none}
}

/* ============================================================================
   SERVICES OVERVIEW — /services/
   ----------------------------------------------------------------------------
   Everything is namespaced .svco-* so this page can be redesigned without
   touching a single shared selector. A directory, not a sales page: hero and
   introduction are one compact block, then three editorial rows whose
   photographs sit in a reserved 4:3 frame that the real files drop straight
   into. See SERVICE_PHOTOS in services.py.
   ========================================================================== */

/* ---- introduction: hero and "what we do" combined, deliberately short ---- */
.svco-intro{padding:92px 0 44px;border-bottom:1px solid var(--line)}
/* full-bleed photographic opening. The van sits in the right half of both
   crops, so the copy column is held to the left 54% and never covers it. */
.svco-intro.has-media{position:relative;overflow:hidden;min-height:min(86svh,780px);display:flex;align-items:center;padding:120px 0 76px}
.svco-intro.has-media .wrap{position:relative;z-index:2}
.svco-intro.has-media .svco-intro-grid{grid-template-columns:minmax(0,.54fr) minmax(0,.46fr)}
.svco-intro.has-media .svco-lead,.svco-intro.has-media .svco-where{color:var(--text)}
.svco-intro.has-media .svco-tel{color:var(--text);border-color:rgba(255,255,255,.4)}
.svco-crumbs{margin:0 0 24px;opacity:.42;font-size:11.5px}
.svco-crumbs a{color:var(--muted)}
.svco-intro .eyebrow{margin-bottom:16px}
.svco-h1{
  font-family:var(--display);font-weight:700;text-transform:uppercase;
  font-size:clamp(2.1rem,5.4vw,4rem);line-height:.98;letter-spacing:-.025em;
  margin:0 0 18px;max-width:16ch
}
/* the two halves of the statement each hold together; the line only breaks
   where it is meant to */
.svco-h1 span{display:inline-block}
.svco-lead{max-width:56ch;color:var(--muted);font-size:clamp(1rem,1.3vw,1.14rem);line-height:1.62;margin:0 0 16px}
.svco-where{
  display:flex;align-items:flex-start;gap:9px;max-width:56ch;margin:0 0 24px;
  color:var(--muted-2);font-size:14.4px;line-height:1.55
}
.svco-where svg{width:16px;height:16px;color:var(--red);flex:none;margin-top:2px}
.svco-actions{display:flex;align-items:center;gap:22px;flex-wrap:wrap}
.svco-tel{
  font-family:var(--display);font-weight:600;font-size:13.5px;letter-spacing:.06em;
  color:var(--muted);border-bottom:1px solid var(--line-2);padding-bottom:3px;transition:color .2s,border-color .2s
}
.svco-tel:hover,.svco-tel:focus-visible{color:var(--text);border-color:var(--red)}

/* the photograph sits beside the copy on desktop, so it costs no extra height
   and fills what was an empty right-hand column */
.svco-intro-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.62fr);gap:clamp(32px,4.5vw,72px);align-items:center}
.svco-intro-copy{min-width:0}
.svco-intro-photo{
  position:relative;aspect-ratio:3/4;max-height:min(58svh,520px);overflow:hidden;
  border-radius:var(--r-lg);border:1px solid var(--line);background:var(--surface)
}
.svco-intro-photo picture{display:block;width:100%;height:100%}
.svco-intro-photo img{width:100%;height:100%;object-fit:cover;object-position:52% 58%;display:block}
.svco-intro-photo.is-empty{
  background:repeating-linear-gradient(115deg,rgba(255,255,255,.018) 0 1px,transparent 1px 4px),
             linear-gradient(150deg,#161619 0%,#0E0E10 100%);
  display:grid;place-items:center
}

/* ---- introduction entrance ------------------------------------------------
   A pure CSS animation with fill-mode:both, not a class an observer has to
   arrive and add. Nothing above the fold can therefore be left invisible by a
   script that failed to load: with scripting off the .js gate never matches and
   the copy is simply there. Reduced motion turns it off entirely. ---------- */
@keyframes svcoIn{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.js .svco-crumbs,.js .svco-intro .eyebrow,.js .svco-h1,
.js .svco-lead,.js .svco-where,.js .svco-actions,.js .svco-intro-photo{
  animation:svcoIn .5s var(--ease-premium) both
}
.js .svco-intro-photo{animation-duration:.6s;animation-delay:.16s}
.js .svco-crumbs{animation-duration:.45s;animation-delay:0s}
.js .svco-intro .eyebrow{animation-duration:.45s;animation-delay:.05s}
.js .svco-h1{animation-delay:.12s}
.js .svco-lead{animation-duration:.45s;animation-delay:.22s}
.js .svco-where{animation-duration:.45s;animation-delay:.3s}
.js .svco-actions{animation-duration:.45s;animation-delay:.38s}

/* ---- the three services ------------------------------------------------- */
.svco-list-sec{padding-top:52px}
.svco-list{display:flex;flex-direction:column}
.svco-row{
  display:grid;grid-template-columns:minmax(0,45fr) minmax(0,55fr);
  /* top-aligned, not centred: centring made each text block float against its
     own photograph, so the three service names started at three different
     heights. Aligned to the top, the purpose label always meets the top edge
     of the frame and the three rows read as one system. */
  gap:clamp(32px,4vw,64px);align-items:start;padding:52px 0
}
.svco-row:first-child{padding-top:0}
.svco-row + .svco-row{border-top:1px solid var(--line)}

/* the media frame. Size is reserved whether or not a file exists, so dropping
   the photographs in later cannot shift the layout. */
.svco-media{
  position:relative;aspect-ratio:4/3;overflow:hidden;border-radius:var(--r);
  border:1px solid var(--line);background:var(--surface)
}
.svco-media picture{display:block;width:100%;height:100%}
.svco-media img{
  width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .6s var(--ease-premium)
}
/* empty state: a restrained dark surface with a fine technical texture.
   No gradients pretending to be a car, no illustration, no broken <img>. */
.svco-media.is-empty{
  background:
    repeating-linear-gradient(115deg,rgba(255,255,255,.018) 0 1px,transparent 1px 4px),
    linear-gradient(150deg,#161619 0%,#0E0E10 100%);
  display:grid;place-items:center
}
.svco-media-label{
  font-family:var(--display);font-weight:700;font-size:10px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--muted-2);text-align:center;padding:0 18px
}
/* hover scale belongs to real photography only, and never to an empty frame */
@media (hover:hover) and (pointer:fine){
  .svco-row:hover .svco-media:not(.is-empty) img{transform:scale(1.018)}
}

.svco-body{min-width:0}
.svco-index{
  display:flex;align-items:center;gap:12px;margin:0 0 14px;
  font-family:var(--display);font-weight:700;font-size:11px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--muted-2)
}
.svco-index span{color:var(--red)}
.svco-name{
  font-family:var(--display);font-weight:700;text-transform:uppercase;letter-spacing:-.01em;
  font-size:clamp(1.45rem,2.5vw,2.05rem);line-height:1.08;margin:0 0 16px
}
.svco-name a{color:var(--text);transition:color .2s}
.svco-name a:hover,.svco-name a:focus-visible{color:var(--red)}
.svco-desc{color:var(--muted);font-size:15.4px;line-height:1.62;margin:0 0 22px;max-width:52ch}
.svco-meta{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 34px;margin:0 0 24px;
  padding:16px 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line)
}
.svco-meta dt{
  font-family:var(--display);font-weight:700;font-size:10px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--muted-2);margin-right:-24px
}
.svco-meta dd{margin:0 0 0 0;font-size:14.6px;color:var(--text)}
.svco-price{font-family:var(--display);font-weight:700;font-size:1.3rem;color:var(--red);line-height:1}
.svco-cta{
  display:inline-flex;align-items:center;gap:10px;min-height:44px;
  font-family:var(--display);font-weight:700;font-size:12.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--text);
  border-bottom:1px solid var(--line-2);transition:color .2s,border-color .25s
}
.svco-cta:hover,.svco-cta:focus-visible{color:var(--red);border-color:var(--red)}
.svco-arrow{width:17px;height:17px;color:var(--red);transition:transform .3s var(--ease-premium)}
.svco-cta:hover .svco-arrow,.svco-cta:focus-visible .svco-arrow{transform:translateX(4px)}
.svco-note{margin:44px 0 0;color:var(--muted-2);font-size:13.4px;line-height:1.6;max-width:70ch}

/* ---- compact availability ----------------------------------------------- */
.svco-areas-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.5fr);gap:clamp(28px,4vw,64px);align-items:start}
.svco-areas-grid h2{font-size:clamp(1.5rem,2.4vw,2rem);line-height:1.12;margin:0}
.svco-areas-body p{color:var(--muted);margin:0 0 16px;line-height:1.65;max-width:58ch}
.svco-areas-lead{
  font-family:var(--display);font-weight:700;font-size:10.5px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--muted-2);margin:0 0 12px !important
}

/* ---- responsive --------------------------------------------------------- */
@media (max-width:1024px){
  .svco-areas-grid{grid-template-columns:1fr;gap:26px}
  .svco-intro.has-media .svco-intro-grid{grid-template-columns:minmax(0,.62fr) minmax(0,.38fr)}
}
@media (max-width:760px){
  /* stacked: a short band under the actions rather than a tall portrait, so
     the first service is still only a short scroll away */
  /* phones: the copy sits over the photograph, not beside it */
  .svco-intro.has-media{min-height:min(84svh,660px);padding:96px 0 44px;align-items:flex-end}
  .svco-intro-grid,.svco-intro.has-media .svco-intro-grid{grid-template-columns:1fr;gap:20px}
}
@media (max-width:860px){
  /* the split survives to 860px: below that the text column gets cramped
     before the photograph does, so stacking is the better trade */
  .svco-row{grid-template-columns:1fr;gap:26px;padding:44px 0;align-items:start}
}
@media (max-width:760px){
  .svco-intro{padding:66px 0 34px}
  .svco-crumbs{margin-bottom:16px}
  .svco-h1{font-size:clamp(1.95rem,8.6vw,2.7rem);max-width:none}
  .svco-lead{font-size:1rem}
  .svco-where{margin-bottom:20px}
  .svco-actions{gap:18px}
  .svco-actions .btn{width:100%;justify-content:center}
  .svco-list-sec{padding-top:38px}
  .svco-row{padding:36px 0;gap:22px}
  .svco-desc{font-size:15px;max-width:none}
  .svco-meta{gap:4px 28px;margin-bottom:20px}
  .svco-note{margin-top:34px}
}
@media (max-width:420px){
  /* the introduction photograph costs about 140px here, so the surrounding
     padding gives some of it back and the first service stays one swipe away */
  .svco-intro{padding-top:54px;padding-bottom:26px}
  .svco-intro-grid{gap:16px}
  .svco-list-sec{padding-top:26px}
  .svco-meta{flex-direction:column;align-items:flex-start;gap:12px}
  .svco-meta dt{margin-right:0}
}
@media (prefers-reduced-motion:reduce){
  .svco-media img,.svco-arrow{transition:none}
  .svco-row:hover .svco-media:not(.is-empty) img{transform:none}
  .js .svco-crumbs,.js .svco-intro .eyebrow,.js .svco-h1,
  .js .svco-lead,.js .svco-where,.js .svco-actions,.js .svco-intro-photo{animation:none}
}

/* article header photograph: below the title block, inside the reading column's
   own measure, so it illustrates rather than delays the article */
.post-hero{margin-top:28px}
.post-hero-pic{display:block;border-radius:var(--r-lg);overflow:hidden;border:1px solid var(--line);background:var(--surface)}
/* a band, not a billboard: at the full wrap width a 16:9 frame ran to 649px and
   pushed the first paragraph past 1200px down the page */
.post-hero-pic img{display:block;width:100%;height:auto;aspect-ratio:21/9;max-height:380px;object-fit:cover}
@media (max-width:760px){
  .post-hero{margin-top:20px}
  .post-hero-pic img{aspect-ratio:16/9;max-height:none}
}
@media (prefers-reduced-motion:reduce){
  .lib-card-pic img,.post-card .thumb img{transition:none}
  .lib-card:hover .lib-card-pic img,.post-card:hover .thumb img{transform:none}
}

/* ============================================================================
   ENQUIRY FORM — optional extras and the pre-submit summary
   ----------------------------------------------------------------------------
   Extras are real checkboxes so more than one can be chosen and each submits
   its own readable value. The summary is built from the visible fields, so the
   customer reads exactly what the email will contain.
   ========================================================================== */
.opts{border:1px solid var(--line);border-radius:var(--r);padding:18px 18px 16px;margin:0 0 18px;background:var(--surface)}
.opts legend{
  padding:0 8px;margin-left:-8px;font-family:var(--display);font-weight:700;font-size:10.5px;
  letter-spacing:.18em;text-transform:uppercase;color:var(--muted)
}
.opts-note{margin:0 0 14px;color:var(--muted-2);font-size:12.8px;line-height:1.55}
.opts-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px 18px}
.opt{display:flex;align-items:flex-start;gap:11px;cursor:pointer;padding:7px 0;min-height:44px}
.opt input{position:absolute;opacity:0;width:1px;height:1px}
.opt-box{
  flex:none;width:19px;height:19px;margin-top:2px;border:1px solid var(--line-2);border-radius:4px;
  background:var(--black);position:relative;transition:border-color .2s,background .2s
}
.opt-box::after{
  content:"";position:absolute;left:5px;top:1px;width:6px;height:11px;
  border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg) scale(.6);
  opacity:0;transition:opacity .15s ease,transform .15s ease
}
.opt input:checked + .opt-box{background:var(--red);border-color:var(--red)}
.opt input:checked + .opt-box::after{opacity:1;transform:rotate(45deg) scale(1)}
.opt input:focus-visible + .opt-box{outline:2px solid var(--red);outline-offset:3px}
.opt:hover .opt-box{border-color:var(--line-2)}
.opt-text{display:flex;flex-direction:column;gap:2px;min-width:0}
.opt-text b{font-weight:600;font-size:14.4px;color:var(--text);line-height:1.3}
.opt-text small{color:var(--muted-2);font-size:12.4px}

.form-summary{
  border:1px solid var(--line-2);border-left:2px solid var(--red);border-radius:var(--r);
  background:var(--elev);padding:16px 18px;margin-bottom:18px
}
.form-summary-title{
  margin:0 0 10px;font-family:var(--display);font-weight:700;font-size:10.5px;
  letter-spacing:.18em;text-transform:uppercase;color:var(--red)
}
.form-summary dl{display:grid;grid-template-columns:auto 1fr;gap:6px 18px;margin:0}
.form-summary dt{
  font-family:var(--display);font-weight:700;font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted-2);padding-top:3px
}
.form-summary dd{margin:0;font-size:14.4px;color:var(--text);line-height:1.5}
@media (max-width:560px){
  .opts-grid{grid-template-columns:1fr;gap:4px}
  .form-summary dl{grid-template-columns:1fr;gap:2px 0}
  .form-summary dd{margin-bottom:8px}
}
@media (prefers-reduced-motion:reduce){
  .opt-box,.opt-box::after{transition:none}
}

/* ============================================================================
   FULL-BLEED HERO MEDIA — shared by the ceramic, valeting and services heroes
   ----------------------------------------------------------------------------
   One treatment, three pages. The photograph fills the hero; a directional
   scrim runs dark where the type sits and opens across the subject, so the car
   stays desirable and the copy stays readable. Tuned against the actual
   photography rather than a flat wash.
   ========================================================================== */
.hero-full-media{position:absolute;inset:0;z-index:0;overflow:hidden;background:var(--black)}
.hero-full-media picture{display:block;width:100%;height:100%}
.hero-full-media img{width:100%;height:100%;object-fit:cover;display:block}
/* valeting: the crops put the Ferrari in the right 60% and object-position
   only handles the secondary crop the viewport forces. A LOW X keeps the car
   right; a high X would slide the window right and drag the car leftwards. */
.page-hero .hero-full-media img{object-position:22% 62%}
@media (max-width:1100px){
  .page-hero .hero-full-media img{object-position:90% 58%}
}
@media (max-width:767px){
  .page-hero .hero-full-media img{object-position:50% 62%}
}
/* ceramic hero: the crops are art directed so the Focus RS sits right of
   centre with the copy column clear of it, and object-position is tuned per
   crop rather than left at the 50% default. The wide crop is 16:9 and the
   desktop box is close to it, so these values only bite at the extremes:
   X when the viewport is narrower than the crop, Y when it is wider. */
.cc-hero .hero-full-media img{object-position:64% 70%}
@media (max-width:1100px){
  .cc-hero .hero-full-media img{object-position:61% 68%}
}
@media (max-width:767px){
  .cc-hero .hero-full-media img{object-position:50% 50%}
}
.hero-full-scrim{
  position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(90deg,
      rgba(10,10,11,.95) 0%,
      rgba(10,10,11,.88) 26%,
      rgba(10,10,11,.60) 52%,
      rgba(10,10,11,.22) 76%,
      rgba(10,10,11,.06) 100%),
    linear-gradient(0deg,
      rgba(10,10,11,.80) 0%,
      rgba(10,10,11,.30) 18%,
      transparent 42%);
}
/* phones: the type sits over the photograph rather than beside it, so the
   darkening is stronger and runs top-down instead of left-to-right */
@media (max-width:767px){
  .hero-full-scrim{
    background:
      linear-gradient(180deg,
        rgba(10,10,11,.94) 0%,
        rgba(10,10,11,.86) 30%,
        rgba(10,10,11,.62) 52%,
        rgba(10,10,11,.42) 72%,
        rgba(10,10,11,.72) 100%),
      linear-gradient(90deg,rgba(10,10,11,.55) 0%,rgba(10,10,11,.10) 70%,transparent 100%);
  }
}

/* ---- 404 ----------------------------------------------------------------
   One page served from any depth, so nothing here may depend on position. */
.nf-head{font-size:clamp(1.4rem,3vw,2rem);text-transform:uppercase;margin:0 0 26px}
.nf-links{list-style:none;margin:0;padding:0;display:grid;gap:12px;
  grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
.nf-links a{display:flex;flex-direction:column;gap:4px;min-height:44px;
  padding:16px 18px;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r-lg);text-decoration:none;transition:border-color .25s ease}
.nf-links a:hover{border-color:var(--red)}
.nf-links b{font-family:var(--display);font-size:15px;color:var(--text)}
.nf-links small{color:var(--muted);font-size:13px}
.nf-call{margin:28px 0 0;color:var(--muted)}
.nf-call a{color:var(--text);text-decoration:underline;text-underline-offset:3px}

/* ---- third-party embed facades -----------------------------------------
   Nothing is requested from Google or Vimeo until the visitor presses the
   button. See assets/embeds.js. The placeholder occupies exactly the space
   the real embed will, so loading it shifts nothing. */
.embed{position:relative;width:100%;aspect-ratio:var(--embed-ratio,16/9);
  border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;background:var(--surface)}
.embed-shell{position:absolute;inset:0;display:block}
.embed-shell iframe{width:100%;height:100%;border:0;display:block}
.embed-ask{position:absolute;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:10px;text-align:center;padding:24px;
  background:linear-gradient(160deg,#151518,#0A0A0B)}
.embed-label{font-family:var(--display);font-weight:700;font-size:13px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--text);margin:0}
.embed-note{color:var(--muted);font-size:13.5px;line-height:1.5;margin:0;max-width:44ch}
.embed-ask .btn{margin-top:4px}
.embed-fallback{margin:2px 0 0;font-size:12.5px}
.embed-fallback a{color:var(--muted);text-decoration:underline;text-underline-offset:3px}
.embed-fallback a:hover{color:var(--text)}
/* A facade placed inside a wrapper that already defines the frame must take
   that frame exactly, so loading the real embed changes nothing on the page.
   The ceramic clips are portrait (Vimeo reports 240x426), so .cc-video is
   9:16; the PPF clips are landscape in .bf-video.landscape; the map was a
   450px band. Imposing the facade's own aspect ratio here put the portrait
   videos in a 16:9 strip and stretched the map to over 1,000px. */
.map-full > .embed{aspect-ratio:auto;height:450px;border:0;border-radius:0}
/* ---- video previews (build.py video_embed, assets/embeds.js) --------------
   A local poster frame fills the existing .cc-video / .bf-video frame, which
   already sets the aspect ratio, border and radius, so the preview occupies
   exactly the space the player will. One press loads that video's player and
   asks it to start. Nothing covers the photograph except a play button and a
   small title chip. */
.vid{position:absolute;inset:0;overflow:hidden;background:var(--elev)}
.vid-poster{position:absolute;inset:0;display:block}
.vid-poster picture,.vid-poster img{display:block;width:100%;height:100%}
.vid-poster img{object-fit:cover}
.vid-ic{
  position:absolute;left:50%;top:50%;z-index:1;width:64px;height:64px;margin:-32px 0 0 -32px;
  display:grid;place-items:center;border-radius:50%;pointer-events:none;color:#fff;
  background:rgba(10,10,11,.6);border:1px solid rgba(255,255,255,.6);
  -webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);
  box-shadow:0 10px 30px rgba(0,0,0,.35);
  transition:background .2s ease,border-color .2s ease,transform .25s var(--ease-premium)
}
.vid-ic svg{width:24px;height:24px;margin-left:3px}
/* the button is the whole frame, so a tap anywhere on the photograph plays it */
.vid-play{
  position:absolute;inset:0;z-index:2;width:100%;height:100%;margin:0;padding:0;
  border:0;border-radius:0;background:transparent;cursor:pointer;
  -webkit-tap-highlight-color:transparent
}
.vid-play:focus-visible{outline:3px solid var(--red);outline-offset:-3px}
.vid--js:hover .vid-ic,.vid--js:has(.vid-play:focus-visible) .vid-ic{
  background:var(--red);border-color:var(--red);transform:scale(1.06)
}
.vid-chip{
  position:absolute;left:12px;bottom:12px;z-index:1;margin:0;max-width:calc(100% - 24px);
  display:inline-flex;align-items:center;gap:8px;padding:6px 10px;border-radius:999px;
  background:rgba(10,10,11,.72);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  pointer-events:none;color:#fff;font-size:11px;line-height:1.2
}
.vid-chip b{font-family:var(--display);font-weight:600;letter-spacing:.08em;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vid-chip span{color:rgba(242,242,244,.78);font-variant-numeric:tabular-nums}
/* the status line is a live region from the start, so it is always rendered;
   it is only visually shown while loading or after a failure */
.vid-status{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0
}
.vid.is-loading .vid-chip,.vid.is-failed .vid-chip{opacity:0}
.vid.is-loading .vid-status,.vid.is-failed .vid-status{
  position:absolute;left:12px;right:12px;bottom:12px;z-index:3;width:auto;height:auto;margin:0;
  overflow:visible;clip:auto;white-space:normal;
  padding:8px 12px;border-radius:12px;background:rgba(10,10,11,.82);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  color:var(--text);font-size:12.5px;line-height:1.5;text-align:center
}
.vid-status a{color:#fff;text-decoration:underline;text-underline-offset:3px}
.vid-retry{
  margin-left:4px;padding:2px 10px;min-height:28px;border-radius:999px;cursor:pointer;
  border:1px solid rgba(255,255,255,.45);background:transparent;color:#fff;font:inherit
}
.vid-retry:hover{border-color:#fff}
.vid.is-loading .vid-ic svg{display:none}
.vid.is-loading .vid-ic::after{
  content:"";width:22px;height:22px;border-radius:50%;
  border:2px solid rgba(255,255,255,.3);border-top-color:#fff;animation:vidSpin .8s linear infinite
}
@keyframes vidSpin{to{transform:rotate(360deg)}}
.vid.is-failed .vid-ic{opacity:.35}
/* the player sits over the poster and fades in once it has loaded, so there is
   never a flash of empty black between the two */
.vid-frame{position:absolute;inset:0;z-index:4;width:100%;height:100%;border:0;background:#000;opacity:0;transition:opacity .3s ease}
.vid.is-playing .vid-frame{opacity:1}
.vid.is-playing .vid-ic,.vid.is-playing .vid-chip,.vid.is-playing .vid-play{display:none}
.vid-note{display:block;margin-top:6px;font-size:12px;line-height:1.5;color:var(--muted-2)}
.vid-note a{color:var(--muted);text-decoration:underline;text-underline-offset:3px}
.vid-note a:hover{color:var(--text)}
@media (max-width:560px){
  .vid-ic{width:56px;height:56px;margin:-28px 0 0 -28px}
  .vid-ic svg{width:21px;height:21px}
  .vid-chip{left:10px;bottom:10px}
}
@media (prefers-reduced-motion:reduce){
  .vid-ic,.vid-frame{transition:none}
  .vid.is-loading .vid-ic::after{animation:none;border-top-color:rgba(255,255,255,.3)}
}

/* with scripting the direct link is redundant; the button does the job */
.js .embed-fallback{display:none}
@media (max-width:560px){
  .embed-ask{padding:18px;gap:8px}
  .embed-note{font-size:12.5px}
}
