/* ============================================================
   PIT STOP PROS PERFORMANCE — West Kelowna, BC
   ------------------------------------------------------------
   The palette is sampled from the hero footage, not from the old
   flat brand sheet: cool near-black brick, hot neon orange, and a
   cold white light-tube accent. Three light sources, one hue each.
   Everything else is greyscale so the orange always reads as light
   rather than as paint.
   ============================================================ */

:root {
  /* surfaces — cool, not neutral. The video's shadows are blue-grey. */
  --ink:       #08090b;
  --surface:   #0e1013;
  --surface-2: #14171b;
  --surface-3: #1b1f24;
  --line:      #22272d;
  --line-hot:  #33393f;

  /* light */
  --orange:      #ff8a1f;
  --orange-deep: #f2660d;
  --orange-dim:  rgba(255, 138, 31, 0.14);
  --tube:        #dce8ff;   /* the cold white light tubes */

  /* type */
  --text:  #f4f6f8;
  --muted: #98a0a9;
  --faint: #5d656d;

  --display: "Bahnschrift Condensed", "Bahnschrift", "Archivo Narrow", "Arial Narrow",
             "Helvetica Neue Condensed", Impact, sans-serif;
  --body: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;

  --slash: -18deg;
  --gut: clamp(20px, 5vw, 88px);
  --maxw: 1400px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--text);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.62;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: inherit; }
::selection { background: var(--orange); color: #000; }
:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 300;
  background: var(--orange); color: #000; padding: 12px 20px; font-weight: 700;
  text-decoration: none;
}
.skip-link:focus { left: 12px; top: 12px; }

/* The visible masthead is gone, but the page still needs a top-level heading. */
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ============================================================
   ACTION BAR — nav + phone. Slides in only after the hero, so the
   masthead stays "banner only" the way it was asked for, without
   costing the shop its call button.
   ============================================================ */

.actionbar {
  position: fixed; z-index: 90; left: 0; right: 0; top: 0;
  display: flex; align-items: center; gap: 24px;
  padding: 12px var(--gut);
  background: rgba(10, 12, 15, .86);
  backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--line);
  transform: translateY(-101%);
  transition: transform .5s var(--ease);
}
.actionbar.is-in { transform: none; }
.actionbar__mark {
  font-family: var(--display); text-transform: uppercase; letter-spacing: .18em;
  font-size: .92rem; text-decoration: none; margin-right: auto; white-space: nowrap;
}
.actionbar__mark em { font-style: normal; color: var(--orange); }
.actionbar__links { display: flex; gap: 28px; }
.actionbar__links a {
  position: relative; text-decoration: none;
  font-family: var(--display); text-transform: uppercase;
  letter-spacing: .13em; font-size: .86rem; color: var(--muted);
  padding: 4px 0; transition: color .3s var(--ease);
}
.actionbar__links a::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 2px; width: 100%;
  background: var(--orange); box-shadow: 0 0 10px var(--orange);
  transform: scaleX(0); transform-origin: left;
  transition: transform .35s var(--ease);
}
.actionbar__links a:hover, .actionbar__links a.is-current { color: var(--text); }
.actionbar__links a:hover::after, .actionbar__links a.is-current::after { transform: scaleX(1); }

/* ---------- buttons ---------- */

.btn {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  padding: 15px 30px;
  font-family: var(--display); font-weight: 700; font-size: 1rem;
  letter-spacing: .1em; text-transform: uppercase; text-decoration: none;
  white-space: nowrap;
  border: 1px solid transparent;
  transition: color .3s var(--ease), background .3s var(--ease),
              border-color .3s var(--ease), box-shadow .4s var(--ease), transform .3s var(--ease);
}
.btn--call {
  background: var(--orange); color: #120a02;
  box-shadow: 0 0 0 rgba(255,138,31,0), 0 10px 30px -12px rgba(255,138,31,.9);
}
.btn--call:hover {
  background: #ffa040; transform: translateY(-2px);
  box-shadow: 0 0 26px rgba(255,138,31,.5), 0 14px 34px -12px rgba(255,138,31,1);
}
.btn--ghost { border-color: var(--line-hot); color: var(--text); }
.btn--ghost:hover {
  border-color: var(--orange); color: var(--orange);
  box-shadow: inset 0 0 22px rgba(255,138,31,.12), 0 0 18px rgba(255,138,31,.22);
}
.btn--sm { padding: 10px 20px; font-size: .86rem; }

/* ---------- shared type ---------- */

.chip {
  display: inline-block; width: 9px; height: 18px; margin-right: 12px;
  background: var(--orange); transform: skewX(var(--slash)); vertical-align: -2px;
  box-shadow: 0 0 12px rgba(255,138,31,.7);
}
.eyebrow {
  font-family: var(--display); text-transform: uppercase; letter-spacing: .24em;
  font-size: .78rem; color: var(--orange); margin: 0 0 18px;
}
.h-display {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(2.3rem, 6vw, 5.2rem);
  line-height: .95; letter-spacing: -.005em; text-transform: uppercase; margin: 0 0 22px;
}
.h-display em { color: var(--orange); font-style: normal; }
.lede { color: var(--muted); max-width: 60ch; margin: 0; font-size: 1.05rem; }

/* ============================================================
   HERO
   Default = static stacked (no JS, touch, reduced motion, rig
   failure). `.scrub` on <html> upgrades it to the scrubbed rig.
   ============================================================ */

.hero { position: relative; }
.hero__stage { position: relative; background: var(--ink); }

.hero__poster {
  position: relative; width: 100%;
  height: clamp(340px, 64vh, 620px); object-fit: cover; object-position: center top;
}
.hero__canvas, .hero__loader, .hero__hint { display: none; }

/* Only a soft foot, to hand off into the CTA band. Nothing is written over
   the footage any more, so the scrim no longer has to buy text contrast. */
.hero__scrim {
  position: absolute; inset: 0 0 auto 0; height: clamp(340px, 64vh, 620px);
  background: linear-gradient(to top, rgba(6,7,9,.92) 0%, rgba(6,7,9,.25) 22%, transparent 45%);
}

/* --- scrub upgrade --- */

/* Length comes from chapters.json via --hero-vh (set before ScrollTrigger
   measures). The fallback matters only if the config fails to load. */
.scrub .hero { height: var(--hero-vh, 640vh); }
.scrub .hero__stage {
  position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden;
}
.scrub .hero__poster, .scrub .hero__canvas {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}
.scrub .hero__canvas { display: block; opacity: 0; transition: opacity .6s var(--ease); }
.scrub .hero__canvas.is-live { opacity: 1; }
.scrub .hero__poster { object-position: center top; }   /* matches the canvas crop rule */
.scrub .hero__loader { display: flex; }
.scrub .hero__hint { display: flex; }

/* Bare minimum: a foot to hand off into the CTA, and the faintest corner
   vignette. The garbled floor lettering is removed by the 12% source crop in
   paint(), not by darkening, so the picture stays open. */
.scrub .hero__scrim {
  inset: 0; height: auto;
  background:
    linear-gradient(to top, rgba(5,6,8,.85) 0%, rgba(5,6,8,.22) 14%, transparent 34%),
    radial-gradient(140% 90% at 50% 46%, transparent 62%, rgba(0,0,0,.42) 100%);
}

/* scroll affordance — the word, then a falling light beneath it */
.hero__hint {
  position: absolute; left: 50%; bottom: 34px; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  transition: opacity .5s var(--ease);
}
.hero__hint b {
  font-family: var(--display); font-weight: 700; text-transform: uppercase;
  font-size: .84rem; letter-spacing: .40em; text-indent: .40em;
  color: rgba(255,255,255,.88);
  text-shadow: 0 2px 16px rgba(0,0,0,.95), 0 0 26px rgba(0,0,0,.7);
}
.hero__hint span {
  position: relative; display: block; width: 1px; height: 50px; overflow: hidden;
  background: linear-gradient(180deg, rgba(255,138,31,.20), rgba(255,138,31,.04));
}
.hero__hint span::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent, var(--orange));
  box-shadow: 0 0 10px rgba(255,138,31,.85);
  animation: fall 2.6s cubic-bezier(.6,0,.4,1) infinite;
}
@keyframes fall {
  0%   { transform: translateY(-100%); opacity: 0; }
  35%  { opacity: 1; }
  100% { transform: translateY(100%); opacity: 0; }
}
.hero__hint.is-gone { opacity: 0; }
/* Invisible, but still animating a glow on every frame until you leave. */
.hero__hint.is-gone span::after { animation: none; }

/* The bar alone read as a decorative hairline, not as "this is loading" —
   on a phone, where the wait is longest, people were left guessing. A turning
   ring says it is working, the percentage says how much longer.
   It takes the scroll cue's place at the foot of the frame, and hands it back
   when the film is ready. Nothing useful happens if you scroll before then, and
   the middle of the frame — where a loader would normally sit — is the shop's
   logo on the door, which small type is unreadable over. */
.hero__loader {
  position: absolute; left: 50%; bottom: 30px; transform: translateX(-50%);
  width: min(230px, 62vw); transition: opacity .6s var(--ease);
  flex-direction: column; align-items: center; gap: 13px;
}
.hero__loader.is-done { opacity: 0; pointer-events: none; }
.hero__spinner {
  display: block; width: 26px; height: 26px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.16);
  border-top-color: var(--orange);
  box-shadow: 0 0 14px rgba(255,138,31,.35);
  animation: psp-spin .85s linear infinite;
}
@keyframes psp-spin { to { transform: rotate(360deg); } }
.hero__loaderbar { display: block; width: 100%; height: 2px; background: rgba(255,255,255,.14); overflow: hidden; }
.hero__loaderbar i {
  display: block; height: 100%; width: 0; background: var(--orange);
  box-shadow: 0 0 12px var(--orange); transition: width .2s linear;
}
.hero__loadertxt {
  font-family: var(--display); text-transform: uppercase;
  font-size: .62rem; letter-spacing: .2em; color: rgba(255,255,255,.66);
  text-align: center; text-shadow: 0 2px 14px rgba(0,0,0,.95), 0 0 22px rgba(0,0,0,.8);
}
.hero__loadertxt b { color: #fff; font-weight: 700; }
.hero__loader.is-done .hero__spinner { animation: none; }
/* One at a time, in the same spot: no "Scroll" until there is film to scroll. */
.hero__loader:not(.is-done) ~ .hero__hint { opacity: 0; }

/* ============================================================
   HERO CTA
   Default (static, no JS, touch): its own band under the poster, sitting on
   the final still of the sequence.
   Scrub: the same markup lifts off the page and becomes an overlay that rises
   over the last stretch of the scroll, on the real footage, while the hero is
   still pinned — so the page never "spits you out" into a separate screen.
   ============================================================ */

.hero__cta {
  position: relative; overflow: hidden; isolation: isolate;
  padding: clamp(74px, 12vh, 132px) var(--gut) clamp(62px, 10vh, 112px);
}
.hero__cta::before {
  content: ""; position: absolute; inset: 0; z-index: -2;
  background: url("../assets/cta-still.webp") center 40% / cover no-repeat;
}
.hero__cta::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(90deg, rgba(6,7,9,.95) 0%, rgba(6,7,9,.86) 34%, rgba(6,7,9,.42) 66%, rgba(6,7,9,.62) 100%),
    linear-gradient(180deg, rgba(6,7,9,.92) 0%, rgba(6,7,9,.15) 26%, rgba(8,9,11,.75) 82%, var(--ink) 100%);
}
.hero__ctatitle {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(2.7rem, 8vw, 6.4rem);
  line-height: .92; letter-spacing: -.01em; text-transform: uppercase;
  margin: 0 0 20px; max-width: 16ch;
}
.hero__ctatitle em {
  font-style: normal; color: var(--orange);
  text-shadow: 0 0 40px rgba(255,138,31,.5);
}
.hero__ctacopy { color: #d3d8dd; max-width: 46ch; margin: 0 0 30px; font-size: 1.06rem; }
.hero__ctaactions { display: flex; flex-wrap: wrap; gap: 12px; }

/* --- scrub: overlay inside the pinned stage --- */

.scrub .hero__cta {
  position: absolute; overflow: visible;
  left: var(--gut); right: var(--gut); bottom: clamp(60px, 10vh, 116px);
  max-width: 900px; padding: 0;
  opacity: 0; transform: translateY(28px);
  pointer-events: none; will-change: opacity, transform;
  transition: opacity .8s var(--ease), transform .8s var(--ease);
}
.scrub .hero__cta::before, .scrub .hero__cta::after { display: none; }
.scrub .hero__stage.cta-in .hero__cta { opacity: 1; transform: none; pointer-events: auto; }

/* The contrast wash arrives with the CTA and only then — the footage stays
   clean for the whole reveal before it. */
.hero__ctascrim { display: none; }
.scrub .hero__ctascrim {
  display: block; position: absolute; inset: 0; opacity: 0;
  transition: opacity .8s var(--ease);
  /* Weighted hard to the left, where the copy sits, and released early so the
     car and the lit half of the shop stay bright. The whole point of the hold
     is to show this frame — dimming it globally would undo that. */
  background:
    linear-gradient(100deg, rgba(6,7,9,.90) 0%, rgba(6,7,9,.66) 26%, rgba(6,7,9,.14) 54%, transparent 72%),
    linear-gradient(180deg, transparent 62%, rgba(6,7,9,.42) 100%);
}
.scrub .hero__stage.cta-in .hero__ctascrim { opacity: 1; }
.scrub .hero__stage.cta-in .hero__hint { opacity: 0; }

/* ============================================================
   NEON EDGE — the hover system.
   A hairline that lights up around the whole element, a soft inner
   bloom, and a single sweep of light across the surface. One idea,
   applied consistently, so hover reads as "the tube switched on"
   rather than as five different effects.
   ============================================================ */

.edge {
  position: relative; isolation: isolate;
  overflow: hidden;              /* contains the sweep; box-shadow is unaffected */
  background: var(--surface);
  border: 1px solid var(--line);
  transition: border-color .45s var(--ease), background .45s var(--ease),
              transform .45s var(--ease), box-shadow .5s var(--ease);
}
.edge::before {   /* bloom */
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: radial-gradient(120% 90% at 50% 110%, rgba(255,138,31,.20), transparent 62%);
  opacity: 0; transition: opacity .5s var(--ease);
}
.edge::after {    /* sweep */
  content: ""; position: absolute; top: 0; bottom: 0; left: -60%; width: 45%;
  background: linear-gradient(100deg, transparent, rgba(255,180,90,.13), transparent);
  transform: skewX(var(--slash));
  transition: left .85s var(--ease);
  pointer-events: none;
}
.edge:hover, .edge:focus-within {
  background: var(--surface-2);
  border-color: rgba(255,138,31,.55);
  transform: translateY(-3px);
  box-shadow:
    0 0 0 1px rgba(255,138,31,.18),
    0 0 26px -4px rgba(255,138,31,.32),
    0 22px 40px -26px rgba(0,0,0,.9);
}
.edge:hover::before, .edge:focus-within::before { opacity: 1; }
.edge:hover::after, .edge:focus-within::after { left: 120%; }

/* ---------- sections ---------- */

.section {
  max-width: var(--maxw); margin: 0 auto;
  padding: clamp(76px, 11vh, 150px) var(--gut);
  position: relative; z-index: 2; background: var(--ink);
}
.section__head { margin-bottom: clamp(38px, 6vh, 68px); }

/* ---------- trust strip ---------- */

.trust { position: relative; z-index: 3; background: var(--surface); border-block: 1px solid var(--line); }
.trust__list {
  max-width: var(--maxw); margin: 0 auto; padding: 0 var(--gut);
  list-style: none; display: grid; grid-template-columns: repeat(4, 1fr);
}
.trust__item { padding: 32px 24px 32px 0; position: relative; }
.trust__item + .trust__item { padding-left: 24px; }
.trust__item + .trust__item::before {
  content: ""; position: absolute; left: 0; top: 20px; bottom: 20px; width: 2px;
  background: linear-gradient(180deg, transparent, var(--line-hot), transparent);
  transform: skewX(var(--slash));
}
.trust__item b {
  display: block; font-family: var(--display); text-transform: uppercase;
  letter-spacing: .05em; font-size: 1.2rem; margin-bottom: 5px;
}
.trust__item span { color: var(--muted); font-size: .9rem; }

/* ---------- performance grid ---------- */

/* Explicitly three across. auto-fit gave four columns at this max-width, which
   left the 6-card set as an orphaned 4+2. Three divides the content cleanly:
   6 perf cards = 2 full rows, and the service groups of 3/6/3 all land square. */
.perf__grid { display: grid; gap: 14px; grid-template-columns: repeat(3, 1fr); }
.perf__card { padding: 38px 30px 42px; }
.perf__num {
  font-family: var(--display); font-size: .82rem; letter-spacing: .22em; color: var(--orange);
}
.perf__card h3 {
  font-family: var(--display); text-transform: uppercase;
  font-size: 1.68rem; line-height: 1.02; margin: 12px 0 12px;
}
.perf__card p { color: var(--muted); margin: 0; font-size: .95rem; }

/* ---------- services ---------- */

.svc__group { margin-bottom: 44px; }
.svc__grouptitle {
  display: flex; align-items: center; gap: 16px;
  font-family: var(--display); text-transform: uppercase; letter-spacing: .22em;
  font-size: .84rem; color: var(--orange); margin: 0 0 18px;
}
.svc__grouptitle::after {
  content: ""; flex: 1; height: 1px;
  background: linear-gradient(90deg, var(--line-hot), transparent);
}
.svc__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; grid-template-columns: repeat(3, 1fr); }
.svc { padding: 22px 24px 26px; }
.svc h4 { font-family: var(--display); text-transform: uppercase; font-size: 1.16rem; margin: 0 0 6px; }
.svc p { color: var(--muted); margin: 0; font-size: .91rem; }

/* ---------- band / marquee ---------- */

.trust + .band { border-top: 0; }

.band {
  position: relative; z-index: 2; overflow: hidden;
  background: var(--surface); border-block: 1px solid var(--line);
  padding: clamp(44px, 7vh, 84px) 0;
}
.band__intro {
  text-align: center; margin: 0 0 26px;
  font-family: var(--display); text-transform: uppercase; letter-spacing: .24em;
  font-size: .82rem; color: var(--faint);
}
.marquee { overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent); mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent); }
.marquee__track { display: flex; align-items: center; gap: 24px; white-space: nowrap; width: max-content; will-change: transform; }
/* Neon tubing: the stroke is the glass, the drop-shadow is the light it throws.
   drop-shadow traces the stroke's alpha, so the glow hugs the letterform instead
   of blooming a solid slab the way text-shadow would on hollow type.
   Alternating white and orange — no dead grey. */
.marquee__track span {
  font-family: var(--display); text-transform: uppercase;
  font-size: clamp(2rem, 5vw, 4.2rem); line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1.4px var(--tube);
  filter: drop-shadow(0 0 5px rgba(220,232,255,.55)) drop-shadow(0 0 16px rgba(190,215,255,.28));
}
.marquee__track span:nth-child(4n+1) {
  -webkit-text-stroke-color: var(--orange);
  filter: drop-shadow(0 0 5px rgba(255,138,31,.65)) drop-shadow(0 0 18px rgba(255,120,20,.34));
}
.marquee__track i {
  color: var(--orange); font-style: normal; font-size: 1.2rem; opacity: .75;
  filter: drop-shadow(0 0 6px rgba(255,138,31,.6));
}

/* ---------- reviews ---------- */

.reviews__grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); }
.review { margin: 0; padding: 34px 30px 28px; }
.review__stars { color: var(--orange); letter-spacing: .18em; font-size: .8rem; margin-bottom: 16px; text-shadow: 0 0 12px rgba(255,138,31,.5); }
.review blockquote { margin: 0 0 18px; font-size: 1.03rem; color: #d3d8dd; line-height: 1.6; }
.review figcaption {
  font-family: var(--display); text-transform: uppercase; letter-spacing: .18em;
  font-size: .8rem; color: var(--orange);
}

/* ---------- locations ---------- */

.loc__grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.loc { padding: 42px 34px 38px; }
/* With a single location a full-bleed card reads as empty space. :only-child
   means this un-applies by itself if a second location is ever added back. */
.loc__grid > .loc:only-child { max-width: 700px; }
.loc--primary { background: var(--surface-2); border-color: var(--line-hot); }
.loc__tag {
  font-family: var(--display); text-transform: uppercase; letter-spacing: .22em;
  font-size: .72rem; color: var(--orange); margin: 0 0 8px;
}
.loc__city { font-family: var(--display); text-transform: uppercase; font-size: clamp(1.9rem, 3.6vw, 2.9rem); line-height: 1; margin: 0 0 14px; }
.loc__addr { font-style: normal; color: var(--muted); margin-bottom: 20px; }
.loc__meta { margin: 0 0 26px; display: grid; gap: 10px; }
.loc__meta div { display: flex; gap: 16px; align-items: baseline; border-top: 1px solid var(--line); padding-top: 10px; }
.loc__meta dt {
  font-family: var(--display); text-transform: uppercase; letter-spacing: .17em;
  font-size: .7rem; color: var(--faint); min-width: 58px;
}
.loc__meta dd { margin: 0; }
.loc__meta a { text-decoration: none; }
.loc__meta a:hover { color: var(--orange); }
.loc__actions { display: flex; flex-wrap: wrap; gap: 10px; }

/* ---------- footer ---------- */

.foot { position: relative; z-index: 2; background: var(--surface); border-top: 1px solid var(--line); padding: clamp(52px, 7vh, 88px) var(--gut) 36px; }
.foot__top { max-width: var(--maxw); margin: 0 auto 40px; }
.foot__word {
  font-family: var(--display); text-transform: uppercase;
  font-size: clamp(2.3rem, 10vw, 8rem); line-height: .86; margin: 0;
  /* Same neon tubing as the marquee: the stroke is the glass, the drop-shadow
     is the light. Was a dead grey outline, which read as disabled type. */
  color: transparent;
  -webkit-text-stroke: 1.6px var(--tube);
  filter: drop-shadow(0 0 5px rgba(220,232,255,.5)) drop-shadow(0 0 18px rgba(190,215,255,.26));
}
.foot__tag { font-family: var(--display); text-transform: uppercase; letter-spacing: .3em; font-size: .76rem; color: var(--orange); margin: 12px 0 0; }
.foot__cols {
  max-width: var(--maxw); margin: 0 auto; display: grid; gap: 30px;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  border-top: 1px solid var(--line); padding-top: 36px;
}
.foot__cols h4 {
  font-family: var(--display); text-transform: uppercase; letter-spacing: .2em;
  font-size: .74rem; color: var(--faint); margin: 0 0 10px;
}
.foot__cols p { margin: 0; color: #c6ccd2; font-size: .93rem; line-height: 1.78; }
.foot__cols a { text-decoration: none; }
.foot__cols a:hover { color: var(--orange); }
.foot__legal {
  max-width: var(--maxw); margin: 40px auto 0; padding-top: 20px;
  border-top: 1px solid var(--line); color: var(--faint); font-size: .78rem;
}

/* ---------- reveals ----------
   Class-driven, not tween-driven. The visible state is a plain CSS class, so
   if the animation never runs (throttled rAF, GSAP failed to load, background
   tab) the content still ends up visible instead of stuck at opacity 0. */

.js .reveal {
  opacity: 0; transform: translateY(30px);
  transition: opacity .85s var(--ease), transform .85s var(--ease);
}
.js .reveal.is-in { opacity: 1; transform: none; }
/* last-resort: jump to the visible state with no transition at all */
.js .reveal.is-forced { transition: none !important; opacity: 1 !important; transform: none !important; }


/* ============================================================
   MOBILE SCRUB (.mhero)
   Same full-screen stage as desktop. paint() does the work: the
   4:5 portrait frame is drawn whole over a blurred copy of itself,
   so there is never a dead band, and it rises as the CTA arrives.
   The CTA is trimmed to eyebrow + headline + call button so it
   fits beneath the panel on every phone.
   ============================================================ */

.mhero.scrub .hero__poster { object-fit: contain; object-position: center; }
.mhero.scrub .hero__scrim { display: none; }
.mhero.scrub .hero__ctascrim {
  background: linear-gradient(to top, rgba(6,7,9,.92) 0%, rgba(6,7,9,.55) 24%, transparent 46%);
}
.mhero.scrub .hero__cta {
  left: var(--gut); right: var(--gut);
  bottom: calc(22px + env(safe-area-inset-bottom, 0px));
  max-width: none;
}
.mhero.scrub .hero__ctacopy,
.mhero.scrub .hero__ctaactions .btn--ghost { display: none; }
.mhero.scrub .hero__ctatitle { font-size: clamp(2rem, 9vw, 2.9rem); margin-bottom: 14px; }
.mhero.scrub .hero__ctaactions { flex-direction: column; align-items: stretch; }
.mhero.scrub .hero__ctaactions .btn { width: 100%; }
.mhero.scrub .hero__hint { bottom: calc(18px + env(safe-area-inset-bottom, 0px)); }


/* ============================================================
   TOUCH TAP TARGETS
   Apple and Google both want 44px minimum. The action-bar call
   button was 41px and the phone/social text links about 20px —
   on a site whose main conversion is a phone tap, that is the
   wrong place to be a few pixels short.
   ============================================================ */

@media (pointer: coarse) {
  .actionbar .btn--sm { min-height: 44px; padding: 10px 20px; }
  /* column-gap: flex drops the space between the text and the <em>, which ran
     PROS and PERFORMANCE together on phones */
  .actionbar__mark { display: inline-flex; align-items: center; min-height: 44px; column-gap: .32em; }
  .loc__meta a,
  .foot__cols a {
    display: inline-flex; align-items: center;
    min-height: 44px;     /* explicit, rather than hoping padding adds up */
    padding: 6px 0;
    line-height: 1.2;
  }
  .loc__meta div { padding-top: 4px; }
  .foot__cols p { line-height: 1.4; }
}


/* ============================================================
   SERVICE-CARD LINKS (homepage)
   The whole card is the link (stretched ::after), so the neon
   hover still belongs to the card and the tap target is huge.
   ============================================================ */

.card-link { color: inherit; text-decoration: none; }
/* keep long titles clear of the corner arrow */
.svc h4:has(.card-link), .perf__card h3:has(.card-link) { padding-right: 30px; }
.card-link::after { content: ""; position: absolute; inset: 0; z-index: 3; }
.card-link::before {
  content: "\2192"; position: absolute; top: 18px; right: 22px;
  font-family: var(--body); font-size: 1.1rem; color: var(--faint);
  transition: color .35s var(--ease), transform .35s var(--ease);
}
.edge:hover .card-link::before,
.edge:focus-within .card-link::before { color: var(--orange); transform: translateX(4px); }
.card-link:focus-visible { outline: none; }
.edge:has(.card-link:focus-visible) { outline: 2px solid var(--orange); outline-offset: 3px; }

/* ============================================================
   SERVICE PAGES
   ============================================================ */

.page-hero {
  position: relative; isolation: isolate; overflow: hidden;
  min-height: clamp(540px, 76vh, 780px);
  display: flex; align-items: flex-end;
  padding: 124px var(--gut) clamp(52px, 9vh, 104px);
}
.page-hero__img {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover; object-position: center 40%;
}
.page-hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(100deg, rgba(6,7,9,.95) 0%, rgba(6,7,9,.8) 36%, rgba(6,7,9,.3) 68%, rgba(6,7,9,.5) 100%),
    linear-gradient(180deg, rgba(6,7,9,.6) 0%, transparent 28%, rgba(8,9,11,.92) 100%);
}
.page-hero__inner { width: 100%; max-width: var(--maxw); margin: 0 auto; }
.crumbs {
  display: flex; flex-wrap: wrap; gap: 6px 10px; list-style: none; margin: 0 0 24px; padding: 0;
  font-family: var(--display); text-transform: uppercase; letter-spacing: .18em;
  font-size: .72rem; color: var(--faint);
}
.crumbs li + li::before { content: "/"; margin-right: 10px; color: var(--line-hot); }
.crumbs a { color: var(--muted); text-decoration: none; }
.crumbs a:hover { color: var(--orange); }
.page-hero h1 {
  font-family: var(--display); font-weight: 700; text-transform: uppercase;
  font-size: clamp(2.5rem, 7vw, 5.8rem); line-height: .92; letter-spacing: -.01em;
  margin: 0 0 20px; max-width: 15ch;
}
.page-hero h1 em { font-style: normal; color: var(--orange); text-shadow: 0 0 40px rgba(255,138,31,.45); }
.page-hero__lede { color: #d3d8dd; max-width: 52ch; font-size: 1.1rem; margin: 0 0 30px; }
.page-hero__actions { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }
.badge {
  display: inline-flex; align-items: center; gap: 10px; min-height: 44px;
  font-family: var(--display); text-transform: uppercase; letter-spacing: .16em; font-size: .74rem;
  color: var(--text); border: 1px solid var(--line-hot); padding: 0 16px;
  background: rgba(8,9,11,.5); backdrop-filter: blur(6px);
}
.badge::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--orange); box-shadow: 0 0 10px var(--orange);
}

.page-body {
  max-width: var(--maxw); margin: 0 auto;
  padding: clamp(64px, 10vh, 124px) var(--gut);
  display: grid; grid-template-columns: minmax(0, 1fr) 340px;
  gap: clamp(40px, 5vw, 88px); align-items: start;
}
.page-main > section + section { margin-top: clamp(56px, 8vh, 96px); }
.page-main h2 {
  font-family: var(--display); text-transform: uppercase; font-weight: 700;
  font-size: clamp(1.9rem, 3.6vw, 2.9rem); line-height: 1; margin: 0 0 22px;
}
.page-main h2 em { font-style: normal; color: var(--orange); }
.prose p { color: #c9ced4; font-size: 1.06rem; margin: 0 0 18px; max-width: 66ch; }

.inc-grid { display: grid; gap: 10px; grid-template-columns: repeat(2, minmax(0, 1fr)); list-style: none; margin: 0; padding: 0; }
.inc-grid li { padding: 22px 24px 24px; }
.inc-grid h3 { font-family: var(--display); text-transform: uppercase; font-size: 1.14rem; margin: 0 0 6px; }
.inc-grid p { color: var(--muted); margin: 0; font-size: .93rem; }

.checklist { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.checklist li { position: relative; padding-left: 30px; color: #c9ced4; font-size: 1.02rem; }
.checklist li::before {
  content: ""; position: absolute; left: 3px; top: .38em; width: 8px; height: 15px;
  background: var(--orange); transform: skewX(var(--slash)); box-shadow: 0 0 10px rgba(255,138,31,.6);
}

.faq details { border-top: 1px solid var(--line); }
.faq details:last-of-type { border-bottom: 1px solid var(--line); }
.faq summary {
  cursor: pointer; list-style: none; min-height: 44px;
  display: flex; justify-content: space-between; align-items: center; gap: 18px;
  padding: 20px 0; font-family: var(--display); text-transform: uppercase;
  font-size: 1.08rem; letter-spacing: .02em; transition: color .3s var(--ease);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; flex: none; color: var(--orange); font-size: 1.6rem; line-height: 1;
  transition: transform .3s var(--ease);
}
.faq summary:hover { color: var(--orange); }
.faq details[open] summary::after { transform: rotate(45deg); }
.faq details p { color: #c9ced4; margin: 0 0 22px; max-width: 66ch; }

.page-aside { position: sticky; top: 96px; }
.aside-card { padding: 30px 28px 28px; }
.aside-card h2 {
  font-family: var(--display); text-transform: uppercase; font-size: 1.7rem; line-height: 1; margin: 0 0 18px;
}
.aside-card h2 em { font-style: normal; color: var(--orange); }
.aside-card .loc__meta { margin-bottom: 22px; }
.aside-card .btn { width: 100%; }
.aside-card .btn + .btn { margin-top: 10px; }

.related { max-width: var(--maxw); margin: 0 auto; padding: 0 var(--gut) clamp(72px, 11vh, 128px); }
.related__grid { display: grid; gap: 14px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.related__card { display: block; padding: 30px 28px 32px; text-decoration: none; color: inherit; }
.related__eyebrow {
  display: block; font-family: var(--display); text-transform: uppercase; letter-spacing: .2em;
  font-size: .72rem; color: var(--orange); margin-bottom: 12px;
}
.related__card h3 { font-family: var(--display); text-transform: uppercase; font-size: 1.5rem; line-height: 1.02; margin: 0 0 10px; }
.related__card p { color: var(--muted); margin: 0; font-size: .94rem; }

.cta-band__inner { position: relative; max-width: var(--maxw); margin: 0 auto; }

/* footer services column - on every page, so every page links to every service */
.foot__cols { grid-template-columns: repeat(3, minmax(0, 1fr)) minmax(0, 2fr); }
.foot__services ul { list-style: none; margin: 0; padding: 0; columns: 2; column-gap: 28px; }
.foot__services li { break-inside: avoid; }
.foot__services a { color: #c6ccd2; font-size: .93rem; line-height: 1.95; text-decoration: none; }
.foot__services a:hover { color: var(--orange); }

@media (max-width: 1080px) {
  .related__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 980px) {
  .page-body { grid-template-columns: minmax(0, 1fr); }
  .page-aside { position: static; }
  .foot__cols { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .foot__services { grid-column: 1 / -1; }
}
@media (max-width: 700px) {
  .page-hero { min-height: 82svh; padding-top: 104px; }
  .inc-grid, .related__grid { grid-template-columns: minmax(0, 1fr); }
  .page-hero__actions .btn { width: 100%; }
}
@media (max-width: 620px) {
  .foot__cols { grid-template-columns: minmax(0, 1fr); }
}

/* phones: reveals were 0.85s from 30px down and read as blank gaps mid-flick */
@media (pointer: coarse) {
  .js .reveal { transform: translateY(14px); transition-duration: .45s; }
}

/* anchor targets clear the action bar */
[id] { scroll-margin-top: 90px; }

/* ============================================================
   RESPONSIVE
   ============================================================ */

@media (max-width: 1080px) {
  .perf__grid, .svc__list { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 980px) {
  .actionbar__links { display: none; }
  .trust__list { grid-template-columns: repeat(2, 1fr); }
  .trust__item:nth-child(3)::before { display: none; }
  .trust__item:nth-child(3) { padding-left: 0; }
}

@media (max-width: 700px) {
  .perf__grid, .svc__list { grid-template-columns: 1fr; }
}

@media (max-width: 620px) {
  body { font-size: 16px; }
  /* keep the phone button whole; the wordmark yields space, not the CTA */
  .actionbar { gap: 12px; padding: 10px var(--gut); }
  .actionbar__mark { font-size: .74rem; letter-spacing: .1em; overflow: hidden; text-overflow: ellipsis; }
  .actionbar .btn--sm { padding: 9px 14px; font-size: .8rem; }
  .trust__list { grid-template-columns: 1fr; }
  .trust__item { padding: 22px 0 !important; border-top: 1px solid var(--line); }
  .trust__item::before { display: none !important; }
  .trust__item:first-child { border-top: 0; }
  .loc { padding: 30px 22px; }
  [id] { scroll-margin-top: 72px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
  .js .reveal { opacity: 1; transform: none; }
  .edge:hover { transform: none; }
}

/* Touch devices get no hover lift — it sticks after tap on iOS. */
@media (hover: none) {
  .edge:hover { transform: none; box-shadow: none; border-color: var(--line); background: var(--surface); }
  .edge:hover::before { opacity: 0; }
}

/* ============================================================
   PHONE RENDERING COST
   A phone GPU pays for these continuously, not once. The action bar is
   position:fixed over a canvas that repaints on every scroll tick, so its
   backdrop-filter re-blurs the strip behind it every one of those frames;
   the neon type stacks two drop-shadow passes per element, on a marquee that
   translates forever. None of it is load-bearing for the design at phone
   size, so touch devices get the cheaper version: a solid bar, and one glow
   pass instead of two. The look survives; the frame budget does not
   otherwise. (Desktop keeps the full treatment.)
   ============================================================ */
@media (pointer: coarse) {
  .actionbar {
    background: rgba(10, 12, 15, .96);
    backdrop-filter: none; -webkit-backdrop-filter: none;
  }
  .badge { background: rgba(8, 9, 11, .85); backdrop-filter: none; -webkit-backdrop-filter: none; }

  .marquee__track span {
    filter: drop-shadow(0 0 7px rgba(220,232,255,.5));
  }
  .marquee__track span:nth-child(4n+1) {
    filter: drop-shadow(0 0 7px rgba(255,138,31,.6));
  }
  .foot__word {
    filter: drop-shadow(0 0 8px rgba(220,232,255,.46));
  }
}
