/* =============================================================
   BC HOME SERVICE — NOVA v17.1 "AURORA LIGHT" DESIGN LAYER
   (css/v17.css)
   ---------------------------------------------------------------
   The "giant upgrade" skin. Layered AFTER css/v16.css (Kinetic),
   which itself loads after main / v5-fixes / v10 / v15 (Aurora).

   v17.1 MISSION (owner directive): every content section EXCEPT
   the homepage hero becomes a modern, award-site-grade experience
   — WHILE KEEPING its authored background (white stays white,
   navy stays navy, orange stays orange). The modernizing comes
   from craft, not repaints: light-wash color bleeds, gradient-ink
   headlines, glass cards with glare + tilt, bento grids, staggered
   blur reveals, trust chips, magnet buttons, count-up stats
   (Linear / Stripe / Arc / Apple register).

   *** HOMEPAGE HERO PROTECTION (NON-NEGOTIABLE) ***
   The homepage hero (#home — the React hero band) is ABSOLUTELY
   FORBIDDEN to restyle or animate. This file contains ZERO
   selectors that can match it:
     - no `#home` selector exists anywhere below,
     - no `.hero` / `.hero-*` (hero / hero-grid / hero-contact-form /
       hero-particles / hero-split-grid / hero-visual-3d) selector
       exists anywhere below.
   Every v17 class is either (a) a brand-new .v17-* component, or
   (b) an EXISTING site component restyled ONLY when it sits inside
   a scope the runtime tags (.v17-band--soft for dark-by-design
   sections / .v17-seen — applied by js/v17.js which never tags
   anything inside #home, .hero, .hero-contact-form or
   [data-v17-skip]).
   The service-areas map SURFACE (#service-map / .bcat) owns its
   own skin: v17 never tags or styles anything inside it. The
   #service-areas section around it is seen but never reskinned
   beyond its header copy (generic .v17-underline / .v17-ink
   classes) and the city-chip list row (section 06).

   COEXISTENCE MAP (what already exists and is NOT duplicated):
   - main.css : .btn shine sweep, card chrome, footer base, quote
     form base — v17 only re-skins tagged scopes on top.
   - modern.css: .m-card, .m-eyebrow, .m-bento, marquee, FAQ,
     tables, mobile nav — v17 re-skins inside tagged scopes only.
   - v10.css  : dark-mode surface repaint + .v10-progress — v17.1
     keeps every authored background in dark mode too (no repaint
     rules remain anywhere in this sheet).
   - v15.css : eyebrow chips, glass cards, glow cards, marquee,
     stat cards, scrollbar, focus rings — v17 goes FURTHER (light
     wash, bento, glare, magnet buttons, dividers) and only
     lightly re-polishes the v15 marquee strip.
   - v16.css : word-split reveals, spotlight, hours chip, mobile
     action bar, orbs — untouched; v17's reveal classes are a
     different, opt-in system (.v17-r/.v17-in).

   MOTION SAFETY: every animation/transitions uses transform,
   opacity, filter, clip-path or background-position ONLY. No
   width/height/top/left/margin animation anywhere. prefers-
   reduced-motion kills ALL v17 motion. Touch devices and small
   screens lose the hover-only effects. English-only UI. No CJK.
   ============================================================= */

/* ===================== TABLE OF CONTENTS =====================
   01. TOKENS — colors, easings, durations, radii, glass, shadows
   02. SCROLL PROGRESS — top ribbon + vertical rail + consolidation
   03. SCROLLBAR / SELECTION / FOCUS-VISIBLE
   04. OWN-PAINT SECTIONS + LIGHT WASH — no repaints ever; soft
       aurora veils for dark-by-design sections, whisper color
       bleeds for light sections
   05. OWN-DARK CHILD RESKINS — glass cards / eyebrows inside
       sections that are dark by their own design
   06. SECTION-SPECIFIC FINE-TUNING (service-areas city chips)
   07. SECTION HEADERS — eyebrow chips v2, display h2, gradient
       ink (.v17-ink), animated underline (.v17-underline)
   08. TRUST CHIP ROW (.v17-trust-row / .v17-chip)
   09. GLASS CARDS v2 (.v17-card) — glare sweep + hairline ring
   10. BENTO GRID (.v17-bento) + numbered corner chips
   11. BUTTONS v2 (.v17-btn2) — gradient fill, glow, shine, magnet
   12. MARQUEE v2 (.v17-marquee) + v15 marquee polish
   13. STATS (.v17-stat / .v17-stat-label)
   14. REVEAL ENGINE v2 (.v17-r / .v17-in)
   15. FORMS — quote/contact/booking/faq inputs, focus, errors
   16. FOOTER — immersive navy, hairline, tick titles, bottom bar
   17. EMERGENCY PULSE (.v17-pulse)
   18. IMAGE TREATMENT (.v17-img)
   19. DIVIDERS (.v17-divider)
   20. TABLE / FAQ / BREADCRUMB POLISH
   21. SEASONAL ACCENTS (html.v17-winter / -spring / -summer / -fall)
   22. RESPONSIVE + TOUCH GUARDS
   23. REDUCED MOTION
   24. PRINT
   25. PERFORMANCE NOTES (why every animation is compositor-only)
   ============================================================= */

/* ===================== 01. TOKENS =====================
   Extends the brand palette (navy #0a1628 family, cyan #00b4d8,
   orange #ff6b35) with NO new hues — only depth, glass and glow
   variants of what v15/v16 already established. */
:root {
  /* — brand depth — */
  --v17-navy: #0a1628;
  --v17-navy-2: #0d1f3c;
  --v17-navy-3: #16294a;
  --v17-navy-ink: #071120;      /* deepest — band bottom edge */
  --v17-blue: #2e86de;
  --v17-cyan: #00b4d8;
  --v17-cyan-2: #48cae4;
  --v17-cyan-ice: #b9ecf7;      /* light end of the cyan ink ramp */
  --v17-orange: #ff6b35;
  --v17-orange-2: #ff8c42;
  --v17-orange-deep: #e55a28;

  /* — motion — */
  --v17-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --v17-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --v17-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --v17-ease-soft: cubic-bezier(0.65, 0, 0.35, 1);
  --v17-dur-fast: 0.35s;
  --v17-dur: 0.55s;
  --v17-dur-slow: 0.85s;
  --v17-dur-glare: 0.9s;       /* card glare sweep */

  /* — geometry (radii ladder 14 / 20 / 28) — */
  --v17-r-sm: 14px;
  --v17-r: 20px;
  --v17-r-lg: 28px;

  /* — glass fills — */
  --v17-glass: rgba(255, 255, 255, 0.06);
  --v17-glass-2: rgba(255, 255, 255, 0.09);
  --v17-glass-strong: rgba(255, 255, 255, 0.13);
  --v17-glass-dark: rgba(10, 22, 40, 0.92);
  --v17-glass-blur: 14px;

  /* — hairlines — */
  --v17-line: rgba(255, 255, 255, 0.09);
  --v17-line-soft: rgba(255, 255, 255, 0.16);
  --v17-line-strong: rgba(255, 255, 255, 0.28);
  --v17-line-dark: rgba(10, 22, 40, 0.10);

  /* — shadows with colored glows — */
  --v17-shadow-sm: 0 2px 10px rgba(7, 17, 32, 0.08), 0 1px 3px rgba(7, 17, 32, 0.05);
  --v17-shadow-md: 0 12px 38px -10px rgba(7, 17, 32, 0.20), 0 3px 10px rgba(7, 17, 32, 0.06);
  --v17-shadow-lg: 0 30px 80px -18px rgba(7, 17, 32, 0.32), 0 10px 26px rgba(7, 17, 32, 0.10);
  --v17-glow-cyan: 0 18px 48px -14px rgba(0, 180, 216, 0.45);
  --v17-glow-orange: 0 18px 48px -14px rgba(255, 107, 53, 0.50);
  --v17-glow-btn: 0 8px 24px -8px rgba(255, 107, 53, 0.55);
  --v17-glow-btn-hover: 0 12px 34px -8px rgba(255, 107, 53, 0.70);
  --v17-inset-top: inset 0 1px 0 rgba(255, 255, 255, 0.16);

  /* — aurora paint (seasonal classes retune these) — */
  --v17-aurora-c: rgba(0, 180, 216, 0.26);   /* cyan veil   */
  --v17-aurora-c2: rgba(72, 202, 228, 0.20);
  --v17-aurora-o: rgba(255, 107, 53, 0.22);  /* orange veil */
  --v17-aurora-o2: rgba(255, 140, 66, 0.15);
  --v17-grid-dot: rgba(255, 255, 255, 0.04);

  /* — z scale (page chrome) — */
  --v17-z-progress: 2147483002;
}

/* ===================== 02. SCROLL PROGRESS =====================
   js/v17.js injects ONE ribbon (.v17-progress) + a desktop-only
   vertical rail (.v17-progress-rail). v10.js, modern.js, main.js
   and the React bundle each already paint their own top bar
   (.v10-progress / .m-progress / .scroll-progress /
   #scroll-progress) — four bars doing one job. v17 consolidates:
   the legacy bars are retired (display:none) so exactly ONE
   aurora ribbon owns the top edge. To hand the edge back to an
   older layer, delete the retirement rule + the v17 injection. */
.v17-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: var(--v17-z-progress);
  pointer-events: none;
  background: transparent;
  opacity: 0;
  -webkit-transition: opacity var(--v17-dur-fast) var(--v17-ease);
  transition: opacity var(--v17-dur-fast) var(--v17-ease);
}
.v17-progress.v17-on {
  opacity: 1;
}
.v17-progress-fill {
  height: 100%;
  width: 100%;
  -webkit-transform: scaleX(0);
  transform: scaleX(0);
  -webkit-transform-origin: 0 50%;
  transform-origin: 0 50%;
  background: linear-gradient(
    90deg,
    #00b4d8 0%,
    #48cae4 34%,
    #7fdcf0 52%,
    #ff8c42 78%,
    #ff6b35 100%
  );
  -webkit-box-shadow:
    0 0 14px rgba(0, 180, 216, 0.60),
    0 0 5px rgba(255, 140, 66, 0.55);
  box-shadow:
    0 0 14px rgba(0, 180, 216, 0.60),
    0 0 5px rgba(255, 140, 66, 0.55);
  will-change: transform;
}

/* — vertical rail (desktop, fine pointers only) — */
.v17-progress-rail {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 3px;
  z-index: calc(var(--v17-z-progress) - 1);
  pointer-events: none;
  display: none;
}
.v17-progress-rail-fill {
  position: absolute;
  inset: 0;
  -webkit-transform: scaleY(0);
  transform: scaleY(0);
  -webkit-transform-origin: 50% 0;
  transform-origin: 50% 0;
  background: linear-gradient(180deg, #00b4d8 0%, #48cae4 45%, #ff8c42 100%);
  -webkit-box-shadow: -2px 0 12px rgba(0, 180, 216, 0.45);
  box-shadow: -2px 0 12px rgba(0, 180, 216, 0.45);
  will-change: transform;
}
@media (min-width: 1024px) and (hover: hover) and (pointer: fine) {
  .v17-progress-rail { display: block; }
}

/* — legacy bar retirement (see note above) — */
.v10-progress,
.m-progress,
.scroll-progress,
#scroll-progress { display: none !important; }

/* ===================== 03. SCROLLBAR / SELECTION / FOCUS =====================
   Slimmer than the v15 scrollbar, navy-tracked, gradient thumb.
   Selection leans orange on dark, cyan on light. Focus rings are
   2px cyan with a 3px offset — site chrome, applies everywhere
   (v15 already ships global rings; this only sharpens them). */
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: #0d1f3c; }
::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, #00b4d8, #2e86de 55%, #ff8c42 130%);
  border-radius: 99px;
  border: 2px solid #0d1f3c;
}
::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(180deg, #48cae4, #2e86de 55%, #ff6b35 130%);
}
::-webkit-scrollbar-corner { background: #0d1f3c; }
@supports (scrollbar-color: auto) and (scrollbar-width: thin) {
  html {
    scrollbar-color: #00b4d8 #0d1f3c;
    scrollbar-width: thin;
  }
}

::selection {
  background: rgba(255, 107, 53, 0.30);
  color: #071120;
}
.v17-band ::selection,
.v17-band--soft ::selection,
footer.footer ::selection,
footer.site-footer ::selection {
  background: rgba(0, 180, 216, 0.42);
  color: #ffffff;
}

:focus-visible {
  outline: 2px solid var(--v17-cyan, #00b4d8);
  outline-offset: 3px;
  border-radius: 6px;
}

/* ===================== 04. OWN-PAINT SECTIONS + LIGHT WASH =====================
   v17.1 "AURORA LIGHT" (owner directive: section backgrounds stay
   white or their previous color). js/v17.js never repaints a
   section anymore:
     .v17-band--soft — section is dark BY ITS OWN design (navy
                       #about / #how-it-works, orange #emergency,
                       .m-aurora, .m-glass-dark). Authored paint and
                       authored text colors stay; only the child
                       polish (section 05) layers on top.
     .v17-band       — legacy alias of --soft (kept so a cached
                       mixed v17.0 + v17.1 load can never repaint a
                       section either).
   Neither class sets background, color or design tokens anymore. */
.v17-band,
.v17-band--soft {
  position: relative;
  isolation: isolate;
  /* crop the oversized aurora veils (progressive overflow:clip with
     the hidden fallback; same contract v17.0 shipped with) */
  overflow: hidden;
  overflow: clip;
  /* aurora phase seed (set by js/v17.js) — still consumed by the
     light wash drift + soft veil delays below */
  --v17-seed: 0;
}

/* — SOFT VEIL: sections that are dark by their own design get a
   whisper aurora drift as a paint layer ABOVE their authored
   background (not a repaint). Invisible on fully opaque inline
   backgrounds by nature (z-index:-1 sits behind the paint), and
   additive on CSS-painted / .m-aurora hosts. Zero steady-state
   cost: transform-only keyframes, compositor-driven. — */
.v17-band--soft::before,
.v17-band::before {
  content: "";
  position: absolute;
  inset: -30%;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(ellipse 34% 44% at 26% 32%, rgba(0, 180, 216, 0.10), transparent 66%),
    radial-gradient(ellipse 24% 32% at 78% 20%, rgba(72, 202, 228, 0.07), transparent 64%);
  -webkit-animation: v17AuroraA 70s var(--v17-ease-soft) infinite alternate;
  animation: v17AuroraA 70s var(--v17-ease-soft) infinite alternate;
  -webkit-animation-delay: calc(var(--v17-seed, 0) * -13s);
  animation-delay: calc(var(--v17-seed, 0) * -13s);
  will-change: transform;
}
.v17-band--soft::after,
.v17-band::after {
  content: "";
  position: absolute;
  inset: -32%;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(ellipse 28% 38% at 72% 74%, rgba(255, 107, 53, 0.07), transparent 68%),
    radial-gradient(ellipse 20% 28% at 16% 82%, rgba(255, 140, 66, 0.05), transparent 62%);
  -webkit-animation: v17AuroraB 90s var(--v17-ease-soft) infinite alternate;
  animation: v17AuroraB 90s var(--v17-ease-soft) infinite alternate;
  -webkit-animation-delay: calc(var(--v17-seed, 0) * -21s);
  animation-delay: calc(var(--v17-seed, 0) * -21s);
  will-change: transform;
}
@keyframes v17AuroraA {
  0%   { -webkit-transform: translate3d(-3%, -2%, 0) scale(1); transform: translate3d(-3%, -2%, 0) scale(1); }
  50%  { -webkit-transform: translate3d(2.5%, 2%, 0) scale(1.07); transform: translate3d(2.5%, 2%, 0) scale(1.07); }
  100% { -webkit-transform: translate3d(4%, -1.5%, 0) scale(1.03); transform: translate3d(4%, -1.5%, 0) scale(1.03); }
}
@keyframes v17AuroraB {
  0%   { -webkit-transform: translate3d(3%, 2%, 0) scale(1.04); transform: translate3d(3%, 2%, 0) scale(1.04); }
  50%  { -webkit-transform: translate3d(-2.5%, -2%, 0) scale(1); transform: translate3d(-2.5%, -2%, 0) scale(1); }
  100% { -webkit-transform: translate3d(-4%, 2.5%, 0) scale(1.08); transform: translate3d(-4%, 2.5%, 0) scale(1.08); }
}

/* — LIGHT WASH: ultra-soft color-bleed veils for every seen LIGHT
   section. Painted as pseudos ABOVE the section background at
   whisper opacity (4.5–7%), pointer-events:none — they add depth
   and "designed paper" life WITHOUT changing the background color.
   The cyan bleed anchors the top edge, the warm ember anchors the
   bottom, so consecutive white sections still read as separated
   movements of one composition. Transform-only drift (compositor,
   zero repaints); phase varies per section via --v17-seed. — */
.v17-seen:not(.v17-band):not(.v17-band--soft) {
  position: relative;
}
.v17-seen:not(.v17-band):not(.v17-band--soft)::before {
  content: "";
  position: absolute;
  top: 0;
  left: -6%;
  right: -6%;
  height: clamp(140px, 24vw, 300px);
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 55% 100% at 16% 0%, rgba(0, 180, 216, 0.07), transparent 70%),
    radial-gradient(ellipse 42% 92% at 84% 0%, rgba(255, 107, 53, 0.055), transparent 68%);
  -webkit-animation: v17WashA 46s ease-in-out infinite alternate;
  animation: v17WashA 46s ease-in-out infinite alternate;
  -webkit-animation-delay: calc(var(--v17-seed, 0) * -9s);
  animation-delay: calc(var(--v17-seed, 0) * -9s);
  will-change: transform;
}
.v17-seen:not(.v17-band):not(.v17-band--soft)::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: -6%;
  right: -6%;
  height: clamp(110px, 18vw, 240px);
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 50% 100% at 82% 100%, rgba(255, 140, 66, 0.05), transparent 72%),
    radial-gradient(ellipse 40% 90% at 12% 100%, rgba(0, 180, 216, 0.045), transparent 66%);
  -webkit-animation: v17WashB 56s ease-in-out infinite alternate;
  animation: v17WashB 56s ease-in-out infinite alternate;
  -webkit-animation-delay: calc(var(--v17-seed, 0) * -13s);
  animation-delay: calc(var(--v17-seed, 0) * -13s);
  will-change: transform;
}
@keyframes v17WashA {
  0%   { -webkit-transform: translate3d(-1.5%, -1%, 0) scale(1.02); transform: translate3d(-1.5%, -1%, 0) scale(1.02); }
  100% { -webkit-transform: translate3d(2%, 1.5%, 0) scale(1.05); transform: translate3d(2%, 1.5%, 0) scale(1.05); }
}
@keyframes v17WashB {
  0%   { -webkit-transform: translate3d(1.5%, 1%, 0) scale(1.03); transform: translate3d(1.5%, 1%, 0) scale(1.03); }
  100% { -webkit-transform: translate3d(-2%, -1.5%, 0) scale(1.06); transform: translate3d(-2%, -1.5%, 0) scale(1.06); }
}
/* phones: one veil is enough (battery + layer budget) */
@media (max-width: 767px) {
  .v17-seen:not(.v17-band):not(.v17-band--soft)::before {
    height: clamp(110px, 26vw, 190px);
  }
  .v17-seen:not(.v17-band):not(.v17-band--soft)::after {
    content: none;
  }
}
/* sections that own their ::before / ::after design (authored
   decorations) can opt out of the wash with data-v17-nowash —
   the veil never paints over an authored pseudo */
.v17-seen[data-v17-nowash]::before,
.v17-seen[data-v17-nowash]::after {
  content: none;
}

/* ===================== 05. BAND CHILD RESKINS =====================
   Everything below scopes to .v17-band / .v17-band--soft, which
   js/v17.js only ever applies outside the protected zones — so
   the homepage hero can never catch any of these rules. */
.v17-band h1, .v17-band--soft h1,
.v17-band h2, .v17-band--soft h2,
.v17-band h3, .v17-band--soft h3,
.v17-band h4, .v17-band--soft h4 {
  color: #ffffff;
}
.v17-band .section-title,
.v17-band .m-h2,
.v17-band .section-head h2,
.v17-band--soft .section-title,
.v17-band--soft .m-h2,
.v17-band--soft .section-head h2 {
  color: #ffffff;
  text-shadow: 0 2px 30px rgba(7, 17, 32, 0.55);
}
.v17-band .section-subtitle,
.v17-band .m-sub,
.v17-band .section-sub,
.v17-band--soft .section-subtitle,
.v17-band--soft .m-sub,
.v17-band--soft .section-sub {
  color: rgba(255, 255, 255, 0.74);
}
.v17-band p, .v17-band--soft p {
  color: rgba(255, 255, 255, 0.74);
}
.v17-band a:not(.btn), .v17-band--soft a:not(.btn) {
  color: var(--v17-cyan-2, #48cae4);
}
.v17-band li, .v17-band--soft li {
  color: rgba(255, 255, 255, 0.76);
}

/* — eyebrows flip to glass-on-dark chips — */
.v17-band .section-eyebrow,
.v17-band .section-eyebrow.dark,
.v17-band .section-eyebrow.light,
.v17-band .m-eyebrow,
.v17-band--soft .section-eyebrow,
.v17-band--soft .section-eyebrow.dark,
.v17-band--soft .section-eyebrow.light,
.v17-band--soft .m-eyebrow {
  display: -webkit-inline-flex;
  display: inline-flex;
  -webkit-align-items: center;
  align-items: center;
  gap: 9px;
  padding: 8px 16px 8px 13px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: var(--v17-cyan-2, #48cae4);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  -webkit-box-shadow: var(--v17-inset-top);
  box-shadow: var(--v17-inset-top);
}
.v17-band .section-eyebrow::before,
.v17-band .m-eyebrow::before,
.v17-band--soft .section-eyebrow::before,
.v17-band--soft .m-eyebrow::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: linear-gradient(135deg, #00b4d8, #48cae4);
  -webkit-box-shadow: 0 0 0 3px rgba(0, 180, 216, 0.16), 0 0 10px rgba(0, 180, 216, 0.7);
  box-shadow: 0 0 0 3px rgba(0, 180, 216, 0.16), 0 0 10px rgba(0, 180, 216, 0.7);
  -webkit-animation: v17DotBreathe 2.8s var(--v17-ease-soft) infinite;
  animation: v17DotBreathe 2.8s var(--v17-ease-soft) infinite;
}
@keyframes v17DotBreathe {
  0%, 100% { -webkit-transform: scale(1); transform: scale(1); opacity: 1; }
  50%      { -webkit-transform: scale(0.8); transform: scale(0.8); opacity: 0.72; }
}

/* — dark glass treatment for every card family inside a band — */
.v17-band .m-card,
.v17-band .service-card,
.v17-band .feature-card,
.v17-band .value-card,
.v17-band .offer,
.v17-band .offer-card,
.v17-band .deal,
.v17-band .deal-card,
.v17-band .pricing-card,
.v17-band .blog-card,
.v17-band .post-card,
.v17-band .stat-card,
.v17-band .quote-form-card,
.v17-band .card,
.v17-band .gr-card,
.v17-band--soft .m-card,
.v17-band--soft .service-card,
.v17-band--soft .feature-card,
.v17-band--soft .value-card,
.v17-band--soft .pricing-card,
.v17-band--soft .card {
  background:
    linear-gradient(160deg, rgba(255, 255, 255, 0.085) 0%, rgba(255, 255, 255, 0.03) 55%, rgba(255, 255, 255, 0.05) 100%);
  border: 1px solid rgba(255, 255, 255, 0.14);
  -webkit-box-shadow: 0 18px 50px -18px rgba(0, 0, 0, 0.55), var(--v17-inset-top);
  box-shadow: 0 18px 50px -18px rgba(0, 0, 0, 0.55), var(--v17-inset-top);
  -webkit-backdrop-filter: blur(var(--v17-glass-blur, 14px));
  backdrop-filter: blur(var(--v17-glass-blur, 14px));
}
/* React-built cards carry inline background/border — !important
   is required to win over the inline style attribute (author
   !important outranks non-important inline styles). Their inline
   hover transforms remain owned by React (inline beats CSS).
   .service-card is listed for the React homepage (inline #fff +
   token text); on static pages it simply wins over main.css. */
.v17-band .service-card,
.v17-band .blog-grid > article,
.v17-band .financing-grid > div,
.v17-band .offers-grid > *,
.v17-band--soft .blog-grid > article,
.v17-band--soft .financing-grid > div {
  background:
    linear-gradient(160deg, rgba(255, 255, 255, 0.085) 0%, rgba(255, 255, 255, 0.03) 55%, rgba(255, 255, 255, 0.05) 100%) !important;
  border-color: rgba(255, 255, 255, 0.14) !important;
  -webkit-box-shadow: 0 18px 50px -18px rgba(0, 0, 0, 0.55), var(--v17-inset-top) !important;
  box-shadow: 0 18px 50px -18px rgba(0, 0, 0, 0.55), var(--v17-inset-top) !important;
}
/* token-driven inline text inside React cards flips via the
   vars; a few literal grays need explicit help */
.v17-band .financing-grid li,
.v17-band .blog-grid h3,
.v17-band .blog-grid p {
  color: rgba(255, 255, 255, 0.78);
}
.v17-band .blog-grid h3 { color: #ffffff; }

/* — icon chips + avatar rings brighten on dark — */
.v17-band .m-chip {
  background: rgba(0, 180, 216, 0.14);
  border-color: rgba(72, 202, 228, 0.32);
}
.v17-band .gr-av,
.v17-band .gr-avatar {
  -webkit-box-shadow: 0 0 0 2px rgba(72, 202, 228, 0.35);
  box-shadow: 0 0 0 2px rgba(72, 202, 228, 0.35);
}

/* — FAQ accordions inside bands: glass open state — */
.v17-band .m-faq-item,
.v17-band--soft .m-faq-item {
  background: rgba(255, 255, 255, 0.045);
  border-color: rgba(255, 255, 255, 0.12);
}
.v17-band .m-faq-item.open,
.v17-band .m-faq-item[open],
.v17-band--soft .m-faq-item.open {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(72, 202, 228, 0.40);
  -webkit-box-shadow: 0 16px 44px -16px rgba(0, 0, 0, 0.6), 0 0 34px -14px rgba(0, 180, 216, 0.35);
  box-shadow: 0 16px 44px -16px rgba(0, 0, 0, 0.6), 0 0 34px -14px rgba(0, 180, 216, 0.35);
}
.v17-band .m-faq-q { color: #ffffff; }
.v17-band .m-faq-a-inner { color: rgba(255, 255, 255, 0.72); }
.v17-band .m-faq-q .m-faq-icon { background: rgba(0, 180, 216, 0.14); }
.v17-band .m-faq-icon svg { stroke: #48cae4; }

/* — hairline separators inside bands — */
.v17-band .m-step,
.v17-band--soft .m-step {
  border-bottom-color: rgba(255, 255, 255, 0.10);
}
.v17-band .m-table-wrap,
.v17-band--soft .m-table-wrap {
  border-color: rgba(255, 255, 255, 0.14);
}
.v17-band table.m-table { background: rgba(255, 255, 255, 0.04); }
.v17-band table.m-table td { color: rgba(255, 255, 255, 0.78); border-top-color: rgba(255, 255, 255, 0.09); }
.v17-band table.m-table tbody tr:hover { background: rgba(0, 180, 216, 0.10); }

/* — legacy v15/v16 widgets already navy: deepen their ring — */
.v17-band .v15-widget,
.v17-band .v16-widget {
  border-color: rgba(255, 255, 255, 0.18);
  -webkit-box-shadow: 0 24px 60px -20px rgba(0, 0, 0, 0.7), var(--v17-glow-cyan);
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, 0.7), var(--v17-glow-cyan);
}

/* ===================== 06. SECTION-SPECIFIC FINE-TUNING =====================
   v17.1: with the repaint retired, the old band overrides for
   #reviews / #financing / #emergency / #blog and the dark-theme
   re-assertion are gone — those sections keep their authored
   backgrounds. What remains here is the one cross-section polish
   that survived: the service-areas city-chip row (homepage +
   internal), which is scoped to .v17-seen (never the map atlas
   itself — NOTHING inside #service-map / .bcat is touched by any
   rule in this file). */

.v17-seen .city-chip {
  background: rgba(255, 255, 255, 0.72);
  border: 1px solid rgba(10, 22, 40, 0.12);
  color: #14416b;
  font-weight: 700;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  -webkit-box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.8),
    0 2px 10px -4px rgba(7, 17, 32, 0.20);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.8),
    0 2px 10px -4px rgba(7, 17, 32, 0.20);
  -webkit-transition:
    -webkit-transform var(--v17-dur-fast) var(--v17-ease),
    -webkit-box-shadow var(--v17-dur-fast) var(--v17-ease),
    border-color var(--v17-dur-fast) var(--v17-ease),
    color var(--v17-dur-fast) var(--v17-ease),
    background var(--v17-dur-fast) var(--v17-ease);
  transition:
    transform var(--v17-dur-fast) var(--v17-ease),
    box-shadow var(--v17-dur-fast) var(--v17-ease),
    border-color var(--v17-dur-fast) var(--v17-ease),
    color var(--v17-dur-fast) var(--v17-ease),
    background var(--v17-dur-fast) var(--v17-ease);
}
.v17-seen .city-chip svg {
  color: var(--v17-cyan, #00b4d8);
  -webkit-filter: drop-shadow(0 0 6px rgba(0, 180, 216, 0.45));
  filter: drop-shadow(0 0 6px rgba(0, 180, 216, 0.45));
}
.v17-seen .city-chip:hover {
  -webkit-transform: translateY(-3px);
  transform: translateY(-3px);
  border-color: rgba(0, 180, 216, 0.55);
  color: #0a1628;
  background: #ffffff;
  -webkit-box-shadow:
    inset 0 1px 0 #ffffff,
    0 12px 24px -8px rgba(0, 180, 216, 0.45);
  box-shadow:
    inset 0 1px 0 #ffffff,
    0 12px 24px -8px rgba(0, 180, 216, 0.45);
}
.v17-seen .city-chip.is-active {
  background: linear-gradient(135deg, #00b4d8 0%, #2e86de 100%);
  border-color: transparent;
  color: #ffffff;
  -webkit-box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    0 10px 24px -8px rgba(0, 180, 216, 0.60);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    0 10px 24px -8px rgba(0, 180, 216, 0.60);
}
.v17-seen .city-chip.is-active svg { color: #ffffff; }

/* ===================== 07. SECTION HEADERS =====================
   Header upgrades apply to sections js/v17.js has seen
   (.v17-seen — every content section below the protected zones).
   The homepage hero header is never .v17-seen, so it can never
   catch these rules. */
.v17-seen .section-title,
.v17-seen .m-h2,
.v17-seen .section-head h2 {
  font-size: clamp(1.9rem, 4vw, 3.2rem);
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1.08;
}
.v17-seen .section-header {
  margin-bottom: clamp(38px, 5vw, 60px);
}

/* — light-section eyebrow chips (the band variant is section 05):
   the flat "line + caps" eyebrow becomes a soft pill with a live
   dot — the same geometry on both rhythms. Scoped to seen sections
   only, so the homepage hero eyebrow (never .v17-seen) and every
   page-hero eyebrow keep their original paint. */
.v17-seen:not(.v17-band):not(.v17-band--soft) .section-eyebrow,
.v17-seen:not(.v17-band):not(.v17-band--soft) .m-eyebrow {
  display: -webkit-inline-flex;
  display: inline-flex;
  -webkit-align-items: center;
  align-items: center;
  gap: 9px;
  padding: 8px 16px 8px 13px;
  border-radius: 999px;
  background: rgba(10, 22, 40, 0.04);
  border: 1px solid rgba(46, 134, 222, 0.24);
  color: #14416b;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1;
  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.85);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.85);
}
/* the 24px lead-in line becomes the breathing dot */
.v17-seen:not(.v17-band):not(.v17-band--soft) .section-eyebrow::before,
.v17-seen:not(.v17-band):not(.v17-band--soft) .m-eyebrow::before {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: linear-gradient(135deg, #00b4d8, #2e86de);
  -webkit-box-shadow: 0 0 0 3px rgba(0, 180, 216, 0.14), 0 0 10px rgba(0, 180, 216, 0.55);
  box-shadow: 0 0 0 3px rgba(0, 180, 216, 0.14), 0 0 10px rgba(0, 180, 216, 0.55);
  -webkit-animation: v17DotBreathe 2.8s var(--v17-ease-soft) infinite;
  animation: v17DotBreathe 2.8s var(--v17-ease-soft) infinite;
}
/* the on-dark / .light eyebrow variants sometimes carry their own
   color; the pill keeps it legible either way */
.v17-seen:not(.v17-band):not(.v17-band--soft) .section-eyebrow.on-dark {
  color: #0f3a56;
}

/* — gradient ink —
   On light sections: navy -> cyan. Inside bands: white -> cyan. */
.v17-ink {
  background: linear-gradient(100deg, #0a1628 0%, #14416b 34%, #00b4d8 78%, #48cae4 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.v17-band .v17-ink,
.v17-band--soft .v17-ink {
  background: linear-gradient(100deg, #ffffff 0%, #dff6fd 38%, #48cae4 72%, #00b4d8 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* — animated underline draw (scaleX 0 -> 1 once the section is
   seen; transform-only, origin left) — */
.v17-underline {
  position: relative;
  display: inline-block;
}
.v17-underline::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -0.16em;
  height: 3px;
  border-radius: 99px;
  background: linear-gradient(90deg, #00b4d8 0%, #48cae4 45%, #ff8c42 100%);
  -webkit-transform: scaleX(0);
  transform: scaleX(0);
  -webkit-transform-origin: 0 50%;
  transform-origin: 0 50%;
  -webkit-transition: -webkit-transform 0.7s var(--v17-ease) 0.2s;
  transition: transform 0.7s var(--v17-ease) 0.2s;
  pointer-events: none;
}
.v17-seen .v17-underline::after,
.v17-underline.v17-in::after {
  -webkit-transform: scaleX(1);
  transform: scaleX(1);
}
/* ink text + underline: keep the bar visible under the
   transparent fill by painting it slightly stronger */
.v17-underline.v17-ink::after {
  height: 4px;
  background: linear-gradient(90deg, rgba(0, 180, 216, 0.9) 0%, rgba(72, 202, 228, 0.9) 45%, rgba(255, 140, 66, 0.95) 100%);
}

/* ===================== 08. TRUST CHIP ROW =====================
   js/v17.js injects max ONE row of glass trust chips under the
   header of every banded section (+ [data-v17-trust] hosts). */
.v17-trust-row {
  display: -webkit-flex;
  display: flex;
  -webkit-flex-wrap: wrap;
  flex-wrap: wrap;
  -webkit-justify-content: center;
  justify-content: center;
  -webkit-align-items: center;
  align-items: center;
  gap: 10px;
  margin-top: 18px;
}
.m-section-head > .v17-trust-row,
.section-header > .v17-trust-row {
  margin-top: 16px;
}
.v17-chip {
  display: -webkit-inline-flex;
  display: inline-flex;
  -webkit-align-items: center;
  align-items: center;
  gap: 8px;
  padding: 7px 14px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: rgba(255, 255, 255, 0.85);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  line-height: 1;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  -webkit-box-shadow: var(--v17-inset-top);
  box-shadow: var(--v17-inset-top);
  white-space: nowrap;
}
/* light-section variant (chips also render on [data-v17-trust]
   hosts that are not bands) */
.v17-seen:not(.v17-band):not(.v17-band--soft) .v17-chip {
  background: rgba(10, 22, 40, 0.045);
  border-color: rgba(46, 134, 222, 0.22);
  color: #14416b;
}
.v17-chip .v17-chip-dot {
  -webkit-flex: 0 0 auto;
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: linear-gradient(135deg, #00b4d8, #48cae4);
  -webkit-box-shadow: 0 0 8px rgba(0, 180, 216, 0.8);
  box-shadow: 0 0 8px rgba(0, 180, 216, 0.8);
}
.v17-chip .v17-chip-dot--warm {
  background: linear-gradient(135deg, #ff6b35, #ff8c42);
  -webkit-box-shadow: 0 0 8px rgba(255, 107, 53, 0.8);
  box-shadow: 0 0 8px rgba(255, 107, 53, 0.8);
}
.v17-chip svg {
  -webkit-flex: 0 0 auto;
  flex: 0 0 auto;
  color: var(--v17-cyan-2, #48cae4);
}

/* ===================== 09. GLASS CARDS v2 (.v17-card) =====================
   js/v17.js tags the site's card families inside seen sections
   with .v17-card. Layers:
     - element background: cursor-follow glare radial (position
       fed as --v17gx / --v17gy by JS, repaint-only) + glass ramp
     - inset 1px hairline via box-shadow (cheap, composited)
     - ::before — numbered corner chip (bento grids only)
     - ::after  — diagonal glare sweep on hover (0.9s, transform)
   Transitions touch transform/opacity/box-shadow ONLY. */
.v17-card {
  position: relative;
  border-radius: var(--v17-r, 20px);
  background:
    radial-gradient(
      320px circle at var(--v17gx, 50%) var(--v17gy, -20%),
      rgba(255, 255, 255, 0.13),
      rgba(255, 255, 255, 0.05) 42%,
      transparent 68%
    ),
    linear-gradient(160deg, rgba(255, 255, 255, 0.075) 0%, rgba(255, 255, 255, 0.028) 58%, rgba(255, 255, 255, 0.05) 100%);
  -webkit-box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.14),
    inset 0 1px 0 rgba(255, 255, 255, 0.13),
    0 14px 40px -14px rgba(7, 17, 32, 0.22);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.14),
    inset 0 1px 0 rgba(255, 255, 255, 0.13),
    0 14px 40px -14px rgba(7, 17, 32, 0.22);
  -webkit-transition:
    -webkit-transform var(--v17-dur) var(--v17-ease),
    -webkit-box-shadow var(--v17-dur) var(--v17-ease);
  transition:
    transform var(--v17-dur) var(--v17-ease),
    box-shadow var(--v17-dur) var(--v17-ease);
}
/* light sections: white glass reads as a soft frost */
.v17-seen:not(.v17-band):not(.v17-band--soft) .v17-card {
  background:
    radial-gradient(
      320px circle at var(--v17gx, 50%) var(--v17gy, -20%),
      rgba(255, 255, 255, 0.85),
      rgba(255, 255, 255, 0.4) 42%,
      transparent 68%
    ),
    linear-gradient(160deg, #ffffff 0%, #fbfdff 58%, #f4f8fc 100%);
  -webkit-box-shadow:
    inset 0 0 0 1px rgba(10, 22, 40, 0.07),
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    0 14px 40px -14px rgba(7, 17, 32, 0.16);
  box-shadow:
    inset 0 0 0 1px rgba(10, 22, 40, 0.07),
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    0 14px 40px -14px rgba(7, 17, 32, 0.16);
}
/* v17.1: light-card hover — cyan hairline + deeper lift + a faint
   brand-tinted aura under the card (still all box-shadow channel:
   composited, no repaints) */
.v17-seen:not(.v17-band):not(.v17-band--soft) .v17-card:hover {
  -webkit-box-shadow:
    inset 0 0 0 1px rgba(0, 180, 216, 0.38),
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    0 26px 60px -16px rgba(10, 22, 40, 0.22),
    0 12px 44px -18px rgba(0, 180, 216, 0.30);
  box-shadow:
    inset 0 0 0 1px rgba(0, 180, 216, 0.38),
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    0 26px 60px -16px rgba(10, 22, 40, 0.22),
    0 12px 44px -18px rgba(0, 180, 216, 0.30);
}
/* cards inside bands: deeper glass + cyan ring on hover */
.v17-band .v17-card:hover,
.v17-band--soft .v17-card:hover {
  -webkit-box-shadow:
    inset 0 0 0 1px rgba(72, 202, 228, 0.5),
    inset 0 1px 0 rgba(255, 255, 255, 0.2),
    0 26px 64px -16px rgba(0, 0, 0, 0.66),
    0 0 48px -12px rgba(0, 180, 216, 0.38);
  box-shadow:
    inset 0 0 0 1px rgba(72, 202, 228, 0.5),
    inset 0 1px 0 rgba(255, 255, 255, 0.2),
    0 26px 64px -16px rgba(0, 0, 0, 0.66),
    0 0 48px -12px rgba(0, 180, 216, 0.38);
}
/* — 3D tilt consumed from JS-fed custom properties (JS never
   writes style.transform on these cards). The hover lift REPEATS
   the tilt channel so hovering never cancels an active tilt — */
.v17-card {
  -webkit-transform: perspective(900px) rotateX(var(--v17rx, 0deg)) rotateY(var(--v17ry, 0deg));
  transform: perspective(900px) rotateX(var(--v17rx, 0deg)) rotateY(var(--v17ry, 0deg));
}
.v17-card:hover {
  -webkit-transform: perspective(900px) rotateX(var(--v17rx, 0deg)) rotateY(var(--v17ry, 0deg)) translateY(-6px) scale(1.015);
  transform: perspective(900px) rotateX(var(--v17rx, 0deg)) rotateY(var(--v17ry, 0deg)) translateY(-6px) scale(1.015);
  -webkit-box-shadow:
    inset 0 0 0 1px rgba(72, 202, 228, 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.22),
    0 26px 60px -16px rgba(7, 17, 32, 0.34),
    0 0 44px -14px rgba(0, 180, 216, 0.30);
  box-shadow:
    inset 0 0 0 1px rgba(72, 202, 228, 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.22),
    0 26px 60px -16px rgba(7, 17, 32, 0.34),
    0 0 44px -14px rgba(0, 180, 216, 0.30);
}
.v17-card.v17-tilting {
  -webkit-transition: -webkit-box-shadow var(--v17-dur) var(--v17-ease);
  transition: box-shadow var(--v17-dur) var(--v17-ease);
}
/* — glare sweep: diagonal light bar translating across on hover — */
.v17-card::after {
  content: "";
  position: absolute;
  top: -22%;
  bottom: -22%;
  left: -34%;
  width: 36%;
  z-index: 2;
  border-radius: inherit;
  background: linear-gradient(
    104deg,
    transparent 0%,
    rgba(255, 255, 255, 0.06) 32%,
    rgba(255, 255, 255, 0.18) 47%,
    rgba(255, 255, 255, 0.30) 50%,
    rgba(255, 255, 255, 0.18) 53%,
    rgba(255, 255, 255, 0.06) 68%,
    transparent 100%
  );
  -webkit-transform: skewX(-16deg) translateX(0);
  transform: skewX(-16deg) translateX(0);
  opacity: 0;
  pointer-events: none;
}
.v17-card:hover::after {
  opacity: 1;
  -webkit-animation: v17GlareSweep var(--v17-dur-glare, 0.9s) var(--v17-ease-out);
  animation: v17GlareSweep var(--v17-dur-glare, 0.9s) var(--v17-ease-out);
}
@keyframes v17GlareSweep {
  from { -webkit-transform: skewX(-16deg) translateX(0); transform: skewX(-16deg) translateX(0); }
  to   { -webkit-transform: skewX(-16deg) translateX(460%); transform: skewX(-16deg) translateX(460%); }
}
/* v17 cards must never swallow content clicks — the sweep layer
   and chip stay pointer-transparent (set above) and content sits
   above the glare ring where stacking matters */
.v17-card > * { position: relative; }

/* ===================== 10. BENTO GRID =====================
   js/v17.js tags qualifying card grids (>= 3 cards) with
   .v17-bento and gives the first card .span-2. The grid keeps
   whatever column template the page already ships (auto-fit in
   modern.css, fixed in React <style> tags) — v17 only adds dense
   flow + span utilities, so nothing can break; on narrow screens
   the utilities collapse to auto. */
.v17-bento {
  grid-auto-flow: dense;
}
@media (min-width: 900px) {
  .v17-bento .span-2 { grid-column: span 2; }
  .v17-bento .row-2 { grid-row: span 2; }
  .v17-bento .span-2.row-2 { grid-column: span 2; grid-row: span 2; }
}
/* the enlarged first card gets a hero-grade surface */
.v17-bento > .span-2.v17-card {
  background:
    radial-gradient(
      420px circle at var(--v17gx, 50%) var(--v17gy, -20%),
      rgba(255, 255, 255, 0.14),
      rgba(255, 255, 255, 0.05) 44%,
      transparent 70%
    ),
    radial-gradient(340px 200px at 88% -12%, rgba(0, 180, 216, 0.14), transparent 64%),
    radial-gradient(300px 190px at 4% 112%, rgba(255, 107, 53, 0.10), transparent 62%),
    linear-gradient(160deg, rgba(255, 255, 255, 0.085) 0%, rgba(255, 255, 255, 0.03) 58%, rgba(255, 255, 255, 0.055) 100%);
}
.v17-seen:not(.v17-band):not(.v17-band--soft) .v17-bento > .span-2.v17-card {
  background:
    radial-gradient(340px 200px at 88% -12%, rgba(0, 180, 216, 0.10), transparent 64%),
    radial-gradient(300px 190px at 4% 112%, rgba(255, 107, 53, 0.08), transparent 62%),
    linear-gradient(160deg, #ffffff 0%, #fbfdff 58%, #f2f7fc 100%);
}

/* — numbered corner chips (01 / 02 / 03 …) via a CSS counter on
   the grid; painted by the card's ::before — */
.v17-bento {
  counter-reset: v17num;
}
.v17-bento > .v17-card::before {
  content: counter(v17num, decimal-leading-zero);
  counter-increment: v17num;
  position: absolute;
  top: 12px;
  right: 14px;
  z-index: 3;
  display: -webkit-inline-flex;
  display: inline-flex;
  -webkit-align-items: center;
  align-items: center;
  padding: 4px 9px;
  border-radius: 8px;
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  line-height: 1;
  color: rgba(255, 255, 255, 0.55);
  background: rgba(10, 22, 40, 0.30);
  border: 1px solid rgba(255, 255, 255, 0.14);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  pointer-events: none;
  -webkit-transition: color var(--v17-dur-fast) var(--v17-ease),
    background var(--v17-dur-fast) var(--v17-ease);
  transition: color var(--v17-dur-fast) var(--v17-ease),
    background var(--v17-dur-fast) var(--v17-ease);
}
.v17-bento > .v17-card:hover::before {
  color: rgba(255, 255, 255, 0.92);
  background: rgba(10, 22, 40, 0.46);
}
.v17-seen:not(.v17-band):not(.v17-band--soft) .v17-bento > .v17-card::before {
  color: rgba(10, 22, 40, 0.5);
  background: rgba(10, 22, 40, 0.05);
  border-color: rgba(10, 22, 40, 0.10);
}
.v17-seen:not(.v17-band):not(.v17-band--soft) .v17-bento > .v17-card:hover::before {
  color: rgba(10, 22, 40, 0.85);
  background: rgba(10, 22, 40, 0.09);
}
/* cards that already paint their own ::before (m-beam ring)
   cannot host the chip — silently skip them */
.v17-bento > .m-beam::before { content: none; }

/* ===================== 11. BUTTONS v2 (.v17-btn2) =====================
   js/v17.js tags call-to-action buttons inside seen sections
   (never inside the protected zones, so the homepage hero's
   .btn-primary keeps its original paint). Variants:
     .v17-btn2            — orange gradient primary
     .v17-btn2--cool      — cyan/blue gradient
     .v17-btn2--glass     — glass secondary (outline/ghost) */
.v17-btn2 {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  display: -webkit-inline-flex;
  display: inline-flex;
  -webkit-align-items: center;
  align-items: center;
  -webkit-justify-content: center;
  justify-content: center;
  gap: 9px;
  border: none;
  border-radius: 999px;
  cursor: pointer;
  font-family: inherit;
  font-size: 0.95rem;
  font-weight: 800;
  letter-spacing: 0.01em;
  line-height: 1;
  padding: 15px 28px;
  color: #ffffff;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  background: linear-gradient(180deg, #ff8c42 0%, #ff6b35 58%, #e55a28 100%);
  -webkit-box-shadow:
    var(--v17-glow-btn),
    inset 0 1px 0 rgba(255, 255, 255, 0.38),
    inset 0 -2px 6px rgba(120, 30, 0, 0.28);
  box-shadow:
    var(--v17-glow-btn),
    inset 0 1px 0 rgba(255, 255, 255, 0.38),
    inset 0 -2px 6px rgba(120, 30, 0, 0.28);
  -webkit-transition:
    -webkit-transform 0.22s var(--v17-ease-spring),
    -webkit-box-shadow var(--v17-dur-fast) var(--v17-ease);
  transition:
    transform 0.22s var(--v17-ease-spring),
    box-shadow var(--v17-dur-fast) var(--v17-ease);
}
.v17-btn2 > * { position: relative; z-index: 2; }
.v17-btn2:hover {
  -webkit-transform: translateY(-3px);
  transform: translateY(-3px);
  -webkit-box-shadow:
    var(--v17-glow-btn-hover),
    inset 0 1px 0 rgba(255, 255, 255, 0.45),
    inset 0 -2px 6px rgba(120, 30, 0, 0.28);
  box-shadow:
    var(--v17-glow-btn-hover),
    inset 0 1px 0 rgba(255, 255, 255, 0.45),
    inset 0 -2px 6px rgba(120, 30, 0, 0.28);
}
.v17-btn2:active {
  -webkit-transform: translateY(-1px) scale(0.97);
  transform: translateY(-1px) scale(0.97);
}
.v17-btn2.btn-lg { padding: 18px 34px; font-size: 1.02rem; }
.v17-btn2.btn-sm { padding: 11px 20px; font-size: 0.86rem; }
.v17-btn2:focus-visible {
  outline: 2px solid var(--v17-cyan-2, #48cae4);
  outline-offset: 3px;
}
/* — shine sweep (replaces main.css's flatter .btn-primary::after;
   same DOM hook, richer light) — */
.v17-btn2::after {
  content: "";
  position: absolute;
  top: -20%;
  bottom: -20%;
  left: -32%;
  width: 34%;
  z-index: 1;
  background: linear-gradient(
    100deg,
    transparent 0%,
    rgba(255, 255, 255, 0.10) 34%,
    rgba(255, 255, 255, 0.42) 50%,
    rgba(255, 255, 255, 0.10) 66%,
    transparent 100%
  );
  -webkit-transform: skewX(-18deg) translateX(0);
  transform: skewX(-18deg) translateX(0);
  pointer-events: none;
}
.v17-btn2:hover::after {
  -webkit-animation: v17BtnShine 0.9s var(--v17-ease-out);
  animation: v17BtnShine 0.9s var(--v17-ease-out);
}
@keyframes v17BtnShine {
  from { -webkit-transform: skewX(-18deg) translateX(0); transform: skewX(-18deg) translateX(0); }
  to   { -webkit-transform: skewX(-18deg) translateX(430%); transform: skewX(-18deg) translateX(430%); }
}
/* — cool (cyan) variant — */
.v17-btn2--cool {
  background: linear-gradient(180deg, #35a5e6 0%, #2e86de 55%, #1e69b8 100%);
  -webkit-box-shadow:
    0 8px 24px -8px rgba(46, 134, 222, 0.60),
    inset 0 1px 0 rgba(255, 255, 255, 0.34),
    inset 0 -2px 6px rgba(10, 40, 80, 0.30);
  box-shadow:
    0 8px 24px -8px rgba(46, 134, 222, 0.60),
    inset 0 1px 0 rgba(255, 255, 255, 0.34),
    inset 0 -2px 6px rgba(10, 40, 80, 0.30);
}
.v17-btn2--cool:hover {
  -webkit-box-shadow:
    0 12px 34px -8px rgba(46, 134, 222, 0.75),
    inset 0 1px 0 rgba(255, 255, 255, 0.4),
    inset 0 -2px 6px rgba(10, 40, 80, 0.30);
  box-shadow:
    0 12px 34px -8px rgba(46, 134, 222, 0.75),
    inset 0 1px 0 rgba(255, 255, 255, 0.4),
    inset 0 -2px 6px rgba(10, 40, 80, 0.30);
}
/* — glass secondary — */
.v17-btn2--glass {
  background: rgba(255, 255, 255, 0.08);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  -webkit-box-shadow:
    inset 0 0 0 1.5px rgba(255, 255, 255, 0.32),
    inset 0 1px 0 rgba(255, 255, 255, 0.18);
  box-shadow:
    inset 0 0 0 1.5px rgba(255, 255, 255, 0.32),
    inset 0 1px 0 rgba(255, 255, 255, 0.18);
  color: #ffffff;
}
.v17-seen:not(.v17-band):not(.v17-band--soft) .v17-btn2--glass {
  background: rgba(10, 22, 40, 0.05);
  color: #0a1628;
  -webkit-box-shadow:
    inset 0 0 0 1.5px rgba(10, 22, 40, 0.22),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
  box-shadow:
    inset 0 0 0 1.5px rgba(10, 22, 40, 0.22),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
}
.v17-btn2--glass:hover {
  background: rgba(255, 255, 255, 0.14);
  -webkit-box-shadow:
    inset 0 0 0 1.5px rgba(255, 255, 255, 0.55),
    inset 0 1px 0 rgba(255, 255, 255, 0.26);
  box-shadow:
    inset 0 0 0 1.5px rgba(255, 255, 255, 0.55),
    inset 0 1px 0 rgba(255, 255, 255, 0.26);
}
.v17-seen:not(.v17-band):not(.v17-band--soft) .v17-btn2--glass:hover {
  background: rgba(10, 22, 40, 0.09);
  -webkit-box-shadow:
    inset 0 0 0 1.5px rgba(10, 22, 40, 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
  box-shadow:
    inset 0 0 0 1.5px rgba(10, 22, 40, 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
}
/* — arrow nudge — */
.v17-btn2 svg {
  -webkit-transition: -webkit-transform var(--v17-dur-fast) var(--v17-ease);
  transition: transform var(--v17-dur-fast) var(--v17-ease);
}
.v17-btn2:hover svg.btn-arrow,
.v17-btn2:hover > svg {
  -webkit-transform: translateX(4px);
  transform: translateX(4px);
}

/* — magnetic pull (class + vars driven by js/v17.js; no DOM
   reparenting, so React-owned buttons are safe). --v17mx/--v17my
   = button pull (max 10px), --v17lx/--v17ly = label counter-
   translate (max 4px) — */
.v17-btn-magnet,
.v17-btn-magnet.v17-btn-magnet {
  -webkit-transform: translate(var(--v17mx, 0px), var(--v17my, 0px));
  transform: translate(var(--v17mx, 0px), var(--v17my, 0px));
  -webkit-transition: -webkit-transform 0.3s var(--v17-ease-spring);
  transition: transform 0.3s var(--v17-ease-spring);
}
/* the doubled class above out-ranks .v17-btn2:hover on purpose:
   for magnet buttons the pull IS the hover motion (the glow +
   shine sweep still fire) */
.v17-btn-magnet.v17-mag-live {
  -webkit-transition: none;
  transition: none; /* while tracking, JS lerps; on leave the
                       spring transition takes over again */
}
.v17-btn-magnet .v17-btn-label,
.v17-btn-magnet svg {
  -webkit-transform: translate(var(--v17lx, 0px), var(--v17ly, 0px));
  transform: translate(var(--v17lx, 0px), var(--v17ly, 0px));
  -webkit-transition: -webkit-transform 0.3s var(--v17-ease-spring);
  transition: transform 0.3s var(--v17-ease-spring);
}
.v17-btn-magnet.v17-mag-live .v17-btn-label,
.v17-btn-magnet.v17-mag-live svg { -webkit-transition: none; transition: none; }

/* ===================== 12. MARQUEE v2 (.v17-marquee) =====================
   Built by js/v17.js from [data-v17-marquee] lists and
   .brand-strip hosts: children get cloned twice inside one
   track (data-v17-clone="2"), the viewport is edge-faded with a
   mask, the loop is a pure translateX, and hover/focus pauses
   it. Without JS the host stays a normal static list. */
.v17-marquee {
  position: relative;
  overflow: hidden;
  display: -webkit-flex;
  display: flex;
  -webkit-align-items: center;
  align-items: center;
  min-height: 56px;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 7%, #000 93%, transparent 100%);
}
.v17-marquee-track {
  display: -webkit-flex;
  display: flex;
  -webkit-align-items: center;
  align-items: center;
  gap: 44px;
  width: -webkit-max-content;
  width: max-content;
  padding: 12px 0;
  will-change: transform;
}
.v17-marquee[data-v17-clone] .v17-marquee-track {
  -webkit-animation: v17Marquee var(--v17-mq-dur, 40s) linear infinite;
  animation: v17Marquee var(--v17-mq-dur, 40s) linear infinite;
}
.v17-marquee[data-v17-clone]:hover .v17-marquee-track,
.v17-marquee[data-v17-clone]:focus-within .v17-marquee-track {
  -webkit-animation-play-state: paused;
  animation-play-state: paused;
}
.v17-marquee[data-v17-dir="reverse"] .v17-marquee-track {
  -webkit-animation-direction: reverse;
  animation-direction: reverse;
}
@keyframes v17Marquee {
  from { -webkit-transform: translateX(0); transform: translateX(0); }
  to   { -webkit-transform: translateX(-50%); transform: translateX(-50%); }
}
.v17-mq-item {
  display: -webkit-inline-flex;
  display: inline-flex;
  -webkit-align-items: center;
  align-items: center;
  gap: 11px;
  color: rgba(255, 255, 255, 0.85);
  font-size: 0.88rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.v17-mq-item svg { color: var(--v17-cyan, #00b4d8); -webkit-flex: 0 0 auto; flex: 0 0 auto; }
/* brand-logo variant: monochrome at rest, full color + lift on hover */
.v17-marquee--brands .v17-mq-item img {
  height: 44px;
  width: auto;
  opacity: 0.62;
  -webkit-filter: grayscale(0.85);
  filter: grayscale(0.85);
  -webkit-transition: opacity var(--v17-dur-fast) var(--v17-ease),
    -webkit-filter var(--v17-dur-fast) var(--v17-ease),
    -webkit-transform var(--v17-dur-fast) var(--v17-ease);
  transition: opacity var(--v17-dur-fast) var(--v17-ease),
    filter var(--v17-dur-fast) var(--v17-ease),
    transform var(--v17-dur-fast) var(--v17-ease);
}
.v17-marquee--brands .v17-mq-item:hover img {
  opacity: 1;
  -webkit-filter: grayscale(0);
  filter: grayscale(0);
  -webkit-transform: translateY(-2px) scale(1.04);
  transform: translateY(-2px) scale(1.04);
}
/* light-surface variant */
.v17-marquee--light .v17-mq-item { color: rgba(10, 22, 40, 0.72); }

/* — composition polish for the v15 trust strip (already injected
   under internal-page heroes): same edge-fade, calmer items — */
.v15-marquee {
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%);
  background: linear-gradient(180deg, #0a1628 0%, #0d1f3c 100%);
}
.v15-marquee::before,
.v15-marquee::after { display: none; } /* mask replaces the fades */
.v15-marquee-item { font-weight: 700; }

/* ===================== 13. STATS =====================
   .v17-stat is a v17-owned numeral block (markup hook or built
   by v17 components). js/v17.js count-ups the number and keeps
   the final text exactly as authored. */
.v17-stat {
  display: block;
  font-size: clamp(2.1rem, 4.4vw, 3.1rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.02;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(100deg, #ffffff 0%, #dff6fd 40%, #48cae4 80%, #00b4d8 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
.v17-seen:not(.v17-band):not(.v17-band--soft) .v17-stat {
  background: linear-gradient(100deg, #0a1628 0%, #14416b 38%, #00b4d8 82%, #48cae4 100%);
  -webkit-background-clip: text;
  background-clip: text;
}
.v17-stat--warm {
  background: linear-gradient(100deg, #ffffff 0%, #ffe3d3 42%, #ff8c42 82%, #ff6b35 100%) !important;
  -webkit-background-clip: text;
  background-clip: text;
}
.v17-stat-label {
  display: block;
  margin-top: 8px;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.56);
}
.v17-seen:not(.v17-band):not(.v17-band--soft) .v17-stat-label {
  color: #4a5568;
}

/* ===================== 14. REVEAL ENGINE v2 =====================
   [data-v17-reveal] + JS-claimed stragglers get .v17-r (hidden
   state) ONLY after the observer is live, then .v17-in once 15%
   visible. blur + translateY + scale -> sharp. Stagger comes from
   --v17-i (70ms steps, capped at 8 by JS). One-shot. */
.v17-r {
  opacity: 0;
  -webkit-transform: translateY(28px) scale(0.98);
  transform: translateY(28px) scale(0.98);
  -webkit-filter: blur(10px);
  filter: blur(10px);
  -webkit-transition:
    opacity var(--v17-dur-slow) var(--v17-ease-out),
    -webkit-transform var(--v17-dur-slow) var(--v17-ease-out),
    -webkit-filter var(--v17-dur-slow) var(--v17-ease-out);
  transition:
    opacity var(--v17-dur-slow) var(--v17-ease-out),
    transform var(--v17-dur-slow) var(--v17-ease-out),
    filter var(--v17-dur-slow) var(--v17-ease-out);
  -webkit-transition-delay: calc(var(--v17-i, 0) * 70ms);
  transition-delay: calc(var(--v17-i, 0) * 70ms);
  will-change: transform, opacity, filter;
}
.v17-r.v17-in {
  opacity: 1;
  -webkit-transform: none;
  transform: none;
  -webkit-filter: none;
  filter: none;
  will-change: auto;
}
/* no-JS / failed-observer safety: never leave content hidden */
@supports not (transform: translateY(1px)) {
  .v17-r { opacity: 1; -webkit-transform: none; transform: none; -webkit-filter: none; filter: none; }
}

/* ===================== 15. FORMS =====================
   Scoped to the site's CONTENT forms only:
     .quote-form-wrap (3-step quote form, 855 pages)
     .v17-form / .contact-form / .booking form / #faq form
     .m-section form (modern.css content sections)
   The homepage hero form (.hero-contact-form + .hcf-input) is
   NOT in any of these scopes and keeps its original paint. */
.quote-form-wrap input[type="text"],
.quote-form-wrap input[type="tel"],
.quote-form-wrap input[type="email"],
.quote-form-wrap input[type="number"],
.quote-form-wrap input[type="search"],
.quote-form-wrap input:not([type]),
.quote-form-wrap select,
.quote-form-wrap textarea,
.v17-form input,
.v17-form select,
.v17-form textarea,
.contact-form input,
.contact-form select,
.contact-form textarea,
.booking form input,
.booking form select,
.booking form textarea,
#faq form input,
#faq form select,
#faq form textarea,
.m-section form input[type="text"],
.m-section form input[type="tel"],
.m-section form input[type="email"],
.m-section form select,
.m-section form textarea {
  border-radius: var(--v17-r-sm, 14px);
  border: 1.5px solid rgba(10, 22, 40, 0.14);
  background: rgba(255, 255, 255, 0.85);
  -webkit-box-shadow: inset 0 1px 2px rgba(10, 22, 40, 0.05);
  box-shadow: inset 0 1px 2px rgba(10, 22, 40, 0.05);
  color: #0a1628;
  font-family: inherit;
  -webkit-transition:
    border-color var(--v17-dur-fast) var(--v17-ease),
    -webkit-box-shadow var(--v17-dur-fast) var(--v17-ease),
    background var(--v17-dur-fast) var(--v17-ease);
  transition:
    border-color var(--v17-dur-fast) var(--v17-ease),
    box-shadow var(--v17-dur-fast) var(--v17-ease),
    background var(--v17-dur-fast) var(--v17-ease);
}
.quote-form-wrap input:focus,
.quote-form-wrap select:focus,
.quote-form-wrap textarea:focus,
.v17-form input:focus,
.v17-form select:focus,
.v17-form textarea:focus,
.contact-form input:focus,
.contact-form select:focus,
.contact-form textarea:focus,
.booking form input:focus,
.booking form select:focus,
.booking form textarea:focus,
#faq form input:focus,
#faq form select:focus,
#faq form textarea:focus,
.m-section form input:focus,
.m-section form select:focus,
.m-section form textarea:focus {
  outline: none;
  border-color: var(--v17-cyan, #00b4d8);
  background: #ffffff;
  -webkit-box-shadow:
    0 0 0 4px rgba(0, 180, 216, 0.16),
    inset 0 1px 2px rgba(10, 22, 40, 0.04);
  box-shadow:
    0 0 0 4px rgba(0, 180, 216, 0.16),
    inset 0 1px 2px rgba(10, 22, 40, 0.04);
}
/* floating-label friendly: labels read as calm small caps */
.quote-form-wrap label,
.v17-form label,
.contact-form label,
.booking form label,
.m-section form label {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(10, 22, 40, 0.55);
}
/* select chevron */
.quote-form-wrap select,
.v17-form select,
.contact-form select,
.booking form select,
.m-section form select {
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2300b4d8' stroke-width='2.5' stroke-linecap='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 38px;
}
/* error / success states */
.quote-form-wrap .qf-input[aria-invalid="true"],
.v17-form input[aria-invalid="true"],
.v17-form select[aria-invalid="true"],
.v17-form textarea[aria-invalid="true"],
.contact-form input[aria-invalid="true"] {
  border-color: #e74c3c;
  -webkit-box-shadow: 0 0 0 4px rgba(231, 76, 60, 0.14);
  box-shadow: 0 0 0 4px rgba(231, 76, 60, 0.14);
}
.quote-form-wrap .qf-error {
  color: #d64541;
  font-size: 0.78rem;
  font-weight: 600;
}
.v17-form-success,
.contact-form .form-success {
  border-radius: var(--v17-r-sm, 14px);
  background: rgba(46, 204, 113, 0.10);
  border: 1px solid rgba(46, 204, 113, 0.35);
  color: #1b7a45;
  font-weight: 600;
}
/* form cards themselves get the v17 frost */
.quote-form-card,
.quote-form-wrap {
  border-radius: var(--v17-r, 20px);
}
/* submit buttons inside these forms inherit the v17 primary skin
   once js/v17.js tags them (.v17-btn2) — CSS above handles it */

/* ===================== 16. FOOTER =====================
   Immersive navy: animated top hairline, cyan-ticked column
   titles, slide-underlines on links, emphasized license + phone
   in the bottom bar. Three footers ship on this site, all covered:
     footer.footer      — static internal pages (main.css)
     footer.site-footer — legacy/alternate class name
     footer#footer      — the React homepage footer (inline-styled:
                          only the shell can be repainted — the
                          aurora base needs !important to beat its
                          inline #0A1628; its inline-owned children
                          stay React's business)
   None of them can appear inside the protected hero zones. */
footer.footer,
footer.site-footer {
  background:
    radial-gradient(900px 400px at 88% -10%, rgba(0, 180, 216, 0.09), transparent 62%),
    radial-gradient(700px 380px at 6% 108%, rgba(255, 107, 53, 0.07), transparent 60%),
    linear-gradient(175deg, #071120 0%, #0a1628 46%, #0d1f3c 100%);
  -webkit-box-shadow: 0 -30px 80px -40px rgba(7, 17, 32, 0.8);
  box-shadow: 0 -30px 80px -40px rgba(7, 17, 32, 0.8);
}
/* — React homepage footer shell (see block comment above) — */
footer#footer {
  position: relative;
  isolation: isolate;
  background:
    radial-gradient(900px 400px at 88% -10%, rgba(0, 180, 216, 0.09), transparent 62%),
    radial-gradient(700px 380px at 6% 108%, rgba(255, 107, 53, 0.07), transparent 60%),
    linear-gradient(175deg, #071120 0%, #0a1628 46%, #0d1f3c 100%) !important;
  -webkit-box-shadow: 0 -30px 80px -40px rgba(7, 17, 32, 0.8);
  box-shadow: 0 -30px 80px -40px rgba(7, 17, 32, 0.8);
}
/* — animated gradient hairline across the top edge — */
footer.footer::before,
footer.site-footer::before,
footer#footer::before {
  content: "";
  position: absolute;
  top: 0;
  left: -60%;
  width: 220%;
  height: 3px;
  background: linear-gradient(
    90deg,
    rgba(0, 180, 216, 0) 0%,
    rgba(0, 180, 216, 0.85) 22%,
    rgba(72, 202, 228, 1) 40%,
    rgba(255, 140, 66, 0.9) 66%,
    rgba(255, 107, 53, 0.85) 82%,
    rgba(255, 107, 53, 0) 100%
  );
  /* v18 perf: the sweep is a translateX on an oversized pseudo —
     compositor-only (was: background-position animation) */
  -webkit-animation: v17FooterBeam 9s linear infinite;
  animation: v17FooterBeam 9s linear infinite;
  pointer-events: none;
  z-index: 2;
}
@keyframes v17FooterBeam {
  0%   { -webkit-transform: translateX(45%); transform: translateX(45%); }
  100% { -webkit-transform: translateX(-45%); transform: translateX(-45%); }
}
/* — column titles with a cyan tick — */
footer.footer .footer-col h4,
footer.site-footer .footer-col h4 {
  position: relative;
  padding-left: 16px;
  font-size: 0.82rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #ffffff;
}
footer.footer .footer-col h4::before,
footer.site-footer .footer-col h4::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.28em;
  width: 7px;
  height: 12px;
  border-radius: 3px;
  background: linear-gradient(180deg, #48cae4, #00b4d8);
  -webkit-box-shadow: 0 0 10px rgba(0, 180, 216, 0.55);
  box-shadow: 0 0 10px rgba(0, 180, 216, 0.55);
}
/* — links: slide-underline instead of the old nudge — */
footer.footer .footer-col ul a,
footer.site-footer .footer-col ul a {
  position: relative;
  width: -webkit-fit-content;
  width: fit-content;
  color: rgba(255, 255, 255, 0.66);
  -webkit-transform: none;
  transform: none;
  -webkit-transition: color var(--v17-dur-fast) var(--v17-ease);
  transition: color var(--v17-dur-fast) var(--v17-ease);
}
footer.footer .footer-col ul a::after,
footer.site-footer .footer-col ul a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -3px;
  height: 1.5px;
  border-radius: 99px;
  background: linear-gradient(90deg, #00b4d8, #48cae4);
  -webkit-transform: scaleX(0);
  transform: scaleX(0);
  -webkit-transform-origin: 0 50%;
  transform-origin: 0 50%;
  -webkit-transition: -webkit-transform var(--v17-dur-fast) var(--v17-ease);
  transition: transform var(--v17-dur-fast) var(--v17-ease);
}
footer.footer .footer-col ul a:hover,
footer.site-footer .footer-col ul a:hover {
  color: #ffffff;
  -webkit-transform: none;
  transform: none;
}
footer.footer .footer-col ul a:hover::after,
footer.site-footer .footer-col ul a:hover::after {
  -webkit-transform: scaleX(1);
  transform: scaleX(1);
}
/* — contact values: phone gets the hero treatment — */
footer.footer .footer-contact-item .value,
footer.site-footer .footer-contact-item .value {
  font-size: 1.02rem;
}
footer.footer .footer-contact-item a.value[href^="tel:"],
footer.site-footer .footer-contact-item a.value[href^="tel:"] {
  background: linear-gradient(100deg, #ffffff 20%, #48cae4 90%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  font-weight: 800;
  letter-spacing: 0.01em;
}
/* — socials: glass rings — */
footer.footer .footer-social,
footer.site-footer .footer-social {
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.12);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
footer.footer .footer-social:hover,
footer.site-footer .footer-social:hover {
  background: linear-gradient(135deg, rgba(46, 134, 222, 0.85), rgba(0, 180, 216, 0.85));
  border-color: transparent;
}
/* — bottom bar: license + phone emphasis — */
footer.footer .footer-bottom,
footer.site-footer .footer-bottom {
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(4, 9, 18, 0.5);
  padding-left: 0;
  padding-right: 0;
}
footer.footer .footer-bottom::before,
footer.site-footer .footer-bottom::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 50%;
  -webkit-transform: translateX(-50%);
  transform: translateX(-50%);
  width: min(320px, 40%);
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(72, 202, 228, 0.5), transparent);
  pointer-events: none;
}
footer.footer .footer-bottom a,
footer.site-footer .footer-bottom a {
  -webkit-transition: color var(--v17-dur-fast) var(--v17-ease);
  transition: color var(--v17-dur-fast) var(--v17-ease);
}
footer.footer .footer-bottom strong,
footer.site-footer .footer-bottom strong {
  color: #ffffff;
  font-weight: 800;
}

/* ===================== 17. EMERGENCY PULSE =====================
   js/v17.js tags emergency CTAs with .v17-pulse. v18 perf: the
   ping ring is a scaling ::after (transform+opacity only). */
/* v18 perf: the ring now runs on a ::after that scales + fades
   (compositor-only) instead of animating box-shadow (paint). */
.v17-pulse {
  position: relative;
}
.v17-pulse::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: inherit;
  border: 2px solid rgba(255, 107, 53, 0.55);
  opacity: 0;
  pointer-events: none;
  z-index: -1;
  -webkit-animation: v17PulseRingScale 2.6s var(--v17-ease-soft) infinite;
  animation: v17PulseRingScale 2.6s var(--v17-ease-soft) infinite;
}
@keyframes v17PulseRingScale {
  0%   { opacity: 0.9; -webkit-transform: scale(1); transform: scale(1); }
  70%  { opacity: 0; -webkit-transform: scale(1.28); transform: scale(1.28); }
  100% { opacity: 0; -webkit-transform: scale(1.28); transform: scale(1.28); }
}
/* cyan variant for on-nav emergency chips */
.v17-pulse--cool::after {
  border-color: rgba(0, 180, 216, 0.6);
  -webkit-animation-name: v17PulseRingCool;
  animation-name: v17PulseRingCool;
}
@keyframes v17PulseRingCool {
  0%   { opacity: 0.85; -webkit-transform: scale(1); transform: scale(1); }
  70%  { opacity: 0; -webkit-transform: scale(1.3); transform: scale(1.3); }
  100% { opacity: 0; -webkit-transform: scale(1.3); transform: scale(1.3); }
}

/* ===================== 18. IMAGE TREATMENT (.v17-img) =====================
   js/v17.js tags suitable image wrappers (figure / picture /
   .svc-img-wrap / [data-v17-img]) inside seen sections. */
.v17-img {
  position: relative;
  overflow: hidden;
  overflow: clip;
  border-radius: 22px;
  -webkit-box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.16),
    0 18px 50px -18px rgba(7, 17, 32, 0.35);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.16),
    0 18px 50px -18px rgba(7, 17, 32, 0.35);
  -webkit-transform: translateZ(0);
  transform: translateZ(0); /* own layer so the inner zoom never
                               repaints neighbors */
}
.v17-seen:not(.v17-band):not(.v17-band--soft) .v17-img {
  -webkit-box-shadow:
    inset 0 0 0 1px rgba(10, 22, 40, 0.08),
    0 18px 50px -18px rgba(7, 17, 32, 0.22);
  box-shadow:
    inset 0 0 0 1px rgba(10, 22, 40, 0.08),
    0 18px 50px -18px rgba(7, 17, 32, 0.22);
}
/* gradient ring: a second inset stroke with the brand ramp */
.v17-img::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(135deg, rgba(72, 202, 228, 0.35), rgba(255, 140, 66, 0.28));
  padding: 1px;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0.7;
}
/* duotone veil that lifts on hover */
.v17-img::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(160deg, rgba(10, 22, 40, 0.30) 0%, rgba(0, 180, 216, 0.10) 60%, rgba(255, 107, 53, 0.10) 100%);
  mix-blend-mode: multiply;
  opacity: 0.45;
  -webkit-transition: opacity var(--v17-dur) var(--v17-ease);
  transition: opacity var(--v17-dur) var(--v17-ease);
}
.v17-img:hover::after { opacity: 0.08; }
.v17-img img,
.v17-img picture {
  display: block;
  width: 100%;
  -webkit-transform: scale(1.001);
  transform: scale(1.001);
  -webkit-transition: -webkit-transform var(--v17-dur-slow) var(--v17-ease);
  transition: transform var(--v17-dur-slow) var(--v17-ease);
  will-change: transform;
}
.v17-img:hover img {
  -webkit-transform: scale(1.03);
  transform: scale(1.03);
}

/* ===================== 19. DIVIDERS =====================
   js/v17.js lays a .v17-divider between consecutive top-level
   sections on static pages wherever at least one side is a band.
   A slow light pulse travels along the hairline
   (background-position — paint-only). */
.v17-divider {
  position: relative;
  height: 1px;
  border: none;
  margin: 0;
  overflow: visible;
  pointer-events: none;
}
.v17-divider::before {
  content: "";
  position: absolute;
  top: 0;
  left: -70%;
  width: 240%;
  height: 100%;
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(0, 180, 216, 0.28) 26%,
    rgba(72, 202, 228, 0.75) 50%,
    rgba(255, 140, 66, 0.30) 74%,
    rgba(255, 255, 255, 0) 100%
  );
  /* v18 perf: translateX sweep instead of background-position */
  -webkit-animation: v17DividerFlow 6s linear infinite;
  animation: v17DividerFlow 6s linear infinite;
  pointer-events: none;
  z-index: 3;
}
@keyframes v17DividerFlow {
  0%   { -webkit-transform: translateX(42%); transform: translateX(42%); }
  100% { -webkit-transform: translateX(-42%); transform: translateX(-42%); }
}
.v17-divider--static {
  -webkit-animation: none;
  animation: none;
  background-size: 100% 100%;
}
.v17-divider--half {
  margin-left: auto;
  margin-right: auto;
  width: min(560px, 72%);
}

/* ===================== 20. TABLE / FAQ / BREADCRUMB POLISH ===================== */
/* — pricing tables (light sections) — */
.m-table-wrap {
  border-radius: var(--v17-r, 20px);
  border: 1px solid rgba(10, 22, 40, 0.10);
  -webkit-box-shadow: var(--v17-shadow-md), inset 0 1px 0 rgba(255, 255, 255, 0.7);
  box-shadow: var(--v17-shadow-md), inset 0 1px 0 rgba(255, 255, 255, 0.7);
  overflow: hidden;
}
table.m-table { border-radius: inherit; }
table.m-table th {
  background: linear-gradient(135deg, #0a1628 0%, #14416b 60%, #0d1f3c 100%);
  color: #ffffff;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  -webkit-box-shadow: inset 0 -2px 0 rgba(0, 180, 216, 0.4);
  box-shadow: inset 0 -2px 0 rgba(0, 180, 216, 0.4);
}
table.m-table tbody tr {
  -webkit-transition: background var(--v17-dur-fast) var(--v17-ease);
  transition: background var(--v17-dur-fast) var(--v17-ease);
}
table.m-table tbody tr:hover {
  background: rgba(0, 180, 216, 0.06);
}
table.m-table td:first-child { font-weight: 700; color: #0a1628; }

/* — FAQ accordion polish (light sections; band variant in 05) — */
.m-faq-item {
  border-radius: var(--v17-r-sm, 14px);
  -webkit-transition: border-color var(--v17-dur-fast) var(--v17-ease),
    -webkit-box-shadow var(--v17-dur-fast) var(--v17-ease);
  transition: border-color var(--v17-dur-fast) var(--v17-ease),
    box-shadow var(--v17-dur-fast) var(--v17-ease);
}
.m-faq-item:hover {
  border-color: rgba(0, 180, 216, 0.35);
  -webkit-box-shadow: var(--v17-shadow-sm);
  box-shadow: var(--v17-shadow-sm);
}
.m-faq-item.open,
.m-faq-item[open] {
  border-color: rgba(0, 180, 216, 0.45);
  -webkit-box-shadow: var(--v17-shadow-md), 0 0 34px -14px rgba(0, 180, 216, 0.30);
  box-shadow: var(--v17-shadow-md), 0 0 34px -14px rgba(0, 180, 216, 0.30);
  background: linear-gradient(160deg, #ffffff 0%, #f6fbfe 100%);
}
/* chevron rotation already lives in modern.css; v17 adds the
   glow to the open state icon */
.m-faq-item.open .m-faq-icon {
  -webkit-box-shadow: 0 8px 20px -6px rgba(46, 134, 222, 0.55);
  box-shadow: 0 8px 20px -6px rgba(46, 134, 222, 0.55);
}

/* — breadcrumb pill (internal page heroes — NOT the homepage
   hero, which has no breadcrumb) — */
.page-hero .breadcrumb,
.bc-page-hero .breadcrumb {
  display: -webkit-inline-flex;
  display: inline-flex;
  -webkit-align-items: center;
  align-items: center;
  gap: 9px;
  padding: 8px 16px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.09);
  border: 1px solid rgba(255, 255, 255, 0.16);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
  font-size: 0.8rem;
}
.page-hero .breadcrumb a {
  color: rgba(255, 255, 255, 0.72);
  -webkit-transition: color var(--v17-dur-fast) var(--v17-ease);
  transition: color var(--v17-dur-fast) var(--v17-ease);
}
.page-hero .breadcrumb a:hover { color: #48cae4; }
.page-hero .breadcrumb .current,
.page-hero .breadcrumb [aria-current] { color: #ffffff; font-weight: 700; }

/* ===================== 21. SEASONAL ACCENTS =====================
   js/v17.js sets ONE of these on <html> from the visitor's
   month. They only retune the aurora veil colors inside the
   band custom properties — brand hues only, no new colors. */
html.v17-winter {
  /* Dec-Feb: icy cyan emphasis */
  --v17-aurora-c: rgba(0, 180, 216, 0.17);
  --v17-aurora-c2: rgba(72, 202, 228, 0.13);
  --v17-aurora-o: rgba(255, 107, 53, 0.07);
  --v17-aurora-o2: rgba(255, 140, 66, 0.06);
}
html.v17-spring {
  /* Mar-May: balanced blue-teal */
  --v17-aurora-c: rgba(46, 134, 222, 0.14);
  --v17-aurora-c2: rgba(0, 180, 216, 0.11);
  --v17-aurora-o: rgba(255, 107, 53, 0.09);
  --v17-aurora-o2: rgba(255, 140, 66, 0.07);
}
html.v17-summer {
  /* Jun-Aug: warm ember emphasis (cooling season) */
  --v17-aurora-c: rgba(0, 180, 216, 0.10);
  --v17-aurora-c2: rgba(72, 202, 228, 0.08);
  --v17-aurora-o: rgba(255, 107, 53, 0.16);
  --v17-aurora-o2: rgba(255, 140, 66, 0.12);
}
html.v17-fall {
  /* Sep-Nov: amber prep season */
  --v17-aurora-c: rgba(0, 180, 216, 0.10);
  --v17-aurora-c2: rgba(72, 202, 228, 0.08);
  --v17-aurora-o: rgba(255, 107, 53, 0.13);
  --v17-aurora-o2: rgba(255, 140, 66, 0.11);
}
/* section-specific tuning wins over seasonal (higher place in
   the cascade is not enough — the section rules set the vars on
   themselves, so they beat the html-level seasonal values by
   simple inheritance proximity). */

/* ===================== 22. RESPONSIVE + TOUCH GUARDS ===================== */
@media (max-width: 1023px) {
  .v17-progress-rail { display: none !important; }
}
@media (max-width: 768px) {
  /* bands keep the aurora but go cheaper: one static veil, no
     animation, no blur on card glass */
  .v17-band::before,
  .v17-band--soft::before {
    -webkit-animation: none;
    animation: none;
    inset: -20%;
    background:
      radial-gradient(ellipse 42% 40% at 24% 22%, var(--v17-aurora-c, rgba(0, 180, 216, 0.26)), transparent 68%),
      radial-gradient(var(--v17-grid-dot, rgba(255, 255, 255, 0.04)) 1px, transparent 1.4px);
    background-size: 100% 100%, 30px 30px;
  }
  .v17-band::after,
  .v17-band--soft::after {
    -webkit-animation: none;
    animation: none;
    inset: -20%;
    background:
      radial-gradient(ellipse 40% 38% at 76% 80%, var(--v17-aurora-o, rgba(255, 107, 53, 0.22)), transparent 70%);
  }
  .v17-band .m-card,
  .v17-band .service-card,
  .v17-band .feature-card,
  .v17-band .gr-card,
  .v17-band .card,
  .v17-band--soft .m-card,
  .v17-band--soft .card {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  /* cards full-width inside their grids */
  .v17-bento > * { grid-column: auto !important; grid-row: auto !important; }
  /* numbered chips off on small screens (density) */
  .v17-bento > .v17-card::before { display: none; }
  /* stats + headers tighten */
  .v17-seen .section-title,
  .v17-seen .m-h2 {
    font-size: clamp(1.7rem, 6.4vw, 2.3rem);
  }
  .v17-trust-row { gap: 8px; }
  .v17-chip { padding: 6px 12px; font-size: 0.68rem; }
  .v17-btn2 { padding: 14px 24px; font-size: 0.92rem; }
  .v17-img { border-radius: var(--v17-r, 20px); }
}
/* touch / coarse pointers: no hover-only effects */
@media (hover: none), (pointer: coarse) {
  .v17-card:hover {
    -webkit-transform: none;
    transform: none;
  }
  .v17-card:hover::after { -webkit-animation: none; animation: none; opacity: 0; }
  .v17-btn2:hover { -webkit-transform: none; transform: none; }
  .v17-btn2:hover::after { -webkit-animation: none; animation: none; }
  .v17-img:hover img { -webkit-transform: none; transform: none; }
  .v17-img:hover::after { opacity: 0.45; }
  .v17-marquee--brands .v17-mq-item img {
    opacity: 0.9;
    -webkit-filter: none;
    filter: none;
  }
  .v17-progress-rail { display: none !important; }
}

/* ===================== 23. REDUCED MOTION =====================
   ALL v17 motion off: transitions none, animations none, every
   reveal/underline/aurora state forced to its final resting
   paint. Content is never left hidden. */
@media (prefers-reduced-motion: reduce) {
  .v17-progress,
  .v17-progress-rail { display: none !important; }
  .v17-band::before,
  .v17-band::after,
  .v17-band--soft::before,
  .v17-band--soft::after,
  .v17-seen:not(.v17-band):not(.v17-band--soft)::before,
  .v17-seen:not(.v17-band):not(.v17-band--soft)::after,
  .v17-divider,
  footer.footer::before,
  footer.site-footer::before,
  footer#footer::before,
  .v17-pulse,
  .v17-pulse--cool,
  .v17-marquee[data-v17-clone] .v17-marquee-track,
  .v17-card::after,
  .v17-btn2::after,
  .v17-band .section-eyebrow::before,
  .v17-band .m-eyebrow::before,
  .v17-seen:not(.v17-band):not(.v17-band--soft) .section-eyebrow::before,
  .v17-seen:not(.v17-band):not(.v17-band--soft) .m-eyebrow::before {
    -webkit-animation: none !important;
    animation: none !important;
  }
  .v17-band::before,
  .v17-band::after,
  .v17-band--soft::before,
  .v17-band--soft::after,
  .v17-seen:not(.v17-band):not(.v17-band--soft)::before,
  .v17-seen:not(.v17-band):not(.v17-band--soft)::after {
    -webkit-animation: none !important;
    animation: none !important;
    -webkit-transform: none !important;
    transform: none !important;
  }
  .v17-card,
  .v17-btn2,
  .v17-btn-magnet,
  .v17-btn-magnet .v17-btn-label,
  .v17-btn-magnet svg,
  .v17-img img,
  .v17-img::after,
  .v17-underline::after,
  .v17-r,
  .v17-chip,
  .v17-seen .city-chip,
  .v17-seen .city-chip svg,
  .m-faq-item,
  .m-table-wrap,
  table.m-table tbody tr,
  .v17-marquee--brands .v17-mq-item img {
    -webkit-transition: none !important;
    transition: none !important;
  }
  .v17-seen .city-chip:hover {
    -webkit-transform: none !important;
    transform: none !important;
  }
  .v17-r {
    opacity: 1 !important;
    -webkit-transform: none !important;
    transform: none !important;
    -webkit-filter: none !important;
    filter: none !important;
  }
  .v17-underline::after {
    -webkit-transform: scaleX(1) !important;
    transform: scaleX(1) !important;
  }
  .v17-card,
  .v17-btn-magnet {
    -webkit-transform: none !important;
    transform: none !important;
  }
  .v17-btn-magnet .v17-btn-label,
  .v17-btn-magnet svg {
    -webkit-transform: none !important;
    transform: none !important;
  }
  .v17-img img { -webkit-transform: none !important; transform: none !important; }
  .v17-img::after { opacity: 0.12; }
}

/* ===================== 24. PRINT =====================
   Chrome off, bands flattened to paper, content intact. */
@media print {
  .v17-progress,
  .v17-progress-rail,
  .v17-divider,
  .v17-marquee,
  .v15-marquee,
  .v17-trust-row,
  .v17-pulse,
  .v17-card::after,
  .v17-card::before,
  .v17-btn2::after,
  footer#footer::before { display: none !important; }
  .v17-band,
  .v17-band--soft {
    background: #ffffff !important;
    background-image: none !important;
    color: #000000 !important;
    --color-text-dark: #0a1628;
    --color-text-medium: #2d3748;
    --color-text-light: #4a5568;
    --color-border: #d7dee8;
    overflow: visible;
  }
  .v17-band::before,
  .v17-band::after,
  .v17-band--soft::before,
  .v17-band--soft::after,
  .v17-seen:not(.v17-band):not(.v17-band--soft)::before,
  .v17-seen:not(.v17-band):not(.v17-band--soft)::after { display: none !important; }
  .v17-band h1, .v17-band h2, .v17-band h3, .v17-band h4,
  .v17-band--soft h1, .v17-band--soft h2, .v17-band--soft h3, .v17-band--soft h4 {
    color: #0a1628 !important;
    text-shadow: none !important;
  }
  .v17-band p, .v17-band li, .v17-band .section-subtitle,
  .v17-band--soft p, .v17-band--soft li {
    color: #2d3748 !important;
  }
  .v17-band .m-card,
  .v17-band .service-card,
  .v17-band .gr-card,
  .v17-band .card,
  .v17-band--soft .m-card,
  .v17-band--soft .card {
    background: #ffffff !important;
    -webkit-box-shadow: none !important;
    box-shadow: none !important;
    border: 1px solid #d7dee8 !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
  .v17-band .blog-grid > article,
  .v17-band .financing-grid > div {
    background: #ffffff !important;
    border-color: #d7dee8 !important;
    -webkit-box-shadow: none !important;
    box-shadow: none !important;
  }
  .v17-ink,
  .v17-stat {
    background: none !important;
    -webkit-text-fill-color: currentColor !important;
    color: #0a1628 !important;
  }
  .v17-img { -webkit-box-shadow: none !important; box-shadow: none !important; }
  .v17-img::after { display: none !important; }
}

/* ===================== 25. PERFORMANCE NOTES =====================
   Why every v17 animation is compositor-only (or paint-cheap):

   1. AURORA BANDS (::before/::after) — animate transform ONLY on
      oversized pseudo-elements already on their own layer
      (will-change: transform). translate3d + rotate(0.001deg)
      forces the compositor path; 70-90s loops mean ~1 style
      recalc per second per band at most, and the Intersection
      Observer only tags sections near the viewport, so at most
      2-3 bands are ever animating simultaneously.
   2. DOT GRID + NAVY GRADIENT — static background-image layers
      on the band element; painted once, never animated.
   3. GLARE SWEEP (.v17-card::after) — one translateX + skew on
      a pseudo-element, triggered ONLY on hover, 0.9s, then it
      stops. Idle cost zero.
   4. CURSOR GLARE — --v17gx/--v17gy custom properties feed a
      background radial. Repaint-only (no layout, no compositing
      churn), hovered card only, rAF-lerped by js/v17.js.
   5. HOVER LIFTS — transform + box-shadow transitions. Shadow
      animation is the most expensive part and is why lifts are
      disabled on touch/small screens and capped to the cards
      the runtime tagged (max 40 per page).
   6. TILT — transform via custom properties consumed by a
      single transform declaration; JS never writes inline
      styles, so the browser keeps one cached style per change.
   7. MARQUEE — translateX keyframes on a width:max-content
      track; pause-on-hover via animation-play-state. The track
      is cloned exactly 2x so -50% is a seamless loop.
   8. PROGRESS RIBBON — scaleX/scaleY on a fixed 3px strip;
      updated inside a rAF-throttled scroll handler (passive),
      one write per frame max.
   9. DIVIDER / FOOTER BEAM — background-position keyframes;
      paint-only, GPU-hosted layer thanks to the fixed strip
      being its own compositor layer.
  10. REVEALS — opacity/transform/filter transitions, one-shot
      (observer disconnects), stagger via transition-delay
      custom property (--v17-i), never re-triggered.
  11. REDUCED MOTION — a single media block kills every v17
      animation and forces final states; nothing stays hidden.
  12. LOADING — this file contains no @import, no fonts, no
      external URLs; it is pure static CSS, cacheable forever. */
