/* ============================================================
   Dealer Payments: "Night showroom meets fintech precision"
   Design system + cinematic sections. Tokens per docs/BRAND-KIT.md.
   ============================================================ */

/* ---------- 1. TOKENS ---------- */
:root {
  /* Brand core */
  --navy:#10172A; --carmine:#B2363F; --orange:#FF8C23; --white:#FFFFFF;
  --gradient-brand:linear-gradient(90deg,#B2363F 0%,#FF8C23 100%);

  /* Dark UI surfaces (derived tints of brand navy) */
  --bg-primary:#0B0F1A; --bg-surface:#0B0F1A; --bg-elevated:#0B0F1A;

  /* Text ramp */
  --text-primary:#F0F2F5; --text-secondary:#A0AEC0; --text-muted:#718096; --text-inverse:#10172A;

  /* Borders */
  --border-color:rgba(255,255,255,0.08); --border-subtle:rgba(255,255,255,0.04);

  /* Semantic */
  --success:#10B981; --warning:#FFB020; --error:#E5484D;

  /* Type */
  --font-sans:"Poppins",system-ui,sans-serif;
  --tabular:"tnum" 1;
  --text-display:clamp(2.75rem,1rem + 7vw,6rem);
  --text-h1:clamp(2.25rem,1rem + 5vw,4rem);
  --text-h2:clamp(2rem,1.2rem + 3vw,3.25rem);
  --text-h3:clamp(1.5rem,1rem + 1.5vw,2rem);
  --text-h4:clamp(1.25rem,1rem + 0.6vw,1.5rem);
  --text-body:clamp(1rem,0.92rem + 0.4vw,1.125rem);
  --tracking-tight:-0.02em; --tracking-wide:0.04em;

  /* Spacing */
  --space-4:16px; --space-5:24px; --space-6:32px; --space-8:48px; --space-9:64px;
  --space-section:clamp(4.5rem,3.4rem + 2vw,6rem);
  --container-max:1200px; --gutter:24px;

  /* Radii */
  --radius-sm:6px; --radius-md:10px; --radius-lg:16px; --radius-card:14px; --radius-pill:999px;

  /* Elevation */
  --shadow-sm:0 1px 2px rgba(0,0,0,0.40);
  --shadow-md:0 8px 24px rgba(0,0,0,0.45);
  --shadow-lg:0 24px 64px rgba(0,0,0,0.55);

  /* Glass */
  --glass-bg:rgba(11,15,26,0.60); --glass-blur:16px; --glass-border:rgba(255,255,255,0.08);

  /* Motion */
  --dur-fast:150ms; --dur-normal:320ms; --dur-slow:600ms; --stagger:80ms;
  --ease-out-expo:cubic-bezier(0.16,1,0.3,1);
  --ease-in-out:cubic-bezier(0.65,0,0.35,1);
  --ease-overshoot:cubic-bezier(0.34,1.56,0.64,1);

  /* Focus */
  --focus-ring:0 0 0 2px var(--bg-primary),0 0 0 4px var(--orange);
}

/* ---------- 2. BASE ---------- */
/* Section snapping is JS-driven (pageStepper() in main.js): scroll within a section, then any flick
   past its edge drags you hard to the next. scroll-padding keeps anchor jumps clear of the navbar. */
html{background:var(--bg-primary);scroll-padding-top:72px}
body{background:transparent}
h1,h2,h3,h4,h5{line-height:1.1;letter-spacing:var(--tracking-tight);font-weight:700}
h2{font-size:var(--text-h2)} h3{font-size:var(--text-h3)} h4{font-size:var(--text-h4);font-weight:600}
p{color:var(--text-secondary)}
strong{color:var(--text-primary);font-weight:600}
::selection{background:var(--orange);color:var(--text-inverse)}
:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:var(--radius-sm)}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}

.container{max-width:var(--container-max);margin:0 auto;padding:0 var(--gutter)}
.container--narrow{max-width:820px}
/* Structural breakout (2026-07-24): prose keeps its measure inside .container--narrow,
   but figures use more of the viewport on desktop — tables and callout boxes to 980px,
   FAQ lists and callout grids to 1080px. Margin-based (NO transform) so it never fights
   the .fade-up transform. Scoped >=1025px: below that, the section-19 media rules own
   the stacking (e.g. .callout-grid max-width:520px at <=1024px must keep winning). */
@media (min-width:1025px){
  .container--narrow .table-wrap,
  .container--narrow .tech-callout{--bw:min(980px,100vw - 48px);width:var(--bw);margin-left:calc((100% - var(--bw))/2)}
  .container--narrow .faq-list,
  .container--narrow .callout-grid{--bw:min(1080px,100vw - 48px);width:var(--bw);margin-left:calc((100% - var(--bw))/2)}
  .container--narrow .callout-grid--four{max-width:none}
}

.grad-text{background:var(--gradient-brand);-webkit-background-clip:text;background-clip:text;color:transparent}
.wordmark{font-weight:700;letter-spacing:-0.01em}
.wordmark em{font-style:italic;font-weight:600}

/* Film grain: subtle film over dark fields to kill banding (pointer-events:none) */
.grain{
  position:fixed;inset:0;z-index:60;pointer-events:none;opacity:0.045;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size:140px 140px;
}

/* Glass surface recipe */
.glass{
  background:var(--glass-bg);
  -webkit-backdrop-filter:blur(var(--glass-blur));backdrop-filter:blur(var(--glass-blur));
  border:1px solid var(--glass-border);
}

/* Concentric-arc brand motif, bleeding from a corner */
.corner-arcs{position:absolute;width:min(46vw,520px);height:min(46vw,520px);color:var(--orange);opacity:0.06;pointer-events:none}
.corner-arcs--tr{top:-40px;right:-60px}

/* Section rhythm — all content sections share the brand-kit surface */
.section{position:relative;padding:var(--space-section) 0;overflow:hidden;background:var(--bg-surface)}
/* De-double the seam between two stacked content sections: without this, adjacent .section
   elements each contribute a full --space-section top+bottom, stacking into a much wider dark
   band than intended. Zeroing the LOWER section's top padding leaves exactly one gap (the
   upper section's bottom padding). Excludes .page-cta/.page-outro: both ARE `.section` siblings
   of the content above them (e.g. #faq + .section.page-cta), but they are page CLOSERS that must
   keep their own full top breathing room — do not remove this :not() guard. */
.section + .section:not(.page-cta):not(.page-outro){padding-top:0}
.section-header{position:relative;isolation:isolate;max-width:880px;margin:0 auto var(--space-8);text-align:center;--hp:0}
.section-header h2{margin-bottom:var(--space-4);text-wrap:balance}
.section-header p{font-size:var(--text-body);max-width:60ch;margin:0 auto}
/* Header parallax: eyebrow / headline / subcopy drift at different rates as the section crosses the
   viewport. --hp (-0.5 at the bottom edge .. +0.5 at the top) is set by headerParallax() in main.js.
   Compositor-only transforms. */
.section-header .eyebrow{transform:translateY(calc(var(--hp) * -56px))}
.section-header h2{transform:translateY(calc(var(--hp) * -30px))}
.section-header p{transform:translateY(calc(var(--hp) * -14px))}

/* Interior headings are PLAIN WHITE (2026-07-24 calm pass): the old illuminated-header
   treatment (warm light pool on h2::before + halo text-shadow + top-lit-metal gradient
   on the .grad-text span, incl. the #pain-points carmine variant) was retired sitewide.
   The .grad-text spans REMAIN in every page's markup; this override is the single switch
   that neutralizes them inside section headers. Page-level titles keep the gradient via
   the base .grad-text rule (.page-hero h1, .hero-title, .pband-title are untouched). */
.section-header h2 .grad-text{background:none;color:var(--text-primary);filter:none}

.eyebrow{display:inline-block;font-size:0.75rem;font-weight:600;letter-spacing:var(--tracking-wide);
  text-transform:uppercase;color:var(--orange);margin-bottom:var(--space-4)}
.eyebrow--danger{color:var(--carmine)}

/* Inline links inside body copy (subpage prose, FAQ answers) must read as links —
   the global a{color:inherit} otherwise makes them invisible in a paragraph */
.section p a{color:var(--orange)}
.section p a:hover{text-decoration:underline}

/* Section prose rhythm (2026-07-13) — the global reset zeroes EVERY margin and there is
   no base <p> margin rule, so bare paragraphs / callout blocks stacked directly in a
   section container sit flush against each other (every subpage was patching this
   locally, e.g. #story p). Adjacent-sibling margin-top COLLAPSES into any larger
   neighbor margin (.section-header's bottom, .table-wrap's bottom), so these rules only
   fill gaps that are currently near-zero and leave already-spaced layouts unchanged. */
.section .container>p+p{margin-top:20px}
.section .container>*+.tech-callout,
.section .container>.tech-callout+*,
.section .container>*+.callout-grid,
.section .container>.callout-grid+*,
.section .container>p+.table-wrap{margin-top:28px}

/* Deep-page handoff link that closes a homepage beat ("See the full …") — Wave 1 cutover */
.section-more{display:flex;justify-content:center;margin-top:var(--space-6)}
.section-more a{display:inline-flex;align-items:center;gap:8px;color:var(--orange);font-weight:600;font-size:0.98rem}
.section-more a svg{width:16px;height:16px;transition:transform var(--dur-fast) ease}
.section-more a:hover svg{transform:translateX(4px)}

/* ---------- 3. BUTTONS ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-family:inherit;
  font-weight:600;letter-spacing:0.01em;border-radius:var(--radius-md);cursor:pointer;border:1px solid transparent;
  transition:transform var(--dur-fast) ease,background var(--dur-fast) ease,border-color var(--dur-fast) ease,box-shadow var(--dur-fast) ease;
  padding:12px 24px;font-size:var(--text-body)}
.btn-sm{padding:8px 16px;font-size:0.875rem}
.btn-lg{padding:16px 32px;font-size:1.0625rem}
/* Glow effect ported from 21st.dev @wisedev "Glow Button", recolored to the brand orange.
   Click sets [data-state=clicked] from main.js for 200ms -> soft press + brighter glow. */
.btn-primary{--btn-glow-base:#D96A0F;--btn-glow-hi:#FFCE8C;color:var(--text-inverse);
  background-image:linear-gradient(325deg,var(--btn-glow-base) 0%,var(--btn-glow-base) 44%,
    var(--btn-glow-hi) 50%,var(--btn-glow-base) 56%,var(--btn-glow-base) 100%);
  background-size:400%;background-position:0% 0;transition:all 0.8s;transform:scale(1);
  box-shadow:0 0 20px rgba(255,140,35,0.5),0 5px 5px -1px rgba(224,110,20,0.25),
    inset 4px 4px 8px rgba(255,220,175,0.5),inset -4px -4px 8px rgba(181,78,8,0.35)}
/* Ambient "Book a Demo" gleam (user-required): the page-content conversion CTAs — all
   .btn-lg — carry a continuous, unhurried light sweep to keep the primary CTA drawing the
   eye. Deliberate exception to the old "CTAs stay steady" rule, scoped to .btn-lg so the
   nav's .btn-sm CTA is untouched and stays steady. Declared BEFORE the :hover rule (equal
   specificity) so hover still wins with its one-shot sweep; the one-time .glare rules
   (calc nudge / value-result) are higher specificity and override while active. The global
   prefers-reduced-motion reset clamps iteration-count to 1, so this self-disables there. */
.btn-primary.btn-lg{animation:btnShine 3.6s ease-in-out infinite}
@media (hover:hover){
  .btn-primary:hover{animation:btnGlare 1.2s ease-in-out 1}
}
/* One-way downward sweep (100% -> 0%): the resting position (0% 0) matches both keyframe
   ends, so the pass starts and finishes flat with no seam. The gradient is diagonal, so
   the face sees a wider slice of it than the horizontal window alone (corners project
   onto the gradient axis) — the 400% size + narrow streak (44-56%) keep the face flat. */
@keyframes btnGlare{0%{background-position:100% 0}70%{background-position:0% 0}100%{background-position:0% 0}}
/* Ambient loop: a quick gleam (streak sweeps 100%->0% over the first ~24%) then a long rest
   at 0% 0 = the flat resting position, so every cycle starts and ends seamless — reads as a
   periodic shine, not a strobe. Same one-way sweep + flat endpoints as btnGlare. */
@keyframes btnShine{0%{background-position:100% 0}24%{background-position:0% 0}100%{background-position:0% 0}}
.btn-primary[data-state=clicked]{transform:scale(0.95);
  box-shadow:0 0 30px rgba(255,140,35,0.8),0 5px 5px -1px rgba(224,110,20,0.4),
    inset 4px 4px 12px rgba(255,220,175,0.7),inset -4px -4px 12px rgba(181,78,8,0.5)}
.btn-primary:focus-visible{outline:2px solid rgba(255,140,35,0.6);outline-offset:2px}
.btn-primary:focus:not(:focus-visible){outline:none}
.btn-secondary{background:transparent;border-color:var(--border-color);color:var(--text-primary)}
.btn-secondary:hover{border-color:var(--orange);background:rgba(255,140,35,0.08)}
.btn-secondary:active{transform:scale(0.98)}

/* ---------- 4. NAVBAR ---------- */
.navbar{position:fixed;top:0;left:0;right:0;z-index:var(--z-nav,100);height:72px;display:flex;align-items:center;
  transition:background var(--dur-normal) ease,border-color var(--dur-normal) ease,backdrop-filter var(--dur-normal) ease}
.navbar.scrolled{background:var(--glass-bg);-webkit-backdrop-filter:blur(var(--glass-blur));backdrop-filter:blur(var(--glass-blur));
  border-bottom:1px solid var(--border-color)}
.nav-inner{display:flex;align-items:center;justify-content:space-between;width:100%}
.nav-logo{display:flex;align-items:center;gap:10px;font-size:1.15rem}
.brand-mark{width:30px;height:30px;flex:none}
.nav-links{display:flex;gap:30px}
.nav-links a{color:var(--text-secondary);font-size:0.95rem;font-weight:500;transition:color var(--dur-fast) ease;position:relative}
.nav-links a:hover{color:var(--text-primary)}
.nav-links a::after{content:"";position:absolute;left:0;right:100%;bottom:-6px;height:2px;background:var(--orange);
  transition:right var(--dur-normal) var(--ease-out-expo)}
.nav-links a:hover::after{right:0}
/* current-page marker (subpages set aria-current="page" on their own nav link) */
.nav-links > a[aria-current="page"]{color:var(--text-primary)}
.nav-links > a[aria-current="page"]::after{right:0}
.mobile-toggle{display:none;flex-direction:column;gap:5px;background:none;border:none;cursor:pointer;padding:8px}
.mobile-toggle span{width:24px;height:2px;background:var(--text-primary);border-radius:2px;transition:transform var(--dur-fast) ease,opacity var(--dur-fast) ease}
.mobile-toggle[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.mobile-toggle[aria-expanded="true"] span:nth-child(2){opacity:0}
.mobile-toggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* Solutions dropdown (Wave 1 cutover). Desktop: opens on hover (hover:hover only), on
   keyboard focus (:focus-within), and on click (.open set by navDropdown() in main.js,
   which also mirrors aria-expanded). ≤768px it flattens into the mobile panel — the
   "Solutions" button hides and the four links render inline with the other nav links.
   visibility (not display) keeps the open/close transition; the ::before strip bridges
   the hover gap between the button and the floating panel so the menu doesn't close
   while the pointer crosses it. */
.nav-drop{position:relative;display:flex;align-items:center}
.nav-drop-btn{display:inline-flex;align-items:center;gap:6px;background:none;border:none;cursor:pointer;padding:0;
  font-family:inherit;font-size:0.95rem;font-weight:500;color:var(--text-secondary);
  transition:color var(--dur-fast) ease}
.nav-drop-btn:hover,.nav-drop.open .nav-drop-btn{color:var(--text-primary)}
.nav-drop-chev{width:14px;height:14px;transition:transform var(--dur-normal) var(--ease-out-expo)}
.nav-drop.open .nav-drop-chev{transform:rotate(180deg)}
.nav-drop-menu{position:absolute;top:calc(100% + 18px);left:-14px;min-width:220px;display:grid;gap:2px;
  padding:10px;border-radius:var(--radius-md);border:1px solid var(--border-color);
  background:var(--glass-bg);-webkit-backdrop-filter:blur(var(--glass-blur));backdrop-filter:blur(var(--glass-blur));
  box-shadow:var(--shadow-md);
  opacity:0;visibility:hidden;transform:translateY(-6px);
  transition:opacity var(--dur-fast) ease,transform var(--dur-fast) ease,visibility 0s linear var(--dur-fast)}
.nav-drop-menu::before{content:"";position:absolute;left:0;right:0;top:-18px;height:18px}
/* NO :focus-within auto-open here — the clicked button keeps focus, which would pin the
   panel open after Escape/toggle-close. Keyboard flow is .open-driven: Enter/Space on the
   button toggles it (JS), Tab walks the links while .open holds the panel visible, and
   navDropdown() closes on Escape/outside-click/focusout. */
.nav-drop.open .nav-drop-menu{opacity:1;visibility:visible;transform:none;transition-delay:0s}
@media (hover:hover){
  .nav-drop:hover .nav-drop-menu{opacity:1;visibility:visible;transform:none;transition-delay:0s}
  .nav-drop:hover .nav-drop-chev{transform:rotate(180deg)}
}
.nav-drop-menu a{display:block;padding:9px 12px;border-radius:var(--radius-sm);
  font-size:0.92rem;font-weight:500;color:var(--text-secondary);
  transition:color var(--dur-fast) ease,background var(--dur-fast) ease}
.nav-drop-menu a::after{content:none} /* no sliding underline inside the panel */
.nav-drop-menu a:hover{color:var(--text-primary);background:rgba(255,140,35,0.08)}
/* current-page marker inside the dropdown (solution pages set aria-current="page") */
.nav-drop-menu a[aria-current="page"]{color:var(--text-primary);background:rgba(255,140,35,0.08)}

/* ---------- 5. HERO ---------- */
.hero{position:relative;padding:calc(72px + var(--space-9)) 0 var(--space-8);isolation:isolate;overflow:hidden}
.hero-glow{position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(620px circle at var(--mx,72%) var(--my,38%),rgba(255,140,35,0.16),transparent 62%),
             radial-gradient(900px circle at 50% -10%,rgba(178,54,63,0.10),transparent 60%)}
.hero-grid{display:grid;grid-template-columns:1.05fr 0.95fr;gap:var(--space-8);align-items:center;min-height:min(72vh,620px)}
.hero-copy{max-width:600px}
.hero-title{font-size:var(--text-h1);margin-bottom:var(--space-5)}
.hero-sub{font-size:var(--text-body);max-width:52ch;margin-bottom:var(--space-6)}
.hero-buttons{display:flex;gap:14px;flex-wrap:wrap;margin-bottom:var(--space-5)}
/* Trust strip (D5 numbers): scale proof right under the CTA pair, above the compliance chips */
.hero-cred{display:flex;flex-wrap:wrap;align-items:center;gap:10px 14px;margin-bottom:var(--space-6);
  font-size:0.92rem;color:var(--text-muted)}
.hero-cred strong{color:var(--text-primary);font-weight:700}
.hero-cred-sep{width:4px;height:4px;border-radius:50%;background:var(--text-muted);opacity:0.6}
.trust-bar{display:flex;flex-wrap:wrap;gap:20px 28px}
.trust-item{display:flex;align-items:center;gap:9px;font-size:0.9rem;color:var(--text-secondary);font-weight:500}
.trust-icon{display:grid;place-items:center;width:30px;height:30px;border-radius:8px;background:rgba(255,140,35,0.1);color:var(--orange)}
.trust-icon svg{width:17px;height:17px}

/* Hero showroom stage */
.hero-stage{position:relative;height:100%;min-height:360px;display:grid;place-items:center}
/* Hero credit card: black pebbled-leather material, floating, cursor-reactive 3D tilt */
.hero-card-scene{position:relative;width:min(100%,420px);aspect-ratio:1.586/1;perspective:1100px;z-index:1}
.hero-card-float{position:relative;width:100%;height:100%;transform-style:preserve-3d;animation:cardBob 6s ease-in-out infinite}
.hero-card{--tiltX:8deg;--tiltY:-18deg;position:relative;width:100%;height:100%;border-radius:18px;overflow:hidden;
  transform-style:preserve-3d;transform:rotateX(var(--tiltX)) rotateY(var(--tiltY));transition:transform .3s var(--ease-out-expo);
  box-shadow:0 34px 64px rgba(0,0,0,0.55),0 0 0 1px rgba(255,140,35,0.20),inset 0 1px 0 rgba(255,170,90,0.18)}
/* Black pebbled leather, fully procedural (no WebGL, no assets): near-black base + an SVG
   feTurbulence->feDiffuseLighting grain tile (lit bumps = pebbles) blended soft-light so the
   texture reads as material, not noise. stitchTiles keeps the tile seamless. */
.hero-card-leather{position:absolute;inset:0;border-radius:18px;overflow:hidden;
  background:radial-gradient(120% 100% at 28% 0%,rgba(255,178,102,0.07),transparent 55%),
    linear-gradient(160deg,#17161a 0%,#0e0d11 55%,#09080b 100%)}
.hero-card-leather::before{content:"";position:absolute;inset:0;opacity:0.5;mix-blend-mode:soft-light;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='260'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.55' numOctaves='4' seed='11' stitchTiles='stitch'/%3E%3CfeDiffuseLighting lighting-color='%23ffffff' surfaceScale='1.7' diffuseConstant='1.1'%3E%3CfeDistantLight azimuth='235' elevation='55'/%3E%3C/feDiffuseLighting%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23p)'/%3E%3C/svg%3E");
  background-size:260px 260px}
/* Cursor-driven orange sheen: a warm light pool raking the grain, its position fed by the same
   pointer math as the tilt (--shx/--shy, unitless 0..1 set on #heroCard by main.js; rest pose =
   upper right). Lives on the leather's ::after with screen blend so the glow genuinely catches
   the pebble highlights beneath it (the leather element creates no stacking context, so the
   blend reaches the texture; putting this on .hero-card-sheen would isolate + screen away its
   own dark vignette). */
/* Sheen shares the foreground bloom's card-local center (--cgx/--cgy) and intensity (--cg-op) so
   both lights sit exactly under the cursor and rise/fall together. Card-local (not the old
   hero-relative 18%+shx*64% mapping, which put the pool in the card's MIDDLE when the cursor was at
   an edge). --cg-op is a proximity ramp set by heroPointer(): full over the card, fading out just
   outside it, so the card is caught in the cursor's glow as you approach and there's no permanent
   rest pool. Coords are unclamped, so when the cursor is just OUTSIDE, the center sits off-card and
   only the near edge catches the radial's tail. */
.hero-card-leather::after{content:"";position:absolute;inset:0;mix-blend-mode:screen;
  opacity:var(--cg-op,0);
  background:radial-gradient(70% 95% at calc(var(--cgx,0.5) * 100%) calc(var(--cgy,0.5) * 100%),
    rgba(255,140,35,0.15),rgba(255,120,30,0.05) 45%,transparent 72%);
  transition:opacity .25s var(--ease-out-expo)}
/* The usual 115deg vignette keeps the lower-right falloff so the black card has form */
.hero-card-sheen{position:absolute;inset:0;border-radius:18px;pointer-events:none;z-index:2;
  background:linear-gradient(115deg,rgba(255,255,255,0.05) 0%,transparent 28%,transparent 60%,rgba(0,0,0,0.40) 100%)}
.hero-card-face{position:absolute;inset:0;z-index:3;color:var(--white)}
/* Cursor-following FOREGROUND light. Unlike .hero-card-leather::after (the sheen, blended UNDER
   the printing), this sits ABOVE the face (z:4 > z:3) so it passes in front of the wordmark/chip/
   seal — reading as a light source ahead of the card rather than the ambient .hero-glow that hides
   behind it. Clipped to the card by the parent's overflow:hidden + radius, so it stays "only over
   the card" and can never wash the hero copy. screen blend adds warm light without dimming whites.
   Center = --cgx/--cgy (card-local 0..1 set by heroPointer); --cg-op keeps it dark until the
   pointer moves, so the resting card, touch, and reduced-motion look exactly as before. Position
   is NOT transitioned — the pool tracks the cursor instantly (like the ambient .hero-glow); only
   --cg-op fades so it appears/vanishes softly. Broad, low-contrast radial = a diffuse pool that
   matches the ambient hover light rather than a tight focused hotspot. */
.hero-card-frontglow{position:absolute;inset:0;z-index:4;pointer-events:none;mix-blend-mode:screen;
  opacity:var(--cg-op,0);transition:opacity .25s var(--ease-out-expo);
  background:radial-gradient(82% 82% at calc(var(--cgx,0.5) * 100%) calc(var(--cgy,0.5) * 100%),
    rgba(255,166,86,0.21),rgba(255,140,35,0.09) 40%,rgba(255,120,24,0.028) 64%,transparent 84%)}
/* EMV chip in its real-card position: left edge, just above vertical center */
.hc-chip{position:absolute;top:44%;left:26px;transform:translateY(-50%);width:46px;height:34px;border-radius:6px;
  background:linear-gradient(135deg,#f0cd6a,#b9822b);box-shadow:inset 0 0 0 1px rgba(0,0,0,0.25)}
.hc-chip::after{content:"";position:absolute;inset:6px 8px;border:1px solid rgba(0,0,0,0.3);border-radius:2px}
.hc-wave{position:absolute;top:26px;right:26px;width:34px;height:34px;color:rgba(255,252,247,0.9);filter:drop-shadow(0 1px 2px rgba(0,0,0,0.45))} /* ivory — orange-on-orange vanished once the metal went brand-orange */
/* White hot-foil pressed into the leather: WHITE glyphs (the brand name must stay white — a dark
   blind-stamp was tried and rejected), with a top-edge inner shadow so the foil still reads
   slightly sunk into the hide rather than floating on it. */
.hc-brand{position:absolute;left:26px;bottom:52px;font-size:1.5rem;font-weight:700;letter-spacing:-0.01em;
  color:#EDF0F5;
  text-shadow:0 -1px 1px rgba(0,0,0,0.55),0 1px 1px rgba(255,178,102,0.18),0 2px 4px rgba(0,0,0,0.35)}
.hc-brand em{font-style:italic;font-weight:600}
.hc-number{position:absolute;left:26px;bottom:22px;display:flex;gap:14px}
.hc-number i::before{content:"\2022\2022\2022\2022";letter-spacing:2px;color:rgba(255,255,255,0.55);font-size:0.78rem;text-shadow:0 1px 1px rgba(0,0,0,0.55)}
/* Faint "lit floor" pool so the dark contact shadow reads on the near-black background */
/* Visible floor surface (lighter than the black bg) so the dark shadow has contrast */
.hero-card-floor{position:absolute;left:50%;bottom:-17%;width:120%;height:66px;transform:translateX(-50%);border-radius:50%;z-index:-2;
  background:radial-gradient(65% 100% at 50% 45%,rgba(218,213,208,0.20),rgba(218,213,208,0.05) 60%,transparent 82%);filter:blur(16px)}
/* Genuine dark shadow on the floor */
.hero-card-shadow{position:absolute;left:50%;bottom:-15%;width:56%;height:26px;transform:translateX(-50%);border-radius:50%;z-index:-1;
  background:radial-gradient(closest-side,#000,rgba(0,0,0,0.88) 44%,rgba(0,0,0,0.32) 70%,transparent 82%);filter:blur(10px);
  animation:groundCard 6s ease-in-out infinite}

/* Hero "CDK Integrated" seal: DEBOSSED into the card — a shallow recess stamped into the chrome,
   not an object sitting on it (a solid disc of any color read as a foreign sticker on the
   luminous metal). The recess is a translucent darkening over the card's own liquid-metal
   surface, so the shader literally shows through it; z-index:1 keeps it above the metal canvas
   but BELOW .hero-card-sheen (z2), so the card's light sweep continues across the recess.
   Deboss lighting: top inner shadow (overhead light), bottom inner light catch, lit lower lip.
   Child of #heroCard — rides the card's tilt + bob 1:1; pure CSS, no JS, no hover state. */
.cdk-seal{position:absolute;right:1%;bottom:1%;z-index:1;width:32%;aspect-ratio:1/1;border-radius:50%;
  display:grid;place-items:center;
  /* darker center protects text legibility over the moving chrome; translucent rim keeps the stamped read */
  background:radial-gradient(circle,rgba(8,11,17,0.74) 0%,rgba(8,11,17,0.58) 58%,rgba(8,11,17,0.38) 100%);
  box-shadow:
    inset 0 3px 7px rgba(0,0,0,0.55),          /* top inner shadow — recess wall under the light */
    inset 0 -1px 2px rgba(255,255,255,0.14),   /* bottom inner edge catching the light */
    0 1px 1px rgba(255,255,255,0.16),          /* lower lip of the stamp catching light */
    0 -1px 1px rgba(0,0,0,0.25)}               /* upper lip shading */
/* Hairline orange enamel inlaid in the stamp groove — pigment, not glow */
.cdk-seal::before{content:"";position:absolute;inset:5.5%;border-radius:50%;pointer-events:none;
  border:1px solid rgba(255,140,35,0.55)}
.cdk-seal-core{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:5px;text-align:center}
/* Engraved orange check — bare mark, no filled chip (a fill reads sticker-ish inside a stamp).
   Orange (not the site-wide teal --success): teal was the lone cool hue on the warm chrome/gold/
   orange card; the check shape alone carries "verified". */
.cdk-seal-check{display:grid;place-items:center;color:var(--orange);
  filter:drop-shadow(0 1px 1px rgba(0,0,0,0.5))}
.cdk-seal-check svg{width:22px;height:22px}
.cdk-seal-text{font-size:0.82rem;font-weight:600;line-height:1.15;color:rgba(240,242,245,0.88);
  text-shadow:0 1px 1px rgba(0,0,0,0.45)}
.cdk-seal-text strong{display:block;font-size:1.05rem;letter-spacing:0.02em;
  background:var(--gradient-brand);-webkit-background-clip:text;background-clip:text;color:transparent;
  /* drop-shadow (not text-shadow, which bleeds through transparent gradient glyphs) for contrast over chrome */
  filter:drop-shadow(0 1px 1px rgba(0,0,0,0.65))}
@keyframes cardBob{0%,100%{transform:translateY(0)}50%{transform:translateY(-14px)}}
/* ground shadow shrinks as the card rises (in sync with the float) */
@keyframes groundCard{0%,100%{transform:translateX(-50%) scale(1)}50%{transform:translateX(-50%) scale(0.9)}}

/* ---------- 6. LOGO MARQUEE ---------- */
/* Full-bleed band: solid hairlines above/below the emblems. The edge fade lives on the inner
   .logo-marquee-viewport — a mask on .logo-marquee itself would fade the border lines too.
   No discs/backgrounds behind the logos: the hero's cursor-following glow made any opaque
   punch-out read as visible circles on hover. */
.logo-marquee{--marquee-dur:90s;position:relative;margin-top:var(--space-8);padding:22px 0;
  border-top:1px solid var(--border-color);border-bottom:1px solid var(--border-color)}
.logo-marquee--section{margin-top:0}
.logo-marquee-viewport{overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 10%,#000 90%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 10%,#000 90%,transparent)}
.logo-marquee-track{display:flex;width:max-content;animation:marquee var(--marquee-dur) linear infinite}
.logo-marquee--reverse .logo-marquee-track{animation-direction:reverse}
.logo-marquee:hover .logo-marquee-track{animation-play-state:paused}
.logo-set{display:flex;gap:28px;padding-right:28px}
.logo-chip span{display:inline-flex;transition:filter var(--dur-normal) ease}
.logo-chip img{display:block;width:64px;height:64px;object-fit:contain}
.logo-marquee--warm .logo-chip span{filter:grayscale(1)}
.logo-marquee--warm.in-view .logo-chip span{filter:grayscale(0)}
@keyframes marquee{to{transform:translateX(-50%)}}

/* ---------- 7b. HOW-IT-WORKS — compact, native-scroll TIMELINE ----------
   Replaces the old full-screen pinned/sticky-rail scrollytelling deck (position:sticky,
   100vh scenes, a nested overflow scroller, a wheel-stepper, scroll-linked --sp parallax)
   with a normal-flow vertical timeline: <ol class="hiw-timeline"> holds one <li
   class="hiw-step"> per beat — a node button on a continuous spine in column 1, its glass
   card in column 2. main.js reads normal WINDOW scroll (rAF-throttled) to toggle
   .is-current/.is-passed on the nodes and grow .hiw-spine-fill to the current node; a node
   click scrolls its step into view. No pin, no overflow scroller, no wheel capture, no
   scroll-linked transforms anywhere below — .fade-up (global, section 19) handles the
   reveal-in via IntersectionObserver same as every other section. */
.hiw{--hiw-node:52px;--led-mono:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,monospace;
  position:relative;max-width:1100px;margin:0 auto}

/* The timeline list: a plain flex column of rows. ::before is the continuous spine (the
   "hiw-spine" from the class contract — a pseudo-element, not its own class), centred on
   the node column and inset by half a node's height at each end so it runs exactly
   first-node-center -> last-node-center. ::after is the "hiw-spine-fill" progress overlay —
   same pseudo-element treatment (no DOM node to grow), reading the --spine-top/--spine-fill
   custom properties ledgerCurrent() already sets on .hiw-timeline every scroll frame. */
.hiw-timeline{position:relative;list-style:none;margin:0;padding:0;
  display:flex;flex-direction:column;gap:clamp(28px,4vh,52px)}
.hiw-timeline::before{content:"";position:absolute;top:calc(var(--hiw-node) / 2);
  bottom:calc(var(--hiw-node) / 2);left:calc(var(--hiw-node) / 2);width:2px;
  transform:translateX(-50%);border-radius:2px;background:var(--border-color)}
.hiw-timeline::after{content:"";position:absolute;left:calc(var(--hiw-node) / 2);width:2px;
  top:var(--spine-top,calc(var(--hiw-node) / 2));height:var(--spine-fill,0px);
  transform:translateX(-50%);border-radius:2px;pointer-events:none;
  background:linear-gradient(180deg,var(--carmine),var(--orange));
  box-shadow:0 0 12px rgba(255,140,35,0.5);transition:height 0.9s var(--ease-out-expo)}

/* One row: node in the auto-sized marker column, card filling the rest. Top-aligned so
   the node stays level with the card's badge no matter how tall the card grows below
   (the step-4 fork row is taller than a plain icon row). */
.hiw-step{position:relative;display:grid;grid-template-columns:auto minmax(0,1fr);
  column-gap:clamp(20px,4vw,36px);align-items:start}

/* Node button — ignite visuals unchanged from the old rail: base ring; .is-current =
   orange ring + breathing glow + spinning conic halo + slight scale; .is-passed =
   gradient-brand fill; .hiw-node--check swaps the accent to teal/success. */
.hiw-node{position:relative;z-index:1;width:var(--hiw-node);height:var(--hiw-node);border-radius:50%;
  display:grid;place-items:center;cursor:pointer;-webkit-appearance:none;appearance:none;padding:0;
  font-family:var(--led-mono);font-weight:600;font-size:0.95rem;color:var(--text-muted);
  background:var(--bg-primary);border:1px solid var(--border-color);
  transition:color .4s ease,border-color .4s ease,background .4s ease,box-shadow .4s ease,transform .4s var(--ease-out-expo)}
.hiw-node svg{width:22px;height:22px}
.hiw-node-num{line-height:1}
.hiw-node.is-passed{color:var(--text-inverse);border-color:transparent;background:var(--gradient-brand)}
.hiw-node.is-current{color:var(--orange);border-color:var(--orange);box-shadow:0 0 22px rgba(255,140,35,0.5);transform:scale(1.08)}
.hiw-node::before,.hiw-node::after{content:"";position:absolute;border-radius:50%;pointer-events:none;opacity:0;transition:opacity .35s ease}
.hiw-node::before{inset:-10px;filter:blur(8px);background:radial-gradient(circle,rgba(178,54,63,0.45),rgba(255,140,35,0.22) 50%,transparent 70%)}
.hiw-node::after{inset:-4px;padding:2px;background:conic-gradient(from 0deg,var(--carmine),var(--orange),var(--carmine));
  -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}
.hiw-node.is-current::before{opacity:1;animation:ledBreathe 2s ease-in-out infinite}
.hiw-node.is-current::after{opacity:1;animation:ledSpin 3s linear infinite}
.hiw-node--check.is-current{color:var(--success);border-color:var(--success);box-shadow:0 0 22px rgba(16,185,129,0.5)}
.hiw-node--check.is-passed{background:rgba(16,185,129,0.16);border-color:rgba(16,185,129,0.5);color:var(--success)}
@keyframes ledSpin{to{transform:rotate(360deg)}}
@keyframes ledBreathe{0%,100%{transform:scale(1);opacity:.5}50%{transform:scale(1.22);opacity:.82}}

/* Card — markup pairs "hiw-card" with the ".glass" utility (background/blur/border), so
   this only adds the box shape plus a soft highlight while its own step is current. */
.hiw-card{position:relative;padding:26px 30px;border-radius:var(--radius-lg);
  transition:border-color .4s ease,box-shadow .4s ease}
.hiw-step:has(.hiw-node.is-current) .hiw-card{border-color:rgba(255,140,35,0.35);
  box-shadow:0 0 0 1px rgba(255,140,35,0.10),var(--shadow-md)}

.hiw-badge{display:inline-flex;align-items:center;gap:10px;padding:6px 16px 6px 6px;border-radius:999px;
  border:1px solid var(--border-color);background:rgba(255,255,255,0.03);font-family:var(--led-mono);
  font-size:0.76rem;font-weight:600;letter-spacing:0.04em;color:var(--text-secondary);margin-bottom:16px}
.hiw-badge-dot{display:grid;place-items:center;width:28px;height:28px;border-radius:50%;flex:none;
  background:var(--gradient-brand);color:var(--text-inverse);font-size:0.82rem}
.hiw-badge-dot--ok{background:rgba(16,185,129,0.18);color:var(--success)}
.hiw-badge-dot--ok svg{width:15px;height:15px}
.hiw-badge--ok{color:var(--success)}
.hiw-title{font-size:clamp(1.75rem,3vw,2.5rem);line-height:1.08;letter-spacing:-0.02em;font-weight:800;margin:0 0 12px}
/* margin was "0 auto 40px" on the old centred hero-scale scene; the timeline reads
   left-aligned now, so only the auto (horizontal-centering) half of that is dropped —
   size/color/rhythm are unchanged. */
.hiw-desc{font-size:clamp(1.02rem,1.3vw,1.18rem);line-height:1.55;color:var(--text-secondary);max-width:48ch;margin:0 0 22px}
.hiw-visual-ico{display:grid;place-items:center;width:64px;height:64px;border-radius:16px;color:var(--orange);
  background:rgba(255,140,35,0.10);border:1px solid rgba(255,140,35,0.28)}
.hiw-visual-ico svg{width:32px;height:32px}
.hiw-visual-ico--ok{color:var(--success);background:rgba(16,185,129,0.10);border-color:rgba(16,185,129,0.3)}

/* Fork scene (step 4): credit / debit panels, side by side under the copy. Same drop-the-
   auto-margin note as .hiw-desc above — max-width/gap/colors are unchanged. */
.hiw-fork{display:grid;grid-template-columns:1fr 1fr;gap:20px;max-width:560px}
.hiw-branch{padding:22px 24px;border-radius:var(--radius-lg);background:rgba(255,255,255,0.03);border:1px solid var(--border-subtle)}
.hiw-branch--credit{border-top:2px solid rgba(255,140,35,0.6)}
.hiw-branch--debit{border-top:2px solid var(--border-color)}
.hiw-branch-label{display:block;font-family:var(--led-mono);font-size:0.72rem;font-weight:600;text-transform:uppercase;
  letter-spacing:0.1em;color:var(--orange);margin-bottom:8px}
.hiw-branch--debit .hiw-branch-label{color:var(--text-muted)}
.hiw-branch h4{margin:0 0 5px;font-size:1.2rem}
.hiw-branch p{margin:0;font-size:0.98rem;line-height:1.5;color:var(--text-secondary)}

/* Reduced motion: no local override needed. The sitewide universal reset (section 20)
   already forces `*,*::before,*::after{animation-duration:.001ms!important;
   transition-duration:.001ms!important}`, which collapses the node spin/breathe
   keyframes and the .hiw-spine-fill height transition to effectively instant. */

@media (max-width:768px){
  /* Compact responsive sizing only — there is no pin/scroller left to undo on touch. */
  .hiw{--hiw-node:40px}
  .hiw-node{font-size:0.82rem}
  .hiw-step{column-gap:16px}
  .hiw-card{padding:22px 20px}
  .hiw-title{font-size:clamp(1.7rem,6vw,2.2rem)}
  .hiw-desc{font-size:1.02rem}
  .hiw-fork{grid-template-columns:1fr;gap:14px}
}

/* Callout row */
.callout-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:16px;text-align:center;max-width:960px;margin:0 auto}
/* The homepage How-It-Works recap strip is the sole child of its own .container (it follows
   the timeline, a separate sibling), so the generic "*+.callout-grid" spacing never fires and
   it jams up under the last step — give it its own breathing room from the timeline above. */
#how-it-works .callout-grid{margin-top:var(--space-8)}
/* 4-up variant: the base grid is a 5-up strip (homepage + overview pages), so 4-item
   uses (network-rules grids on /surcharge-laws/* and /cdk-integration/) left a phantom
   empty 5th column and the row read off-center under its centered header. The
   1024px/480px media rules in section 19 still win at their widths (equal specificity,
   later in the file), so responsive stacking is unchanged. */
.callout-grid--four{grid-template-columns:repeat(4,1fr);max-width:880px}
.callout-item h5{font-size:0.92rem;margin-bottom:3px;font-weight:600}
.callout-item p{font-size:0.8rem;margin:0}
.callout-icon{display:grid;place-items:center;width:46px;height:46px;margin:0 auto 12px;border-radius:12px;
  background:rgba(255,140,35,0.1);color:var(--orange)}
.callout-icon svg{width:22px;height:22px}

/* ---------- 8. PAIN SECTION (Act II "The Leak" — restaged 2026-07-28) ----------
   The card bento is GONE. The section is an abstract passage of the room: the carmine
   mood lives in the BACKGROUND (leak-atmosphere shader via showcase.js; this ::before
   wash is its no-WebGL / reduced-motion fallback) and the content is bare type floating
   on that stage (.leak-hero / .leak-lines — styled in css/showcase.css S4, which owns
   section lighting and the Act II look). styles.css keeps only the fallback wash, the
   container promotion, and the bridge pill below. .card-icon stays here — contact-us
   still uses it. */
#pain-points::before{content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  background:
    radial-gradient(44% 48% at 22% 58%, rgba(178,54,63,0.15), transparent 72%),
    radial-gradient(46% 50% at 82% 64%, rgba(255,140,35,0.06), transparent 74%)}
#pain-points .container{position:relative;z-index:1}

.card-icon{display:grid;place-items:center;width:52px;height:52px;margin-bottom:16px;border-radius:12px;
  background:rgba(178,54,63,0.12);color:var(--carmine)}
.card-icon svg{width:26px;height:26px}

/* Pain -> relief bridge: hands the eye down into "How It Works" */
.pain-bridge-row{display:flex;justify-content:center;margin-top:38px}
.pain-bridge{display:inline-flex;align-items:center;gap:9px;padding:11px 22px;border-radius:var(--radius-pill);
  font-size:0.92rem;font-weight:600;color:var(--text-secondary);border:1px solid var(--border-color);
  background:var(--glass-bg);-webkit-backdrop-filter:blur(var(--glass-blur));backdrop-filter:blur(var(--glass-blur));
  transition:color var(--dur-normal) ease,border-color var(--dur-normal) ease,transform var(--dur-normal) var(--ease-out-expo)}
.pain-bridge svg{width:18px;height:18px;flex:none;animation:painNudge 1.9s var(--ease-out-expo) infinite}
.pain-bridge:hover{color:var(--orange);border-color:rgba(255,140,35,0.42);transform:translateY(-2px)}
@keyframes painNudge{0%,58%,100%{transform:translateY(0)}78%{transform:translateY(4px)}}

/* ---------- 9. PRICING + SAVINGS ---------- */
.pricing-cards{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;margin-bottom:var(--space-8);perspective:1000px}
.pricing-card{position:relative;padding:34px 28px;border-radius:var(--radius-lg);background:var(--bg-elevated);
  border:1px solid var(--border-color);overflow:hidden;transition:transform var(--dur-normal) var(--ease-out-expo),box-shadow var(--dur-normal) ease;
  transform-style:preserve-3d}
.pricing-card::before{content:"";position:absolute;top:0;left:0;right:0;height:3px;background:var(--gradient-brand)}
.pricing-card::after{content:"";position:absolute;top:20px;right:22px;width:34px;height:26px;border-radius:5px;
  background:linear-gradient(135deg,#d9a441,#b9822b);opacity:0.5;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,0.2)}
.pricing-card.featured{border-color:rgba(255,140,35,0.5);box-shadow:0 0 0 1px rgba(255,140,35,0.2),var(--shadow-md)}
.pricing-card.featured::after{opacity:0.85}
.pricing-card:hover{box-shadow:var(--shadow-lg)}
.card-label{font-size:0.8rem;font-weight:600;text-transform:uppercase;letter-spacing:0.04em;color:var(--text-secondary)}
.card-price{font-size:3rem;font-weight:700;margin:14px 0 12px;font-feature-settings:var(--tabular)}
.card-price span{font-size:1.1rem;color:var(--text-muted);font-weight:600}
.card-qual{display:block;margin:-6px 0 12px;font-size:0.72rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;color:var(--text-muted)}
.card-desc{font-size:0.9rem;margin:0}

/* Interactive savings calculator: tri-gauge instrument cluster in a dashboard binnacle.
   Housing is a curved cowl (elliptical top radii + inner bevels) rather than a glass card;
   hierarchy comes from borders/overlays since every surface is the same near-black. No dark
   drop shadows (they band on --bg-primary) — glow and bevels only. */
.value.before{color:var(--carmine)} .value.after{color:var(--text-primary)} .value.saved{color:var(--success)}

.calc-binnacle{position:relative;isolation:isolate;padding:clamp(28px,4vw,46px) clamp(20px,4vw,52px) clamp(24px,3vw,34px);overflow:hidden;
  border:1px solid var(--border-color);
  border-radius:clamp(28px,5vw,60px) clamp(28px,5vw,60px) var(--radius-lg) var(--radius-lg) / clamp(40px,7vw,92px) clamp(40px,7vw,92px) var(--radius-lg) var(--radius-lg);
  background:linear-gradient(180deg,rgba(255,255,255,0.045),rgba(255,255,255,0.012) 34%,rgba(0,0,0,0.24));
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.07),inset 0 -1px 0 rgba(0,0,0,0.5),inset 0 -26px 48px rgba(0,0,0,0.26)}
.calc-binnacle::before{content:"";position:absolute;top:0;left:14%;right:14%;height:1px;
  background:linear-gradient(90deg,transparent,rgba(178,54,63,0.9) 28%,rgba(255,140,35,0.95) 72%,transparent);
  box-shadow:0 0 14px rgba(255,140,35,0.35)}
/* Backlight behind the dials; .is-lit is added by main.js at ignition (instantly under
   reduced motion). z-index:-1 inside the binnacle's isolated context: the light lives
   BEHIND the instruments — painted over them it reads as a muddy film once the night-beat
   surge brightens it (the "glitched" look Gabriel flagged 2026-07-28). */
.calc-binnacle::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:-1;opacity:0;transition:opacity 900ms ease;
  background:radial-gradient(56% 44% at 50% 24%,rgba(255,140,35,0.09),transparent 70%)}
.calc-binnacle.is-lit::after{opacity:1}

/* Dash plate: the binnacle's own nameplate + display headline (grilled 2026-07-28; re-cut
   2026-07-30 — Gabriel called the old caption-scale plate bland). The headline is dash
   LETTERING, not a caption: warm backlit display type, ALWAYS lit — an etched-until-
   ignition sleep state was tried 2026-07-30 and pulled the same day (the headline is the
   invitation; hiding it before the press dims it exactly when it must sell the panel).
   drop-shadow (filter) only, never text-shadow — it bleeds through transparent
   background-clip glyphs (CDK-seal lesson). */
.calc-plate{position:relative;text-align:center;margin:0 auto clamp(20px,3vw,30px);max-width:720px}
.calc-plate-name{display:inline-flex;align-items:center;padding:6px 15px;border-radius:var(--radius-pill);
  font-size:0.62rem;font-weight:700;text-transform:uppercase;letter-spacing:0.2em;color:var(--text-muted);
  border:1px solid rgba(255,255,255,0.10);
  background:linear-gradient(180deg,rgba(255,255,255,0.07),rgba(255,255,255,0.02));
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.10),0 1px 2px rgba(0,0,0,0.5)}
.calc-plate-head{margin-top:14px;font-size:clamp(1.85rem,1.3rem + 2.4vw,2.7rem);font-weight:800;
  letter-spacing:-0.015em;text-wrap:balance;
  background:linear-gradient(180deg,#FFF6E9 15%,#FFDCAE 60%,#FFB061);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  filter:drop-shadow(0 0 18px rgba(255,140,35,0.22)) drop-shadow(0 1px 1px rgba(0,0,0,0.4))}


.cluster{position:relative;display:grid;grid-template-columns:minmax(140px,190px) minmax(250px,320px) minmax(140px,190px);
  justify-content:center;align-items:end;gap:clamp(14px,3.5vw,44px);margin-bottom:10px}
.dial{display:flex;flex-direction:column;align-items:center;min-width:0}
.dial-svg,.gauge-svg{display:block;width:100%;height:auto;overflow:visible}

/* Center speedo */
.dial--center{position:relative}
.gauge-bezel{fill:none;stroke:rgba(255,255,255,0.06);stroke-width:1.5}
.gauge-track{fill:none;stroke:rgba(255,255,255,0.08);stroke-width:12;stroke-linecap:round}
/* dasharray "100 200" (not plain 100): at full retraction (dashoffset 100, the parked state)
   a plain 100 pattern restarts exactly at the path end and the round linecap paints a stray
   dot there — the oversized gap keeps the whole path inside one gap instead. */
.gauge-value{fill:none;stroke:url(#gaugeGrad);stroke-width:12;stroke-linecap:round;stroke-dasharray:100 200;stroke-dashoffset:14;
  transition:stroke-dashoffset var(--dur-normal) var(--ease-out-expo);filter:drop-shadow(0 0 6px rgba(255,140,35,0.25))}
.gauge-minor{fill:none;stroke:rgba(255,255,255,0.16);stroke-width:5;stroke-dasharray:0.5 4.5;stroke-dashoffset:0.25}
.gauge-major{fill:none;stroke:rgba(255,255,255,0.38);stroke-width:9;stroke-dasharray:1 24;stroke-dashoffset:0.5}
.gauge-nums text{fill:var(--text-muted);font-size:10px;font-weight:600;text-anchor:middle;font-family:var(--font-sans)}
.gauge-needle{transform-box:view-box;transform-origin:110px 118px;transform:rotate(64.8deg);
  transition:transform var(--dur-normal) var(--ease-overshoot)}
.gauge-needle line{stroke:var(--orange);stroke-width:3.5;stroke-linecap:round;filter:drop-shadow(0 0 5px rgba(255,140,35,0.7))}
.gauge-needle .hub{fill:#1A2030;stroke:rgba(255,255,255,0.25);stroke-width:1}
.gauge-needle .hub-dot{fill:var(--orange)}
.gauge-center{position:absolute;left:0;right:0;bottom:4px;text-align:center;pointer-events:none}
.gauge-pct{display:block;font-size:clamp(1.8rem,3vw,2.4rem);font-weight:700;color:var(--success);font-feature-settings:var(--tabular);line-height:1}
.gauge-center small{font-size:0.72rem;text-transform:uppercase;letter-spacing:0.08em;color:var(--text-muted)}

/* Side dials: BEFORE pegged in its carmine redline, AFTER idling near zero in teal */
.dial-track{fill:none;stroke:rgba(255,255,255,0.08);stroke-width:8;stroke-linecap:round}
.dial-zone{fill:none;stroke-width:8}
.dial-zone--red{stroke:rgba(178,54,63,0.55);stroke-dasharray:16 84;stroke-dashoffset:-84}
.dial-zone--teal{stroke:rgba(16,185,129,0.45);stroke-dasharray:22 78}
.dial-ticks{fill:none;stroke:rgba(255,255,255,0.2);stroke-width:5;stroke-dasharray:0.7 19.3;stroke-dashoffset:0.35}
.dial-needle{transform-box:view-box;transform-origin:60px 72px;transition:transform var(--dur-normal) var(--ease-overshoot)}
.dial-needle line{stroke-width:3;stroke-linecap:round}
.dial-needle circle{fill:#1A2030;stroke:rgba(255,255,255,0.22);stroke-width:1}
.dial--before .dial-needle{transform:rotate(77.4deg)}
.dial--before .dial-needle line{stroke:var(--carmine);filter:drop-shadow(0 0 4px rgba(178,54,63,0.7))}
.dial--after .dial-needle{transform:rotate(-66.6deg)}
.dial--after .dial-needle line{stroke:var(--success);filter:drop-shadow(0 0 4px rgba(16,185,129,0.6))}
.dial-readout{display:flex;align-items:baseline;gap:5px;margin-top:2px}
.dial-readout .label{font-size:0.7rem;text-transform:uppercase;letter-spacing:0.07em;color:var(--text-muted)}
.dial-readout .value{font-size:1.25rem;font-weight:700;font-feature-settings:var(--tabular);line-height:1.05}
.dial-readout .unit{font-size:0.72rem;color:var(--text-muted)}

/* Ignition sweep: needles swing to full scale and back, the arc chases, then both settle
   onto the live values (main.js parks everything at zero, then adds .ignite on scroll-in).
   Endpoints are per-element custom properties so one keyframe serves every dial. */
@keyframes needleSweep{
  0%{transform:rotate(-90deg)}
  10%{transform:rotate(-90deg);animation-timing-function:cubic-bezier(0.55,0,0.35,1)}
  58%{transform:rotate(88deg);animation-timing-function:cubic-bezier(0.5,0,0.35,1.1)}
  100%{transform:rotate(var(--needle-final,-90deg))}
}
@keyframes arcSweep{
  0%{stroke-dashoffset:100}
  10%{stroke-dashoffset:100;animation-timing-function:cubic-bezier(0.55,0,0.35,1)}
  58%{stroke-dashoffset:2;animation-timing-function:cubic-bezier(0.5,0,0.35,1.1)}
  100%{stroke-dashoffset:var(--arc-final,100)}
}
.ignite .gauge-needle,.ignite .dial-needle{animation:needleSweep 1.55s linear both}
.ignite .dial--before .dial-needle{animation-delay:100ms}
.ignite .dial--after .dial-needle{animation-delay:200ms}
.ignite .gauge-value{animation:arcSweep 1.55s linear both}
/* While the V12 rev sim drives the center dial (slider input), its CSS transitions step aside
   so the per-frame spring + flutter writes land raw. */
.rev-live .gauge-needle,.rev-live .gauge-value{transition:none}

/* Odometer: mechanical digit drums. Each cell is a masked window over a 0-9x2 strip;
   main.js rolls strips to the nearest matching digit via --odo-i. */
.odo-row{display:flex;flex-direction:column;align-items:center;gap:10px;margin:12px 0 4px}
.odo-label{font-size:0.82rem;font-weight:700;text-transform:uppercase;letter-spacing:0.12em;color:var(--text-secondary)}
/* Hero-scale drum (grilled 2026-07-28): the savings figure is the payoff of the whole
   instrument — it reads at pricing-card scale, not at trip-meter scale */
.odo{position:relative;display:flex;align-items:center;gap:3px;padding:10px 18px;border-radius:var(--radius-md);
  background:linear-gradient(180deg,rgba(0,0,0,0.5),rgba(0,0,0,0.28));border:1px solid rgba(255,255,255,0.08);
  box-shadow:inset 0 2px 6px rgba(0,0,0,0.6),inset 0 -1px 0 rgba(255,255,255,0.04);
  will-change:transform; /* keeps the odoLand swell's layer alive — demotion at animation end re-rasters the digit tile */
  font-size:clamp(1.9rem,1.3rem + 2.4vw,2.75rem);font-weight:700;font-feature-settings:var(--tabular)}
/* The landing glow is a dedicated overlay animated ONLY via opacity (compositor-safe).
   Never transition text-shadow/box-shadow on the drum or its cells: shadow blurs
   re-raster the whole readout tile every frame, and on slow raster paths the number
   visibly blanks to nothing mid-fade — that bug shipped twice; this overlay is the fix. */
.odo::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  box-shadow:0 0 0 1px rgba(16,185,129,0.38),0 0 44px rgba(16,185,129,0.3),inset 0 0 30px rgba(16,185,129,0.16);
  opacity:0;transition:opacity 700ms ease}
/* THE GLOW NEVER TURNS OFF once the number has landed (.odo-lit stays until the next
   replay parks the panel). Every fade-out shipped here — keyframe decay, 700ms ease,
   compositor fade — was reported as "the number blinks away": turning the payoff's
   light off reads as a glitch, not a rest state. Do not re-add a glow fade-out. */
.odo-lit .odo::after{opacity:1;transition-duration:200ms} /* fast bloom in, then held */
.odo-cur{color:var(--success);font-size:0.72em;margin-right:2px}
.odo-sep{color:var(--success);line-height:1}
.odo-unit{font-size:0.44em;color:var(--text-muted);font-weight:600;margin-left:6px;align-self:flex-end;padding-bottom:0.35em}
.odo-cell{position:relative;height:1.35em;width:0.72em;overflow:hidden;border-radius:3px;
  line-height:1.35em;text-align:center;color:var(--success);
  background:linear-gradient(180deg,#060910,#0D1220 50%,#060910);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,0.05)}
.odo-cell::after{content:"";position:absolute;inset:0;pointer-events:none;border-radius:inherit;
  background:linear-gradient(180deg,rgba(0,0,0,0.55),transparent 32%,transparent 68%,rgba(0,0,0,0.55))}
.odo-strip{display:block;transition:transform 560ms cubic-bezier(0.22,1,0.36,1);
  transform:translateY(calc(var(--odo-i,0) * -1.35em))}
.odo-strip i{display:block;height:1.35em;line-height:1.35em;font-style:normal}
.odo-cell.odo-dim .odo-strip{opacity:0.22}
/* Ignition roll: longer travel, cascading left to right */
.odo-ignite .odo-strip{transition-duration:1350ms;transition-delay:120ms}
.odo-ignite .odo-cell:nth-child(3) .odo-strip{transition-delay:180ms}
.odo-ignite .odo-cell:nth-child(5) .odo-strip{transition-delay:240ms}
.odo-ignite .odo-cell:nth-child(6) .odo-strip{transition-delay:300ms}
.odo-ignite .odo-cell:nth-child(7) .odo-strip{transition-delay:360ms}
.calc-annual{font-size:1.05rem;color:var(--text-secondary)}
.calc-annual span{color:var(--success);font-weight:700;font-size:1.12em;font-feature-settings:var(--tabular)}
/* Savings landing: slight swell on the drum the moment the sweep settles (.odo-land is
   added by main.js for ~1.5s, then removed). The glow itself is the .odo::after overlay
   defined above — transform-only keyframes here, opacity-only glow there, zero repaint
   of the digits during the whole payoff. */
.odo-land .odo{animation:odoLand 1.15s var(--ease-out-expo)}
@keyframes odoLand{
  0%,100%{transform:none}
  26%{transform:scale(1.045)}
}
/* NO night beat / no darkness of any kind around this moment: every darkness treatment
   tried here (opacity dim, brightness dim, spotlight pool, blackout veil) read as a dark
   flash on the freshly-landed number — do not add a fifth. And never animate text-shadow
   or box-shadow on the drum (see the .odo::after comment) — that was the OTHER blink. */

/* Engine-catch shake: two tiny cabin jolts synced to the throttle blips main.js fires
   right after the ignition sweep (.rev-shake lives ~1.1s) */
.rev-shake{animation:calcShake 1.1s linear}
@keyframes calcShake{
  0%,22%,52%,70%,100%{transform:none}
  6%{transform:translate(0,-1.6px) rotate(-0.12deg)}
  14%{transform:translate(0.6px,0.8px) rotate(0.1deg)}
  57%{transform:translate(0,-1.2px) rotate(-0.09deg)}
  63%{transform:translate(0.5px,0.6px) rotate(0.07deg)}
}

/* Conversion CTA: kicker + primary glow button rise in under the annual line after the first
   ignition settles. The .glare class (added by JS for ~2s, then removed) fires the button's
   btnGlare sweep once as it lands — it must NOT be left on permanently or its higher
   specificity would permanently shadow the :hover sweep declaration. */
.calc-demo-nudge{display:flex;flex-direction:column;align-items:center;gap:12px;margin:14px 0 4px;
  opacity:0;transform:translateY(10px);transition:opacity 600ms ease,transform 600ms var(--ease-out-expo)}
.calc-demo-nudge[hidden]{display:none} /* display:flex would otherwise defeat the hidden attribute */
.calc-demo-nudge.show{opacity:1;transform:none}
.nudge-kicker{font-size:0.85rem;color:var(--text-secondary)}
.calc-demo-nudge.glare .btn-primary{animation:btnGlare 1.2s ease-in-out 550ms 1}

/* Dead panel: until the starter is pressed the dials + odometer sit dim and desaturated.
   Scoped to .is-armed (added by JS) so no-JS visitors keep the full-brightness static seed. */
.cluster,.odo-row{transition:opacity 800ms ease,filter 800ms ease}
.calc-binnacle.is-armed:not(.is-lit) :is(.cluster,.odo-row){opacity:0.78;filter:saturate(0.5)}

/* Console controls: machined groove tracks, engraved panel lettering, knurled metal thumb,
   and the round ACTIVATE push-start at the end of the row (a real dash layout) */
.calc-controls{display:grid;grid-template-columns:1fr 1fr auto;gap:36px;margin-top:30px;padding-top:30px;border-top:1px solid var(--border-subtle)}
.calc-field--start{display:flex;align-items:center;justify-content:center;padding:0 4px}
.push-start{position:relative;width:124px;height:124px;border-radius:50%;cursor:pointer;font-family:inherit;
  display:grid;place-items:center;border:1px solid rgba(255,255,255,0.18);
  background:radial-gradient(circle at 34% 28%,#3A4356,#232A3A 55%,#141926 82%);
  box-shadow:0 0 0 4px rgba(15,19,31,0.9),0 0 0 5px rgba(255,255,255,0.09),
    inset 0 2px 3px rgba(255,255,255,0.12),inset 0 -6px 12px rgba(0,0,0,0.55);
  transition:transform var(--dur-fast) ease,filter var(--dur-fast) ease}
.push-start:hover{filter:brightness(1.12)}
.push-start:active{transform:translateY(1px) scale(0.96)}
.push-start:disabled{cursor:default}
/* Bezel lettering: "DEALER PAYMENTS" rides the top arc like stamped metal (upright glyphs only —
   the bottom arc gets two engraved dots as balance). One crank-spin on press, static otherwise. */
.ps-arc{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
.ps-arc-text{font-family:var(--font-sans);font-size:8.5px;font-weight:600;letter-spacing:0.14em;
  fill:rgba(216,224,238,0.8);text-anchor:middle;
  filter:drop-shadow(0 -1px 0 rgba(0,0,0,0.6))}
.ps-arc-dot{fill:rgba(216,224,238,0.32)}
.is-cranking .ps-arc{animation:psSpin 500ms var(--ease-out-expo)}
@keyframes psSpin{from{transform:rotate(-360deg)}to{transform:rotate(0deg)}}
.ps-ring{position:absolute;inset:7px;border-radius:50%;pointer-events:none;
  border:2px solid rgba(255,255,255,0.10);transition:border-color 300ms ease,box-shadow 300ms ease}
/* READY state (armed, engine off): the ring breathes a slow warm orange — a start button
   signals readiness with its ring, and the invitation state is the one that needs the
   light. The glow is a static-painted overlay breathing by OPACITY only (compositor —
   see the .odo::after lesson). Crank flicker and the steady lit ring take over from it. */
.ps-ring::after{content:"";position:absolute;inset:-2px;border-radius:50%;pointer-events:none;
  border:2px solid rgba(255,140,35,0.7);
  box-shadow:0 0 10px rgba(255,140,35,0.32),inset 0 0 7px rgba(255,140,35,0.16);
  opacity:0}
.calc-binnacle.is-armed:not(.is-lit):not(.is-cranking) .ps-ring::after{animation:psReady 2.8s ease-in-out infinite}
@keyframes psReady{0%,100%{opacity:0.08}50%{opacity:0.34}}
.is-lit .ps-ring{border-color:rgba(255,140,35,0.85);
  box-shadow:0 0 12px rgba(255,140,35,0.5),inset 0 0 10px rgba(255,140,35,0.25)}
.ps-face{display:flex;flex-direction:column;align-items:center;line-height:1}
.ps-face strong{font-size:0.82rem;font-weight:700;letter-spacing:0.13em;text-transform:uppercase;color:var(--text-primary)}
/* Ready lettering comes up a step: white with a faint warm cast until the engine is lit */
.calc-binnacle.is-armed:not(.is-lit) .ps-face strong{color:#fff;text-shadow:0 0 10px rgba(255,140,35,0.35)}
/* Starter crank: LED flickers and the parked needles shudder before the engine catches */
@keyframes ledFlicker{
  0%,100%{border-color:rgba(255,140,35,0.2)}
  20%{border-color:rgba(255,140,35,0.9)}
  40%{border-color:rgba(255,140,35,0.3)}
  60%{border-color:rgba(255,140,35,0.8)}
  80%{border-color:rgba(255,140,35,0.4)}
}
@keyframes crankJitter{
  0%,100%{transform:rotate(-90deg)}
  25%{transform:rotate(-86.5deg)}
  50%{transform:rotate(-89deg)}
  75%{transform:rotate(-85deg)}
}
.is-cranking .ps-ring{animation:ledFlicker 500ms linear}
.is-cranking .gauge-needle,.is-cranking .dial-needle{animation:crankJitter 260ms linear 2}
.calc-field-top{display:flex;justify-content:space-between;align-items:baseline;gap:12px;margin-bottom:10px}
.calc-field label{font-size:0.76rem;font-weight:600;text-transform:uppercase;letter-spacing:0.08em;color:var(--text-secondary)}
.calc-out{font-size:1.02rem;font-weight:700;color:var(--orange);font-feature-settings:var(--tabular);
  text-shadow:0 0 12px rgba(255,140,35,0.35)}
.calc-ticks{height:6px;margin-bottom:7px;
  background:repeating-linear-gradient(90deg,rgba(255,255,255,0.14) 0 1px,transparent 1px calc(100%/24));
  -webkit-mask:linear-gradient(90deg,transparent,#000 4% 96%,transparent);
  mask:linear-gradient(90deg,transparent,#000 4% 96%,transparent)}
.calc-scale{display:flex;justify-content:space-between;font-size:0.7rem;color:var(--text-muted);margin-top:9px;
  font-feature-settings:var(--tabular);letter-spacing:0.06em;text-shadow:0 1px 0 rgba(0,0,0,0.6)}
input[type=range]{-webkit-appearance:none;appearance:none;width:100%;height:10px;border-radius:6px;cursor:pointer;
  border:1px solid rgba(255,255,255,0.07);
  background:linear-gradient(90deg,#B2363F,var(--orange) var(--range-fill,50%),rgba(9,12,20,0.9) var(--range-fill,50%));
  box-shadow:inset 0 1px 3px rgba(0,0,0,0.7),inset 0 -1px 0 rgba(255,255,255,0.04),0 1px 0 rgba(255,255,255,0.05)}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:26px;height:26px;border-radius:50%;cursor:pointer;
  background:radial-gradient(circle at 34% 30%,#F2F4F7,#B9C1CC 40%,#59637A 72%,#262D3D);
  border:1px solid rgba(255,255,255,0.35);
  box-shadow:0 0 0 3px rgba(11,15,26,0.9),0 0 10px rgba(255,140,35,0.45),0 2px 6px rgba(0,0,0,0.5);
  transition:transform var(--dur-fast) ease}
input[type=range]::-webkit-slider-thumb:hover{transform:scale(1.12)}
input[type=range]::-moz-range-thumb{width:26px;height:26px;border-radius:50%;cursor:pointer;
  background:radial-gradient(circle at 34% 30%,#F2F4F7,#B9C1CC 40%,#59637A 72%,#262D3D);
  border:1px solid rgba(255,255,255,0.35);
  box-shadow:0 0 0 3px rgba(11,15,26,0.9),0 0 10px rgba(255,140,35,0.45),0 2px 6px rgba(0,0,0,0.5)}
input[type=range]:focus-visible{box-shadow:var(--focus-ring)}

/* Credit/debit mix reads as its own diagram: the track IS 100% of card volume and the
   thumb splits it — credit share in the brand ramp left of the thumb, debit share in
   quiet teal right of it (teal = the cheap 1.05% side, matching the After dial) */
input#calcSplit{background:linear-gradient(90deg,#B2363F,var(--orange) var(--range-fill,50%),
  rgba(16,185,129,0.5) var(--range-fill,50%),rgba(16,185,129,0.26))}

/* Drag readout chip riding the thumb (JS-positioned via left/top; aria-hidden — the
   .calc-out echo stays the accessible value). Engraved console chip, not a tooltip. */
.calc-field{position:relative}
.calc-bubble{position:absolute;transform:translate(-50%,-136%);padding:3px 10px;border-radius:6px;
  background:linear-gradient(180deg,#141A2A,#0B0F1A);border:1px solid rgba(255,255,255,0.14);
  box-shadow:0 3px 10px rgba(0,0,0,0.55),inset 0 1px 0 rgba(255,255,255,0.06);
  font-size:0.78rem;font-weight:700;color:var(--orange);font-feature-settings:var(--tabular);
  white-space:nowrap;pointer-events:none;z-index:3;opacity:0;transition:opacity 140ms ease}
.calc-bubble::after{content:"";position:absolute;left:50%;bottom:-4px;width:8px;height:8px;
  transform:translateX(-50%) rotate(45deg);background:#0B0F1A;
  border-right:1px solid rgba(255,255,255,0.14);border-bottom:1px solid rgba(255,255,255,0.14)}
.calc-bubble.show{opacity:1}

.calc-note{font-size:0.8rem;color:var(--text-muted);margin-top:24px;margin-inline:auto;text-align:center;text-wrap:balance}

/* ---------- 10. TABLES ---------- */
.table-wrap{overflow-x:auto;border-radius:var(--radius-lg);border:1px solid var(--border-color);margin-bottom:28px}
table{width:100%;border-collapse:collapse;min-width:560px}
th{background:var(--bg-elevated);color:var(--orange);text-transform:uppercase;font-size:0.75rem;letter-spacing:var(--tracking-wide);
  font-weight:700;text-align:left;padding:16px 20px}
/* Faint row lift under the cursor — row tracking in wide tables (2026-07-24) */
tbody tr{transition:background-color 150ms ease}
tbody tr:hover{background-color:rgba(255,255,255,0.035)}
td{padding:15px 20px;border-top:1px solid var(--border-subtle);font-size:0.92rem;color:var(--text-secondary)}
td:first-child{color:var(--text-primary);font-weight:500}
.check{color:var(--success);font-weight:600} .cross{color:var(--text-muted)}
.check::before{content:"\2713  ";font-weight:700} .cross::before{content:"\2715  "}
.negative{color:var(--text-muted)} .highlight{color:var(--success);font-weight:600}
/* Tech callout — "notched spec plate" (2026-07-28): hairline frame, label cut into
   the top edge. Replaced the orange left-bar admonition card sitewide (owner call —
   the left-bar + orange-heading shape read as template). <=768px the notch retires
   and the label steps inside the frame as an in-flow eyebrow so long headings wrap. */
.tech-callout{position:relative;margin-top:10px;padding:32px 32px 27px;
  border-radius:var(--radius-sm);background:rgba(255,255,255,0.015);
  border:1px solid rgba(255,255,255,0.10)}
.tech-callout h4{position:absolute;top:0;left:20px;transform:translateY(-50%);
  margin:0;background:var(--bg-primary);padding:0 12px;
  display:flex;align-items:center;gap:10px;white-space:nowrap;
  font-size:0.72rem;font-weight:600;letter-spacing:0.16em;text-transform:uppercase;
  color:var(--text-primary)}
.tech-callout h4::before{content:"";width:16px;height:2px;background:var(--gradient-brand);flex:none}
.tech-callout p{font-size:0.98rem;margin:0}
@media (max-width:768px){
  .tech-callout{padding:24px 22px}
  .tech-callout h4{position:static;transform:none;background:transparent;padding:0;
    margin:0 0 12px;white-space:normal;line-height:1.6;align-items:flex-start;letter-spacing:0.12em}
  .tech-callout h4::before{margin-top:6px}
}

/* ---------- 11. SECURITY: encrypt-a-live-card pipeline ---------- */
.enc-demo{position:relative;isolation:isolate;max-width:1120px;margin:0 auto 40px;
  display:flex;flex-direction:column;align-items:center;gap:28px}

/* --- terminal card (the real <button>) --- */
.enc-terminal-col{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center}
.enc-terminal{position:relative;display:block;padding:0;border:none;background:none;cursor:pointer;border-radius:18px}
.enc-terminal:focus-visible{outline:none;box-shadow:var(--focus-ring)}
/* real credit-card proportions: ISO 7810 ID-1 is 1.585:1 (was ~2.6:1 — too long/short) */
.enc-card{display:flex;flex-direction:column;justify-content:space-between;width:min(360px,86vw);aspect-ratio:1.585;
  padding:22px 24px;border-radius:14px;text-align:left;
  background:linear-gradient(150deg,#222c46 0%,#141b2e 58%,#0e1424 100%);
  border:1px solid rgba(255,255,255,0.10);
  box-shadow:var(--shadow-lg),inset 0 1px 0 rgba(255,255,255,0.06);
  transition:transform var(--dur-fast) ease,box-shadow var(--dur-normal) ease}
.enc-terminal:hover .enc-card{transform:translateY(-4px)}
.enc-terminal:active .enc-card{transform:translateY(-1px) scale(0.99)}
/* pulsing "ping" ring — makes it unmistakable the card is clickable (idle only) */
.enc-terminal::after{content:"";position:absolute;inset:0;border-radius:14px;pointer-events:none;border:2px solid var(--orange);opacity:0}
.enc-demo:not(.is-running):not(.is-secure) .enc-terminal::after{animation:encPing 2s ease-out infinite}
@keyframes encPing{0%{opacity:0.75;transform:scale(1)}70%,100%{opacity:0;transform:scale(1.06)}}
/* capture punch: the terminal jolts as encryption fires (beat 1) */
.enc-card.enc-punch{animation:encPunch 200ms var(--ease-out-expo)}
@keyframes encPunch{0%{transform:translateY(0) scale(1)}32%{transform:translateY(2px) scale(0.955)}100%{transform:translateY(0) scale(1)}}
/* idle glow invites the click; suppressed while running/sealed */
.enc-demo:not(.is-running):not(.is-secure) .enc-card{animation:encGlow 2.4s ease-in-out infinite}
@keyframes encGlow{0%,100%{box-shadow:var(--shadow-lg),0 0 0 0 rgba(255,140,35,0)}
  50%{box-shadow:var(--shadow-lg),0 0 40px 2px rgba(255,140,35,0.55)}}
.enc-card-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:0}
.enc-card-chip{position:relative;width:34px;height:26px;border-radius:6px;
  background:linear-gradient(135deg,#efc963,#b9822b);box-shadow:inset 0 0 0 1px rgba(0,0,0,0.25)}
.enc-card-chip::after{content:"";position:absolute;inset:5px 7px;border:1px solid rgba(0,0,0,0.25);border-radius:1px}
.enc-card-wave{width:22px;height:22px;color:var(--orange)}
.enc-pan{display:flex;align-items:center;gap:2px;font-weight:700;font-size:1.18rem;letter-spacing:0.01em;
  color:var(--text-primary);font-variant-numeric:tabular-nums}
.enc-digit{display:inline-block;width:0.66em;text-align:center;transition:color var(--dur-fast) ease}
.enc-gap{display:inline-block;width:0.5em}
/* ciphertext: orange while being captured, teal once "in transit / secure" */
.enc-pan.is-cipher .enc-digit{color:var(--orange);text-shadow:0 0 10px rgba(255,140,35,0.35)}
.enc-demo.is-transit .enc-pan.is-cipher .enc-digit,
.enc-demo.is-decrypt .enc-pan.is-cipher .enc-digit,
.enc-demo.is-secure  .enc-pan.is-cipher .enc-digit{color:var(--success);text-shadow:0 0 10px rgba(16,185,129,0.4)}
.enc-card-foot{display:flex;align-items:center;justify-content:space-between;margin-top:0;
  font-size:0.7rem;text-transform:uppercase;letter-spacing:0.08em;color:var(--text-muted)}
.enc-card-state{font-weight:700;color:var(--orange);transition:color var(--dur-normal) ease}
.enc-demo.is-secure .enc-card-state{color:var(--success)}

/* --- click prompt: two states stacked in one grid cell so swapping never reflows --- */
.enc-cta{display:inline-grid;justify-items:center;margin-top:20px;font-size:0.92rem;font-weight:700}
.enc-cta-state{grid-area:1/1;display:inline-flex;align-items:center;gap:9px;padding:10px 20px;border-radius:var(--radius-pill);
  border:1px solid transparent;transition:opacity var(--dur-normal) ease}
.enc-cta svg{width:18px;height:18px;flex:none}
/* FIRST-click prompt: a bright, gently BOUNCING orange pill — unmistakably clickable */
.enc-cta-state--run{color:var(--orange);background:rgba(255,140,35,0.14);border-color:rgba(255,140,35,0.55)}
.enc-demo:not(.is-running):not(.is-secure) .enc-cta-state--run{animation:encCtaBounce 1.7s ease-in-out infinite}
@keyframes encCtaBounce{0%,100%{transform:translateY(0)}50%{transform:translateY(-5px)}}
/* replay is calmer once they've already seen it run */
.enc-cta-state--again{color:var(--text-secondary);background:rgba(255,255,255,0.04);border-color:var(--border-color)}
.enc-demo.is-secure .enc-cta-state--run,
.enc-demo:not(.is-secure) .enc-cta-state--again{opacity:0;visibility:hidden}

/* --- connected 4-beat pipeline: rail + traveling comet behind the node row --- */
.enc-flow{position:relative;z-index:1;width:100%}
.enc-rail{position:absolute;left:12.5%;right:12.5%;top:26px;height:2px;border-radius:2px;
  background:var(--border-color);pointer-events:none}
.enc-rail-fill{position:absolute;left:0;top:0;height:100%;width:0;border-radius:2px;
  background:linear-gradient(90deg,var(--orange),var(--success));box-shadow:0 0 9px rgba(255,140,35,0.55);
  transition:width .7s var(--ease-out-expo)}
.enc-comet{position:absolute;top:50%;left:0;width:12px;height:12px;margin:-6px 0 0 -6px;border-radius:50%;
  background:#fff;box-shadow:0 0 16px 4px rgba(255,140,35,0.9),0 0 5px 1px #fff;opacity:0;
  transition:left .7s var(--ease-out-expo),opacity .3s ease}
/* comet wake: a glowing streak trailing behind as it charges down the rail */
.enc-comet::before{content:"";position:absolute;top:50%;right:5px;transform:translateY(-50%);
  width:46px;height:4px;border-radius:3px;pointer-events:none;opacity:0;
  background:linear-gradient(270deg,rgba(255,170,80,0.85),rgba(255,140,35,0));transition:opacity .3s ease}
.enc-demo.is-running .enc-comet::before{opacity:1}
.enc-demo[data-beat="1"] .enc-comet{left:0;opacity:1}
.enc-demo[data-beat="2"] .enc-rail-fill{width:33.33%}
.enc-demo[data-beat="2"] .enc-comet{left:33.33%;opacity:1}
.enc-demo[data-beat="3"] .enc-rail-fill{width:66.66%}
.enc-demo[data-beat="3"] .enc-comet{left:66.66%;opacity:1}
.enc-demo[data-beat="4"] .enc-rail-fill{width:100%}
.enc-demo[data-beat="4"] .enc-comet{left:100%;opacity:1}
/* at the finale the comet DISSOLVES before it parks on "Your Exposure" (opacity fades faster
   than it travels) — the rail-fill still completes the connection, but no light sits on the far card */
.enc-demo.is-secure .enc-comet{opacity:0}

/* --- steps: <ol> with markers killed (bug fix); dim-until-active only when JS arms it --- */
.enc-steps{position:relative;list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(4,1fr);gap:18px}
.enc-step{position:relative;display:flex;flex-direction:column;align-items:center;text-align:center;gap:12px;
  transition:opacity .4s ease,transform .4s var(--ease-out-expo),filter .4s ease}
.enc-demo.is-armed .enc-step{opacity:.4;filter:saturate(.55)}
.enc-demo.is-armed .enc-step.is-active{opacity:1;filter:none;transform:translateY(-3px)}
.enc-demo.is-armed .enc-step.is-done{opacity:.85;filter:none}
.enc-node{position:relative;z-index:1;width:52px;height:52px;border-radius:15px;display:grid;place-items:center;
  color:var(--text-muted);background:var(--bg-elevated);border:1px solid var(--border-color);
  transition:color .4s ease,background .4s ease,border-color .4s ease,box-shadow .4s ease,transform .4s var(--ease-out-expo)}
.enc-node svg{width:24px;height:24px}
/* the active step's icon GROWS while the beat is on it (each node in turn); returns to size once done */
.enc-step.is-active .enc-node{color:var(--text-inverse);background:var(--gradient-brand);border-color:transparent;transform:scale(1.12);
  box-shadow:0 0 0 5px rgba(255,140,35,0.12),0 8px 22px -10px rgba(255,140,35,0.7)}
.enc-step.is-done .enc-node{color:var(--success);background:rgba(16,185,129,0.12);border-color:rgba(16,185,129,0.4)}
/* node 4 ("Your Exposure") grows like the others when active but casts NO glow (user: no light on the far card) */
.enc-step[data-step="4"].is-active .enc-node{color:var(--success);background:rgba(16,185,129,0.16);border-color:transparent;box-shadow:none}
.enc-step-txt{display:flex;flex-direction:column;gap:3px}
.enc-step-txt b{font-size:1rem;color:var(--text-primary)}
.enc-step-txt span{font-size:0.82rem;color:var(--text-secondary);line-height:1.4}
.enc-step[data-step="4"] .enc-step-txt strong{color:var(--success)}

/* --- payoff: seal + label + value chip --- */
.enc-payoff{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;gap:14px}
.enc-seal-label{font-size:0.8rem;font-weight:700;letter-spacing:0.05em;text-transform:uppercase;color:var(--success)}
.enc-value-chip{display:inline-flex;align-items:center;gap:9px;padding:7px 15px;border-radius:var(--radius-pill);
  background:rgba(16,185,129,0.10);border:1px solid rgba(16,185,129,0.28);font-size:0.86rem}
.enc-value-chip s{color:var(--text-muted);text-decoration-thickness:1px}
.enc-value-chip svg{width:16px;height:16px;color:var(--text-muted)}
.enc-value-chip b{color:var(--success);font-weight:700}

/* --- converge burst: ciphertext tokens implode into the seal (WAAPI, built in JS) --- */
.enc-burst{position:absolute;width:0;height:0;pointer-events:none;z-index:2}
.enc-token{position:absolute;left:0;top:0;transform:translate(-50%,-50%);font-size:0.7rem;font-weight:700;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--success);
  text-shadow:0 0 8px rgba(16,185,129,0.8);will-change:transform,opacity}

/* ---------- Promoted authority stat band ---------- */
/* real dark liquid-glass slab (flow-body recipe) so it reads as a surface on near-black */
.trust-band{position:relative;display:flex;align-items:center;gap:22px;padding:26px 30px;margin-bottom:26px;
  border-radius:var(--radius-lg);border:1px solid transparent;overflow:hidden;
  background:
    linear-gradient(160deg,rgba(255,255,255,0.05),rgba(255,255,255,0) 42%) padding-box,
    linear-gradient(rgba(7,10,18,0.62),rgba(7,10,18,0.62)) padding-box,
    linear-gradient(168deg,rgba(255,255,255,0.20),rgba(255,255,255,0.05) 30%,rgba(255,255,255,0.02) 62%,rgba(255,255,255,0.10)) border-box;
  -webkit-backdrop-filter:blur(22px) saturate(1.5);backdrop-filter:blur(22px) saturate(1.5);
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.10),inset 0 -16px 30px -20px rgba(0,0,0,0.45)}
.trust-band::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(130% 80% at 12% -10%,rgba(16,185,129,0.10),rgba(255,255,255,0) 55%)}
.trust-seal{position:relative;flex:none;width:58px;height:58px;border-radius:50%;display:grid;place-items:center;
  color:var(--success);background:rgba(16,185,129,0.10);border:1px solid rgba(16,185,129,0.32)}
.trust-seal svg{width:30px;height:30px}
.trust-stat{position:relative;flex:none;display:flex;flex-direction:column;line-height:1}
.trust-stat .count{font-size:2.6rem;font-weight:800;color:var(--orange);letter-spacing:-0.01em}
.trust-stat small{font-size:0.72rem;text-transform:uppercase;letter-spacing:0.08em;color:var(--text-muted);margin-top:5px}
.trust-copy{position:relative;font-size:0.98rem;color:var(--text-secondary);
  border-left:1px solid var(--border-color);padding-left:22px}
.trust-copy strong{color:var(--text-primary);font-weight:600}

/* ---------- Battle-card table — scoped to .security-table only (shared table/th/td + #cdk untouched) ---------- */
.security-table{min-width:600px}
.security-table thead th{border-bottom:1px solid var(--border-color)}
.security-table th:nth-child(2){color:var(--carmine)}
.security-table th:nth-child(3){color:var(--success)}
.security-table th:nth-child(2),.security-table td.negative{background:rgba(178,54,63,0.06)}
.security-table th:nth-child(3),.security-table td.highlight{background:rgba(16,185,129,0.07);
  box-shadow:inset 1px 0 0 rgba(16,185,129,0.22),inset -1px 0 0 rgba(16,185,129,0.22)}
.security-table td.negative{color:var(--text-secondary)}
.security-table td.negative::before{content:"\2715\00a0\00a0";color:var(--carmine);font-weight:800}
.security-table td.highlight{color:var(--success);font-weight:600}
.security-table td.highlight::before{content:"\2713\00a0\00a0";color:var(--success);font-weight:800}
/* emphasize the killer deltas: 329->21 and ~$130K/yr->$0 */
.security-table tr.enc-key td.negative,.security-table tr.enc-key td.highlight{font-size:1.05rem;font-weight:800}
.security-table tr.enc-key td.negative{color:var(--text-primary)}

/* ---------- tighten vertical dead-space ---------- */
#security .section-header{margin-bottom:var(--space-6)}
#security .table-wrap{margin-bottom:0}   /* last element in the section */

/* ---------- 11b. SECURITY PROOF BAND (slim homepage beat — Wave 1 cutover) ----------
   The homepage's #security section is now ONE glass slab: shield + claim on the left, the
   three killer numbers on the right, and a handoff link to /security/ (where the full
   encryption demo + trust band + comparison table moved). Glass recipe = .trust-band's
   (gradient rim as the border-box layer, teal cast), so the two read as siblings once the
   trust band re-appears on /security/. */
.sec-band{position:relative;display:grid;grid-template-columns:1.25fr auto;gap:20px 44px;align-items:center;
  padding:36px 40px;border-radius:var(--radius-lg);border:1px solid transparent;overflow:hidden;
  background:
    linear-gradient(160deg,rgba(255,255,255,0.05),rgba(255,255,255,0) 42%) padding-box,
    linear-gradient(rgba(7,10,18,0.62),rgba(7,10,18,0.62)) padding-box,
    linear-gradient(168deg,rgba(255,255,255,0.20),rgba(255,255,255,0.05) 30%,rgba(255,255,255,0.02) 62%,rgba(255,255,255,0.10)) border-box;
  -webkit-backdrop-filter:blur(22px) saturate(1.5);backdrop-filter:blur(22px) saturate(1.5);
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.10),inset 0 -16px 30px -20px rgba(0,0,0,0.45)}
.sec-band::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(130% 80% at 12% -10%,rgba(16,185,129,0.10),rgba(255,255,255,0) 55%)}
.sec-band-head{position:relative;display:flex;gap:22px;align-items:flex-start}
.sec-band-seal{flex:none;width:58px;height:58px;border-radius:50%;display:grid;place-items:center;margin-top:4px;
  color:var(--success);background:rgba(16,185,129,0.10);border:1px solid rgba(16,185,129,0.32)}
.sec-band-seal svg{width:30px;height:30px}
.sec-band .eyebrow{margin-bottom:8px}
.sec-band h2{font-size:clamp(1.45rem,1.05rem + 1.6vw,2.05rem);margin-bottom:10px;max-width:22ch}
.sec-band-head p{font-size:0.97rem;max-width:52ch}
.sec-band-stats{position:relative;display:grid;gap:16px;border-left:1px solid var(--border-color);padding-left:40px}
.sec-band-stats li{display:flex;flex-direction:column;line-height:1.2}
.sec-band-stats strong{font-size:1.4rem;font-weight:800;color:var(--success);
  font-variant-numeric:tabular-nums;font-feature-settings:var(--tabular)}
.sec-band-stats span{font-size:0.8rem;color:var(--text-muted)}
.sec-band-link{position:relative;grid-column:1 / -1;justify-self:start;display:inline-flex;align-items:center;gap:8px;
  color:var(--orange);font-weight:600;font-size:0.98rem}
.sec-band-link svg{width:16px;height:16px;transition:transform var(--dur-fast) ease}
.sec-band-link:hover svg{transform:translateX(4px)}
@media (max-width:900px){
  .sec-band{grid-template-columns:1fr;padding:30px 26px}
  .sec-band-stats{border-left:none;border-top:1px solid var(--border-color);
    padding:20px 0 0;grid-template-columns:repeat(3,auto);gap:24px;justify-content:start}
}
@media (max-width:520px){
  .sec-band-head{flex-direction:column}
  .sec-band-stats{grid-template-columns:1fr;gap:14px}
}

/* ---------- SECURITY responsive (self-contained; replaces the deleted .security-steps rule at old line 1243) ---------- */
@media (max-width:1024px){
  .enc-steps{grid-template-columns:repeat(2,1fr);gap:26px 18px}
  .enc-rail,.enc-comet{display:none}   /* the horizontal comet only makes sense in one row */
}
@media (max-width:768px){
  .enc-steps{grid-template-columns:1fr;gap:0}
  .enc-step{flex-direction:row;text-align:left;gap:16px;padding:14px 0}
  .enc-step-txt{align-items:flex-start}
  .enc-steps::before{content:"";position:absolute;left:25px;top:30px;bottom:30px;width:2px;border-radius:2px;
    background:var(--border-color)}   /* vertical spine keeps the beats connected when stacked */
  .trust-band{flex-direction:column;text-align:center;gap:14px}
  .trust-copy{border-left:none;border-top:1px solid var(--border-color);padding:14px 0 0}
}

/* ---------- 12. INCLUDED — ZERO-OUT LEDGER ----------
   A designed dealer "statement". As each row scrolls into view its sticker price is
   aggressively slashed (carmine) and a green "FREE" stamps in; the total counts up to
   $2,900 on scroll, and the "$0 to get started · $99/month" payoff sits below with the
   Book-a-Demo CTA. No button — the reveal is scroll-driven (the row-strike cascade is
   the delight moment). Rest / no-JS / reduced-motion floor = the honest end state (every
   line "FREE", full total, payoff visible); JS adds .is-armed (hide FREE, show the price)
   so there is something to reveal, then per-row .is-struck fires the slash + stamp. */
/* /pricing/ page: small print under the rate cards + the worked-math payoff line */
.rate-note{max-width:72ch;margin:-24px auto 0;text-align:center;font-size:0.85rem;color:var(--text-muted)}
.rate-note a{color:var(--orange)}
.math-payoff{max-width:56ch;margin:0 auto var(--space-6);text-align:center;font-size:var(--text-body)}

/* Intro for the ledger now that it lives INSIDE #pricing (the old #included section header) */
.included-head{max-width:760px;margin:var(--space-9) auto var(--space-6);text-align:center}
.included-head h3{font-size:clamp(1.6rem,1.1rem + 2vw,2.4rem);margin-bottom:12px}
.included-head p{font-size:var(--text-body)}
.value-ledger{position:relative;max-width:860px;margin:0 auto;padding:6px 0 8px;
  border-radius:var(--radius-lg);overflow:hidden}
.value-ledger::before{content:"";position:absolute;top:0;left:0;right:0;height:2px;
  background:var(--gradient-brand)}
.ledger{list-style:none;margin:0;padding:0}
.ledger-row{position:relative;overflow:hidden;display:grid;grid-template-columns:auto 1fr auto;align-items:center;
  gap:18px;padding:16px 26px;border-bottom:1px solid var(--border-color)}
/* green light that sweeps L->R across a row as it is "freed" (clipped by overflow) */
.ledger-row::after{content:"";position:absolute;inset:0;pointer-events:none;opacity:0;transform:translateX(-100%);
  background:linear-gradient(100deg,transparent 30%,rgba(34,197,94,0.30) 50%,transparent 70%)}
.ledger-icon{display:grid;place-items:center;width:46px;height:46px;border-radius:12px;
  background:rgba(255,140,35,0.10);color:var(--orange);
  transition:background var(--dur-normal) ease,color var(--dur-normal) ease}
.ledger-icon svg{width:22px;height:22px}
.ledger-main{min-width:0}
.ledger-name{display:block;font-weight:600;font-size:1.05rem;color:var(--text-primary)}
.ledger-desc{display:block;font-size:0.85rem;color:var(--text-secondary);margin-top:2px}
/* value cell: crossed price + green "FREE" sit SIDE BY SIDE and BOTH persist at rest, so
   "$800 -> FREE" reads even if the animation is missed. FREE holds its slot via opacity so
   the price never shifts when it lands. */
.ledger-value{display:inline-flex;align-items:baseline;gap:9px;justify-self:end;white-space:nowrap;
  font-variant-numeric:tabular-nums}
.lv-was{color:var(--text-muted);font-weight:600;font-size:0.9rem;position:relative}
.lv-free{color:#22C55E;font-weight:800;font-size:0.95rem;letter-spacing:0.06em;text-transform:uppercase;
  text-shadow:0 0 12px rgba(34,197,94,0.4)}
/* strike over the price: calm GRAY at rest. .is-armed sets it carmine + scaleX(0); .is-struck
   transitions it back to scaleX(1) gray, so it draws left->right while cooling red->gray. */
.ledger-value[data-value] .lv-was::after{content:"";position:absolute;left:-3px;right:-3px;top:50%;
  height:2px;border-radius:2px;background:var(--text-secondary);box-shadow:none;
  transform:translateY(-50%) scaleX(1);transform-origin:left center}
/* feature row (Ingenico): scale contrast + brand edge */
.ledger-row--feature::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;
  background:var(--gradient-brand)}
.ledger-row--feature .ledger-icon{width:56px;height:56px}
.ledger-row--feature .ledger-icon svg{width:26px;height:26px}
.ledger-row--feature .ledger-name{font-size:1.2rem}
@media (hover:hover){
  .ledger-row:hover .ledger-icon{background:rgba(255,140,35,0.20);color:#ffd9a8}
}
/* ---- Foot: total + push-start + payoff ---- */
.ledger-foot{text-align:center;padding:30px 26px 6px}
.ledger-total{display:flex;flex-direction:column;align-items:center;gap:2px;margin-bottom:22px}
.lt-label{font-size:0.78rem;text-transform:uppercase;letter-spacing:0.08em;
  color:var(--text-muted);font-weight:600}
.lt-figure{font-size:clamp(2.6rem,6vw,4rem);font-weight:800;line-height:1;color:var(--text-primary);
  font-variant-numeric:tabular-nums;font-feature-settings:var(--tabular)}
/* payoff — visible by default (no-JS/reduced), hidden while armed, stamps in on settle */
.value-result{margin-top:22px;display:flex;flex-direction:column;align-items:center;gap:16px}
.vr-price{font-size:clamp(1.25rem,3vw,1.75rem);font-weight:600;color:var(--text-primary)}
.vr-zero{color:var(--orange);font-weight:800}
.vr-price strong{color:var(--orange);font-weight:800}
.vr-dot{color:var(--text-muted);margin:0 6px}
/* ---- STATE: scroll-driven ripple ----
   No-JS / reduced-motion never arm, so the honest END state shows: every priced line crossed
   out (gray) beside green "FREE", full total, payoff. JS adds .is-armed (un-strike the price to
   carmine-scaleX0, hide FREE) = the "before"; the ripple adds .is-struck per row. The PERSISTENT
   result (gray strike drawn + FREE shown) is reached by TRANSITION toward declared targets, so a
   row can never get stuck mid-flip. The green light sweep + the shake are the only @keyframes
   animations and are purely additive (a row missing them still ends in the correct state). */
.value-ledger.is-armed .ledger-value[data-value] .lv-was::after{transform:translateY(-50%) scaleX(0)}
.value-ledger.is-armed .lv-free{opacity:0;transform:scale(.7)}
/* prices glare RED while you scroll (the cost), then drain to gray as the green slash kills them */
.value-ledger.is-armed .ledger-value[data-value] .lv-was{color:var(--carmine);font-weight:700}
.value-ledger.is-armed .ledger-row.is-struck .ledger-value[data-value] .lv-was{
  color:var(--text-muted);font-weight:600;transition:color .45s ease}
.value-ledger.is-armed .ledger-row.is-struck .ledger-value[data-value] .lv-was::after{
  transform:translateY(-50%) scaleX(1);background:var(--text-secondary);box-shadow:none;
  transition:transform .28s var(--ease-overshoot);animation:slashFlash .45s ease-out}
/* the cut itself flashes aggressive green, then the crossing line settles to a neutral cross-out */
@keyframes slashFlash{0%{background:#22C55E;box-shadow:0 0 16px rgba(34,197,94,0.95)}
  55%{background:#22C55E;box-shadow:0 0 12px rgba(34,197,94,0.85)}
  100%{background:var(--text-secondary);box-shadow:none}}
.value-ledger.is-armed .ledger-row.is-struck .lv-free{opacity:1;transform:scale(1);
  transition:opacity .3s ease,transform .4s var(--ease-overshoot)}
.value-ledger.is-armed .ledger-row.is-struck::after{animation:rowSweep .6s ease-out}
.value-ledger.is-armed .ledger-row.is-struck .lv-was{animation:priceShake .3s ease}
@keyframes rowSweep{0%{opacity:0;transform:translateX(-100%)}22%{opacity:1}100%{opacity:0;transform:translateX(100%)}}
@keyframes priceShake{0%,100%{transform:translateX(0)}18%{transform:translateX(-3px)}
  38%{transform:translateX(3px)}58%{transform:translateX(-2px)}78%{transform:translateX(2px)}}
/* one-time CTA glare as the payoff scrolls into view (removed by JS so :hover keeps working) */
.value-result.glare .btn-primary{animation:btnGlare 1.2s ease-in-out 1}
/* whole-panel green energy flash the instant the whole list is axed to FREE (.is-axing, main.js) */
.value-ledger::after{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;opacity:0;
  background:radial-gradient(120% 70% at 50% 45%,rgba(34,197,94,0.20),transparent 70%)}
.value-ledger.is-axing::after{animation:ledgerFlash .8s ease-out}
@keyframes ledgerFlash{0%{opacity:0}25%{opacity:1}100%{opacity:0}}
/* rumble: the whole ledger vibrates with intensifying amplitude right before the axe hits */
.value-ledger.is-rumbling{animation:ledgerRumble .72s cubic-bezier(.36,.07,.19,.97)}
@keyframes ledgerRumble{
  0%{transform:translate(0,0)}7%{transform:translate(-1px,1px)}14%{transform:translate(1px,-1px)}
  21%{transform:translate(-1px,-1px)}28%{transform:translate(2px,1px)}35%{transform:translate(-2px,1px)}
  42%{transform:translate(2px,-1px)}50%{transform:translate(-2px,-1px)}58%{transform:translate(2px,1px)}
  65%{transform:translate(-3px,1px)}72%{transform:translate(3px,-1px)}80%{transform:translate(-3px,1px)}
  88%{transform:translate(2px,-1px)}94%{transform:translate(-1px,1px)}100%{transform:translate(0,0)}}
@media (max-width:768px){
  .ledger-row{padding:14px 16px;gap:14px}
  .ledger-row--feature .ledger-name{font-size:1.1rem}
  .ledger-foot{padding:26px 16px 4px}
}
@media (max-width:480px){
  .ledger-icon,.ledger-row--feature .ledger-icon{width:40px;height:40px}
  .ledger-icon svg,.ledger-row--feature .ledger-icon svg{width:20px;height:20px}
  .ledger-name,.ledger-row--feature .ledger-name{font-size:0.98rem}
  .ledger-desc{font-size:0.8rem}
  .ledger-value{font-size:0.85rem}
}

/* ---------- 13. GROWTH CARDS ---------- */
.growth-badge{display:inline-flex;align-items:center;gap:8px;padding:6px 14px;border-radius:var(--radius-pill);
  background:rgba(255,140,35,0.12);color:var(--orange);font-size:0.8rem;font-weight:600;margin-bottom:var(--space-4)}
/* GROWTH SUITE — service-bay tool tray. The 4 tools laid in a felt-lined drawer with brushed
   gunmetal name-plates. PASSIVE: on scroll-in (.fade-up -> .visible) a single sheen sweeps the
   felt once and the plates settle in staggered; static after. Orange is spent ONLY on the sheen
   + a top hairline (the one-accent rule the hero follows). No prices — value stays in the section
   header so it never echoes the $2,900 receipt in #included directly above. Reduced-motion/no-JS:
   reveals() adds .visible up front and the global reduced-motion reset collapses the sweep/stagger
   to an instant, honest, fully-shown state. */
.growth-tray{position:relative;max-width:940px;margin:0 auto;padding:14px;border-radius:var(--radius-lg);
  background:linear-gradient(180deg,#1b1f2a,#0e1119);border:1px solid var(--border-color);
  box-shadow:0 26px 60px rgba(0,0,0,0.5),inset 0 1px 0 rgba(255,255,255,0.06)}
/* the single spent accent besides the sheen: a brand hairline along the drawer lip */
.growth-tray::before{content:"";position:absolute;left:14px;right:14px;top:0;height:1px;border-radius:2px;
  background:var(--gradient-brand);opacity:0.55;pointer-events:none}
.gt-felt{position:relative;overflow:hidden;border-radius:calc(var(--radius-lg) - 5px);padding:clamp(16px,2.4vw,26px);
  background:repeating-linear-gradient(135deg,rgba(0,0,0,0.16) 0 2px,transparent 2px 5px),
    linear-gradient(180deg,#12151f,#0b0e16);
  box-shadow:inset 0 4px 18px rgba(0,0,0,0.75),inset 0 -1px 0 rgba(255,255,255,0.04)}
/* one-shot diagonal sheen — parked off-screen left, sweeps once when the tray reveals */
.gt-felt::after{content:"";position:absolute;inset:0;z-index:3;pointer-events:none;transform:translateX(-120%);
  background:linear-gradient(115deg,transparent 34%,rgba(255,140,35,0.16) 47%,rgba(255,255,255,0.10) 52%,transparent 66%)}
.growth-tray.visible .gt-felt::after{animation:traySheen 1.15s var(--ease-out-expo) 0.25s 1 forwards}
@keyframes traySheen{to{transform:translateX(120%)}}
.gt-slots{position:relative;z-index:1;display:grid;grid-template-columns:1fr 1fr;gap:clamp(12px,1.6vw,18px)}
.growth-slot{display:flex;align-items:center;gap:14px;padding:16px 18px;border-radius:var(--radius-md);
  background:linear-gradient(180deg,#20242e,#14171f);border:1px solid rgba(255,255,255,0.06);
  box-shadow:0 3px 8px rgba(0,0,0,0.5),inset 0 1px 0 rgba(255,255,255,0.05);
  opacity:0;transform:translateY(10px);
  transition:opacity var(--dur-slow) var(--ease-out-expo),transform var(--dur-slow) var(--ease-out-expo),
    border-color var(--dur-normal) ease}
.growth-tray.visible .growth-slot{opacity:1;transform:none}
.growth-tray.visible .growth-slot:nth-child(1){transition-delay:.05s}
.growth-tray.visible .growth-slot:nth-child(2){transition-delay:.13s}
.growth-tray.visible .growth-slot:nth-child(3){transition-delay:.21s}
.growth-tray.visible .growth-slot:nth-child(4){transition-delay:.29s}
/* machined gunmetal name-plate cradling the icon */
.gs-plate{flex:none;display:grid;place-items:center;width:46px;height:46px;border-radius:11px;color:#cfd4de;
  background:linear-gradient(180deg,#3a3f4b,#22262f);border:1px solid rgba(255,255,255,0.12);
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.18),inset 0 -2px 4px rgba(0,0,0,0.5),0 1px 2px rgba(0,0,0,0.5);
  transition:color var(--dur-normal) ease,border-color var(--dur-normal) ease}
.gs-plate svg{width:22px;height:22px}
.gs-text{min-width:0;display:flex;flex-direction:column;gap:2px}
.gs-name{font-weight:600;font-size:1.02rem;color:var(--text-primary);text-shadow:0 1px 0 rgba(0,0,0,0.5)}
.gs-benefit{font-size:0.86rem;color:var(--text-secondary)}
/* desktop hover is ambient polish only — the section is fully passive without it */
@media (hover:hover){
  .growth-slot:hover{border-color:rgba(255,140,35,0.22)}
  .growth-slot:hover .gs-plate{color:#ffd9a8;border-color:rgba(255,140,35,0.3)}
}
@media (max-width:640px){.gt-slots{grid-template-columns:1fr}}
/* reduced motion: drop the per-plate delay so plates appear with the tray, not staggered-late */
@media (prefers-reduced-motion:reduce){.growth-tray .growth-slot{transition-delay:0!important}}

/* ---------- 14. WHO WE SERVE ---------- */
.department-cards{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;margin-top:var(--space-8)}
.department-card{padding:26px;border-radius:var(--radius-card);text-align:center;transition:transform var(--dur-normal) var(--ease-out-expo),box-shadow var(--dur-normal) ease}
.department-card:hover{transform:translateY(-3px);box-shadow:var(--shadow-lg)}
.dept-icon{display:grid;place-items:center;width:50px;height:50px;margin:0 auto 14px;border-radius:12px;background:rgba(255,140,35,0.1);color:var(--orange)}
.dept-icon svg{width:24px;height:24px}
.department-card h4{font-size:1.05rem;margin-bottom:6px} .department-card p{font-size:0.85rem;margin:0}

/* ============ LIQUID GLASS — feature cards (Apple-style, restrained) ============ */
/* Subtle neutral frost that reveals the DARK content behind it (transparency the Apple way — not
   colored light), with a delicate luminous edge + gentle bevel. On-brand warm ambiance ONLY and
   kept very low so it never reads bright/harsh. NO filter:blur behind the glass — that repaints
   under backdrop-filter and causes the flashing. Low saturate keeps refracted color calm. */
.pain-card,.pricing-card,.principle-card{
  position:relative;isolation:isolate;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.055), rgba(255,255,255,0) 42%),   /* faint surface gloss */
    linear-gradient(155deg, rgba(255,255,255,0.045), rgba(255,255,255,0.012));    /* subtle frost fill */
  border:1px solid rgba(255,255,255,0.08);
  -webkit-backdrop-filter:blur(16px) saturate(1.2);
  backdrop-filter:blur(16px) saturate(1.2);
  box-shadow:
    0 16px 40px rgba(0,0,0,0.4),                    /* soft lift */
    inset 0 1px 0.5px rgba(255,255,255,0.24),       /* delicate top edge */
    inset 0 -20px 30px -24px rgba(0,0,0,0.4);       /* gentle bottom depth */
}
/* Refraction rim — a delicate luminous edge, masked to the border only (no body bleed).
   On pricing this REPLACES the old 3px ::before top-edge (inset:0 + height:auto override it). */
.pain-card::before,.pricing-card::before,.principle-card::before{
  content:"";position:absolute;inset:0;height:auto;border-radius:inherit;padding:1px;pointer-events:none;z-index:2;
  background:linear-gradient(140deg,
    rgba(255,255,255,0.4) 0%, rgba(255,255,255,0.04) 34%, rgba(255,255,255,0.015) 64%, rgba(255,255,255,0.18) 100%);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;
}
.pain-card{border-radius:var(--radius-card)}
.pricing-card{border-radius:var(--radius-lg)}
/* Featured pricing card: a soft warm edge (badge ::after stays intact) */
.pricing-card.featured::before{
  background:linear-gradient(140deg,
    rgba(255,170,90,0.5) 0%, rgba(255,140,35,0.08) 36%, rgba(178,54,63,0.05) 64%, rgba(255,140,35,0.3) 100%);
}
.pricing-card.featured{
  box-shadow:
    0 16px 40px rgba(0,0,0,0.4),
    inset 0 1px 0.5px rgba(255,255,255,0.26),
    inset 0 -20px 30px -24px rgba(0,0,0,0.4),
    0 0 0 1px rgba(255,140,35,0.14),
    0 0 30px rgba(255,140,35,0.08);
}
/* Hover: gentle lift + a touch more edge light (pain keeps its carmine hover defined above) */
.pricing-card:hover{
  transform:translateY(-4px);
  box-shadow:
    0 24px 50px rgba(0,0,0,0.48),
    inset 0 1px 0.5px rgba(255,255,255,0.32),
    inset 0 -20px 30px -24px rgba(0,0,0,0.4),
    0 0 26px rgba(255,140,35,0.08);
}
/* No colored light behind the lower grids — they read as clean dark Apple frost (the delicate edge
   + frost carry the glass). Avoids both the off-theme color AND the z-index:-1-behind-backdrop-filter
   flicker. Only the pain section keeps a subtle carmine warmth (see #pain-points::before). */

/* ============ FLIP CARDS — Growth Suite + Who We Serve (hover / focus / tap to reveal) ============ */
/* Vanilla port of a 3D flip card. Faces use a SOLID dark surface (NO backdrop-filter — it breaks
   preserve-3d / backface-visibility on a rotated face), so these two sections trade the frosted
   glass for the flip interaction. Fixed height because the faces are absolutely positioned. */
.growth-cards{display:grid;grid-template-columns:repeat(4,1fr);gap:20px}
/* Six-card variant (/growth-suite/): 3x2 instead of a 4+2 orphan row. Same (0,1,0) specificity
   as the responsive .growth-cards rules further down, so the 2-col/1-col overrides still win. */
.growth-cards--six{grid-template-columns:repeat(3,1fr)}
.flip-card{position:relative;height:238px;border-radius:var(--radius-card);cursor:pointer;outline:none;
  perspective:800px;-webkit-tap-highlight-color:transparent}
.flip-inner{position:absolute;inset:0;border-radius:inherit;transform-style:preserve-3d;
  transition:transform 0.9s var(--ease-out-expo)}
.flip-card:hover .flip-inner,
.flip-card:focus-visible .flip-inner,
.flip-card.is-flipped .flip-inner{transform:rotateY(180deg)}
.flip-card:focus-visible{box-shadow:0 0 0 2px var(--bg-primary),0 0 0 4px var(--orange)}
/* Subtle pulsing orange edge-glow that invites the hover. All cards pulse in unison (user preference),
   breathing low->high (never blinks fully off), and fading out on the hovered/focused card since it's
   already being used. Behind the faces (z-index:-1); these cards have no backdrop-filter, so the
   negative z-index is safe here. */
.flip-card::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:-1;
  box-shadow:0 0 0 1px rgba(255,140,35,0.55),0 0 26px 2px rgba(255,140,35,0.45);
  opacity:0.2;transition:box-shadow 0.3s ease;animation:flipInvite 3s ease-in-out infinite}
/* Hide the glow on the hovered/focused card by dropping its box-shadow — NOT by touching the
   animation. Killing/pausing the animation would restart it on un-hover and desync that card from
   the rest; leaving the timeline untouched keeps all cards pulsing in lockstep no matter what. */
.flip-card:hover::after,.flip-card:focus-visible::after{box-shadow:none}
@keyframes flipInvite{0%,100%{opacity:0.28}50%{opacity:1}}
/* overflow MUST stay visible: overflow:hidden flattens transform-style:preserve-3d and kills the lift.
   The face bg/border still clip to its own rounded corners; only the lifted content can cross edges. */
.flip-face{position:absolute;inset:0;border-radius:inherit;transform-style:preserve-3d;
  -webkit-backface-visibility:hidden;backface-visibility:hidden;
  display:flex;flex-direction:column;justify-content:center;padding:26px;
  border:1px solid rgba(255,255,255,0.09);
  background:linear-gradient(180deg,rgba(255,255,255,0.05),transparent 42%),linear-gradient(158deg,#171d2a 0%,#0d1119 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.14),0 18px 42px rgba(0,0,0,0.45)}
.flip-face--back{transform:rotateY(180deg);border-top:2px solid rgba(255,140,35,0.55)}
/* Constant 3D lift: content floats 50px proud of the face and parallaxes hard as the card turns.
   scale(.94) cancels the perspective magnification so it still fits at rest. backface hidden so the
   floating front content disappears (not mirror-bleeds) once the card is showing its back. */
.flip-face>*{transform:translateZ(50px) scale(.94);-webkit-backface-visibility:hidden;backface-visibility:hidden}
.flip-icon{display:grid;place-items:center;width:50px;height:50px;border-radius:14px;
  color:var(--orange);background:rgba(255,140,35,0.12);border:1px solid rgba(255,140,35,0.22)}
.flip-icon svg{width:25px;height:25px}
.flip-title{font-size:1.12rem;font-weight:700;line-height:1.25;margin:16px 0 0}
.flip-back-title{display:block;font-size:0.78rem;font-weight:700;text-transform:uppercase;
  letter-spacing:var(--tracking-wide);color:var(--orange);margin:0 0 10px}
.flip-face--back p{font-size:0.94rem;line-height:1.5;color:var(--text-secondary);margin:0}
/* Reduced motion: keep the flip animating (user-chosen exception to the global transition kill),
   but flatten the 3D lift so the vestibular-heavy parallax backs off. */
@media (prefers-reduced-motion:reduce){
  .flip-inner{transition-duration:0.9s!important}
  .flip-face>*{transform:none}
  .flip-card::after{animation:none;opacity:0.26}  /* static faint edge instead of a pulse */
}

/* ---------- 15. FAQ ---------- */
.faq-list{display:grid;gap:12px}
.faq-item{border:1px solid var(--border-color);border-radius:var(--radius-card);background:var(--bg-elevated);overflow:hidden;
  transition:border-color var(--dur-fast) ease}
.faq-item.active{border-color:rgba(255,140,35,0.4)}
.faq-question{width:100%;display:flex;align-items:center;justify-content:space-between;gap:16px;text-align:left;
  padding:20px 24px;background:none;border:none;cursor:pointer;font-family:inherit;font-size:1.05rem;font-weight:600;color:var(--text-primary)}
.faq-question:hover{color:var(--orange)}
.faq-toggle{flex:none;display:grid;place-items:center;width:28px;height:28px;border-radius:8px;background:rgba(255,140,35,0.1);color:var(--orange);transition:transform var(--dur-normal) var(--ease-out-expo)}
.faq-item.active .faq-toggle{transform:rotate(135deg)}
.faq-answer{max-height:0;overflow:hidden;transition:max-height var(--dur-normal) var(--ease-in-out)}
.faq-answer p{padding:0 24px 20px;font-size:0.94rem;margin:0}

/* ---------- 16. BOOKING FORM CARD + TRUST LIST ----------
   The standalone .final-cta section is GONE — the booking form now lives inside the parallax
   band (#book-demo, section 17b), which is the page's single merged closer + conversion moment.
   These rules style the pieces the band reuses: the trust list and the glass form card. */
.final-trust{display:grid;gap:12px}
.final-trust li{display:flex;align-items:center;gap:10px;color:var(--text-secondary);font-weight:500}
.final-trust svg{width:20px;height:20px;color:var(--success);flex:none}
.cta-form-card{position:relative;padding:12px;border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);min-height:544px}
.booking-skeleton{position:absolute;inset:0;display:grid;place-items:center;color:var(--text-muted);font-size:0.9rem}
#book-demo.form-ready .booking-skeleton{display:none}
.booking-iframe{width:100%;min-height:520px;border:none;border-radius:calc(var(--radius-lg) - 4px);background:transparent;display:block;
  opacity:0;transition:opacity var(--dur-normal) ease}
#book-demo.form-ready .booking-iframe{opacity:1}

/* ---------- 17. FOOTER ---------- */
.footer{background:var(--bg-primary);padding:64px 0 32px;border-top:1px solid var(--border-color)}
/* Brand column + four link columns (Solutions / Company / Guides / Legal). The Guides
   column landed with issue #22 to kill the orphan deep pages; the link columns share one
   auto-fitting track so a fifth would not need another hand-tuned ratio. */
.footer-grid{display:grid;grid-template-columns:1.6fr repeat(4,minmax(0,1fr));gap:40px;margin-bottom:40px}
.footer-logo{display:flex;align-items:center;gap:10px;font-size:1.15rem;margin-bottom:14px}
.footer-brand p{font-size:0.9rem;max-width:34ch}
.footer-col h4{font-size:0.9rem;margin-bottom:14px;color:var(--text-primary)}
.footer-col ul{display:grid;gap:10px}
.footer-col a{color:var(--text-secondary);font-size:0.9rem;transition:color var(--dur-fast) ease}
.footer-col a:hover{color:var(--orange)}
.footer-col ul .soon{color:var(--text-muted);font-size:0.9rem;cursor:default}
/* D10 canonical contact block (phone / email / Houston address) in the brand column */
.footer-contact{display:grid;gap:9px;margin-top:18px;font-style:normal;font-size:0.9rem}
.footer-contact a,.footer-contact span{display:flex;align-items:flex-start;gap:9px;color:var(--text-secondary);
  transition:color var(--dur-fast) ease}
.footer-contact a:hover{color:var(--orange)}
.footer-contact svg{width:15px;height:15px;flex:none;margin-top:4px;color:var(--orange)}
.footer-bottom{padding-top:24px;border-top:1px solid var(--border-subtle);font-size:0.85rem;color:var(--text-muted)}

/* ---------- 17c. SUBPAGE SCAFFOLDING (templates/page.html) ----------
   Deep pages have no ignition loader and no hero stage — a compact header (breadcrumb +
   eyebrow + H1 + lede) opens the page, {{PAGE_CONTENT}} sections follow the homepage's
   .section rhythm, and .page-cta closes every page at the Book-a-Demo ask (/#book-demo). */
.page-hero{position:relative;padding:calc(72px + var(--space-8)) 0 var(--space-6);overflow:hidden;
  background:var(--bg-surface);border-bottom:1px solid var(--border-subtle);isolation:isolate}
.page-hero h1{font-size:var(--text-h2);max-width:24ch;margin-bottom:0;text-wrap:balance}
.page-lede{font-size:var(--text-body);max-width:62ch;margin-top:var(--space-4)}
.crumbs{margin-bottom:var(--space-5);font-size:0.82rem;color:var(--text-muted)}
.crumbs ol{display:flex;flex-wrap:wrap;gap:8px;list-style:none}
.crumbs li{display:flex;align-items:center;gap:8px}
.crumbs li + li::before{content:"/";opacity:0.5}
.crumbs a{color:var(--text-muted);transition:color var(--dur-fast) ease}
.crumbs a:hover{color:var(--orange)}
.page-cta h2{text-wrap:balance}
.page-cta-inner{max-width:640px;margin:0 auto;text-align:center;display:flex;flex-direction:column;
  align-items:center;gap:var(--space-4)}
.page-cta-copy{max-width:52ch}

/* ---------- Interactive CDK diagram: Classic Countertop terminal -> auto-posts to CDK
   (skin rebuilt 2026-08-03 to mockups/terminal/b.html, the owner-approved Variant B;
   main.js cdkDemo() mechanics untouched — every id, state class, and the wire/pulse
   contract survive). One shared light source: --term-light matches the azimuth-235
   grain tile reused by shell, keys, and card, so no surface invents its own direction.
   --term-headroom reserves room above the device for the floating card + cue; the
   channel and panel carry the same top margin so grid centering keys on the DEVICE
   body, not the card headroom. ---------- */
.cdk-demo{position:relative;isolation:isolate;display:grid;grid-template-columns:auto 1fr auto;align-items:center;max-width:1000px;margin:0 auto 26px;
  --term-headroom:172px;
  --term-light:125deg;--term-light-steep:150deg;
  --term-shell-1:color-mix(in srgb,var(--text-secondary) 22%,var(--bg-primary));
  --term-shell-2:color-mix(in srgb,var(--text-muted) 10%,var(--bg-primary));
  --term-shell-3:color-mix(in srgb,var(--bg-primary) 92%,#000);
  --term-shell-4:color-mix(in srgb,var(--bg-primary) 98%,#000);
  --term-well:color-mix(in srgb,var(--bg-primary) 96%,#000);
  --term-screen-1:color-mix(in srgb,var(--text-secondary) 10%,var(--bg-primary));
  --term-screen-2:color-mix(in srgb,var(--bg-primary) 94%,#000);
  --term-screen-3:color-mix(in srgb,var(--bg-primary) 99%,#000);
  --term-key-1:color-mix(in srgb,var(--text-muted) 22%,var(--bg-primary));
  --term-key-2:color-mix(in srgb,var(--text-muted) 8%,var(--bg-primary));
  --term-key-3:color-mix(in srgb,var(--bg-primary) 94%,#000);
  --term-grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' seed='7' stitchTiles='stitch'/%3E%3CfeDiffuseLighting lighting-color='%23ffffff' surfaceScale='0.9' diffuseConstant='1'%3E%3CfeDistantLight azimuth='235' elevation='58'/%3E%3C/feDiffuseLighting%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23p)'/%3E%3C/svg%3E")}
.cdk-terminal-col{position:relative;width:270px}

/* Shatter burst layer: a 0x0 anchor pinned to the RO panel's center; main.js
   spawns the shards/ring inside and drives them with WAAPI (colors set inline).
   Negative z-index (scoped by the demo's isolation) paints the burst BEHIND the
   panel, so shards/ring emerge from its edges instead of crossing its face. */
.cdk-shatter{position:absolute;width:0;height:0;pointer-events:none;z-index:-1}
.cdk-shard{position:absolute;left:0;top:0}
.cdk-shatter-ring{position:absolute;left:0;top:0;transform:translate(-50%,-50%);border-radius:var(--radius-pill)}

/* Floating DealerPayments card — THE click target (it carries the #cdkTerminal id
   the script binds to; the machined device below is decorative). Bobs while idle,
   dips onto the tap zone during the read, settles quiet once posted. */
.cdk-terminal{position:absolute;top:74px;left:50%;margin-left:-75px;z-index:3;width:150px;height:94px;border-radius:11px;
  padding:0;border:none;background:none;cursor:pointer;-webkit-tap-highlight-color:transparent}
/* the button itself is a STATIC axis-aligned hitbox (Playwright + touch need a
   stable click target); .tc-inner carries every visual transform — tilt, bob, dip */
.tc-inner{position:absolute;inset:0;display:block;border-radius:11px;border:1px solid rgba(255,255,255,0.09);
  transform:rotate(-7deg);
  background:linear-gradient(var(--term-light),
    color-mix(in srgb,var(--text-secondary) 16%,var(--bg-primary)) 0%,
    color-mix(in srgb,var(--bg-primary) 94%,#000) 60%,
    color-mix(in srgb,var(--bg-primary) 99%,#000) 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.08),inset 0 -1px 0 rgba(0,0,0,0.5),
    0 0 0 1px rgba(255,140,35,0.12),0 0 18px -4px rgba(255,140,35,0.35),0 16px 26px -10px rgba(0,0,0,0.8);
  transition:transform .5s var(--ease-out-expo),box-shadow var(--dur-normal) ease}
.tc-inner::before{content:"";position:absolute;inset:0;border-radius:10px;opacity:.3;mix-blend-mode:soft-light;
  background-image:var(--term-grain);background-size:180px 180px}
.cdk-terminal:focus-visible{box-shadow:var(--focus-ring)}
.cdk-demo:not(.is-running):not(.is-done) .tc-inner{animation:tcBob 3s ease-in-out infinite}
@keyframes tcBob{0%,100%{transform:rotate(-7deg) translateY(0)}50%{transform:rotate(-7deg) translateY(-7px)}}
.cdk-demo:not(.is-running):not(.is-done) .tc-wave{animation:waveGlow 2s ease-in-out infinite}
@keyframes waveGlow{0%,100%{opacity:0.5}50%{opacity:1}}
.cdk-demo.is-reading .tc-inner{animation:none;transform:rotate(-2deg) translateY(88px) scale(0.97)}
.cdk-demo.is-approved .tc-inner,.cdk-demo.is-done .tc-inner{animation:none;transform:rotate(-7deg)}
.cdk-demo.is-done .tc-inner{box-shadow:inset 0 1px 0 rgba(255,255,255,0.08),inset 0 -1px 0 rgba(0,0,0,0.5),0 16px 26px -10px rgba(0,0,0,0.8)}
.tc-chip{position:absolute;top:36px;left:16px;width:14px;height:11px;border-radius:2.5px;
  background:linear-gradient(var(--term-light),#d9b36a 0%,#a37c3a 70%,#7e5c26 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.35),inset 0 -1px 1px rgba(0,0,0,0.45)}
.tc-wave{position:absolute;top:16px;right:13px;width:16px;height:16px;color:rgba(240,242,245,0.75)}
.tc-mark{position:absolute;left:15px;bottom:11px;font-size:0.58rem;font-weight:700;letter-spacing:0.03em;color:rgba(240,242,245,0.85)}
.tc-mark span{color:var(--orange)}

/* Machined countertop device (decorative, aria-hidden): wedge shell, recessed glass
   screen, physical backlit key grid — every surface answers to --term-light. */
.term-body{display:block;margin-top:var(--term-headroom);width:270px;height:340px;perspective:1400px}
.term-shell{position:relative;display:block;width:100%;height:100%;border-radius:22px 22px 30px 30px;
  transform:rotateX(9deg) rotateY(-3deg);overflow:hidden;
  background:linear-gradient(var(--term-light),var(--term-shell-1) 0%,var(--term-shell-2) 38%,var(--term-shell-3) 70%,var(--term-shell-4) 100%);
  box-shadow:0 2px 0 rgba(255,255,255,0.05) inset,0 -1px 0 rgba(0,0,0,0.6) inset,0 30px 60px -18px rgba(0,0,0,0.75),0 8px 18px rgba(0,0,0,0.55)}
.term-shell::before{content:"";position:absolute;inset:0;opacity:.35;mix-blend-mode:soft-light;
  background-image:var(--term-grain);background-size:180px 180px}
.term-shell::after{content:"";position:absolute;left:6%;right:6%;top:0;height:46%;pointer-events:none;
  background:linear-gradient(var(--term-light),rgba(255,255,255,0.09) 0%,rgba(255,255,255,0.02) 40%,rgba(255,255,255,0) 70%);
  border-radius:22px 22px 60% 60%/22px 22px 40% 40%}
.term-tapzone{position:absolute;top:9px;left:50%;transform:translateX(-50%);width:96px;height:16px;border-radius:10px;
  display:flex;align-items:center;justify-content:center;gap:6px;
  background:linear-gradient(180deg,color-mix(in srgb,var(--text-muted) 20%,var(--bg-primary)),color-mix(in srgb,var(--bg-primary) 90%,#000));
  box-shadow:inset 0 1px 1px rgba(255,255,255,0.10),inset 0 -2px 3px rgba(0,0,0,0.7),0 1px 0 rgba(255,255,255,0.04)}
.term-tapzone svg{width:13px;height:13px;color:var(--text-muted);opacity:.75}
.tz-dot{width:4px;height:4px;border-radius:50%;background:var(--orange);opacity:.55;box-shadow:0 0 6px rgba(255,140,35,0.6);
  transition:background var(--dur-normal) ease,box-shadow var(--dur-normal) ease,opacity var(--dur-normal) ease}
.cdk-demo.is-approved .tz-dot,.cdk-demo.is-done .tz-dot{background:var(--success);box-shadow:0 0 6px rgba(16,185,129,0.7);opacity:1}
.term-screen-frame{position:absolute;top:38px;left:22px;right:22px;height:104px;display:block;border-radius:12px;padding:3px;
  background:var(--term-well);
  box-shadow:inset 0 2px 5px rgba(0,0,0,0.9),inset 0 -1px 0 rgba(255,255,255,0.04),0 1px 0 rgba(255,255,255,0.06)}
.term-screen{position:relative;display:grid;place-items:center;width:100%;height:100%;border-radius:9px;overflow:hidden;
  background:radial-gradient(120% 140% at 30% 0%,var(--term-screen-1) 0%,var(--term-screen-2) 55%,var(--term-screen-3) 100%);
  border:1px solid rgba(255,255,255,0.04);transition:box-shadow var(--dur-normal) ease}
.term-screen::before{content:"";position:absolute;top:-30%;left:-20%;width:55%;height:180%;pointer-events:none;
  background:linear-gradient(var(--term-light-steep),rgba(255,255,255,0.09) 0%,rgba(255,255,255,0.02) 35%,rgba(255,255,255,0) 60%)}
.cdk-demo.is-approved .term-screen,.cdk-demo.is-done .term-screen{box-shadow:inset 0 0 26px rgba(16,185,129,0.14)}
.ct-line{position:absolute;display:inline-flex;align-items:center;gap:6px;font-size:0.92rem;font-weight:600;opacity:0;transition:opacity var(--dur-normal) ease}
.ct-idle{flex-direction:column;gap:5px;color:color-mix(in srgb,var(--text-primary) 65%,var(--text-secondary))}
.ct-idle .sc-status{display:inline-flex;align-items:center;gap:7px}
.ct-idle .sc-status::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--orange);box-shadow:0 0 8px 1px rgba(255,140,35,0.7)}
.ct-idle .sc-sub{font-size:0.62rem;font-weight:600;color:var(--text-muted);letter-spacing:0.08em;text-transform:uppercase}
.ct-reading{color:var(--orange)}
.ct-approved{color:color-mix(in srgb,var(--success) 55%,var(--text-primary))}
.ct-approved svg{width:15px;height:15px;color:var(--success);filter:drop-shadow(0 0 4px rgba(16,185,129,0.6))}
.cdk-demo:not(.is-reading):not(.is-approved):not(.is-done) .ct-idle{opacity:1}
.cdk-demo.is-reading .ct-reading{opacity:1}
.cdk-demo.is-approved .ct-approved,.cdk-demo.is-done .ct-approved{opacity:1}
.term-keys{position:absolute;left:20px;right:20px;bottom:20px;top:158px;
  display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(4,1fr);gap:7px;padding:9px;border-radius:12px;
  background:linear-gradient(160deg,color-mix(in srgb,var(--bg-primary) 97%,#000),color-mix(in srgb,var(--bg-primary) 99%,#000));
  box-shadow:inset 0 2px 4px rgba(0,0,0,0.75),inset 0 -1px 0 rgba(255,255,255,0.03)}
.term-keys .key{position:relative;display:flex;align-items:center;justify-content:center;border-radius:7px;
  font-size:0.72rem;font-weight:600;color:color-mix(in srgb,var(--text-secondary) 70%,var(--text-muted));
  background:linear-gradient(var(--term-light),var(--term-key-1) 0%,var(--term-key-2) 55%,var(--term-key-3) 100%);
  box-shadow:0 1px 0 rgba(255,255,255,0.07) inset,0 -2px 3px rgba(0,0,0,0.65) inset,0 1.5px 0 rgba(0,0,0,0.5)}
.cdk-demo.is-done .term-keys .key{color:color-mix(in srgb,var(--text-muted) 60%,var(--bg-primary))}
/* single under-tray ambient glow — the device's one accent light, idle only */
.term-keys::before{content:"";position:absolute;left:18%;right:18%;bottom:-6px;height:12px;
  background:radial-gradient(60% 100% at 50% 0%,rgba(255,140,35,0.18),transparent 70%);filter:blur(4px);opacity:0;transition:opacity .3s ease}
.cdk-demo:not(.is-running):not(.is-done) .term-keys::before{opacity:1}

/* Cue above the card. Both hint states share one grid cell so swapping them never
   reflows the demo row. */
.cdk-cta{position:absolute;top:14px;left:50%;transform:translateX(-50%);z-index:3;display:inline-grid;justify-items:center;
  white-space:nowrap;font-size:0.8rem;font-weight:600;color:var(--orange)}
.cdk-cta-state{grid-area:1/1;display:inline-flex;align-items:center;gap:7px;transition:opacity var(--dur-normal) ease}
.cdk-cta svg{width:15px;height:15px;flex:none}
.cdk-demo:not(.is-running):not(.is-done) .cdk-cta svg{animation:ctaNudge 1.8s ease-in-out infinite}
@keyframes ctaNudge{0%,100%{transform:translate(0,0)}50%{transform:translate(2px,2px)}}
.cdk-demo.is-done .cdk-cta{color:var(--text-secondary)}
.cdk-demo.is-done .cdk-cta-state--run,.cdk-demo:not(.is-done) .cdk-cta-state--again{opacity:0;visibility:hidden}

/* Data channel — etched track spanning the TRUE gap (grid auto / 1fr / auto), lit
   carmine -> orange -> teal while posting; wire/pulse class contract preserved. */
.cdk-wire{position:relative;height:6px;border-radius:4px;margin:var(--term-headroom) 26px 0;
  background:linear-gradient(90deg,rgba(255,255,255,0.03),rgba(255,255,255,0.07),rgba(255,255,255,0.03));
  box-shadow:inset 0 1px 2px rgba(0,0,0,0.6)}
.cdk-wire::before{content:"";position:absolute;inset:0;border-radius:4px;
  background:repeating-linear-gradient(90deg,rgba(0,0,0,0.35) 0 3px,transparent 3px 7px);opacity:.5}
.cdk-fill{position:absolute;inset:0;border-radius:4px;opacity:0;transition:opacity var(--dur-normal) ease;
  background:linear-gradient(90deg,var(--carmine) 0%,var(--orange) 55%,var(--success) 100%)}
.cdk-demo.is-posting .cdk-fill,.cdk-demo.is-done .cdk-fill{opacity:1;box-shadow:0 0 14px 1px rgba(255,140,35,0.45)}
.cdk-pulse{position:absolute;top:50%;left:0;width:9px;height:9px;margin-top:-4.5px;border-radius:50%;background:var(--white);
  box-shadow:0 0 10px 3px rgba(16,185,129,0.85);opacity:0}
.cdk-demo.is-posting .cdk-pulse{animation:cdkTravel .7s ease-in forwards}
@keyframes cdkTravel{from{opacity:1;left:0}to{opacity:1;left:100%}}
@keyframes cdkTravelY{from{opacity:1;top:0}to{opacity:1;top:100%}}

/* CDK Drive repair-order panel. Opaque surface (not the 60%-alpha glass bg): the
   shatter burst plays behind this panel and must not glow through its face. Same
   RGB as --bg-surface, so it renders identically to glass over the section bg. */
.cdk-panel{width:286px;margin-top:var(--term-headroom);padding:18px 20px;border-radius:var(--radius-card);
  background:var(--bg-elevated);-webkit-backdrop-filter:none;backdrop-filter:none}
.cdk-head{display:flex;align-items:center;gap:8px;font-size:0.76rem;font-weight:700;text-transform:uppercase;letter-spacing:0.04em;color:var(--text-secondary);margin-bottom:16px}
.cdk-dot{width:8px;height:8px;border-radius:50%;background:var(--text-muted);transition:background var(--dur-normal) ease,box-shadow var(--dur-normal) ease}
.cdk-demo.is-done .cdk-dot{background:var(--success);box-shadow:0 0 0 4px rgba(16,185,129,0.15)}
.cdk-lines{display:grid;gap:12px;margin-bottom:16px}
.cdk-lines li{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:0.9rem}
.cdk-lbl{color:var(--text-primary);font-weight:500}
.cdk-bar{flex:0 0 82px;height:7px;border-radius:4px;background:rgba(255,255,255,0.09)}
.cdk-payment{position:relative;opacity:0.35;transition:opacity var(--dur-normal) ease}
.cdk-awaiting{font-size:0.8rem;color:var(--text-muted);transition:opacity var(--dur-normal) ease}
.cdk-demo.is-done .cdk-awaiting{opacity:0}
.cdk-posted{position:absolute;right:0;top:50%;translate:0 -50%;display:inline-flex;align-items:center;gap:5px;font-size:0.8rem;font-weight:700;color:var(--success);
  opacity:0;transform:translateX(6px);transition:opacity var(--dur-normal) ease,transform var(--dur-normal) var(--ease-out-expo)}
.cdk-posted svg{width:14px;height:14px}
.cdk-demo.is-done .cdk-payment{opacity:1}
.cdk-demo.is-done .cdk-posted{opacity:1;transform:none}
.cdk-status{font-size:0.85rem;color:var(--text-muted);border-top:1px solid var(--border-subtle);padding-top:13px}
.cdk-status-val{font-weight:700;color:var(--warning)}
.cdk-demo.is-done .cdk-status-val{color:var(--success)}
.cdk-caption{text-align:center;font-size:0.92rem;color:var(--text-secondary);margin:0 auto 28px;max-width:600px}

/* ---------- P2PE shield recast as a DEBOSSED SEAL (deboss vocabulary from .cdk-seal, teal enamel) ---------- */
.enc-seal{position:relative;width:132px;height:132px;border-radius:50%;display:grid;place-items:center;
  background:radial-gradient(circle,rgba(8,11,17,0.74) 0%,rgba(8,11,17,0.58) 58%,rgba(8,11,17,0.38) 100%);
  box-shadow:
    inset 0 3px 8px rgba(0,0,0,0.55),          /* top inner recess wall */
    inset 0 -1px 2px rgba(255,255,255,0.14),   /* bottom inner light catch */
    0 1px 1px rgba(255,255,255,0.14),          /* lower lip highlight */
    0 -1px 1px rgba(0,0,0,0.25)}               /* upper lip shade */
.enc-seal::before{content:"";position:absolute;inset:6%;border-radius:50%;pointer-events:none;
  border:1px solid rgba(16,185,129,0.5)}       /* teal enamel inlay — pigment, not glow */
.enc-seal::after{content:"";position:absolute;inset:0;border-radius:50%;pointer-events:none;
  border:2px solid var(--success);opacity:0}
.enc-demo.is-stamped .enc-seal::after{animation:encSealPulse 900ms var(--ease-out-expo) forwards}
@keyframes encSealPulse{0%{opacity:.9;transform:scale(1)}100%{opacity:0;transform:scale(1.9)}}
.enc-shield{position:relative;z-index:1;width:76px;height:auto;filter:drop-shadow(0 1px 2px rgba(0,0,0,0.5))}
/* draw contract preserved; retargeted from scroll (.p2pe-shield.visible) to the demo finale.
   The fast draw is the WIND-UP; the STAMP (.is-stamped, fired from JS after a held beat) is the payoff. */
.shield-outline,.shield-check{stroke-dasharray:1;stroke-dashoffset:1}
.enc-demo.is-secure .shield-outline{animation:draw .35s var(--ease-out-expo) .05s forwards}
.enc-demo.is-secure .shield-check{animation:draw .3s var(--ease-out-expo) .35s forwards}
@keyframes draw{to{stroke-dashoffset:0}}

/* ---- STAMP: the seal punches HARD into the leather; its impact throws flash + shockwave + thunk ---- */
.enc-demo.is-stamped .enc-seal{animation:encStamp 560ms var(--ease-out-expo)}
@keyframes encStamp{0%{transform:scale(1)}26%{transform:scale(0.74)}60%{transform:scale(1.11)}100%{transform:scale(1)}}
/* within-demo flash bloom (bright warm-white core -> teal), centered on the seal, screen-blended, contained by isolate.
   z-index:0 = BEHIND the pipeline/seal content (z-index:1) so the light glows behind the seal, never in front.
   Radius is BOUNDED (210px at the seal) — it must NOT reach the pipeline node row (only brightness was raised, not reach). */
.enc-demo::after{content:"";position:absolute;inset:0;pointer-events:none;z-index:0;opacity:0;transform-origin:50% 83%;
  background:radial-gradient(circle 210px at 50% 83%,rgba(240,255,248,1),rgba(120,255,205,0.72) 24%,rgba(16,185,129,0.55) 42%,rgba(16,185,129,0) 72%);
  mix-blend-mode:screen}
/* the flash BLOOMS outward from the seal (scale) then fades — a slower, boomier release */
.enc-demo.is-stamped::after{animation:encFlash 780ms ease-out}
@keyframes encFlash{0%{opacity:0;transform:scale(0.6)}13%{opacity:1}100%{opacity:0;transform:scale(1.45)}}
/* whole-demo thunk (one decaying bounce) */
.enc-demo.is-stamped{animation:encThunk 400ms var(--ease-out-expo)}
@keyframes encThunk{0%{transform:translateY(0)}20%{transform:translateY(6px)}50%{transform:translateY(-3px)}76%{transform:translateY(1.5px)}100%{transform:translateY(0)}}
/* expanding shockwave ring(s) (JS-spawned .enc-shock, TWO of them for a layered impact); transform-scaled so
   it never grows scrollWidth, and #security's .section overflow:hidden clips it. Bright/thick for punch;
   capped scale keeps each ring below the node row (no light at the pipeline cards). */
.enc-shock{position:absolute;width:300px;height:300px;border-radius:50%;pointer-events:none;z-index:0;
  transform:translate(-50%,-50%);  /* base-center on its (left,top) seal point — so a non-filled animation frame never shoves it down-right */
  border:3px solid rgba(120,255,205,0.9);box-shadow:0 0 34px 4px rgba(16,185,129,0.6),inset 0 0 30px rgba(16,185,129,0.4)}
/* finale ICON REACTION (user, 2026-07-06): as the seal stamps, each node's ICON POPS (scale + brighten) in a
   left->right sweep. The pop lives on the SVG (a child), NOT the node — so it never fights the per-beat node
   scale and casts NO outward glow (brightness only lightens the glyph itself). */
.enc-demo.is-stamped .enc-node svg{animation:encIconPop 560ms var(--ease-out-expo)}
.enc-demo.is-stamped .enc-step[data-step="1"] .enc-node svg{animation-delay:60ms}
.enc-demo.is-stamped .enc-step[data-step="2"] .enc-node svg{animation-delay:190ms}
.enc-demo.is-stamped .enc-step[data-step="3"] .enc-node svg{animation-delay:320ms}
.enc-demo.is-stamped .enc-step[data-step="4"] .enc-node svg{animation-delay:450ms}
@keyframes encIconPop{0%,100%{transform:scale(1);filter:none}42%{transform:scale(1.45);filter:brightness(1.7)}}

/* ---------- 17b. PARALLAX BRAND BAND ("the CDK wedge") ----------
   Full-height cinematic moment. Absolutely-stacked brand layers each DRIFT by their own --dy
   as the band crosses the viewport; main.js parallaxBand() sets --p (0..1) from a passive,
   IO-gated scroll listener — the page scroll itself is never touched. Gentle proximity
   the pageStepper drags to it. Reduced motion: --p parked at .5 (flat). */
.pband{position:relative;min-height:100vh;overflow:hidden;background:var(--bg-primary);
  border-top:1px solid var(--border-color);border-bottom:1px solid var(--border-color)}
.pband-stage{--p:.5;position:relative;width:100%;min-height:100vh;display:grid;place-items:center}
.player{position:absolute;inset:0;display:grid;place-items:center;pointer-events:none;
  transform:translate3d(0,calc((var(--p) - .5) * var(--dy,0px)),0);will-change:transform}

.player--mark{--dy:-90px;opacity:.05}
.pband-mark{width:min(74vw,820px);height:auto}
.player--glow{--dy:-46px}
.player--glow::before{content:"";width:min(82vw,1000px);height:min(82vw,1000px);border-radius:50%;
  background:radial-gradient(circle,rgba(255,140,35,.16),rgba(178,54,63,.05) 45%,transparent 66%);filter:blur(12px)}
.player--arcs{--dy:130px;display:flex;align-items:center;justify-content:space-between;
  padding:0 clamp(8px,6vw,120px);color:var(--orange);opacity:.09}
.player--arcs svg{width:min(42vw,460px);height:auto}
.pband-arcs-flip{transform:scaleX(-1)}
/* Title player is position:RELATIVE (bg layers stay absolute): it's the one layer with real
   content (copy + booking form), so it must size the stage — taller-than-viewport content grows
   the band instead of clipping under .pband's overflow:hidden. */
.player--title{--dy:36px;z-index:2;pointer-events:auto;position:relative;inset:auto;width:100%;
  max-width:1180px;padding:110px 24px 72px;place-self:center}
.pband-grid{display:grid;grid-template-columns:1.05fr 1fr;gap:clamp(32px,4.5vw,72px);align-items:center;width:100%}
.pband-copy{text-align:left}
.pband-copy .final-trust{margin-top:28px}
.pband-kicker{display:inline-block;font-size:.78rem;font-weight:600;letter-spacing:var(--tracking-wide);
  text-transform:uppercase;color:var(--orange);margin:0 0 18px}
.pband-title{font-size:clamp(2.2rem,3.6vw,3.3rem);line-height:1.08;letter-spacing:-0.025em;font-weight:800;margin:0 0 20px} /* sized for the copy COLUMN (~550px), not full width — bigger wraps "now," ragged */
.pband-title .grad-text{white-space:nowrap} /* the gradient phrase must never split across lines — keep it SHORT (1-2 words) or it overflows on mobile */
.pband-sub{font-size:clamp(1rem,1.4vw,1.2rem);line-height:1.6;color:var(--text-secondary);max-width:46ch;margin:0 0 4px}

@media (max-width:1024px){
  .pband{scroll-snap-align:none} /* stacked band is taller than the viewport — center-snap would trap the middle */
  .pband-grid{grid-template-columns:1fr;gap:40px}
  .pband-copy{text-align:center}
  .pband-copy .pband-sub{margin-inline:auto}
  .pband-copy .final-trust{justify-content:center;display:flex;flex-wrap:wrap;gap:12px 24px}
  .player--title{padding:96px 24px 56px}
}
@media (max-width:768px){
  .pband,.pband-stage{min-height:84vh}
  .player--arcs{opacity:.07;padding:0 4px}
}
@media (prefers-reduced-motion:reduce){
  html{scroll-snap-type:none}
  .player{transform:none}
}

/* ---------- 18. SCROLL REVEALS ---------- */
.fade-up{opacity:0;transform:translateY(24px);transition:opacity var(--dur-slow) var(--ease-out-expo),transform var(--dur-slow) var(--ease-out-expo)}
.fade-up.visible{opacity:1;transform:none}
/* stagger children within a revealed grid */
.callout-grid.visible .callout-item{animation:none}

/* ---------- 19. RESPONSIVE ---------- */
@media (max-width:1024px){
  .hero-grid{grid-template-columns:1fr;gap:var(--space-6)}
  .hero-stage{min-height:300px;order:2}
  .callout-grid{grid-template-columns:repeat(2,1fr);max-width:520px}
  .footer-grid{grid-template-columns:1fr 1fr}
  .department-cards,.growth-cards{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:768px){
  /* Phones: the bar is always over content, so keep it opaque instead of scroll-triggered glass */
  .navbar{background:var(--bg-primary);border-bottom:1px solid var(--border-color)}
  .nav-links{display:none}
  /* Keep the primary CTA in the already-sticky top bar on phones: logo … [Book a Demo] [☰] */
  .nav-cta{margin-left:auto;margin-right:12px;flex:none}
  .nav-cta .btn{white-space:nowrap}
  .nav-links.open{display:flex;flex-direction:column;position:absolute;top:72px;left:0;right:0;gap:18px;
    padding:24px;background:var(--bg-primary);border-bottom:1px solid var(--border-color)}
  .mobile-toggle{display:flex}
  /* Solutions dropdown flattens into the mobile panel: hide the button, inline the links */
  .nav-drop{display:contents}
  .nav-drop-btn{display:none}
  .nav-drop-menu{position:static;min-width:0;padding:0;border:none;border-radius:0;background:none;
    -webkit-backdrop-filter:none;backdrop-filter:none;box-shadow:none;
    opacity:1;visibility:visible;transform:none;transition:none;gap:18px}
  .nav-drop-menu::before{display:none}
  .nav-drop-menu a{padding:0;border-radius:0;font-size:0.95rem}
  .nav-drop-menu a:hover{background:none}
  .pricing-cards{grid-template-columns:1fr}
  .calc-controls{grid-template-columns:1fr;gap:24px}
  /* Cluster collapses: center dial stays the hero, side dials become carmine/teal readout chips */
  .cluster{grid-template-columns:1fr 1fr;gap:12px;align-items:stretch;margin-bottom:14px}
  .dial--center{grid-column:1 / -1;order:-1;width:min(100%,300px);margin:0 auto 6px}
  /* Phone-size gauge: smaller center readout so the % never crowds the dial's tick numbers */
  .gauge-pct{font-size:1.5rem}
  .gauge-center{bottom:2px}
  .calc-plate{margin-bottom:16px}
  /* Slider rows: the value chip wraps under its label as a unit instead of breaking mid-text */
  .calc-field-top{flex-wrap:wrap;row-gap:2px}
  .calc-out{font-size:0.95rem;white-space:nowrap}
  /* Room for the start button: it sits clear of the fine print below */
  .calc-field--start{padding:8px 0 6px}
  .dial--side .dial-svg{display:none}
  .dial--side{border-radius:var(--radius-md);padding:10px 14px}
  .dial--before{background:rgba(178,54,63,0.07);border:1px solid rgba(178,54,63,0.30)}
  .dial--after{background:rgba(16,185,129,0.06);border:1px solid rgba(16,185,129,0.26)}
  .dial--side .dial-readout{width:100%;justify-content:space-between;margin-top:0}
  .cdk-demo{grid-template-columns:1fr;justify-items:center}
  /* vertical drop: thick + glowing so the terminal-to-RO story reads on a phone */
  .cdk-wire{width:6px;height:64px;margin:18px 0;
    background:linear-gradient(180deg,rgba(255,255,255,0.03),rgba(255,255,255,0.08),rgba(255,255,255,0.03))}
  .cdk-wire::before{background:repeating-linear-gradient(180deg,rgba(0,0,0,0.35) 0 3px,transparent 3px 7px)}
  .cdk-fill{background:linear-gradient(180deg,var(--carmine) 0%,var(--orange) 55%,var(--success) 100%)}
  .cdk-demo.is-posting .cdk-fill,.cdk-demo.is-done .cdk-fill{box-shadow:0 0 16px 2px rgba(255,140,35,0.5)}
  .cdk-panel{width:100%;max-width:320px;margin-top:0}
  /* packet rides the vertical drop: re-anchor to the top edge and travel down */
  .cdk-pulse{top:0;left:50%;margin-top:0;margin-left:-4.5px}
  .cdk-demo.is-posting .cdk-pulse{animation:cdkTravelY .7s ease-in forwards}
  .cdk-seal{width:28%} /* clears the hc-brand wordmark on the small card */
  .cdk-seal-core{gap:3px}
  .cdk-seal-text{font-size:0.68rem} .cdk-seal-text strong{font-size:0.86rem}
  .cdk-seal-check svg{width:16px;height:16px}
  .hero-card-scene{width:min(86%,330px);margin:0 auto}
  .hero-card{--tiltY:-12deg;--tiltX:6deg}
  .hc-chip{left:20px;width:40px;height:30px} /* keeps the base rule's middle-left top:44% */
  .hc-wave{top:20px;right:20px;width:30px;height:30px}
  .hc-brand{left:20px;bottom:42px;font-size:1.1rem} /* short enough to clear the welded seal */
  .hc-number{left:20px;bottom:18px;gap:11px}
  .hc-number i::before{font-size:0.68rem}
}
@media (max-width:480px){
  .callout-grid{grid-template-columns:1fr}
  .department-cards,.growth-cards{grid-template-columns:1fr}
  .hero-buttons .btn{width:100%}
  .cluster{grid-template-columns:1fr}
  .footer-grid{grid-template-columns:1fr}
  /* Narrow-phone navbar: logo/CTA/toggle overflow the row at <=375px (gap collapses to 0).
     Shrink the logo mark+wordmark, trim the CTA pill, and tighten the row's own gutters so a
     real gap survives down to 320px. Wordmark stays one line, unclipped, un-truncated.
     #navbar-prefixed so these beat showcase.css's same-breakpoint .nav-logo/.brand-mark/
     .nav-cta rules (loaded after styles.css, equal class specificity would otherwise win). */
  #navbar.navbar .container{padding:0 12px}
  #navbar .nav-logo{gap:5px;font-size:clamp(0.78rem,3.6vw + 0.1rem,1.15rem)}
  #navbar .brand-mark{width:24px;height:24px}
  #navbar .nav-cta{margin-right:6px}
  #navbar .nav-cta .btn{padding:7px 9px;font-size:0.78rem}
  .mobile-toggle{padding:8px 3px}
}

/* ---------- 20. REDUCED MOTION ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:0.001ms!important;animation-iteration-count:1!important;transition-duration:0.001ms!important;scroll-behavior:auto!important}
  .fade-up{opacity:1;transform:none}
  html{scroll-snap-type:none}
  .section-header .eyebrow,.section-header h2,.section-header p{transform:none}
  .section-header::before{transform:translateX(-50%)}
  .hero-card-float,.hero-card-shadow{animation:none!important;opacity:1}
  .logo-marquee-track{animation:none;transform:none}
  .logo-marquee--warm .logo-chip span{filter:none}
  .tc-inner,.tc-wave,.cdk-cta svg,.cdk-pulse{animation:none!important}
  .shield-outline,.shield-check{stroke-dashoffset:0}
  .gauge-value{transition:none}
  .gauge-needle,.dial-needle,.odo-strip{transition:none}
  .calc-binnacle::after{transition:none}
  .enc-comet,.enc-seal::after,.enc-comet::before,.enc-shock,.enc-demo::after{display:none}
  .enc-rail-fill,.enc-step,.enc-node,.enc-card,.enc-card-state{transition:none}
  .enc-card.enc-punch,.enc-demo.is-stamped,.enc-demo.is-stamped .enc-seal,.enc-demo.is-stamped .enc-node{animation:none!important}
}

/* ---------- 21. ABOUT PAGE — numbers stat band + operating principles (Wave 1 item 9) ---------- */
/* Three-up stat band: reuses .trust-band's dark liquid-glass recipe (border-box gradient rim,
   backdrop blur) but as an even 3-column grid instead of the seal+2-stat+copy layout, since all
   three entries here are equal-weight brand numbers, not a stat-plus-explanation pairing. */
/* Story prose: the global reset zeroes <p> margins, so give the plain stacked paragraphs
   real rhythm (this page has no card/table scaffolding to space them). #story only exists
   on /about/. */
#story p{margin:0 0 18px;font-size:1.02rem;color:var(--text-secondary)}
#story p:last-child{margin-bottom:0}
#story p a{font-weight:600}
.about-stats{position:relative;display:grid;grid-template-columns:repeat(3,1fr);gap:0;
  border-radius:var(--radius-lg);border:1px solid transparent;overflow:hidden;
  background:
    linear-gradient(160deg,rgba(255,255,255,0.05),rgba(255,255,255,0) 42%) padding-box,
    linear-gradient(rgba(7,10,18,0.62),rgba(7,10,18,0.62)) padding-box,
    linear-gradient(168deg,rgba(255,255,255,0.20),rgba(255,255,255,0.05) 30%,rgba(255,255,255,0.02) 62%,rgba(255,255,255,0.10)) border-box;
  -webkit-backdrop-filter:blur(22px) saturate(1.5);backdrop-filter:blur(22px) saturate(1.5);
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.10),inset 0 -16px 30px -20px rgba(0,0,0,0.45)}
.about-stat{position:relative;padding:36px 30px;text-align:center}
.about-stat + .about-stat::before{content:"";position:absolute;left:0;top:20%;bottom:20%;width:1px;
  background:var(--border-color)}
.about-stat .count{display:block;font-size:clamp(2.4rem,1.8rem + 2.2vw,3.2rem);font-weight:800;
  line-height:1;letter-spacing:-0.02em;color:var(--orange);font-variant-numeric:tabular-nums}
.about-stat-label{display:block;margin-top:10px;font-size:0.82rem;font-weight:600;
  color:var(--text-secondary);text-transform:uppercase;letter-spacing:var(--tracking-wide)}
/* The non-animated stat ("Houston, TX") gets the same display treatment as the .count
   numbers so the three cells read as equal-weight brand facts. */
.about-stat-figure{display:block;font-size:clamp(2.4rem,1.8rem + 2.2vw,3.2rem);font-weight:800;
  line-height:1;letter-spacing:-0.02em;color:var(--orange)}

/* Operating principles: four equal cards, same surface language as .pain-card but a neutral
   orange top edge (these are strengths, not pain points, so no carmine). */
.principle-cards{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;margin-top:var(--space-8)}
.principle-card{position:relative;padding:28px 26px;border-radius:var(--radius-card);
  border-top:2px solid var(--orange);transition:transform var(--dur-normal) var(--ease-out-expo),box-shadow var(--dur-normal) ease}
.principle-card:hover{transform:translateY(-4px);
  box-shadow:inset 0 1px 0.5px rgba(255,255,255,0.4),inset -1px -3px 9px rgba(0,0,0,0.36),
    0 0 0 1px rgba(255,140,35,0.28),0 0 40px rgba(255,140,35,0.14),0 30px 60px rgba(0,0,0,0.5)}
.principle-card h3{font-size:1.05rem;margin-bottom:8px}
.principle-card p{font-size:0.92rem;margin:0}
.principle-card p a{color:var(--orange);font-weight:600}
.principle-card p a:hover{text-decoration:underline}

@media (max-width:1024px){
  .principle-cards{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:768px){
  .about-stats{grid-template-columns:1fr}
  .about-stat + .about-stat::before{left:20%;right:20%;top:0;bottom:auto;width:auto;height:1px}
}
@media (max-width:480px){
  .principle-cards{grid-template-columns:1fr}
}
@media (prefers-reduced-motion:reduce){
  .principle-card{transition:none}
}

/* ---------- 20. CONTACT PAGE (Wave 1 item 10, /contact-us/) ----------
   Two contact-channel cards (phone, email) share the .pain-card/.principle-card surface
   language (neutral orange top edge, same hover lift) but add a centered icon chip + a link
   row, since each card's job is "get the visitor to tap/click a channel" rather than state a
   fact. #quick-answers reuses the .principle-card glass recipe as whole-card links (4 teasers
   to shipped deep pages). The booking section reuses .cta-form-card/.glass (the exact recipe
   from the homepage's parallax finale) inside a plain two-column grid — no parallax here, this
   is a normal .section, not .pband — so the same iframe skeleton/sizing holds without dragging
   in the drift/scroll-snap machinery. #location is a single centered glass locator card (map
   pin + canonical address + Get directions), no map embed per COPY-VOICE.md. */
.contact-cards{display:grid;grid-template-columns:repeat(2,1fr);gap:20px;margin-top:var(--space-8);max-width:640px;margin-left:auto;margin-right:auto}
.contact-card{position:relative;padding:32px 28px;border-radius:var(--radius-card);
  border-top:2px solid var(--orange);text-align:center;
  transition:transform var(--dur-normal) var(--ease-out-expo),box-shadow var(--dur-normal) ease}
.contact-card:hover{transform:translateY(-4px);
  box-shadow:inset 0 1px 0.5px rgba(255,255,255,0.4),inset -1px -3px 9px rgba(0,0,0,0.36),
    0 0 0 1px rgba(255,140,35,0.28),0 0 40px rgba(255,140,35,0.14),0 30px 60px rgba(0,0,0,0.5)}
.contact-card-icon{display:inline-flex;align-items:center;justify-content:center;width:52px;height:52px;
  margin:0 auto 18px;border-radius:var(--radius-md);background:rgba(255,140,35,0.10);
  border:1px solid rgba(255,140,35,0.28);color:var(--orange)}
.contact-card-icon svg{width:24px;height:24px}
.contact-card h3{font-size:1.1rem;margin-bottom:8px}
.contact-card p{font-size:0.92rem;color:var(--text-secondary);margin:0 0 18px}
.contact-card-link{display:inline-flex;align-items:center;gap:6px;font-weight:700;color:var(--orange);font-size:1rem}
.contact-card-link:hover{text-decoration:underline}
.contact-card-link svg{width:15px;height:15px;flex:none;transition:transform var(--dur-fast) ease}
.contact-card-link:hover svg{transform:translateX(3px)}

/* Quick answers: whole-card links (the .principle-card glass recipe, kept a distinct class
   since the interaction is different — the entire card is the <a>, not just a link row). */
.quick-answer-cards{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;margin-top:var(--space-8)}
.quick-answer-card{display:block;position:relative;padding:28px 26px;border-radius:var(--radius-card);
  border-top:2px solid var(--orange);
  transition:transform var(--dur-normal) var(--ease-out-expo),box-shadow var(--dur-normal) ease}
.quick-answer-card:hover,.quick-answer-card:focus-visible{transform:translateY(-4px);
  box-shadow:inset 0 1px 0.5px rgba(255,255,255,0.4),inset -1px -3px 9px rgba(0,0,0,0.36),
    0 0 0 1px rgba(255,140,35,0.28),0 0 40px rgba(255,140,35,0.14),0 30px 60px rgba(0,0,0,0.5)}
.quick-answer-card:focus-visible{outline:2px solid var(--orange);outline-offset:3px}
.quick-answer-card h3{font-size:1.05rem;margin-bottom:8px}
.quick-answer-card p{font-size:0.92rem;color:var(--text-secondary);margin:0 0 16px}
.quick-answer-link{display:inline-flex;align-items:center;gap:6px;font-weight:700;color:var(--orange);font-size:0.92rem}
.quick-answer-link svg{width:15px;height:15px;flex:none;transition:transform var(--dur-fast) ease}
.quick-answer-card:hover .quick-answer-link svg,.quick-answer-card:focus-visible .quick-answer-link svg{transform:translateX(3px)}

/* Booking section: copy + trust list left, form card right, plain (non-parallax) two-column layout. */
.contact-book-grid{display:grid;grid-template-columns:0.85fr 1fr;gap:clamp(32px,4.5vw,64px);align-items:center}
.contact-book-copy{display:flex;flex-direction:column;gap:24px}
.contact-book-copy>p{color:var(--text-secondary);font-size:1.05rem;margin:0}
.contact-book-copy .final-trust{margin:0}
.contact-book-phone{font-size:0.95rem;color:var(--text-muted)}
.contact-book-phone a{color:var(--orange);font-weight:600}
.contact-book-phone a:hover,.contact-book-phone a:focus-visible{text-decoration:underline}

/* Location: single centered glass locator card, reuses the .glass recipe (not .principle-card,
   this is a standalone fact card with no grid siblings). */
.location-card{position:relative;display:flex;flex-direction:column;align-items:center;text-align:center;
  max-width:420px;margin:var(--space-8) auto 0;padding:36px 32px;border-radius:var(--radius-card)}
.location-card-icon{display:inline-flex;align-items:center;justify-content:center;width:56px;height:56px;
  margin-bottom:18px;border-radius:var(--radius-md);background:rgba(255,140,35,0.10);
  border:1px solid rgba(255,140,35,0.28);color:var(--orange)}
.location-card-icon svg{width:26px;height:26px}
.location-card-address{font-style:normal;font-size:1.05rem;color:var(--text-primary);line-height:1.5;margin-bottom:18px}
.location-card-link{display:inline-flex;align-items:center;gap:6px;font-weight:700;color:var(--orange);font-size:1rem}
.location-card-link:hover,.location-card-link:focus-visible{text-decoration:underline}
.location-card-link svg{width:15px;height:15px;flex:none;transition:transform var(--dur-fast) ease}
.location-card-link:hover svg,.location-card-link:focus-visible svg{transform:translateX(3px)}

@media (max-width:1024px){
  .quick-answer-cards{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:768px){
  .contact-cards{grid-template-columns:1fr;max-width:360px}
  .contact-book-grid{grid-template-columns:1fr;gap:32px}
}
@media (max-width:480px){
  .quick-answer-cards{grid-template-columns:1fr}
  .location-card{padding:28px 24px}
}
@media (prefers-reduced-motion:reduce){
  .contact-card,.quick-answer-card{transition:none}
}

/* ---------- 18. LEGAL PAGES (/privacy-policy/ /terms-conditions/ /surcharge-policy/) ----------
   Quiet long-form prose on the shared subpage scaffold. Legal pages are the ONE approved
   deviation from the demo-CTA closer (COPY-VOICE "Legal pages claims" block, grilled
   2026-07-13): they end at .page-outro ("Questions? Contact us" -> /contact-us/), never
   .page-cta. Body copy restores real list bullets (the global reset strips them). */
.legal-meta{font-size:0.85rem;color:var(--text-muted);margin-top:var(--space-4)}
.legal-body{max-width:74ch}
.legal-body h2{font-size:1.5rem;margin:var(--space-8) 0 var(--space-4)}
.legal-body h2:first-of-type{margin-top:0}
.legal-body h3{font-size:1.12rem;margin:var(--space-5) 0 12px}
.legal-body p{color:var(--text-secondary);margin-bottom:var(--space-4)}
.legal-body ul{list-style:disc;padding-left:1.35em;margin-bottom:var(--space-4);color:var(--text-secondary)}
.legal-body li{margin-bottom:8px;padding-left:4px}
.legal-body li::marker{color:var(--orange)}
.legal-body a{color:var(--orange);font-weight:600}
.legal-body a:hover,.legal-body a:focus-visible{text-decoration:underline}
/* Legal note — same spec-plate family, no notch (it has no heading): quiet hairline
   frame; the orange bar + wash retired with the callout redesign (2026-07-28). */
.legal-note{margin:0 0 var(--space-6);padding:16px 20px;
  border:1px solid rgba(255,255,255,0.10);border-radius:var(--radius-sm);
  background:rgba(255,255,255,0.015);color:var(--text-secondary);font-size:0.95rem}
.page-outro{text-align:center}
.page-outro p{color:var(--text-muted);font-size:var(--text-body);max-width:52ch;margin:0 auto}
.page-outro a{color:var(--orange);font-weight:700}
.page-outro a:hover,.page-outro a:focus-visible{text-decoration:underline}

/* ---------- 21. HOMEPAGE RESTRUCTURE: cdk-steps (2026-07-25; surface bands, the cdk-stage
   spotlight/demo-width override, and the why-timeline fit/polish overrides were REMOVED
   2026-07-27 — the showcase overlay (css/showcase.css + js/showcase.js) now owns section
   surfaces, lighting, and the timeline/demo presentation, so this section carries only the
   .cdk-steps markup styling that still lives on this branch). */
.cdk-steps{display:flex;justify-content:center;flex-wrap:wrap;gap:10px 34px;list-style:none;margin:0 auto 34px;padding:0;font-size:0.93rem;color:var(--text-secondary)}
.cdk-steps li{display:flex;align-items:center;gap:9px}
.cdk-steps .step-n{color:var(--orange);font-weight:700}

/* ---------- 22. BOOKING POPUP (spec D3-D7, D16) — one runtime-injected <dialog> serving
   every Book a Demo button on all 81 pages. Deliberately plain: this is the mechanism
   tracer bullet; the visual dialect lands in its own ticket after mockups. No leather,
   no sheen, no rings or sparks, nothing borrowed from the calculator binnacle.
   Two layouts, one breakpoint: full-screen sheet on phones (sized in svh so the iOS URL
   bar cannot clip the submit button, and scrolling as ONE surface so a focused field can
   always be cleared of the keyboard), floating panel over a dimmed page above it. The
   entry transform is authored so the global reduced-motion duration reset leaves a
   correct static state, never a mid-slide one. ---------- */
.bkp{border:0;padding:0;background:transparent;color:var(--text-primary);max-width:none;max-height:none;overflow:visible}
.bkp::backdrop{background:rgba(4,7,14,0.72)}
/* Locking the page behind. overflow:hidden alone does NOT hold on iOS Safari: a touch drag
   over the sheet — most easily over the form, whose own document has nothing to scroll —
   chains straight through to the document behind and drags the whole page. The body is
   therefore taken out of flow while the popup is open; bookingPopup() in main.js parks the
   scroll offset in a custom property and restores it on close so the visitor comes back to
   exactly where they were. */
html.bkp-lock,html.bkp-lock body{overflow:hidden}
html.bkp-lock body{position:fixed;width:100%;top:calc(var(--bkp-scroll, 0px) * -1)}
.bkp-panel{position:relative;background:var(--bg-primary);border:1px solid rgba(255,255,255,0.10);
  box-shadow:0 30px 80px rgba(0,0,0,0.55);outline:none}
.bkp-title{font-size:1.6rem;font-weight:700;line-height:1.2;margin:0 0 8px;padding-right:44px}
.bkp-lede{color:var(--text-secondary);font-size:0.98rem;margin:0 0 var(--space-5);max-width:46ch}
.bkp-close{position:absolute;top:14px;right:14px;width:40px;height:40px;display:grid;place-items:center;
  border:1px solid rgba(255,255,255,0.12);border-radius:50%;background:rgba(255,255,255,0.03);
  color:var(--text-secondary);cursor:pointer}
.bkp-close svg{width:20px;height:20px}
.bkp-close:hover,.bkp-close:focus-visible{color:var(--text-primary);border-color:rgba(255,255,255,0.28)}
.bkp-frame{position:relative;min-height:320px}
/* Calm branded placeholder while the form is in flight — no spinner, no "loading" text. */
.bkp-placeholder{position:absolute;inset:0;border-radius:var(--radius-sm);
  background:linear-gradient(180deg,rgba(255,255,255,0.035),rgba(255,255,255,0.012))}
.bkp.is-form-ready .bkp-placeholder{display:none}
.bkp-iframe{position:relative;width:100%;min-height:320px;border:0;display:block;background:transparent;
  opacity:0;transition:opacity var(--dur-normal) ease}
.bkp.is-form-ready .bkp-iframe{opacity:1}

/* Desktop and up: floating panel over the dimmed page. */
@media (min-width:769px){
  .bkp{margin:auto;width:min(640px,calc(100vw - 48px))}
  .bkp-panel{border-radius:var(--radius-lg);padding:var(--space-8);
    animation:bkpIn 320ms var(--ease-out-expo, ease-out)}
}
/* Phones: full-screen sheet, one scroll surface, slides up from the bottom.
   Sized in svh, never vh or a percentage: the collapsing URL bar changes vh mid-gesture and
   would clip the submit button off the bottom of the sheet. The PANEL is the one and only
   scroll container (the dialog itself never scrolls), so a field focused under the on-screen
   keyboard can always be scrolled clear. The close control stays absolutely placed at the
   sheet's top corner: it sits in view the moment the sheet lands, with nothing to scroll
   past first. (It cannot be position:fixed — the panel carries the entry transform, which
   makes it the containing block for fixed descendants, so "fixed" would scroll anyway.) */
@media (max-width:768px){
  /* svh is the floor, dvh is the truth. svh alone is the SMALL viewport — the height with the
     URL bar showing — so the moment the bar collapses the sheet comes up short and a sliver of
     the page behind shows under it. dvh tracks the bar, so the sheet fills the screen at every
     point of the collapse and is never clipped either. svh stays as the fallback value. */
  .bkp{width:100vw;height:100svh;max-height:100svh;margin:0;position:fixed;inset:0;overflow:hidden}
  .bkp{height:100dvh;max-height:100dvh}
  .bkp-panel{border:0;border-radius:0;height:100svh;padding:var(--space-6) var(--space-5) var(--space-10);
    overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
    /* The LANDED state is the base state, and the slide is authored as a from-keyframe that
       starts fully off the bottom edge. Written the other way round — parked off-screen and
       filled forwards — the sheet's correctness depends on the animation running at all, and
       under the global reduced-motion duration reset WebKit left it sitting at opacity 0,
       i.e. an invisible popup. Authored this way, collapsing the motion can only ever leave
       the sheet where it belongs (spec D7). */
    animation:bkpUp 300ms var(--ease-out-expo, ease-out)}
  .bkp-panel{height:100dvh}
  .bkp-close{top:12px;right:12px;background:rgba(11,15,26,0.92)}
  /* Room under the form so the last field can be scrolled above the keyboard. */
  .bkp-frame{padding-bottom:35svh}
}
@keyframes bkpIn{from{transform:translateY(14px);opacity:0}}
@keyframes bkpUp{from{transform:translateY(100%);opacity:0}}
/* Reduced motion: drop the entry animation outright rather than leaning on the global
   duration reset to collapse it. The rest state is already the landed state, so removing the
   animation is all it takes. This override is load-bearing, not belt-and-braces: WebKit under
   the reset holds the FROM keyframe instead of settling on the base style, which left the
   sheet parked a full viewport below the fold — an open popup showing nothing at all. Spec D7
   asks for a correct static state when motion collapses; this is the only authoring that
   guarantees one in both engines. */
@media (prefers-reduced-motion:reduce){
  .bkp-panel{animation:none}
}

/* ---------- 23. CONSENT NOTICE (2026-08-03) — the gate in front of session replay.
   Owner-picked variant B (2026-08-04): a quiet one-line strip with TEXT actions, not a
   card with a filled orange button. The filled button is what made it read as a
   marketing banner rather than a disclosure. Never an interstitial: position:fixed and
   injected after first paint, so it contributes nothing to CLS and blocks nothing.
   Markup lives in components/site-analytics.html; js/analytics.js unhides it. */
.consent-notice{position:fixed;right:var(--space-5);bottom:var(--space-5);z-index:80;
  display:flex;align-items:center;gap:18px;
  /* 100% (not 100vw) resolves against the initial containing block, which EXCLUDES the
     scrollbar — 100vw here would push the page into horizontal overflow. */
  max-width:min(560px,calc(100% - 2 * var(--space-5)));
  padding:12px 18px;border:1px solid rgba(255,255,255,0.10);border-radius:var(--radius-sm);
  background:rgba(11,15,26,0.94);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  box-shadow:0 14px 36px rgba(0,0,0,0.45);
  opacity:0;transform:translateY(12px);transition:opacity .28s ease,transform .28s ease}
.consent-notice.is-open{opacity:1;transform:translateY(0)}
/* Load-bearing: the global reset gives every element a display, which defeats the UA's
   [hidden]{display:none} — without this the notice occupies the corner before JS decides
   whether to ask at all. (Same trap as .calc-demo-nudge[hidden].) */
.consent-notice[hidden]{display:none}
.consent-copy{margin:0;font-size:0.78rem;line-height:1.5;color:var(--text-muted)}
.consent-copy a{color:var(--text-secondary);text-decoration:underline;
  text-underline-offset:2px}
.consent-copy a:hover,.consent-copy a:focus-visible{color:var(--text-primary)}
.consent-actions{display:flex;gap:16px;white-space:nowrap}
.consent-btn{font-family:inherit;font-size:0.78rem;font-weight:600;cursor:pointer;
  background:none;border:0;padding:0;transition:color .2s ease}
.consent-btn--accept{color:var(--orange)}
.consent-btn--accept:hover,.consent-btn--accept:focus-visible{color:#ffa04d}
.consent-btn--decline{color:var(--text-muted)}
.consent-btn--decline:hover,.consent-btn--decline:focus-visible{color:var(--text-primary)}
@media (max-width:640px){
  .consent-notice{left:var(--space-3);right:var(--space-3);bottom:var(--space-3);
    max-width:none;flex-direction:column;align-items:flex-start;gap:10px;padding:14px 16px}
}
