@import url('https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Figtree:wght@300;400;500;600;700&display=swap');

/* ============================================================
   WA FINANCE HUB — DESIGN SYSTEM
   wafinancehub.com.au · ABN 80 571 725 659
   Hosted on Hostinger · Vanilla HTML / CSS / JS

   FILE: assets/css/design-system.css
   UNIT: 1.1 — Complete Token Block (:root)

   Every colour, size, spacing, radius, easing, duration,
   shadow, border, z-index, and component token used anywhere
   on this site is defined here.

   Zero hardcoded hex values exist outside this :root block.
   Zero rgba() values exist outside this :root block.
   Every component rule references a variable. No exceptions.

   BUILD ORDER:
   1.1  :root tokens          ← YOU ARE HERE
   1.2  Reset + base
   1.3  Typography scale
   1.4  Layout + grid
   1.5  Button system
   1.6  Card system
   1.7  Form system
   1.8  Calculator components
   1.9  Navigation CSS
   1.10 Mobile bars
   1.11 Keyframes + reduced-motion
   ============================================================ */

:root {

  /* ----------------------------------------------------------
     COLOURS — CORE BACKGROUNDS
     Three backgrounds. Used in strict sequence.
     Midnight: hero, calculator, major CTA, footer.
     Forest:   trust bar, stats, testimonials.
     Bone:     how it works, education, about.
     No red. No orange. No pure white backgrounds. Ever.
  ---------------------------------------------------------- */

  --c-midnight:   #0C1E18;
  --c-forest:     #142A1F;
  --c-bone:       #F4EFE4;
  --c-bone-mid:   #DDD6C4;
  --c-bone-deep:  #C8BFA8;
  --c-white:      #FFFFFF;

  /* ----------------------------------------------------------
     COLOURS — BRAND ACCENTS
     Ochre: primary CTA on dark. Never on bone.
     Green: primary CTA on light. Never on dark.
  ---------------------------------------------------------- */

  --c-ochre:            #E8A040;
  --c-ochre-deep:       #C4882A;
  --c-ochre-glow:       rgba(232, 160, 64, 0.18);
  --c-ochre-glow-strong: rgba(232, 160, 64, 0.35);

  --c-green:            #1E8449;
  --c-green-hi:         #25A05A;
  --c-green-glow:       rgba(30, 132, 73, 0.15);
  --c-green-glow-strong: rgba(30, 132, 73, 0.30);

  /* ----------------------------------------------------------
     COLOURS — STATE
     Error uses muted amber. Never red.
     Success uses green. Matches brand.
  ---------------------------------------------------------- */

  --c-error:       #D4A845;
  --c-error-glow:  rgba(212, 168, 69, 0.16);
  --c-success:     var(--c-green);

  /* ----------------------------------------------------------
     COLOURS — SURFACES + OVERLAYS
     Glass morphism for orbital nav.
     Overlay for modal backdrop and form overlay.
  ---------------------------------------------------------- */

  --c-surface-glass:        rgba(12, 30, 24, 0.72);
  --c-surface-glass-solid:  rgba(12, 30, 24, 0.94);
  --c-surface-forest-glass: rgba(20, 42, 31, 0.88);

  --c-overlay-heavy:  rgba(0, 0, 0, 0.80);
  --c-overlay-mid:    rgba(0, 0, 0, 0.55);
  --c-overlay-light:  rgba(0, 0, 0, 0.28);

  --c-glass-border:        rgba(232, 160, 64, 0.20);
  --c-glass-border-active: rgba(232, 160, 64, 0.50);
  --c-shimmer-light:        rgba(244, 239, 228, 0.20);

  /* ----------------------------------------------------------
     COLOURS — TEXT ON DARK BACKGROUNDS
     Use on midnight and forest sections.
  ---------------------------------------------------------- */

  --t-dark-primary:   rgba(244, 239, 228, 1.00);
  --t-dark-secondary: rgba(244, 239, 228, 0.65);
  --t-dark-muted:     rgba(244, 239, 228, 0.38);
  --t-dark-ghost:     rgba(244, 239, 228, 0.18);
  --t-dark-hairline:  rgba(244, 239, 228, 0.07);

  /* ----------------------------------------------------------
     COLOURS — TEXT ON LIGHT BACKGROUNDS
     Use on bone sections.
  ---------------------------------------------------------- */

  --t-light-primary:   rgba(12, 30, 24, 1.00);
  --t-light-secondary: rgba(12, 30, 24, 0.65);
  --t-light-muted:     rgba(12, 30, 24, 0.38);
  --t-light-ghost:     rgba(12, 30, 24, 0.16);

  /* ----------------------------------------------------------
     COLOURS — PARTICLE FIELD
     40 particles in the form overlay.
     Ochre on load. Shifts to green on success.
  ---------------------------------------------------------- */

  --c-particle-ochre-hi:  rgba(232, 160, 64, 0.55);
  --c-particle-ochre-mid: rgba(232, 160, 64, 0.28);
  --c-particle-ochre-lo:  rgba(232, 160, 64, 0.10);
  --c-particle-green-hi:  rgba(30, 132, 73, 0.48);
  --c-particle-green-mid: rgba(30, 132, 73, 0.24);
  --c-particle-green-lo:  rgba(30, 132, 73, 0.10);

  /* ----------------------------------------------------------
     COLOURS — FORM FIELD SURFACES
     Background states per field condition.
  ---------------------------------------------------------- */

  --c-field-default: rgba(244, 239, 228, 0.04);
  --c-field-focus:   rgba(30, 132, 73, 0.05);
  --c-field-valid:   rgba(30, 132, 73, 0.04);
  --c-field-error:   rgba(212, 168, 69, 0.05);

  /* ----------------------------------------------------------
     TYPOGRAPHY
     Two fonts. No others. Ever.
     Display: Bebas Neue — headings, stats, Bebas numbers.
     Body:    Figtree — copy, buttons, labels, micro-copy.
  ---------------------------------------------------------- */

  --f-display: 'Bebas Neue', sans-serif;
  --f-body:    'Figtree', sans-serif;

  /* ----------------------------------------------------------
     TYPE SCALE — FLUID
     All clamp(min, preferred-vw, max).
     No fixed pixel sizes on fluid elements.
     No breakpoint-triggered font jumps.
  ---------------------------------------------------------- */

  --fs-display-hero: clamp(64px, 9.5vw,  130px);
  --fs-display-2xl:  clamp(52px, 7.5vw,  100px);
  --fs-display-xl:   clamp(40px, 5.5vw,   72px);
  --fs-display-lg:   clamp(32px, 4vw,     56px);
  --fs-display-md:   clamp(24px, 3vw,     40px);
  --fs-display-sm:   clamp(18px, 2.2vw,   28px);
  --fs-display-xs:   clamp(14px, 1.6vw,   20px);

  --fs-body-xl:   clamp(18px, 1.5vw, 22px);
  --fs-body-lg:   clamp(16px, 1.2vw, 18px);
  --fs-body-md:   clamp(14px, 1vw,   16px);
  --fs-body-sm:   clamp(12px, 0.9vw, 14px);
  --fs-body-xs:   clamp(11px, 0.8vw, 12px);
  --fs-eyebrow:   clamp(10px, 0.72vw, 11px);

  --fs-wordmark:       clamp(16px, 1.8vw, 22px);
  --fs-nav-overlay:    clamp(36px, 6vw,   56px);
  --fs-form-amount:    clamp(44px, 7vw,   80px);

  /* ----------------------------------------------------------
     LINE HEIGHT
  ---------------------------------------------------------- */

  --lh-display: 0.92;
  --lh-heading: 1.10;
  --lh-body:    1.72;
  --lh-tight:   1.35;
  --lh-snug:    1.50;
  --lh-loose:   1.90;
  --lh-overlay: 1.10;

  /* ----------------------------------------------------------
     LETTER SPACING
  ---------------------------------------------------------- */

  --ls-tight:   -0.01em;
  --ls-normal:   0em;
  --ls-display:  0.02em;
  --ls-button:   0.04em;
  --ls-nav:      0.03em;
  --ls-eyebrow:  0.16em;
  --ls-wide:     0.20em;
  --ls-wordmark: 0.05em;
  --ls-overlay:  0.04em;
  --ls-micro:    0.01em;
  --ls-phone:    0.02em;

  /* ----------------------------------------------------------
     SPACING — BASE SCALE
     8px grid. Every spacing value is intentional.
  ---------------------------------------------------------- */

  --sp-2xs:  4px;
  --sp-xs:   8px;
  --sp-sm:   16px;
  --sp-md:   24px;
  --sp-lg:   40px;
  --sp-xl:   64px;
  --sp-2xl:  100px;
  --sp-3xl:  140px;

  /* ----------------------------------------------------------
     SPACING — FLUID SECTION PADDING
     Scales smoothly. No layout jumps at breakpoints.
  ---------------------------------------------------------- */

  --section-py:    clamp(64px,  8vw, 120px);
  --section-py-sm: clamp(40px,  5vw,  72px);
  --section-py-lg: clamp(80px, 10vw, 160px);

  /* ----------------------------------------------------------
     CONTAINER
     Base value updated per breakpoint in media queries below.
     Components reference --container-px — never hardcode.
  ---------------------------------------------------------- */

  --container-px:        14px;
  --container-max:       1440px;
  --container-max-wide:  1600px;
  --container-max-2xl:   1800px;
  --container-max-narrow: 860px;
  --container-max-form:   640px;

  /* ----------------------------------------------------------
     BORDER RADIUS
  ---------------------------------------------------------- */

  --r-xs:   4px;
  --r-sm:   8px;
  --r-md:   14px;
  --r-lg:   20px;
  --r-xl:   28px;
  --r-2xl:  40px;
  --r-full: 9999px;

  /* ----------------------------------------------------------
     EASING CURVES
     Named for psychological intent, not technical description.
     Zero raw cubic-bezier() values in component rules.
  ---------------------------------------------------------- */

  --ease-smooth:  cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --ease-spring:  cubic-bezier(0.34, 1.56, 0.64, 1.00);
  --ease-out:     cubic-bezier(0.00, 0.00, 0.20, 1.00);
  --ease-in:      cubic-bezier(0.40, 0.00, 1.00, 1.00);
  --ease-in-out:  cubic-bezier(0.40, 0.00, 0.20, 1.00);
  --ease-bounce:  cubic-bezier(0.68, -0.55, 0.27, 1.55);
  --ease-snap:    cubic-bezier(0.22, 1.00, 0.36, 1.00);

  /* ----------------------------------------------------------
     DURATION
     Zero raw millisecond values in component rules.
  ---------------------------------------------------------- */

  --dur-instant: 80ms;
  --dur-fast:    200ms;
  --dur-base:    350ms;
  --dur-slow:    600ms;
  --dur-xslow:   1000ms;
  --dur-xxslow:  1800ms;
  --dur-draw:    1200ms;
  --dur-sweep:     800ms;

  /* ----------------------------------------------------------
     SHADOWS
     Named by weight. Coloured variants for glow states.
  ---------------------------------------------------------- */

  --shadow-xs: 0 1px 4px  rgba(0, 0, 0, 0.18);
  --shadow-sm: 0 2px 8px  rgba(0, 0, 0, 0.22);
  --shadow-md: 0 8px 28px rgba(0, 0, 0, 0.32);
  --shadow-lg: 0 20px 64px rgba(0, 0, 0, 0.44);
  --shadow-xl:  0 32px 96px  rgba(0, 0, 0, 0.56);
  --shadow-2xl: 0 48px 128px rgba(0, 0, 0, 0.64);

  --shadow-ochre-sm: 0 4px 18px  rgba(232, 160, 64, 0.28);
  --shadow-ochre:    0 8px 36px  rgba(232, 160, 64, 0.32);
  --shadow-ochre-lg: 0 16px 56px rgba(232, 160, 64, 0.42);

  --shadow-green-sm: 0 4px 18px  rgba(30, 132, 73, 0.24);
  --shadow-green:    0 8px 36px  rgba(30, 132, 73, 0.28);
  --shadow-green-lg: 0 16px 56px rgba(30, 132, 73, 0.38);

  --shadow-inset-dark:  inset 0 1px 0 rgba(244, 239, 228, 0.06);
  --shadow-inset-light: inset 0 1px 0 rgba(12,  30,  24,  0.06);

  /* ----------------------------------------------------------
     BORDERS
     Never raw rgba() in component rules.
  ---------------------------------------------------------- */

  --border-dark:         1px solid rgba(244, 239, 228, 0.07);
  --border-mid:          1px solid rgba(244, 239, 228, 0.14);
  --border-bright:       1px solid rgba(244, 239, 228, 0.30);
  --border-light:        1px solid rgba(12,  30,  24,  0.09);
  --border-light-mid:    1px solid rgba(12,  30,  24,  0.18);
  --border-green:        1px solid rgba(30,  132, 73,  0.25);
  --border-green-strong: 1px solid rgba(30,  132, 73,  0.50);
  --border-ochre:        1px solid rgba(232, 160, 64,  0.25);
  --border-ochre-strong: 1px solid rgba(232, 160, 64,  0.55);
  --border-error:        1px solid rgba(212, 168, 69,  0.55);
  --border-glass:        1px solid rgba(232, 160, 64,  0.20);

  --c-border-green:        rgba(30,  132, 73,  0.25);
  --c-border-green-strong: rgba(30,  132, 73,  0.50);
  --c-border-ochre:        rgba(232, 160, 64,  0.25);
  --c-border-ochre-strong: rgba(232, 160, 64,  0.55);
  --c-border-error:        rgba(212, 168, 69,  0.55);
  --c-border-glass:        rgba(232, 160, 64,  0.20);
  --c-border-dark:         rgba(244, 239, 228, 0.07);
  --c-border-mid:          rgba(244, 239, 228, 0.14);
  --c-border-bright:       rgba(244, 239, 228, 0.30);
  --c-border-light:        rgba(12,  30,  24,  0.09);
  --c-border-light-mid:    rgba(12,  30,  24,  0.18);

  /* ----------------------------------------------------------
     Z-INDEX SCALE
     Zero raw integers in component rules.
  ---------------------------------------------------------- */

  --z-base:       1;
  --z-raised:     10;
  --z-dropdown:   100;
  --z-sticky:     200;
  --z-nav:        900;
  --z-bar:        910;
  --z-modal-bg:   950;
  --z-modal:      960;
  --z-overlay:    970;
  --z-cursor:     9999;

  /* ----------------------------------------------------------
     COMPONENT TOKENS — NAV (ORBITAL PILL)
     Desktop floating pill. Solidifies at scroll threshold.
  ---------------------------------------------------------- */

  --nav-height-desktop:  58px;
  --nav-height-mobile:   60px;
  --nav-pill-h:          52px;
  --nav-pill-h-lg:       56px;
  --nav-mark-h:          28px;
  --nav-underline-h:      1px;
  --nav-chevron:         10px;
  --nav-phone-icon:      14px;
  --mob-tab-icon:        20px;
  --mob-tab-gap:          3px;
  --mob-indicator-h:     32px;
  --mob-indicator-bot:    8px;
  --mob-label-size:       9px;
  --mob-label-ls:        0.06em;
  --mob-sheet-header-h:  120px;
  --gap-micro:             2px;
  --cue-bounce-travel:     3px;
  --modal-entrance-y:    -16px;

  --ty-lift-sm:          -2px;
  --ty-lift-md:          -3px;
  --ty-lift-lg:          -4px;
  --ty-lift-xl:          -6px;
  --ty-reveal-xs:        12px;
  --ty-reveal-sm:        16px;
  --ty-reveal-md:        20px;
  --ty-reveal-lg:        24px;
  --ty-reveal-xl:        40px;

  --tx-step-enter:       48px;
  --tx-step-exit:       -48px;
  --tx-panel-enter:      20px;
  --nav-scroll-trigger:  80px;
  --nav-blur:            blur(20px);

  /* ----------------------------------------------------------
     COMPONENT TOKENS — MOBILE BARS
     Bottom nav: 68px. CTA bar sits above it at bottom: 68px.
  ---------------------------------------------------------- */

  --mob-nav-height:    68px;
  --mob-cta-height:    56px;
  --mob-calc-bar-h:    44px;

  /* ----------------------------------------------------------
     COMPONENT TOKENS — BUTTONS
  ---------------------------------------------------------- */

  --btn-min-touch:      44px;
  --btn-shimmer:        480ms;
  --btn-radius-default: var(--r-full);
  --btn-radius-lg:      var(--r-full);
  --btn-height-lg:      52px;
  --btn-height-xl:      60px;
  --ls-btn-xl:          0.06em;
  --btn-spinner-size:   18px;
  --btn-spinner-border: 2px;

  /* ----------------------------------------------------------
     COMPONENT TOKENS — CARDS
  ---------------------------------------------------------- */

  --card-radius:        var(--r-xl);
  --card-hover-lift:    translateY(-10px);
  --card-glow-size:     80px;
  --card-deco-offset:  -20px;
  --card-icon-size:     36px;

  /* ----------------------------------------------------------
     COMPONENT TOKENS — FORMS + FIELDS
  ---------------------------------------------------------- */

  --field-height:      52px;
  --field-radius:      var(--r-md);
  --field-label-size:  10px;
  --field-label-ls:    0.10em;

  /* ----------------------------------------------------------
     COMPONENT TOKENS — CALCULATOR SLIDERS
  ---------------------------------------------------------- */

  --slider-track-h:        6px;
  --slider-thumb:          26px;
  --slider-thumb-mob:      32px;
  --slider-thumb-shadow:   0 2px 10px rgba(232, 160, 64, 0.45);
  --slider-thumb-hover:    0 4px 18px rgba(232, 160, 64, 0.65);

  /* ----------------------------------------------------------
     COMPONENT TOKENS — CURSOR (DESKTOP ONLY)
  ---------------------------------------------------------- */

  --cursor-dot:        6px;
  --cursor-ring:       36px;
  --cursor-ring-hover: 56px;
  --cursor-lag:        0.12;

  /* ----------------------------------------------------------
     COMPONENT TOKENS — SCROLL REVEAL
  ---------------------------------------------------------- */

  --reveal-y:       28px;
  --reveal-x:       28px;
  --reveal-scale:   0.88;
  --reveal-stagger:      60ms;
  --card-stagger-2:     150ms;
  --card-stagger-3:     300ms;
  --nav-card-stagger-0:   0ms;
  --nav-card-stagger-4: 180ms;
  --nav-card-stagger-5: 225ms;
  --nav-card-stagger-6: 270ms;
  --nav-card-stagger-7: 315ms;

  /* ----------------------------------------------------------
     COMPONENT TOKENS — HERO LOAD SEQUENCE
     Staggered delays. Applied via .load-* classes in HTML.
  ---------------------------------------------------------- */

  --load-eyebrow:  0ms;
  --load-headline: 100ms;
  --load-sub:      480ms;
  --load-cta:      640ms;
  --load-trust:    720ms;
  --load-stats:    840ms;
  --load-visual:   200ms;

  /* ----------------------------------------------------------
     COMPONENT TOKENS — W MARK PARALLAX
  ---------------------------------------------------------- */

  --parallax-factor: 0.28;
  --parallax-max:    80px;

  /* ----------------------------------------------------------
     COMPONENT TOKENS — FORM OVERLAY
  ---------------------------------------------------------- */

  --form-card-max:     560px;
  --form-progress-h:   4px;
  --form-particle-n:   40;

  --steps-line-h:       1px;
  --a11y-clip-size:     1px;
  --a11y-clip-offset:   -1px;
  --dot-size-sm:        6px;
  --dot-size-pill:       5px;
  --form-handle-w:      32px;
  --form-dot-active-w:  24px;
  --form-step-in:       320ms;
  --form-step-out:      260ms;
  --form-nav-grad-h:    40px;
  --form-nav-grad-top: -40px;
  --form-state-icon:    56px;
  --calc-toggle-w:      48px;
  --calc-toggle-h:      28px;
  --calc-toggle-thumb:  22px;
  --calc-toggle-pad:     3px;
  --calc-toggle-travel: 20px;
  --calc-ticker-gap:     40ms;
  --form-tile-icon:      20px;
  --form-tile-icon-lg:   24px;
  --form-tile-check:     14px;
  --dot-size-md:        8px;
  --dot-size-lg:        12px;

  /* ----------------------------------------------------------
     PHONE — Single source of truth.
     JS reads window.WAFH_PHONE from a global constant.
     This token is the display-formatted version for CSS
     content properties only. JS constant defined in each file.
  ---------------------------------------------------------- */

  --phone-display: "0485 985 532";

}

/* ============================================================
   BREAKPOINT CONTAINER OVERRIDES
   Mobile-first. Base at 386px.
   --container-px cascades to every component that uses it.
   ============================================================ */

@media (min-width: 480px) {
  :root {
    --container-px: 20px;
  }
}

@media (min-width: 780px) {
  :root {
    --container-px: 32px;
  }
}

@media (min-width: 1200px) {
  :root {
    --container-px: 52px;
    --container-max: 1200px;
  }
}

@media (min-width: 1440px) {
  :root {
    --container-px: 72px;
    --container-max: 1440px;
  }
}

@media (min-width: 1920px) {
  :root {
    --container-px:       80px;
    --container-max:      1600px;
    --container-max-wide: 1600px;
  }
}

@media (min-width: 2560px) {
  :root {
    --container-max:      1800px;
    --container-max-wide: 1800px;
  }
}

/* ============================================================
   UNIT 1.2 — RESET + BASE
   Universal box model. Semantic HTML defaults.
   Body, html, images, links, buttons, inputs.
   cursor: none is NOT set here — cursor.js applies it
   at the exact moment custom cursor elements are created.
   This prevents the blank-cursor flash on page load.
   ============================================================ */

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  font-size: 16px; /* root em base — intentional, cannot be var() */
  scroll-behavior: smooth;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  -webkit-text-size-adjust: 100%;
  height: 100%;
}

body {
  font-family: var(--f-body);
  font-weight: 400;
  font-size: var(--fs-body-md);
  line-height: var(--lh-body);
  color: var(--t-dark-primary);
  background-color: var(--c-midnight);
  overflow-x: hidden;
  min-height: 100%;
  -webkit-tap-highlight-color: transparent;
}

body.mob-nav-active {
  padding-bottom: calc(var(--mob-nav-height) + var(--mob-cta-height));
}

@media (min-width: 780px) {
  body.mob-nav-active {
    padding-bottom: 0;
  }
}

img,
video,
svg {
  display: block;
  max-width: 100%;
}

picture {
  display: block;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  border: none;
  background: none;
  font-family: var(--f-body);
  font-size: inherit;
  color: inherit;
  padding: 0;
}

input,
textarea,
select {
  font-family: var(--f-body);
  font-size: var(--fs-body-md);
  color: var(--t-dark-primary);
}

input[type='search']::-webkit-search-decoration,
input[type='search']::-webkit-search-cancel-button {
  -webkit-appearance: none;
}

ul,
ol {
  list-style: none;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--f-display);
  font-weight: 400;
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  color: var(--t-dark-primary);
}

p {
  line-height: var(--lh-body);
}

strong {
  font-weight: 600;
}

/* ----------------------------------------------------------
   TEXT SELECTION
   Ochre highlight on dark. Midnight text stays readable.
---------------------------------------------------------- */

::selection {
  background-color: var(--c-ochre-glow-strong);
  color: var(--t-dark-primary);
}

::-moz-selection {
  background-color: var(--c-ochre-glow-strong);
  color: var(--t-dark-primary);
}

/* ----------------------------------------------------------
   FOCUS VISIBLE
   Keyboard users always see a clear focus ring.
   Mouse users never see it.
   Ochre on dark sections. Green on light sections.
---------------------------------------------------------- */

:focus {
  outline: none;
}

:focus-visible {
  outline: 2px solid var(--c-ochre);
  outline-offset: 3px;
  border-radius: var(--r-xs);
}

.bg-bone :focus-visible {
  outline-color: var(--c-green);
}

/* ----------------------------------------------------------
   SCROLLBAR
   Styled on webkit. Dark and minimal — never disrupts layout.
---------------------------------------------------------- */

::-webkit-scrollbar {
  width: var(--dot-size-sm);
  height: var(--dot-size-sm);
}

::-webkit-scrollbar-track {
  background: var(--c-forest);
}

::-webkit-scrollbar-thumb {
  background: var(--t-dark-ghost);
  border-radius: var(--r-full);
}

::-webkit-scrollbar-thumb:hover {
  background: var(--t-dark-muted);
}

/* ----------------------------------------------------------
   BACKGROUND SECTION CLASSES
   Applied to every <section> element.
   Controls bg colour, text colour inheritance, and
   focus-visible ring colour per context.
   Never nest a bone inside a bone.
   Never nest more than two darks without a forest break.
---------------------------------------------------------- */

.bg-midnight {
  background-color: var(--c-midnight);
  color: var(--t-dark-primary);
}

.bg-forest {
  background-color: var(--c-forest);
  color: var(--t-dark-primary);
}

.bg-bone {
  background-color: var(--c-bone);
  color: var(--t-light-primary);
}

.bg-bone h1,
.bg-bone h2,
.bg-bone h3,
.bg-bone h4,
.bg-bone h5,
.bg-bone h6 {
  color: var(--t-light-primary);
}

.bg-bone p,
.bg-bone li {
  color: var(--t-light-secondary);
}

/* ----------------------------------------------------------
   DOT GRID TEXTURE
   Hero section background texture.
   SVG dot grid at 4% opacity — adds premium depth.
   Applied as a pseudo-element so it never disrupts content.
   transform + opacity only — never layout-triggering.
---------------------------------------------------------- */

.dot-grid {
  position: relative;
}

.dot-grid::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: radial-gradient(
    circle,
    var(--t-dark-ghost) 1.5px,
    transparent 1.5px
  );
  background-size: 22px 22px;
  opacity: 0.5;
  pointer-events: none;
  z-index: var(--z-base);
}

/* ----------------------------------------------------------
   SECTION RADIAL GLOW
   Subtle ochre or green radial gradient behind key sections.
   Applied via class — never hardcoded on a section.
   Purely decorative. pointer-events: none always.
---------------------------------------------------------- */

.glow-ochre {
  position: relative;
}

.glow-ochre::after {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  width: 80%;
  height: 60%;
  transform: translateX(-50%);
  background: radial-gradient(
    ellipse at 50% 0%,
    var(--c-ochre-glow),
    transparent 70%
  );
  pointer-events: none;
  z-index: var(--z-base);
}

.glow-green {
  position: relative;
}

.glow-green::after {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  width: 80%;
  height: 60%;
  transform: translateX(-50%);
  background: radial-gradient(
    ellipse at 50% 0%,
    var(--c-green-glow),
    transparent 70%
  );
  pointer-events: none;
  z-index: var(--z-base);
}

/* ----------------------------------------------------------
   VISUALLY HIDDEN
   Accessible hide. Screen readers see it. Eyes don't.
   Used for icon button labels, skip links, etc.
---------------------------------------------------------- */

.sr-only {
  position: absolute;
  width: var(--a11y-clip-size);
  height: var(--a11y-clip-size);
  padding: 0;
  margin: var(--a11y-clip-offset);
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ----------------------------------------------------------
   SKIP LINK
   First focusable element on every page.
   Keyboard users can skip nav to main content.
---------------------------------------------------------- */

.skip-link {
  position: absolute;
  top: -100%;
  left: var(--sp-sm);
  z-index: var(--z-cursor);
  padding: var(--sp-xs) var(--sp-md);
  background: var(--c-ochre);
  color: var(--c-midnight);
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-body-sm);
  border-radius: var(--r-sm);
  transition: top var(--dur-fast) var(--ease-out);
}

.skip-link:focus {
  top: var(--sp-sm);
}

/* ----------------------------------------------------------
   REDUCED MOTION — GLOBAL KILL SWITCH
   This block sits in unit 1.11 at the end of the file.
   Declared here as a note to the build system:
   Every animation, transition, and scroll-behaviour in
   every unit is overridden by the block in 1.11.
   Do not add prefers-reduced-motion rules in individual
   component units — they all live in 1.11 together.
---------------------------------------------------------- */


/* ============================================================
   UNIT 1.3 — TYPOGRAPHY SCALE
   Complete type system. Every typographic class used anywhere
   on this site is defined here. Zero page-level overrides.

   Two fonts. No others. Ever.
   --f-display: Bebas Neue — headings, stats, numbers, nav mark
   --f-body:    Figtree — body, buttons, labels, micro-copy

   Every size: clamp(min, preferred-vw, max)
   Every colour: CSS variable
   Every spacing: CSS variable
   ============================================================ */

/* ----------------------------------------------------------
   EYEBROW TAG
   Sits above section headlines and form steps.
   Small. Uppercase. Letter-spaced. Ochre on dark. Green on light.
   The pill border variant adds extra premium feel.
---------------------------------------------------------- */

.t-eyebrow {
  display: inline-block;
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--c-ochre);
  line-height: 1;
  margin-bottom: var(--sp-sm);
}

.t-eyebrow--pill {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-xs);
  padding: 6px var(--sp-sm);
  border: var(--border-ochre);
  border-radius: var(--r-full);
  background: var(--c-ochre-glow);
  letter-spacing: var(--ls-eyebrow);
}

.t-eyebrow--pill::before {
  content: '';
  width: var(--dot-size-pill);
  height: var(--dot-size-pill);
  border-radius: var(--r-full);
  background: var(--c-ochre);
  flex-shrink: 0;
}

.bg-bone .t-eyebrow,
.bg-bone .t-eyebrow--pill {
  color: var(--c-green);
  border-color: var(--c-border-green);
  background: var(--c-green-glow);
}

.bg-bone .t-eyebrow--pill::before {
  background: var(--c-green);
}

/* ----------------------------------------------------------
   HERO HEADLINE SYSTEM
   The biggest, most important type on the site.
   Three words: LOCAL. · FAST. · FUNDED.
   Each word wrapped in .load-word for staggered reveal.
   .t-hero-ochre applies the ochre colour to "FUNDED."
   .t-hero is the parent — Bebas Neue, full fluid scale.
---------------------------------------------------------- */

.t-hero {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--fs-display-hero);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
  color: var(--t-dark-primary);
  display: block;
}

.t-hero-word {
  display: block;
  overflow: hidden;
  padding-bottom: 0.06em;
}

.t-hero-inner {
  display: block;
  transform: translateY(110%);
  opacity: 0;
  transition:
    transform var(--dur-slow) var(--ease-out),
    opacity   var(--dur-slow) var(--ease-out);
  will-change: transform, opacity;
}

.t-hero-inner.is-visible {
  transform: translateY(0);
  opacity: 1;
  will-change: auto;
}

.t-hero-ochre {
  color: var(--c-ochre);
}

/* ----------------------------------------------------------
   DISPLAY SCALE — BEBAS NEUE
   Used for: section headlines, stat numbers, calculator results,
   form questions (gamified steps), product card titles,
   nav phone number, footer phone, final CTA headline.
---------------------------------------------------------- */

.t-display-2xl {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--fs-display-2xl);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
}

.t-display-xl {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--fs-display-xl);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-display);
}

.t-display-lg {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--fs-display-lg);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-display);
}

.t-display-md {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--fs-display-md);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-display);
}

.t-display-sm {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--fs-display-sm);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-display);
}

/* ----------------------------------------------------------
   SECTION HEADLINE
   The primary headline for every section below the hero.
   Bebas Neue. Fluid. Always follows an eyebrow tag.
   Two sizes: primary (section headline) and sub (card title).
---------------------------------------------------------- */

.t-headline,
.t-h1 {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--fs-display-xl);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-display);
  color: var(--t-dark-primary);
  max-width: 16ch;
}

.t-headline--wide {
  max-width: 24ch;
}

.t-headline--full {
  max-width: none;
}

.bg-bone .t-headline,
.bg-bone .t-h1 {
  color: var(--t-light-primary);
}

.t-subheadline,
.t-h2 {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--fs-display-lg);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-display);
  color: var(--t-dark-primary);
}

.bg-bone .t-subheadline,
.bg-bone .t-h2 {
  color: var(--t-light-primary);
}

/* ----------------------------------------------------------
   STAT COUNTER NUMBERS
   The big animated numbers: "200+" · "$50M+" · "1hr"
   Bebas Neue. Ochre. Counts up on scroll entry via JS.
   .stat-number is the number itself.
   .stat-suffix / .stat-prefix are the +, $, hr etc.
   .stat-label is the Figtree label beneath.
   .stat-value wraps number + suffix/prefix for resultPulse.
---------------------------------------------------------- */

.stat-value {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2xs);
  line-height: 1;
}

.stat-prefix {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: clamp(43px, 5.4vw, 76px);  /* 35% up from --fs-display-lg */
  letter-spacing: var(--ls-display);
  color: var(--c-ochre);
  line-height: 1;
}

.stat-number {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: clamp(70px, 10.1vw, 135px);  /* 35% up from --fs-display-2xl */
  letter-spacing: var(--ls-display);
  color: var(--c-ochre);
  line-height: 1;
  display: inline-block;
  transition: transform var(--dur-base) var(--ease-spring);
}

.stat-number.is-updating {
  transform: scale(1.08);
  will-change: transform;
}

.stat-suffix {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: clamp(43px, 5.4vw, 76px);  /* 35% up from --fs-display-lg */
  letter-spacing: var(--ls-display);
  color: var(--c-ochre);
  line-height: 1;
}

.stat-label {
  font-family: var(--f-body);
  font-weight: 300;
  font-size: var(--fs-body-sm);
  color: var(--t-dark-secondary);
  margin-top: var(--sp-xs);
  line-height: var(--lh-snug);
}

/* ----------------------------------------------------------
   CALCULATOR RESULT TYPOGRAPHY
   The recommended product name, repayment figure, and
   supporting details beneath a calculator result.
   The big number pulses via .is-updating class from JS.
---------------------------------------------------------- */

.calc-result-label {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--t-dark-muted);
  margin-bottom: var(--sp-xs);
}

.calc-result-product {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--fs-display-xl);
  letter-spacing: var(--ls-display);
  color: var(--c-ochre);
  line-height: 1;
  transition: transform var(--dur-base) var(--ease-spring);
  display: inline-block;
}

.calc-result-product.is-updating {
  transform: scale(1.06);
  will-change: transform;
}

.calc-result-amount {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--fs-display-2xl);
  letter-spacing: var(--ls-display);
  color: var(--c-ochre);
  line-height: 1;
  display: inline-block;
  transition: transform var(--dur-base) var(--ease-spring);
}

.calc-result-amount.is-updating {
  transform: scale(1.06);
  will-change: transform;
}

.calc-result-period {
  font-family: var(--f-body);
  font-weight: 300;
  font-size: var(--fs-body-md);
  color: var(--t-dark-secondary);
  margin-top: var(--sp-2xs);
}

.calc-result-note {
  font-family: var(--f-body);
  font-weight: 300;
  font-size: var(--fs-body-xs);
  color: var(--t-dark-muted);
  margin-top: var(--sp-xs);
  line-height: var(--lh-snug);
}

/* ----------------------------------------------------------
   BODY SCALE — FIGTREE
   Used for: body copy, card descriptions, form answers,
   button labels, micro-copy, captions, compliance text.
---------------------------------------------------------- */

.t-body-xl {
  font-family: var(--f-body);
  font-size: var(--fs-body-xl);
  line-height: var(--lh-body);
  font-weight: 400;
}

.t-body-lg {
  font-family: var(--f-body);
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body);
  font-weight: 400;
}

.t-body-md {
  font-family: var(--f-body);
  font-size: var(--fs-body-md);
  line-height: var(--lh-body);
  font-weight: 400;
}

.t-body-sm {
  font-family: var(--f-body);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-snug);
  font-weight: 400;
}

.t-body-xs {
  font-family: var(--f-body);
  font-size: var(--fs-body-xs);
  line-height: var(--lh-snug);
  font-weight: 300;
}

/* ----------------------------------------------------------
   LEAD TEXT
   The first paragraph under a section headline.
   Larger. More weight. Sets the tone before details.
---------------------------------------------------------- */

.t-lead {
  font-family: var(--f-body);
  font-size: var(--fs-body-xl);
  font-weight: 400;
  line-height: var(--lh-body);
  color: var(--t-dark-secondary);
  max-width: 52ch;
}

.bg-bone .t-lead {
  color: var(--t-light-secondary);
}

/* ----------------------------------------------------------
   MICRO-COPY
   Under every primary CTA button. Every time.
   Trust line: "No obligation · We respond within the hour · WA local team"
   Three items separated by a centred dot.
   Never more than one line. Never generic.
---------------------------------------------------------- */

.hero-trust-cycle {
  display: inline-block;
  transition: opacity 0.4s ease;
}

.t-micro {
  font-family: var(--f-body);
  font-weight: 300;
  font-size: var(--fs-body-xs);
  color: var(--t-dark-muted);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-micro);
}

.t-micro--trust {
  display: flex;
  align-items: center;
  gap: var(--sp-xs);
  flex-wrap: wrap;
}

.t-micro--trust span {
  display: flex;
  align-items: center;
  gap: var(--sp-xs);
}

.t-micro--trust span + span::before {
  content: '·';
  color: var(--t-dark-ghost);
}

.bg-bone .t-micro {
  color: var(--t-light-muted);
}

.bg-bone .t-micro--trust span + span::before {
  color: var(--t-light-ghost);
}

/* ----------------------------------------------------------
   COMPLIANCE TEXT
   Footer disclaimer. Every page. Every time.
   Figtree 300. 11px. Ghost opacity.
   Never hidden. Never styled to be illegible.
   WCAG AA contrast met at this opacity on midnight.
---------------------------------------------------------- */

.t-compliance {
  font-family: var(--f-body);
  font-weight: 300;
  font-size: var(--fs-body-xs);
  color: var(--t-dark-ghost);
  line-height: var(--lh-body);
  max-width: 72ch;
}

/* ----------------------------------------------------------
   TESTIMONIAL TYPOGRAPHY
   Quote. Author. Business. Three elements. One system.
---------------------------------------------------------- */

.t-quote {
  font-family: var(--f-body);
  font-weight: 400;
  font-size: var(--fs-body-lg);
  line-height: var(--lh-body);
  color: var(--t-dark-secondary);
  font-style: italic;
}

.t-quote-author {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-body-sm);
  color: var(--t-dark-primary);
  font-style: normal;
  margin-top: var(--sp-md);
}

.t-quote-business {
  font-family: var(--f-body);
  font-weight: 300;
  font-size: var(--fs-body-xs);
  color: var(--c-green-hi);
  font-style: normal;
  margin-top: var(--sp-2xs);
}

/* ----------------------------------------------------------
   NAVIGATION TYPOGRAPHY
   Orbital pill links. Phone number. Wordmark.
   Mobile overlay links in Bebas Neue — large, spaced.
---------------------------------------------------------- */

.t-nav-link {
  font-family: var(--f-body);
  font-weight: 500;
  font-size: var(--fs-body-sm);
  letter-spacing: var(--ls-nav);
  color: var(--t-dark-secondary);
  line-height: 1;
}

.t-nav-phone {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-body-sm);
  letter-spacing: var(--ls-phone);
  color: var(--c-ochre);
  line-height: 1;
}

.t-wordmark {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--fs-wordmark);
  letter-spacing: var(--ls-wordmark);
  color: var(--t-dark-primary);
  line-height: 1;
}

.t-wordmark-accent {
  color: var(--c-ochre);
}

.t-nav-overlay-link {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--fs-nav-overlay);
  letter-spacing: var(--ls-overlay);
  color: var(--t-dark-primary);
  line-height: var(--lh-overlay);
}

/* ----------------------------------------------------------
   FOOTER TYPOGRAPHY
   Phone number large in Bebas. Links in Figtree.
   All on midnight — dark text variables.
---------------------------------------------------------- */

.t-footer-phone {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--fs-display-sm);
  letter-spacing: var(--ls-display);
  color: var(--c-ochre);
  line-height: 1;
}

.t-footer-link {
  font-family: var(--f-body);
  font-weight: 400;
  font-size: var(--fs-body-sm);
  color: var(--t-dark-secondary);
  line-height: var(--lh-loose);
  transition: color var(--dur-fast) var(--ease-smooth);
}

.t-footer-link:hover {
  color: var(--c-ochre);
}

.t-footer-label {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--t-dark-muted);
  margin-bottom: var(--sp-sm);
}

/* ----------------------------------------------------------
   FORM TYPOGRAPHY
   Step labels, question text, field labels, error messages.
   Success and error states. Privacy micro-copy.
---------------------------------------------------------- */

.t-form-step {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--t-dark-muted);
}

.t-form-question {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--fs-display-md);
  letter-spacing: var(--ls-display);
  color: var(--t-dark-primary);
  line-height: var(--lh-heading);
  margin-bottom: var(--sp-md);
}

.t-form-amount {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--fs-form-amount);
  letter-spacing: var(--ls-display);
  color: var(--c-ochre);
  line-height: 1;
  transition: transform var(--dur-fast) var(--ease-spring);
  display: inline-block;
}

.t-form-amount.is-updating {
  transform: scale(1.04);
  will-change: transform;
}

.t-field-label {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--field-label-size);
  letter-spacing: var(--field-label-ls);
  text-transform: uppercase;
  color: var(--c-green-hi);
  line-height: 1;
}

.t-field-error {
  font-family: var(--f-body);
  font-weight: 400;
  font-size: var(--fs-body-xs);
  color: var(--c-error);
  line-height: var(--lh-tight);
}

.t-form-privacy {
  font-family: var(--f-body);
  font-weight: 300;
  font-size: var(--fs-body-xs);
  color: var(--t-dark-muted);
  line-height: var(--lh-snug);
}

.t-form-success-headline {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--fs-display-lg);
  letter-spacing: var(--ls-display);
  color: var(--c-green-hi);
  line-height: var(--lh-heading);
}

.t-form-success-sub {
  font-family: var(--f-body);
  font-weight: 400;
  font-size: var(--fs-body-lg);
  color: var(--t-dark-secondary);
  line-height: var(--lh-body);
  margin-top: var(--sp-sm);
}

/* ----------------------------------------------------------
   COLOUR MODIFIERS
   Applied to any text element to shift its colour.
   All reference variables. Zero hardcoded values.
---------------------------------------------------------- */

.t-ochre {
  color: var(--c-ochre);
}

.t-green {
  color: var(--c-green-hi);
}
.t-primary {
  color: var(--t-dark-primary);
}

.t-secondary {
  color: var(--t-dark-secondary);
}

.t-muted {
  color: var(--t-dark-muted);
}

.t-ghost {
  color: var(--t-dark-ghost);
}

.t-bone {
  color: var(--c-bone);
}

.t-error {
  color: var(--c-error);
}

.bg-bone .t-primary {
  color: var(--t-light-primary);
}

.bg-bone .t-secondary {
  color: var(--t-light-secondary);
}

.bg-bone .t-muted {
  color: var(--t-light-muted);
}

.bg-bone .t-ghost {
  color: var(--t-light-ghost);
}

/* ----------------------------------------------------------
   WEIGHT MODIFIERS
---------------------------------------------------------- */

.t-300 {
  font-weight: 300;
}

.t-400 {
  font-weight: 400;
}

.t-500 {
  font-weight: 500;
}

.t-600 {
  font-weight: 600;
}

.t-700 {
  font-weight: 700;
}

/* ----------------------------------------------------------
   TEXT ALIGNMENT UTILITIES
---------------------------------------------------------- */

.t-left {
  text-align: left;
}

.t-centre {
  text-align: center;
}

.t-right {
  text-align: right;
}

@media (min-width: 780px) {
  .t-md-left {
    text-align: left;
  }

  .t-md-centre {
    text-align: center;
  }
}

.t-upper {
  text-transform: uppercase;
}

.t-lower {
  text-transform: lowercase;
}

.t-caps {
  text-transform: capitalize;
}

/* ----------------------------------------------------------
   HERO LOAD SEQUENCE
   Applied to elements in the hero section.
   JS adds .is-loaded to <body> on DOMContentLoaded.
   Each class has a specific transition-delay matching
   the --load-* variables in :root.
   Only transform + opacity animated. No layout triggers.
   will-change removed via .is-loaded transition-end.
---------------------------------------------------------- */

.load-eyebrow,
.load-headline,
.load-sub,
.load-cta,
.load-trust,
.load-stats,
.load-visual {
  opacity: 0;
  transform: translateY(var(--ty-reveal-lg));
  transition:
    opacity   var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
  will-change: transform, opacity;
}

.load-visual {
  transform: scale(0.94) translateY(var(--ty-reveal-sm));
  transition:
    opacity   var(--dur-xslow) var(--ease-out),
    transform var(--dur-xslow) var(--ease-spring);
}

body.is-loaded .load-eyebrow {
  opacity: 1;
  transform: translateY(0);
  transition-delay: var(--load-eyebrow);
  will-change: auto;
}

body.is-loaded .load-headline {
  opacity: 1;
  transform: translateY(0);
  transition-delay: var(--load-headline);
  will-change: auto;
}

body.is-loaded .load-sub {
  opacity: 1;
  transform: translateY(0);
  transition-delay: var(--load-sub);
  will-change: auto;
}

body.is-loaded .load-cta {
  opacity: 1;
  transform: translateY(0);
  transition-delay: var(--load-cta);
  will-change: auto;
}

body.is-loaded .load-trust {
  opacity: 1;
  transform: translateY(0);
  transition-delay: var(--load-trust);
  will-change: auto;
}

body.is-loaded .load-stats {
  opacity: 1;
  transform: translateY(0);
  transition-delay: var(--load-stats);
  will-change: auto;
}

body.is-loaded .load-visual {
  opacity: 1;
  transform: scale(1) translateY(0);
  transition-delay: var(--load-visual);
  will-change: auto;
}

/* ----------------------------------------------------------
   SCROLL REVEAL
   .reveal is the base state — invisible, shifted.
   Direction variants for left/right/scale reveals.
   JS IntersectionObserver adds .is-visible.
   Stagger delay applied via JS inline style.
   will-change removed on transition end via JS.
---------------------------------------------------------- */

.reveal {
  opacity: 0;
  transform: translateY(var(--reveal-y));
  transition:
    opacity   var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
}

.reveal--left {
  transform: translateX(calc(-1 * var(--reveal-x)));
}

.reveal--right {
  transform: translateX(var(--reveal-x));
}

.reveal--scale {
  transform: scale(var(--reveal-scale));
}

.reveal--fade {
  transform: none;
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0) translateX(0) scale(1);
}


/* ============================================================
   UNIT 1.4 — LAYOUT + GRID SYSTEM
   Complete layout foundation. Every grid, every container,
   every section wrapper used anywhere on this site.
   Mobile-first. 386px base. Complexity added upward.
   Zero page-level layout overrides needed.

   Breakpoints:
   386px  base     — 14px padding, 1-col, min touch targets
   480px  xs       — 20px padding, 2-col unlocks for small cards
   780px  sm       — 32px padding, tablet, hamburger nav
   1200px md       — 52px padding, 3–4 col grids, cursor active
   1440px lg       — 72px padding, primary design benchmark
   1920px xl       — 80px padding, max-width 1600px
   2560px 2xl      — max-width 1800px, clamp at ceiling
   ============================================================ */

/* ----------------------------------------------------------
   CONTAINER
   The universal width constraint. Used on every section's
   inner wrapper. Never on the section itself — section
   always bleeds full-width for background colour.
   --container-px updates per breakpoint via :root overrides.
   --container-max updates per breakpoint via :root overrides.
---------------------------------------------------------- */

.container {
  width: 100%;
  margin-right: auto;
  margin-left: auto;
  padding-right: var(--container-px);
  padding-left: var(--container-px);
  max-width: var(--container-max);
}

.container--narrow {
  max-width: var(--container-max-narrow);
}

.container--wide {
  max-width: var(--container-max-wide);
}

.container--form {
  max-width: var(--container-max-form);
}

.container--full {
  max-width: none;
}

/* ----------------------------------------------------------
   SECTION
   Semantic wrapper for every page section.
   Controls vertical padding. Position relative so
   ::before / ::after glows and textures position correctly.
   Never set overflow: hidden here — clip on inner elements.
---------------------------------------------------------- */

.section {
  position: relative;
  padding-top: var(--section-py);
  padding-bottom: var(--section-py);
}

.section--sm {
  padding-top: var(--section-py-sm);
  padding-bottom: var(--section-py-sm);
}

.section--lg {
  padding-top: var(--section-py-lg);
  padding-bottom: var(--section-py-lg);
}

.section--flush-top {
  padding-top: 0;
}

.section--flush-bottom {
  padding-bottom: 0;
}

/* Section header block — eyebrow + headline + lead */
.section-header {
  margin-bottom: var(--sp-xl);
}

.section-header--centre {
  text-align: center;
}

.section-header--centre .t-h1,
.section-header--centre .t-headline {
  margin-right: auto;
  margin-left: auto;
}

.section-header--centre .t-lead {
  margin-right: auto;
  margin-left: auto;
}


/* ----------------------------------------------------------
   GRID SYSTEM
   CSS Grid. Mobile-first. All grids start 1-col.
   Gap uses spacing variables — never raw px.
   Each grid variant unlocks at the correct breakpoint.
   Auto-rows: 1fr where all cards must match height.
---------------------------------------------------------- */

.grid {
  display: grid;
  gap: var(--sp-md);
  grid-template-columns: 1fr;
}

.grid--gap-sm {
  gap: var(--sp-sm);
}

.grid--gap-lg {
  gap: var(--sp-lg);
}

/* 2-col: unlocks at 480px (XS) */
.grid-2 {
  display: grid;
  gap: var(--sp-md);
  grid-template-columns: 1fr;
}

@media (min-width: 480px) {
  .grid-2 {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* 3-col: unlocks at 780px (SM) */
.grid-3 {
  display: grid;
  gap: var(--sp-md);
  grid-template-columns: 1fr;
}

@media (min-width: 480px) {
  .grid-3 {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 780px) {
  .grid-3 {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* 4-col: unlocks at 1200px (MD) */
.grid-4 {
  display: grid;
  gap: var(--sp-md);
  grid-template-columns: 1fr;
}

@media (min-width: 480px) {
  .grid-4 {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 780px) {
  .grid-4 {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (min-width: 1200px) {
  .grid-4 {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* Auto-fill: fills available space with min-width items */
.grid-auto {
  display: grid;
  gap: var(--sp-md);
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}

@media (min-width: 780px) {
  .grid-auto {
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  }
}


/* ----------------------------------------------------------
   HERO LAYOUT GRID
   58/42 split on desktop. Left: content. Right: W mark.
   Single column on mobile — mark hidden, content full-width.
   Min-height: 100vh on desktop so the hero fills the screen.
   On mobile: auto height — content drives the height.
   The hero background (dot grid + glow) bleeds to viewport.
   align-items: center — content vertically centred in hero.
---------------------------------------------------------- */

.hero-dot-grid {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

.hero-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-lg);
  align-items: center;
  min-height: auto;
  padding-top: var(--sp-lg);
  padding-bottom: var(--sp-xl);
}

.hero-grid__content {
  display: flex;
  flex-direction: column;
  gap: var(--sp-md);
}

.hero-grid__visual {
  display: none;
}

@media (min-width: 780px) {
  .hero-grid {
    grid-template-columns: 58fr 42fr;
    min-height: 100vh;
    padding-top: calc(var(--nav-height-desktop) + var(--sp-lg));
    padding-bottom: var(--sp-2xl);
    gap: var(--sp-xl);
  }

  .hero-grid__visual {
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
  }
}

/* ----------------------------------------------------------
   HERO RESPONSIVE VISIBILITY
   desktop-hero-grid: hidden on mobile, shown on desktop.
   mobile-hero-grid:  shown on mobile, hidden on desktop.
---------------------------------------------------------- */

.desktop-hero-grid {
  display: none;
}

.mobile-hero-grid {
  display: flex;
  flex-direction: column;
  gap: var(--sp-md);
  padding-top: var(--sp-lg);
  padding-bottom: var(--sp-xl);
  position: relative;
  overflow: hidden;
}

/* ----------------------------------------------------------
   MOBILE W-MARK — faint watermark behind hero content.
   Positioned bottom-right, large, very low opacity.
   Ambient pulse + green glow loop on slow desync'd timers.
---------------------------------------------------------- */
.mobile-w-mark {
  position: absolute;
  bottom: -8%;
  right: -18%;
  width: 85%;
  height: auto;
  opacity: 0.06;
  pointer-events: none;
  z-index: 0;
  animation: mob-w-pulse 4s ease-in-out infinite;
}
.mobile-w-green {
  animation: mob-w-green-glow 6s ease-in-out 2s infinite;
}

/* Ensure all hero content sits above the watermark */
.mobile-hero-grid > *:not(.mobile-w-mark) {
  position: relative;
  z-index: 1;
}

@keyframes mob-w-pulse {
  0%, 100% { opacity: 0.06; }
  50%      { opacity: 0.10; }
}
@keyframes mob-w-green-glow {
  0%, 100% { filter: drop-shadow(0 0 0 rgba(30,132,73,0)); }
  50%      { filter: drop-shadow(0 0 18px rgba(30,132,73,0.5)); }
}

@media (min-width: 780px) {
  .desktop-hero-grid {
    display: grid;
  }

  .mobile-hero-grid {
    display: none;
  }
}

/* ----------------------------------------------------------
   HERO COMPONENTS
   Content, CTA row, proof pill, trust text.
   These sit inside the hero-grid left column.
---------------------------------------------------------- */

.hero-content {
  display: flex;
  flex-direction: column;
  gap: var(--sp-md);
}

.hero-eyebrow {}

.hero-sub {
  color: var(--t-dark-secondary);
  max-width: 42ch;
}

.hero-cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-sm);
  align-items: center;
}

.hero-proof-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-xs);
  font-family: var(--f-body);
  font-size: var(--fs-body-sm);
  color: var(--t-dark-secondary);
  background: var(--t-dark-hairline);
  padding: var(--sp-xs) var(--sp-md);
  border-radius: var(--r-full);
  line-height: 1;
  animation: pill-pulse 2.5s ease-in-out infinite;
}

.hero-proof-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--r-full);
  background: var(--c-green);
  flex-shrink: 0;
  animation: proof-pulse 2.5s ease-in-out infinite;
}

@keyframes proof-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.7; }
}

@keyframes pill-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.02); }
}

@media (prefers-reduced-motion: reduce) {
  .hero-proof-pill { animation: none; }
  .hero-proof-dot  { animation: none; }
}

.hero-trust {
  color: var(--t-dark-muted);
}

/* Hero blinking cursor */
.hero-cursor {
  color: var(--c-ochre);
  animation: cursor-blink 0.8s ease-in-out infinite;
}

/* Hero W mark visual */
.hero-visual {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.hero-mark-parallax {
  position: relative;
  width: 100%;
  max-width: 380px;
}

.hero-mark-glow {
  position: absolute;
  inset: -20%;
  background: radial-gradient(circle, var(--c-ochre-glow) 0%, transparent 70%);
  opacity: 0.3;
  pointer-events: none;
}

.hero-mark-svg {
  width: 100%;
  height: auto;
  position: relative;
  z-index: 1;
}

/* Mobile hero components */
.mobile-hero-call {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-xs);
  padding: var(--sp-sm) var(--sp-lg);
  background: transparent;
  border: var(--border-ochre);
  border-radius: var(--r-full);
  color: var(--c-ochre);
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-body-md);
  text-decoration: none;
  transition: background var(--dur-fast) var(--ease-smooth);
}

.mobile-hero-call:hover {
  background: var(--c-ochre-glow);
}

.mobile-stats-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-xs);
  text-align: center;
}

.mobile-stat {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2xs);
}

.mobile-stat .stat-number {
  font-size: clamp(52px, 8vw, 76px);  /* 45% up from original */
}

.mobile-stat .stat-suffix,
.mobile-stat .stat-prefix {
  font-size: clamp(32px, 4.4vw, 46px);  /* 45% up from original */
}

/* ----------------------------------------------------------
   STATS ROW / STATS GRID
   3 stat cards in a row beneath the hero headline.
   All equal width. Never stack — even at 386px they
   sit side by side (compact treatment on small screens).
   At 780px+ they breathe with more gap.
---------------------------------------------------------- */

.stats-row,
.stats-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-sm);
}

.hero-stats-full {
  grid-column: 1 / -1;
}

@media (min-width: 780px) {
  .stats-row,
  .stats-grid {
    gap: var(--sp-md);
  }
}

/* ----------------------------------------------------------
   TRUST BAR — SCROLLING TICKER
   Bloomberg-style scrolling deal ticker.
   "Live WA deals" label left, ticker scrolls right.
   Duplicated items create seamless infinite loop.
   overflow: hidden clips the scrolling content.
---------------------------------------------------------- */

.trust-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-md);
  overflow: hidden;
}

.trust-bar__label {
  display: flex;
  align-items: center;
  gap: var(--sp-xs);
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-body-sm);
  color: var(--t-dark-primary);
  white-space: nowrap;
  flex-shrink: 0;
}

.trust-bar__dot {
  width: 8px;
  height: 8px;
  border-radius: var(--r-full);
  background: var(--c-green);
  animation: proof-pulse 2s ease-in-out infinite;
}

.trust-bar__track {
  overflow: hidden;
  flex: 1;
  mask-image: linear-gradient(to right, transparent, black 5%, black 95%, transparent);
  -webkit-mask-image: linear-gradient(to right, transparent, black 5%, black 95%, transparent);
}

.trust-bar__inner {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
  white-space: nowrap;
  animation: ticker-scroll 30s linear infinite;
  width: max-content;
}

@keyframes ticker-scroll {
  0%   { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}

.trust-bar__item {
  font-family: var(--f-body);
  font-size: var(--fs-body-sm);
  color: var(--t-dark-secondary);
}

.trust-bar__sep {
  color: var(--t-dark-muted);
}


/* ----------------------------------------------------------
   PRODUCTS GRID
   7 product cards. 1→2→3→4 col progression.
   At 1200px: 4-col but 7 cards = one orphan.
   The orphan card spans 4 col but stays card-width
   via justify-self: start — never stretches full-width.
   At 480px: 2-col always (even number works cleanly).
   At 780px: 3-col (6 cards clean + 1 orphan handled below).
   At 1200px: 4-col (odd 7th auto-placed by grid).
---------------------------------------------------------- */

/* Mobile: horizontal scroll with snap */
.products-grid {
  display: flex;
  gap: var(--sp-md);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scroll-padding: 0;
  padding-bottom: var(--sp-sm);
  /* hide scrollbar */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.products-grid::-webkit-scrollbar { display: none; }

.products-grid > .card--product {
  flex: 0 0 100%;
  scroll-snap-align: start;
}

/* Dot indicator */
.products-dots {
  display: flex;
  justify-content: center;
  gap: 8px;
  padding: var(--sp-sm) 0 var(--sp-xs);
}
.products-dots__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--t-dark-hairline);
  border: none;
  padding: 0;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-smooth),
              transform var(--dur-fast) var(--ease-smooth);
}
.products-dots__dot.is-active {
  background: var(--c-ochre);
  transform: scale(1.25);
}

@media (min-width: 480px) {
  .products-grid > .card--product {
    flex: 0 0 calc(50% - var(--sp-md) / 2);
  }
}

/* Desktop: restore grid */
@media (min-width: 780px) {
  .products-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--sp-lg);
    overflow-x: visible;
    scroll-snap-type: none;
    padding-bottom: 0;
  }
  .products-grid > .card--product {
    flex: none;
  }
  .products-dots { display: none; }
}

@media (min-width: 1200px) {
  .products-grid {
    grid-template-columns: repeat(4, 1fr);
  }

  .products-grid__card:last-child:nth-child(4n - 3) {
    grid-column: span 2;
    justify-self: center;
    width: 50%;
  }

  .products-grid__card:last-child:nth-child(4n - 2) {
    grid-column: span 2;
    justify-self: end;
    width: 50%;
  }
}


/* ----------------------------------------------------------
   HOW IT WORKS — STEPS TIMELINE
   3 numbered steps connected by a drawn ochre line.
   Desktop (≥780px): horizontal timeline, line draws L→R.
   Mobile (<780px): vertical timeline on left edge.
   JS adds .is-active on scroll entry → line draws,
   then step cards rise + fade in with stagger.
---------------------------------------------------------- */

/* --- Grid + mobile vertical timeline --- */
.steps-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-xl);
  position: relative;
  padding-left: 48px;
}

/* Mobile: vertical ochre line on the left */
.steps-grid::before {
  content: '';
  position: absolute;
  top: 0;
  left: 16px;
  width: 2px;
  height: 0;
  background: var(--c-ochre);
  transition: height 1200ms var(--ease-in-out);
  pointer-events: none;
}

.steps-grid.is-active::before {
  height: 100%;
}

/* Desktop: horizontal layout + horizontal line */
@media (min-width: 780px) {
  .steps-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--sp-xl);
    padding-left: 0;
  }

  .steps-grid::before {
    top: 38px;
    left: 10%;
    right: 10%;
    width: 0;
    height: 2px;
    transition: width 1200ms var(--ease-in-out);
  }

  .steps-grid.is-active::before {
    width: 80%;
    height: 2px;
  }
}

/* --- Step card base --- */
.step-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-xs);
  border-left: 2px solid var(--c-green);
  padding-left: var(--sp-md);
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity   600ms var(--ease-out),
    transform 600ms var(--ease-out);
}

/* Staggered reveal once timeline is active */
.steps-grid.is-active .step-card:nth-child(1) { opacity: 1; transform: translateY(0); transition-delay: 200ms; }
.steps-grid.is-active .step-card:nth-child(2) { opacity: 1; transform: translateY(0); transition-delay: 400ms; }
.steps-grid.is-active .step-card:nth-child(3) { opacity: 1; transform: translateY(0); transition-delay: 600ms; }

/* --- Step number — large decorative Bebas --- */
.step-card__number {
  font-family: var(--f-display);
  font-size: 72px;
  color: var(--c-ochre);
  line-height: 0.85;
  letter-spacing: var(--ls-display);
  position: relative;
  z-index: 1;
  background: var(--c-bone);
  width: fit-content;
  padding-right: var(--sp-sm);
}

@media (min-width: 780px) {
  .step-card__number {
    font-size: 88px;
  }
}

/* --- Time pill — green badge --- */
.step-card__pill {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2xs);
  width: fit-content;
  padding: 3px 10px;
  border-radius: var(--r-full);
  background: var(--c-green-glow);
  color: var(--c-green);
  font-family: var(--f-body);
  font-size: var(--fs-body-xs);
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.4;
}

/* --- Heading + body --- */
.step-card__heading {
  font-family: var(--f-display);
  font-size: var(--fs-display-xs);
  letter-spacing: var(--ls-display);
  color: var(--t-light-primary);
  line-height: var(--lh-heading);
}

.step-card__body {
  font-family: var(--f-body);
  font-size: var(--fs-body-sm);
  color: var(--t-light-secondary);
  line-height: var(--lh-body);
}

/* --- Legacy .step class (used elsewhere) --- */
.step {
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
}

.step__number {
  font-family: var(--f-display);
  font-size: var(--fs-display-2xl);
  color: var(--c-ochre);
  line-height: 1;
  letter-spacing: var(--ls-display);
}

/* ----------------------------------------------------------
   CALCULATOR LAYOUT GRID
   Left: inputs (sliders, pills, selectors).
   Right: result panel (sticky on mobile).
   Full-width single col on mobile.
   50/50 split at 780px.
   On mobile: result panel becomes position: sticky
   at bottom: var(--mob-nav-height) so it floats above
   the mobile nav bar and stays visible while adjusting.
---------------------------------------------------------- */

.calc-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-lg);
  align-items: start;
}

.calc-grid__inputs {
  display: flex;
  flex-direction: column;
  gap: var(--sp-md);
}

.calc-grid__result {
  position: sticky;
  bottom: var(--mob-nav-height);
  z-index: var(--z-sticky);
}

@media (min-width: 780px) {
  .calc-grid {
    grid-template-columns: 1fr 1fr;
    gap: var(--sp-xl);
  }

  .calc-grid__result {
    position: sticky;
    top: calc(var(--nav-height-desktop) + var(--sp-md));
    bottom: auto;
    z-index: var(--z-raised);
  }
}

@media (min-width: 1200px) {
  .calc-grid {
    grid-template-columns: 55fr 45fr;
  }
}

/* ----------------------------------------------------------
   STATS + MAP SECTION GRID
   Left: stat counter cards stacked.
   Right: WA SVG map with animated city dots.
   Stacks on mobile. Side by side at 780px.
---------------------------------------------------------- */

.stats-map-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-xl);
  align-items: center;
}

@media (min-width: 780px) {
  .stats-map-grid {
    grid-template-columns: 1fr 1fr;
    gap: var(--sp-2xl);
  }
}

.stats-col {}

.stats-list {
  display: flex;
  flex-direction: column;
  gap: var(--sp-md);
  margin-bottom: var(--sp-lg);
}

.wa-map-col {}

.wa-map-wrap {
  position: relative;
  max-width: 460px;
  margin: 0 auto;
}

.wa-map-svg {
  width: 100%;
  height: auto;
}

.wa-city__label {
  font-family: var(--f-body);
  font-size: 11px;
  font-weight: 500;
  fill: rgba(244,239,228,0.7);
  letter-spacing: 0.3px;
}

.wa-city__dot {
  filter: drop-shadow(0 0 6px rgba(232,160,64,0.5));
}

.wa-map-caption {
  font-family: var(--f-body);
  font-size: var(--fs-body-xs);
  color: var(--t-dark-muted);
  text-align: center;
  margin-top: var(--sp-sm);
}


/* ----------------------------------------------------------
   TESTIMONIALS LAYOUT
   Mobile: horizontal scroll snap — swipe through cards.
   Each card: 85vw wide so next card peeks (implies more).
   Desktop: 3-col grid.
   Dot indicators below on mobile — position updated by JS.
---------------------------------------------------------- */

.testimonials-track,
.testimonials-grid {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  gap: var(--sp-md);
  padding-bottom: var(--sp-md);
}

.testimonials-track::-webkit-scrollbar,
.testimonials-grid::-webkit-scrollbar {
  display: none;
}

.testimonials-track .card--testimonial,
.testimonials-grid .card--testimonial {
  flex: 0 0 85vw;
  scroll-snap-align: center;
}

.testimonials-dots {
  display: flex;
  justify-content: center;
  gap: var(--sp-xs);
  margin-top: var(--sp-md);
}

.testimonials-dot {
  width: var(--dot-size-sm);
  height: var(--dot-size-sm);
  border-radius: var(--r-full);
  background: var(--t-dark-ghost);
  transition: background var(--dur-fast) var(--ease-smooth),
              transform var(--dur-fast) var(--ease-spring);
  cursor: none;
}

.testimonials-dot.is-active {
  background: var(--c-ochre);
  transform: scale(1.4);
}

@media (min-width: 780px) {
  .testimonials-track,
  .testimonials-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    overflow-x: visible;
    scroll-snap-type: none;
  }

  .testimonials-track .card--testimonial,
  .testimonials-grid .card--testimonial {
    flex: none;
    scroll-snap-align: none;
  }

  .testimonials-dots {
    display: none;
  }
}


/* ----------------------------------------------------------
   FOOTER GRID
   4 columns desktop. 2 columns at 780px. 1 col at 480px.
   Col 1: Brand (W mark + wordmark + tagline)
   Col 2: Navigation links
   Col 3: Contact (phone, email, location)
   Col 4: Referral partner note
   Bottom row: Full-width compliance disclaimer.
   Border-top separates footer from final CTA section.
---------------------------------------------------------- */

.site-footer { padding: var(--sp-2xl) 0 var(--sp-xl); border-top: var(--border-dark); }
.footer-grid { display: grid; grid-template-columns: 1fr; gap: var(--sp-xl); margin-bottom: var(--sp-xl); }
@media (min-width: 780px) { .footer-grid { grid-template-columns: repeat(2, 1fr); gap: var(--sp-lg); } }
@media (min-width: 1200px) { .footer-grid { grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: var(--sp-xl); } }

.footer-mark { display: inline-flex; align-items: center; gap: var(--sp-xs); text-decoration: none; margin-bottom: var(--sp-sm); }
.footer-wordmark { font-family: var(--f-display); font-size: var(--fs-wordmark); letter-spacing: var(--ls-wordmark); color: var(--t-dark-primary); }
.footer-tagline { font-family: var(--f-body); font-size: var(--fs-eyebrow); letter-spacing: var(--ls-eyebrow); text-transform: uppercase; color: var(--c-green-hi); margin-bottom: var(--sp-xs); }
.footer-abn { font-family: var(--f-body); font-size: var(--fs-body-xs); color: var(--t-dark-muted); }

.footer-nav__heading { font-family: var(--f-body); font-weight: 600; font-size: var(--fs-eyebrow); letter-spacing: var(--ls-eyebrow); text-transform: uppercase; color: var(--t-dark-muted); margin-bottom: var(--sp-sm); }
.footer-nav ul { list-style: none; display: flex; flex-direction: column; gap: var(--sp-xs); padding: 0; margin: 0; }
.footer-nav a { font-family: var(--f-body); font-size: var(--fs-body-sm); color: var(--t-dark-secondary); text-decoration: none; transition: color var(--dur-fast) var(--ease-smooth); }
.footer-nav a:hover, .footer-nav a[aria-current="page"], .footer-nav a.is-active { color: var(--c-ochre); }

.footer-phone { display: flex; align-items: center; gap: var(--sp-xs); font-family: var(--f-display); font-size: var(--fs-display-xs); letter-spacing: var(--ls-display); color: var(--c-ochre); text-decoration: none; line-height: 1; margin-bottom: var(--sp-xs); }
.footer-email { font-family: var(--f-body); font-size: var(--fs-body-sm); color: var(--t-dark-secondary); text-decoration: none; display: block; margin-bottom: var(--sp-xs); transition: color var(--dur-fast) var(--ease-smooth); }
.footer-email:hover { color: var(--c-ochre); }
.footer-location { font-family: var(--f-body); font-size: var(--fs-body-sm); color: var(--t-dark-muted); margin-bottom: var(--sp-md); }

.footer-partner__label { font-family: var(--f-body); font-size: var(--fs-body-xs); color: var(--t-dark-muted); margin-bottom: var(--sp-2xs); }
.footer-partner__link { display: inline-flex; align-items: center; gap: var(--sp-2xs); font-family: var(--f-body); font-size: var(--fs-body-sm); color: var(--c-green-hi); text-decoration: none; transition: color var(--dur-fast) var(--ease-smooth); }
.footer-partner__link:hover { color: var(--c-ochre); }

.footer-divider { border: none; border-top: var(--border-dark); margin-bottom: var(--sp-lg); }
.footer-disclaimer { font-family: var(--f-body); font-weight: 300; font-size: var(--fs-body-xs); color: var(--t-dark-ghost); line-height: var(--lh-body); max-width: 72ch; margin-bottom: var(--sp-sm); }
.footer-copyright { font-family: var(--f-body); font-weight: 300; font-size: var(--fs-body-xs); color: var(--t-dark-ghost); }

/* ----------------------------------------------------------
   ABOUT / WHY US — TWO COLUMN LAYOUT
   Left: copy block (headline + body text + CTA)
   Right: 2x2 trust point grid
   Stacks on mobile. Side by side at 780px.
   The trust grid never shrinks below readable.
---------------------------------------------------------- */

.about-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-xl);
  align-items: center;
}

@media (min-width: 780px) {
  .about-grid {
    grid-template-columns: 1fr 1fr;
    gap: var(--sp-2xl);
  }
}

.trust-points {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-md);
}

/* About headline — accent border + allow full width for long lines */
.about-headline-accent {
  border-left: 4px solid var(--c-ochre);
  padding-left: 20px;
}

.about-brutal-headline {
  max-width: none;
}

/* About content — clear paragraph spacing on mobile */
@media (max-width: 779px) {
  .about-content-col .t-body {
    margin-bottom: var(--sp-md);
  }

  .about-content-col .about-trust-items {
    margin-top: var(--sp-sm);
  }
}

/* Trust items — checkmark + text in a row */
.about-trust-items {
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
  margin-top: var(--sp-md);
  margin-bottom: var(--sp-lg);
}

.about-trust-item {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-xs);
}

.about-trust-item svg {
  flex-shrink: 0;
  margin-top: 3px;
}

/* ----------------------------------------------------------
   CONTACT PAGE LAYOUT
   Centred single-column. Form is the page.
   Hero above: minimal, focused.
   Alternative contact below: bone section, 3-col.
---------------------------------------------------------- */

.contact-alt-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-lg);
  text-align: center;
}

@media (min-width: 780px) {
  .contact-alt-grid {
    grid-template-columns: repeat(3, 1fr);
    text-align: left;
  }
}

/* ----------------------------------------------------------
   FLEXBOX UTILITIES
   Common flex patterns used throughout the site.
   Named for their purpose not their implementation.
---------------------------------------------------------- */

.flex {
  display: flex;
}

.flex-col {
  display: flex;
  flex-direction: column;
}

.flex-centre {
  display: flex;
  align-items: center;
  justify-content: center;
}

.flex-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.flex-start {
  display: flex;
  align-items: center;
  justify-content: flex-start;
}

.flex-end {
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.flex-wrap {
  flex-wrap: wrap;
}

.flex-gap-xs {
  gap: var(--sp-xs);
}
.flex-gap-sm {
  gap: var(--sp-sm);
}
.flex-gap-md {
  gap: var(--sp-md);
}
.flex-gap-lg {
  gap: var(--sp-lg);
}

.flex-1 {
  flex: 1;
}
.flex-0 {
  flex: 0;
}
.flex-shrink-0 {
  flex-shrink: 0;
}

/* ----------------------------------------------------------
   SPACING UTILITIES
   Margin and padding helpers using spacing tokens.
   mt = margin-top. mb = margin-bottom.
   Used sparingly — component spacing is handled within
   component rules. These are for one-off adjustments.
---------------------------------------------------------- */

.mt-xs {
  margin-top: var(--sp-xs);
}
.mt-sm {
  margin-top: var(--sp-sm);
}
.mt-md {
  margin-top: var(--sp-md);
}
.mt-lg {
  margin-top: var(--sp-lg);
}
.mt-xl {
  margin-top: var(--sp-xl);
}
.mt-2xl {
  margin-top: var(--sp-2xl);
}

.mb-xs {
  margin-bottom: var(--sp-xs);
}
.mb-sm {
  margin-bottom: var(--sp-sm);
}
.mb-md {
  margin-bottom: var(--sp-md);
}
.mb-lg {
  margin-bottom: var(--sp-lg);
}
.mb-xl {
  margin-bottom: var(--sp-xl);
}
.mb-2xl {
  margin-bottom: var(--sp-2xl);
}

/* ----------------------------------------------------------
   DISPLAY + VISIBILITY UTILITIES
   Show/hide at breakpoints without layout shift.
   hidden-mobile: visible ≥780px only.
   hidden-desktop: visible <780px only.
---------------------------------------------------------- */

.hidden-mobile {
  display: none;
}

@media (min-width: 780px) {
  .hidden-mobile {
    display: revert;
  }
}

.hidden-desktop {
  display: revert;
}

@media (min-width: 780px) {
  .hidden-desktop {
    display: none;
  }
}

/* ----------------------------------------------------------
   POSITION UTILITIES
   Used for decorative elements, glows, overlays.
   Never for layout — layout uses grid/flex.
---------------------------------------------------------- */

.relative {
  position: relative;
}
.absolute {
  position: absolute;
}
.inset-0 {
  inset: 0;
}

.overflow-hidden {
  overflow: hidden;
}
.pointer-none {
  pointer-events: none;
}
.pointer-all {
  pointer-events: all;
}

/* ----------------------------------------------------------
   MAX-WIDTH CENTRING UTILITIES
   For centred content blocks within a section.
   Used on eyebrow/headline groups and CTA blocks.
---------------------------------------------------------- */

.mx-auto {
  margin-right: auto;
  margin-left: auto;
}

.max-w-copy {
  max-width: 52ch;
}
.max-w-narrow {
  max-width: var(--container-max-narrow);
}
.max-w-form {
  max-width: var(--container-max-form);
}


/* ============================================================
   UNIT 1.5 — BUTTON SYSTEM
   Every button variant. Every state. No exceptions.

   Variants:
   .btn--primary       Ochre — dark backgrounds (midnight/forest)
   .btn--primary-light Green — light backgrounds (bone)
   .btn--ghost         Transparent bone border — dark backgrounds
   .btn--ghost-light   Transparent midnight border — light backgrounds
   .btn--phone         Ochre border — phone number CTA, any background

   Sizes:
   .btn--sm  .btn--md (default)  .btn--lg  .btn--xl  .btn--full

   States (every button has all of these):
   :hover      translateY(var(--ty-lift-sm)) + shadow deepens
   :active     scale(0.97) spring back
   :focus-visible ochre/green outline offset 3px
   :disabled   opacity 0.4, pointer-events none
   .btn--loading  spinner replaces text, text transparent
   .btn--success  green bg, checkmark, locked
   Shimmer    ::before sweep on hover, 480ms

   Magnetic pull (JS applies transform via inline style on desktop)
   The CSS here allows transform without fighting transitions.
   ============================================================ */

/* ----------------------------------------------------------
   BASE BUTTON
   All shared properties. Every variant extends this.
   cursor: none — custom cursor handles the pointer.
   will-change NOT set here — only applied during animation.
   overflow: hidden — required for shimmer ::before clip.
   -webkit-tap-highlight-color — removes iOS blue flash.
   user-select: none — prevents text selection on rapid click.
---------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-xs);
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-body-md);
  letter-spacing: var(--ls-button);
  line-height: 1;
  padding: 14px var(--sp-lg);
  border-radius: var(--btn-radius-default);
  border: none;
  cursor: none;
  position: relative;
  overflow: hidden;
  white-space: nowrap;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  transition:
    transform    var(--dur-fast) var(--ease-smooth),
    box-shadow   var(--dur-fast) var(--ease-smooth),
    background   var(--dur-fast) var(--ease-smooth),
    border-color var(--dur-fast) var(--ease-smooth),
    color        var(--dur-fast) var(--ease-smooth),
    opacity      var(--dur-fast) var(--ease-smooth);
  min-height: var(--btn-min-touch);
}


/* ----------------------------------------------------------
   SHIMMER — ::before sweep
   Runs on hover. Linear gradient sweeps left to right.
   overflow: hidden on .btn clips it to button bounds.
   transition: none on base, then 480ms on hover trigger.
   This means it only animates on hover entry, not exit.
   That's intentional — exit shimmer looks cheap.
---------------------------------------------------------- */

.btn::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    105deg,
    transparent 20%,
    var(--c-shimmer-light) 50%,
    transparent 80%
  );
  transform: translateX(-110%);
  transition: none;
  pointer-events: none;
}

.btn:hover::before {
  transform: translateX(110%);
  transition: transform var(--btn-shimmer) var(--ease-smooth);
}

/* ----------------------------------------------------------
   BASE INTERACTION STATES
   All variants inherit these. Variants can deepen them.
   :hover lifts 2px — subtle, not dramatic.
   :active presses back — spring feel.
   :focus-visible ring — keyboard users always see this.
   :disabled — locked out, clearly reduced, no pointer.
---------------------------------------------------------- */

.btn:hover {
  transform: translateY(var(--ty-lift-sm));
}

.btn:active {
  transform: translateY(0) scale(0.97);
  transition-duration: var(--dur-instant);
}

.btn:focus-visible {
  outline: 2px solid var(--c-ochre);
  outline-offset: 3px;
}

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.4;
  pointer-events: none;
  cursor: none;
}

/* ----------------------------------------------------------
   LOADING STATE
   Text goes transparent — button holds its size.
   Spinner appears via ::after pseudo.
   pointer-events: none — can't click while loading.
   The spinner is border-based, transform: rotate only.
   No layout shift. No size change. No janky reflow.
---------------------------------------------------------- */

.btn--loading {
  color: transparent;
  pointer-events: none;
}

.btn--loading::after {
  content: '';
  position: absolute;
  width: var(--btn-spinner-size);
  height: var(--btn-spinner-size);
  border-radius: var(--r-full);
  border: var(--btn-spinner-border) solid transparent;
  border-top-color: currentColor;
  border-right-color: currentColor;
  opacity: 0.8;
  animation: btn-spin var(--dur-slow) linear infinite;
  will-change: transform;
}

@keyframes btn-spin {
  to {
    transform: rotate(360deg);
  }
}

/* ----------------------------------------------------------
   SUCCESS STATE
   Applied by JS after successful form submission.
   Green bg regardless of variant — universal success signal.
   pointer-events: none — action is done.
   Checkmark via SVG injected by JS into button content.
   Transition: colour swap with slight scale for satisfaction.
---------------------------------------------------------- */

.btn--success {
  background: var(--c-green) !important;
  color: var(--c-bone) !important;
  border-color: transparent !important;
  pointer-events: none;
  box-shadow: var(--shadow-green-sm) !important;
  transform: scale(1.02);
}


/* ----------------------------------------------------------
   PRIMARY — DARK BACKGROUNDS (midnight / forest)
   Ochre background. Midnight text. Never on bone.
   Hover: deepens to ochre-deep + larger shadow.
   Focus ring inherits ochre from base .btn:focus-visible.
   The lift on hover (-3px not -2px) makes primary feel
   more alive than ghost — hierarchy through motion.
---------------------------------------------------------- */

.btn--primary {
  background: var(--c-ochre);
  color: var(--c-midnight);
  box-shadow: var(--shadow-ochre-sm);
}

.btn--primary:hover {
  background: var(--c-ochre-deep);
  box-shadow: var(--shadow-ochre);
  transform: translateY(var(--ty-lift-md));
}

.btn--primary:active {
  background: var(--c-ochre-deep);
  box-shadow: var(--shadow-ochre-sm);
  transform: translateY(0) scale(0.97);
}

/* ----------------------------------------------------------
   PRIMARY LIGHT — LIGHT BACKGROUNDS (bone)
   Green background. Bone text. Never on dark.
   Focus ring overrides to green on bone sections.
   Shadow uses green glow — cohesive with bg colour.
---------------------------------------------------------- */

.btn--primary-light {
  background: var(--c-green);
  color: var(--c-bone);
  box-shadow: var(--shadow-green-sm);
}

.btn--primary-light:hover {
  background: var(--c-green-hi);
  box-shadow: var(--shadow-green);
  transform: translateY(var(--ty-lift-md));
}

.btn--primary-light:active {
  background: var(--c-green);
  box-shadow: var(--shadow-green-sm);
  transform: translateY(0) scale(0.97);
}

.btn--primary-light:focus-visible {
  outline-color: var(--c-green);
}

/* ----------------------------------------------------------
   GHOST — DARK BACKGROUNDS
   Transparent. Bone border. Bone text.
   Hover: subtle bone tint fills in — not fully solid.
   Paired with .btn--primary in hero CTA row.
   The ghost is always the secondary action.
   Never the only CTA on a section.
---------------------------------------------------------- */

.btn--ghost {
  background: transparent;
  color: var(--t-dark-primary);
  border: var(--border-mid);
  box-shadow: none;
}

.btn--ghost:hover {
  background: var(--t-dark-hairline);
  border-color: var(--c-bone-mid);
  transform: translateY(var(--ty-lift-sm));
}

.btn--ghost:active {
  background: transparent;
  transform: translateY(0) scale(0.97);
}

/* ----------------------------------------------------------
   GHOST LIGHT — LIGHT BACKGROUNDS (bone)
   Transparent. Midnight border. Midnight text.
   Pairs with .btn--primary-light on bone sections.
   Hover: very subtle midnight tint — readable, not heavy.
---------------------------------------------------------- */

.btn--ghost-light {
  background: transparent;
  color: var(--t-light-primary);
  border: var(--border-light-mid);
  box-shadow: none;
}

.btn--ghost-light:hover {
  background: var(--t-light-ghost);
  border-color: var(--t-light-secondary);
  transform: translateY(var(--ty-lift-sm));
}

.btn--ghost-light:active {
  background: transparent;
  transform: translateY(0) scale(0.97);
}

.btn--ghost-light:focus-visible {
  outline-color: var(--c-green);
}

/* ----------------------------------------------------------
   PHONE BUTTON
   Ochre border. Ochre text. Transparent background.
   Used in nav (desktop), mobile bottom nav, ghost CTA rows.
   Hover fills with ochre glow — feels like it's charging.
   The phone number is always in Figtree 600 — readable.
   This button always wraps an <a href="tel:..."> link.
---------------------------------------------------------- */

.btn--phone {
  background: transparent;
  color: var(--c-ochre);
  border: var(--border-ochre);
  box-shadow: none;
  font-weight: 600;
  letter-spacing: var(--ls-phone);
}

.btn--phone:hover {
  background: var(--c-ochre-glow);
  border-color: var(--c-ochre);
  box-shadow: var(--shadow-ochre-sm);
  transform: translateY(var(--ty-lift-sm));
}

.btn--phone:active {
  background: var(--c-ochre-glow);
  transform: translateY(0) scale(0.97);
}

.btn--phone:focus-visible {
  outline-color: var(--c-ochre);
}


/* ----------------------------------------------------------
   BUTTON SIZES
   Default (.btn) is medium — 14px type, 14px/40px padding.
   Sizes scale type AND padding proportionally.
   All maintain min-height: var(--btn-min-touch) = 44px.
   .btn--full spans full container width — used in forms,
   mobile CTA bar, and any single-CTA layout.
   .btn--xl is the hero CTA — maximum presence.
---------------------------------------------------------- */

.btn--sm {
  font-size: var(--fs-body-xs);
  padding: var(--sp-xs) var(--sp-md);
  border-radius: var(--r-sm);
}

.btn--lg {
  font-size: var(--fs-body-lg);
  padding: var(--sp-sm) var(--sp-xl);
  border-radius: var(--btn-radius-lg);
  min-height: var(--btn-height-lg);
}

.btn--xl {
  font-size: var(--fs-body-xl);
  padding: var(--sp-md) var(--sp-2xl);
  border-radius: var(--btn-radius-lg);
  min-height: var(--btn-height-xl);
  letter-spacing: var(--ls-btn-xl);
}

.btn--full {
  width: 100%;
}

/* ----------------------------------------------------------
   MOBILE OVERRIDES
   At 386px: bump lg/xl padding down slightly.
   Prevents buttons overflowing narrow screens.
   sm and default size unchanged — already compact.
   min-height preserved always — never below 44px.
---------------------------------------------------------- */

@media (max-width: 479px) {
  .btn--lg {
    font-size: var(--fs-body-md);
    padding: var(--sp-sm) var(--sp-lg);
  }

  .btn--xl {
    font-size: var(--fs-body-lg);
    padding: var(--sp-sm) var(--sp-xl);
    letter-spacing: var(--ls-button);
  }
}

/* ----------------------------------------------------------
   CTA ROW
   The paired primary + ghost button layout used in
   hero sections and final CTA sections.
   Stacks vertically on mobile. Side by side at 480px+.
   The gap between them is exactly --sp-sm (16px).
   On mobile: both go full-width for maximum tap target.
   Micro-copy (.t-micro--trust) sits below the row.
---------------------------------------------------------- */

.cta-row {
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
  align-items: stretch;
}

.cta-row .btn {
  width: 100%;
  justify-content: center;
}

@media (min-width: 480px) {
  .cta-row {
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
  }

  .cta-row .btn {
    width: auto;
  }
}

/* ----------------------------------------------------------
   SECTION CTA
   Centred CTA block below section content grids.
   Button + trust micro-copy. Centred at 480px+.
---------------------------------------------------------- */

.section-cta {
  text-align: center;
  margin-top: var(--sp-xl);
}


/* ----------------------------------------------------------
   FINAL CTA SECTION
   Full-width centred conversion block at the bottom
   of every page. Typewriter headline, paired buttons,
   trust micro-copy. Content centred, max-width 700px.
   On mobile: buttons stack vertically.
---------------------------------------------------------- */

.final-cta-inner {
  text-align: center;
  max-width: 700px;
  margin: 0 auto;
  position: relative;
}

/* Centered W background mark */
.final-cta-w-mark {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: clamp(300px, 55vw, 520px);
  height: auto;
  opacity: 0.06;
  pointer-events: none;
  user-select: none;
  z-index: 0;
}

.final-cta-inner > *:not(.final-cta-w-mark) {
  position: relative;
  z-index: 1;
}

.final-cta-w-mark .final-cta-w-ochre {
  animation: final-w-breathe 5s ease-in-out infinite;
}
.final-cta-w-mark .final-cta-w-green {
  animation: final-w-green-glow 6s ease-in-out 1s infinite;
}

@keyframes final-w-breathe {
  0%, 100% { stroke-opacity: 0.7; }
  50%      { stroke-opacity: 1; }
}
@keyframes final-w-green-glow {
  0%, 100% { filter: drop-shadow(0 0 0 rgba(30,132,73,0)); stroke-opacity: 0.7; }
  50%      { filter: drop-shadow(0 0 10px rgba(30,132,73,0.35)); stroke-opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .final-cta-w-mark .final-cta-w-ochre,
  .final-cta-w-mark .final-cta-w-green { animation: none !important; }
}

.final-cta-headline {
  font-family: var(--f-display);
  font-size: var(--fs-display-2xl);
  line-height: 0.92;
  letter-spacing: var(--ls-display);
  color: var(--t-dark-primary);
  margin-bottom: var(--sp-md);
}

.final-cta-sub {
  margin-bottom: var(--sp-xs);
}

.final-cta-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-md);
  flex-wrap: wrap;
  margin-top: var(--sp-lg);
}

.final-cta-trust {
  margin-top: var(--sp-md);
}

/* Typewriter blinking cursor */
.typewriter-text::after {
  content: '|';
  animation: cursor-blink 0.8s ease-in-out infinite;
  color: var(--c-ochre);
  margin-left: 2px;
}

@keyframes cursor-blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0; }
}

@media (max-width: 479px) {
  .final-cta-actions {
    flex-direction: column;
  }

  .final-cta-actions .btn {
    width: 100%;
  }
}


/* ----------------------------------------------------------
   INLINE FORM CTA
   Used below calculator results. Name + phone + submit.
   Tight layout. Always horizontal at 480px+.
   The submit button never goes full-width here — it
   sits inline with the fields, occupying its natural width.
   Fields defined in unit 1.7. This handles the row layout.
---------------------------------------------------------- */

.inline-form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
}

@media (min-width: 480px) {
  .inline-form {
    flex-direction: row;
    align-items: flex-end;
  }

  .inline-form .field-wrap {
    flex: 1;
  }

  .inline-form .btn {
    flex-shrink: 0;
  }
}


/* ============================================================
   UNIT 1.6 — CARD SYSTEM
   Every card variant. Every state. Desktop and mobile
   treated as separate experiences — not scaled-down desktop.

   Desktop: magnetic pull, diagonal warm sweep, spring lift.
   Mobile:  tap spring, border flash, no hover dependencies.
   @media (hover: none) strips all hover animations for touch.

   Variants:
   .card                Base card — all variants extend this
   .card--product       7 service product cards
   .card--testimonial   Quote cards with drawn border
   .card--stat          Hero stat counter cards
   .card--trust         Why us trust points (bone section)
   .card--result        Calculator result panel
   ============================================================ */

/* ----------------------------------------------------------
   BASE CARD
   Forest background. Dark border. Rounded corners.
   Position relative — required for all pseudo overlays.
   Transform and box-shadow on transition — no layout props.
   overflow: hidden — clips the diagonal sweep ::after.
   will-change NOT set — JS applies it on mouseenter,
   removes on mouseleave. GPU only when needed.
---------------------------------------------------------- */

.card {
  position: relative;
  background: var(--c-forest);
  border: var(--border-dark);
  border-radius: var(--card-radius);
  overflow: hidden;
  transition:
    transform    var(--dur-base) var(--ease-smooth),
    box-shadow   var(--dur-base) var(--ease-smooth),
    border-color var(--dur-base) var(--ease-smooth);
}

/* ----------------------------------------------------------
   DIAGONAL WARM SWEEP — ::after
   Slow light sweep on hover. var(--dur-sweep). Very subtle.
   Not a shimmer — this is a warm zone, not a flash.
   Moves from bottom-left to top-right.
   opacity stays below 0.07 — felt but never seen.
   pointer-events: none — never blocks card content.
   z-index: 0 — card content sits on z-index: 1.
---------------------------------------------------------- */

.card::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    135deg,
    transparent 0%,
    var(--c-green-glow) 50%,
    transparent 100%
  );
  opacity: 0;
  transform: translateX(-100%) translateY(100%);
  transition:
    opacity    var(--dur-slow)  var(--ease-smooth),
    transform  var(--dur-sweep) var(--ease-smooth);
  pointer-events: none;
  z-index: 0;
}

.card:hover::after {
  opacity: 1;
  transform: translateX(0%) translateY(0%);
}

/* Card content must sit above the sweep ::after */
.card > * {
  position: relative;
  z-index: 1;
}


/* ----------------------------------------------------------
   PRODUCT CARD
   The 7 service cards on the homepage and service pages.
   These are the primary conversion surface after the hero.
   A WA business owner scans these in under 3 seconds and
   decides if WA Finance Hub has what they need.

   Structure:
   .card--product              Outer card wrapper
   .card--product__header      Green top stripe — icon lives here
   .card--product__icon        SVG icon — springs up on hover
   .card--product__body        Content area below header
   .card--product__tag         Product category pill
   .card--product__title       Product name in Bebas Neue
   .card--product__desc        One-line description
   .card--product__cta         "Find out more →" ochre link

   Desktop hover sequence (all transform + opacity, no layout):
   1. Card lifts 10px, border shifts to green glow (0–200ms)
   2. Box-shadow deepens to --shadow-xl + green layer (0–350ms)
   3. Icon springs up 4px + rotates -3° (0–300ms spring)
   4. Diagonal warm sweep crosses card face (0–800ms)
   5. CTA arrow nudges right 4px (0–200ms)

   Mobile (hover: none):
   :active fires spring scale(0.97 → 1.0) and border flash.
   No sweep. No lift. Pure tap response.
   Border flash: brief ochre border on active, back to dark.
---------------------------------------------------------- */

.card--product {
  display: flex;
  flex-direction: column;
  background: var(--c-forest);
  border: var(--border-dark);
  border-radius: var(--card-radius);
  overflow: hidden;
  cursor: none;
  transition:
    transform    var(--dur-base)  var(--ease-smooth),
    box-shadow   var(--dur-base)  var(--ease-smooth),
    border-color var(--dur-base)  var(--ease-smooth);
}

@media (hover: hover) {
  .card--product:hover {
    transform: var(--card-hover-lift);
    border-color: var(--c-border-green-strong);
    box-shadow:
      var(--shadow-xl),
      0 0 0 1px var(--c-border-green),
      var(--shadow-green);
  }
}

@media (hover: none) {
  .card--product:active {
    transform: scale(0.97);
    border-color: var(--c-border-ochre);
    transition-duration: var(--dur-instant);
  }
}

.card--product__header {
  background: var(--c-green);
  padding: var(--sp-md) var(--sp-lg);
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
}

/* Radial glow behind icon — always present, intensifies on hover */
.card--product__header::before {
  content: '';
  position: absolute;
  top: 50%;
  left: var(--sp-md);
  width: var(--card-glow-size);
  height: var(--card-glow-size);
  background: radial-gradient(
    circle,
    var(--c-ochre-glow-strong),
    transparent 70%
  );
  transform: translateY(-50%);
  opacity: 0.6;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-smooth);
}

@media (hover: hover) {
  .card--product:hover .card--product__header::before {
    opacity: 1;
  }
}

/* Decorative circle — bottom right of header */
.card--product__header::after {
  content: '';
  position: absolute;
  bottom: var(--card-deco-offset);
  right: var(--card-deco-offset);
  width: var(--card-glow-size);
  height: var(--card-glow-size);
  border-radius: var(--r-full);
  background: var(--t-dark-hairline);
  pointer-events: none;
}

.card--product__icon {
  width: var(--card-icon-size);
  height: var(--card-icon-size);
  flex-shrink: 0;
  position: relative;
  z-index: 1;
  transition:
    transform var(--dur-base) var(--ease-spring);
}

@media (hover: hover) {
  .card--product:hover .card--product__icon {
    transform: translateY(var(--ty-lift-lg)) rotate(-3deg) scale(1.12);
  }
}

.card--product__body {
  padding: var(--sp-md) var(--sp-lg) var(--sp-lg);
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
  flex: 1;
}

.card--product__tag,
.card--product__badge {
  display: inline-flex;
  align-items: center;
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--c-green-hi);
  line-height: 1;
  flex-shrink: 0;
  margin-left: auto;
}

.card--product__title,
.card--product__name {
  font-family: var(--f-display);
  font-size: var(--fs-display-sm);
  letter-spacing: var(--ls-display);
  color: var(--t-dark-primary);
  line-height: var(--lh-heading);
  flex: 1;
  min-width: 0;
}

/* Mobile: badge drops below heading to prevent clipping */
@media (max-width: 479px) {
  .card--product__header {
    flex-wrap: wrap;
  }
  .card--product__badge {
    margin-left: 0;
    flex-basis: 100%;
    padding-left: calc(28px + var(--sp-sm)); /* align with name (icon width + gap) */
    margin-top: calc(var(--sp-xs) * -1);
  }
}

.card--product__desc {
  font-family: var(--f-body);
  font-size: var(--fs-body-sm);
  color: var(--t-dark-secondary);
  line-height: var(--lh-body);
  flex: 1;
}

/* CTA arrow nudges right on hover — desktop only */
.card--product__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-xs);
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-body-sm);
  color: var(--c-ochre);
  letter-spacing: var(--ls-button);
  margin-top: var(--sp-xs);
  transition: gap var(--dur-fast) var(--ease-smooth),
              color var(--dur-fast) var(--ease-smooth);
}

@media (hover: hover) {
  .card--product:hover .card--product__cta {
    gap: var(--sp-sm);
    color: var(--c-ochre-deep);
  }
}


/* ----------------------------------------------------------
   TESTIMONIAL CARD
   Quote cards on the homepage and service pages.
   The ochre top border DRAWS IN from left on scroll entry.
   This is achieved via scaleX(0→1) with transform-origin:left.
   JS adds .is-visible when the card enters the viewport.
   The quote mark is a decorative Bebas Neue character —
   large, ochre, very low opacity. Rotates slightly on hover.
   Desktop: hover lifts card + quote mark opacity rises.
   Mobile: no hover — just the drawn border on scroll entry.
---------------------------------------------------------- */

.card--testimonial {
  background: var(--c-forest);
  border: var(--border-dark);
  border-top: none;
  border-radius: var(--card-radius);
  padding: var(--sp-xl) var(--sp-lg) var(--sp-lg);
  position: relative;
  overflow: hidden;
  transition:
    transform  var(--dur-base) var(--ease-smooth),
    box-shadow var(--dur-base) var(--ease-smooth);
}

/* Drawn border — starts at scaleX(0), JS reveals on scroll */
.card--testimonial::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: var(--steps-line-h);
  background: var(--c-ochre);
  transform-origin: left;
  transform: scaleX(0);
  transition: transform var(--dur-slow) var(--ease-out);
}

.card--testimonial.is-visible::before {
  transform: scaleX(1);
}

/* Stagger the draw across multiple cards */
.card--testimonial:nth-child(2)::before {
  transition-delay: var(--card-stagger-2);
}

.card--testimonial:nth-child(3)::before {
  transition-delay: var(--card-stagger-3);
}

/* Decorative quote mark */
.card--testimonial__mark {
  font-family: var(--f-display);
  font-size: var(--fs-display-hero);
  color: var(--c-ochre);
  opacity: 0.12;
  line-height: 1;
  position: absolute;
  top: var(--sp-sm);
  right: var(--sp-md);
  user-select: none;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-smooth),
              transform var(--dur-base) var(--ease-smooth);
}

@media (hover: hover) {
  .card--testimonial:hover {
    transform: translateY(var(--ty-lift-xl));
    box-shadow: var(--shadow-lg);
  }

  .card--testimonial:hover .card--testimonial__mark,
  .card--testimonial:hover .card--testimonial__quote-mark {
    opacity: 0.28;
    transform: rotate(-4deg) scale(1.06);
  }
}

/* Alias: HTML uses __quote-mark, CSS had __mark */
.card--testimonial__quote-mark {
  font-family: var(--f-display);
  font-size: var(--fs-display-hero);
  color: var(--c-ochre);
  opacity: 0.12;
  line-height: 0.6;
  position: absolute;
  top: var(--sp-sm);
  right: var(--sp-md);
  user-select: none;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-smooth),
              transform var(--dur-base) var(--ease-smooth);
}

/* Industry / location tag */
.card--testimonial__tag {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--t-dark-muted);
  margin-bottom: var(--sp-sm);
}

/* Quote text */
.card--testimonial__text {
  font-family: var(--f-body);
  font-size: var(--fs-body-md);
  color: var(--t-dark-secondary);
  line-height: var(--lh-body);
  margin: 0;
}

.card--testimonial__text p {
  margin: 0;
}

/* Author footer */
.card--testimonial__author {
  margin-top: var(--sp-sm);
}

.card--testimonial__name {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-body-sm);
  color: var(--t-dark-primary);
  margin: 0;
}

.card--testimonial__business {
  font-family: var(--f-body);
  font-size: var(--fs-body-xs);
  color: var(--t-dark-muted);
  margin: 0;
}

/* ----------------------------------------------------------
   STAT CARD
   Used in the hero stats row and stats section.
   No hover interaction — display element only.
   The number animation is driven by JS (.stat-number counter).
   On counter complete: card gets .count-done class.
   .count-done fires a one-shot ochre glow pulse.
   After pulse: class is removed — no persisting GPU load.
---------------------------------------------------------- */

.card--stat {
  background: radial-gradient(ellipse at 20% 40%, rgba(232,160,64,0.07) 0%, transparent 65%), var(--c-forest);
  border: var(--border-dark);
  border-left: 4px solid var(--c-ochre);
  border-radius: var(--r-md);
  padding: var(--sp-lg) var(--sp-md) var(--sp-lg) var(--sp-lg);
  text-align: left;
  transition: box-shadow var(--dur-slow) var(--ease-out);
}

.card--stat .stat-number {
  font-size: clamp(84px, 12vw, 160px);
}

.card--stat .stat-prefix,
.card--stat .stat-suffix {
  font-size: clamp(52px, 6.5vw, 92px);
}

.card--stat .stat-label {
  color: rgba(244,239,228,0.5);
  font-size: var(--fs-body-xs);
  text-transform: uppercase;
  letter-spacing: 1.5px;
}

/* Mobile: full-width stat cards with generous padding */
@media (max-width: 779px) {
  .card--stat {
    padding: 28px var(--sp-md) 28px var(--sp-lg);
  }

  .card--stat .stat-number {
    font-size: clamp(80px, 20vw, 110px);
  }

  .card--stat .stat-prefix,
  .card--stat .stat-suffix {
    font-size: clamp(48px, 11vw, 60px);
  }

  .stats-row,
  .stats-grid {
    grid-template-columns: 1fr;
    gap: var(--sp-md);
  }
}

.card--stat.count-done {
  box-shadow: var(--shadow-ochre);
  animation: stat-glow var(--dur-xslow) var(--ease-out) forwards;
}

@keyframes stat-glow {
  0%   { box-shadow: var(--shadow-ochre-lg); }
  60%  { box-shadow: var(--shadow-ochre); }
  100% { box-shadow: none; }
}

/* ----------------------------------------------------------
   TRUST CARD
   Used in the Why Us section on bone background.
   Green icon circle + title + one-line descriptor.
   Light card on bone — midnight background, light border.
   Desktop hover: lifts with green shadow.
   Mobile: active tap flash.
---------------------------------------------------------- */

.card--trust {
  background: var(--c-bone-mid);
  border: var(--border-light);
  border-radius: var(--r-lg);
  padding: var(--sp-lg) var(--sp-md);
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
  transition:
    transform  var(--dur-base) var(--ease-smooth),
    box-shadow var(--dur-base) var(--ease-smooth);
}

@media (hover: hover) {
  .card--trust:hover {
    transform: translateY(var(--ty-lift-lg));
    box-shadow: var(--shadow-green);
  }
}

@media (hover: none) {
  .card--trust:active {
    transform: scale(0.98);
    transition-duration: var(--dur-instant);
  }
}

.card--trust__icon {
  width: var(--card-icon-size);
  height: var(--card-icon-size);
  background: var(--c-green-glow);
  border-radius: var(--r-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--dur-fast) var(--ease-smooth),
              transform  var(--dur-fast) var(--ease-spring);
}

@media (hover: hover) {
  .card--trust:hover .card--trust__icon {
    background: var(--c-green-glow-strong);
    transform: scale(1.1);
  }
}

.card--trust__title {
  font-family: var(--f-body);
  font-weight: 700;
  font-size: var(--fs-body-lg);
  color: var(--t-light-primary);
  line-height: var(--lh-tight);
}

.card--trust__desc {
  font-family: var(--f-body);
  font-weight: 400;
  font-size: var(--fs-body-sm);
  color: var(--t-light-secondary);
  line-height: var(--lh-body);
}

/* ----------------------------------------------------------
   RESULT CARD
   The calculator result panel.
   Midnight background — authoritative, premium.
   Ochre top border — full width, always visible (not drawn).
   .is-updating class fires resultPulse via JS on value change.
   On mobile: sticky above bottom nav — always in view.
---------------------------------------------------------- */

.card--result {
  background: var(--c-midnight);
  border: var(--border-dark);
  border-top: var(--border-ochre-strong);
  border-radius: var(--card-radius);
  padding: var(--sp-lg);
  display: flex;
  flex-direction: column;
  gap: var(--sp-md);
}

@media (min-width: 780px) {
  .card--result {
    padding: var(--sp-xl);
    position: sticky;
    top: calc(var(--nav-height-desktop) + var(--sp-md));
  }
}

.card--result__label {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--t-dark-muted);
}

.card--result__amount {
  transition: transform var(--dur-base) var(--ease-spring);
  display: inline-block;
}

.card--result__amount.is-updating {
  transform: scale(1.06);
  will-change: transform;
}

.card--result__disclaimer {
  font-family: var(--f-body);
  font-weight: 300;
  font-size: var(--fs-body-xs);
  color: var(--t-dark-ghost);
  line-height: var(--lh-body);
  border-top: var(--border-dark);
  padding-top: var(--sp-sm);
}


/* ============================================================
   UNIT 1.7 — FORM SYSTEM
   The highest-converting form ever built for a WA finance site.
   Two completely separate experiences. Same data. Same webhook.

   DESKTOP (≥780px):
   Full-viewport overlay · 40 RAF particles · spring-in card
   Liquid fill progress bar · slot-machine amount counter
   Magnetic tile pull (JS) · shimmer CTA · particle colour shift

   MOBILE (<780px):
   Bottom sheet · swipe-to-dismiss · velocity-matched
   Dot progress indicator · 2-col tile grid (4 rows, last centred)
   32px slider thumb · visualViewport keyboard detection
   All CTAs pinned to thumb zone · tap-to-call fallback always

   Zero overlap between desktop and mobile component rules.
   @media (min-width: 780px) activates desktop. Mobile is base.
   ============================================================ */

/* ----------------------------------------------------------
   FORM TRIGGER STATES
   body.form-open: locks scroll, maintains position.
   JS records scrollY before opening, restores on close.
   No layout shift. No scroll jump.
---------------------------------------------------------- */

body.form-open {
  overflow: hidden;
  position: fixed;
  width: 100%;
}

/* ----------------------------------------------------------
   MOBILE — BOTTOM SHEET BACKDROP
   Fades in behind the sheet.
   Tap to dismiss. Always present when sheet is open.
   z-index below sheet, above everything else.
   opacity transition only — no layout triggers.
---------------------------------------------------------- */

.form-backdrop {
  position: fixed;
  inset: 0;
  background: var(--c-overlay-heavy);
  z-index: var(--z-modal-bg);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-smooth);
}

.form-backdrop.is-open {
  opacity: 1;
  pointer-events: all;
}


/* ----------------------------------------------------------
   MOBILE — BOTTOM SHEET
   Slides up from below the viewport on trigger.
   translateY(100%) → translateY(0) on open.
   Spring easing — feels physical, like lifting a panel.
   Top corners rounded only — bottom is flush with screen edge.
   max-height: 92vh — content scrolls inside, page does not.
   Swipe handle: 32px pill, centred, 6px tall.
   position: fixed — but ONLY the outer shell.
   Inner content scrolls independently.
   Never conflict with virtual keyboard — handled by JS
   via visualViewport API adjusting bottom offset.
---------------------------------------------------------- */

.form-sheet {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: var(--z-modal);
  background: var(--c-midnight);
  border-radius: var(--r-2xl) var(--r-2xl) 0 0;
  max-height: 92vh;
  display: flex;
  flex-direction: column;
  transform: translateY(100%);
  transition: transform var(--dur-slow) var(--ease-spring);
  will-change: transform;
  overflow: hidden;
}

.form-sheet.is-open {
  transform: translateY(0);
  will-change: auto;
}

.form-sheet.is-dragging {
  transition: none;
  will-change: transform;
}

/* Swipe handle */
.form-sheet__handle {
  width: var(--form-handle-w);
  height: var(--dot-size-sm);
  background: var(--t-dark-ghost);
  border-radius: var(--r-full);
  margin: var(--sp-sm) auto var(--sp-xs);
  flex-shrink: 0;
  transition: background var(--dur-fast) var(--ease-smooth),
              transform var(--dur-fast) var(--ease-smooth);
}

.form-sheet.is-dragging .form-sheet__handle {
  background: var(--t-dark-muted);
  transform: scaleX(0.85);
}

/* Mobile close button */
.form-sheet__close {
  position: absolute;
  top: var(--sp-sm);
  right: var(--sp-sm);
  z-index: 3;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--t-dark-hairline);
  border: var(--border-dark);
  border-radius: var(--r-full);
  color: var(--t-dark-muted);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-smooth),
              color var(--dur-fast) var(--ease-smooth);
}

.form-sheet__close:active {
  background: var(--c-error-glow);
  color: var(--c-error);
}

/* Scrollable inner area */
.form-sheet__inner {
  overflow-y: auto;
  overflow-x: hidden;
  flex: 1;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 0 var(--sp-md) var(--sp-xl);
}

/* Keyboard offset — JS sets this via visualViewport */
.form-sheet.keyboard-open {
  bottom: var(--keyboard-height, 0px);
  transition: bottom var(--dur-fast) var(--ease-smooth),
              transform var(--dur-slow) var(--ease-spring);
}


/* ----------------------------------------------------------
   MOBILE — PROGRESS DOTS
   4 dots. Active = var(--form-dot-active-w) wide ochre pill.
   Complete = 10px green dot with checkmark SVG inside.
   Remaining = 8px ghost border, no fill.
   The active pill slides between positions via JS
   applying translateX — the pill element itself moves,
   nothing redraws. Pure transform animation.
   Connecting track: 1px line between dots, fills green
   as steps complete via scaleX on a ::after pseudo.
---------------------------------------------------------- */

.form-dots {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-md);
  padding: var(--sp-md) 0 var(--sp-sm);
  position: relative;
}

.form-dot {
  position: relative;
  z-index: 1;
  transition:
    width    var(--dur-base) var(--ease-spring),
    height   var(--dur-base) var(--ease-spring),
    background var(--dur-fast) var(--ease-smooth);
}

.form-dot--remaining {
  width: var(--dot-size-md);
  height: var(--dot-size-md);
  border-radius: var(--r-full);
  background: transparent;
  border: var(--border-mid);
}

.form-dot--active {
  width: var(--form-dot-active-w);
  height: var(--dot-size-md);
  border-radius: var(--r-full);
  background: var(--c-ochre);
  box-shadow: var(--shadow-ochre-sm);
}

.form-dot--complete {
  width: var(--dot-size-md);
  height: var(--dot-size-md);
  border-radius: var(--r-full);
  background: var(--c-green);
  display: flex;
  align-items: center;
  justify-content: center;
}

.form-dot__check {
  width: var(--dot-size-pill);
  height: var(--dot-size-pill);
  stroke: var(--c-bone);
  stroke-width: 2;
  fill: none;
  stroke-dasharray: 10;
  stroke-dashoffset: 10;
  transition: stroke-dashoffset var(--dur-fast) var(--ease-out);
}

.form-dot--complete .form-dot__check {
  stroke-dashoffset: 0;
}

/* Step label above dots */
.form-step-label {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--t-dark-muted);
  text-align: center;
  padding-bottom: var(--sp-xs);
}


/* ----------------------------------------------------------
   FORM STEPS — CONTAINER + TRANSITIONS
   Each step is a .form-step element.
   Only .form-step--active is visible and interactive.
   Exiting step: slides left + fades (var(--form-step-out) ease-in).
   Entering step: slides from right + fades in (var(--form-step-in) ease-out).
   60ms overlap — they cross slightly at the midpoint.
   Height of the step container transitions smoothly
   via JS measuring step heights and setting explicitly.
   No display:none toggle — opacity + pointer-events only.
   This preserves step layout for height measurement.
---------------------------------------------------------- */

.form-steps {
  position: relative;
  overflow: hidden;
}

.form-step {
  opacity: 0;
  pointer-events: none;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  transform: translateX(var(--tx-step-enter));
  transition:
    opacity   var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out);
}

.form-step--active {
  opacity: 1;
  pointer-events: all;
  position: relative;
  transform: translateX(0);
  transition:
    opacity   var(--form-step-in) var(--ease-out),
    transform var(--form-step-in) var(--ease-out);
}

.form-step--exiting {
  opacity: 0;
  pointer-events: none;
  position: absolute;
  transform: translateX(var(--tx-step-exit));
  transition:
    opacity   var(--form-step-out) var(--ease-in),
    transform var(--form-step-out) var(--ease-in);
}

/* ----------------------------------------------------------
   STEP QUESTION HEADLINE
   The big Bebas Neue question at the top of each step.
   Acts as the user's anchor — always the first thing read.
   Margin-bottom creates breathing room before options.
---------------------------------------------------------- */

.form-question {
  font-family: var(--f-display);
  font-size: var(--fs-display-md);
  letter-spacing: var(--ls-display);
  color: var(--t-dark-primary);
  line-height: var(--lh-heading);
  margin-bottom: var(--sp-lg);
}

/* ----------------------------------------------------------
   STEP 1 — PRODUCT TILE GRID (MOBILE)
   2-column grid. 4 rows. Last tile centred.
   Each tile: 64px min-height. Tap: border flash + checkmark.
   Icon: 20px SVG centred above label.
   Selected state: ochre border, ochre bg glow, scale(1.03).
   Others dim to 0.45 opacity when one is selected.
   The last (7th) tile: spans 2 cols, max-width 50%, centred.
---------------------------------------------------------- */

.form-tiles {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-sm);
}

.form-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-xs);
  min-height: 64px;
  padding: var(--sp-sm) var(--sp-xs);
  background: var(--c-field-default);
  border: var(--border-dark);
  border-radius: var(--r-md);
  cursor: none;
  text-align: center;
  transition:
    opacity      var(--dur-fast) var(--ease-smooth),
    border-color var(--dur-fast) var(--ease-smooth),
    background   var(--dur-fast) var(--ease-smooth),
    transform    var(--dur-fast) var(--ease-spring);
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}

/* Last tile centred in 2-col grid */
.form-tile:last-child:nth-child(odd) {
  grid-column: 1 / -1;
  max-width: 50%;
  margin: 0 auto;
  width: 100%;
}

.form-tile__icon {
  width: var(--form-tile-icon);
  height: var(--form-tile-icon);
  color: var(--t-dark-secondary);
  transition: color var(--dur-fast) var(--ease-smooth),
              transform var(--dur-fast) var(--ease-spring);
  flex-shrink: 0;
}

.form-tile__label {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-body-xs);
  color: var(--t-dark-secondary);
  line-height: var(--lh-tight);
  transition: color var(--dur-fast) var(--ease-smooth);
}

/* Selected state */
.form-tile.is-selected {
  border-color: var(--c-border-ochre-strong);
  background: var(--c-ochre-glow);
  transform: scale(1.03);
}

.form-tile.is-selected .form-tile__icon {
  color: var(--c-ochre);
  transform: scale(1.15);
}

.form-tile.is-selected .form-tile__label {
  color: var(--c-ochre);
}

/* Others dim when one is selected */
.form-tiles.has-selection .form-tile:not(.is-selected) {
  opacity: 0.42;
}

/* Checkmark overlay on selected tile */
.form-tile__check {
  position: absolute;
  top: var(--sp-xs);
  right: var(--sp-xs);
  width: var(--form-tile-check);
  height: var(--form-tile-check);
  background: var(--c-ochre);
  border-radius: var(--r-full);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transform: scale(0);
  transition:
    opacity   var(--dur-fast) var(--ease-smooth),
    transform var(--dur-fast) var(--ease-spring);
}

.form-tile {
  position: relative;
}

.form-tile.is-selected .form-tile__check {
  opacity: 1;
  transform: scale(1);
}


/* ----------------------------------------------------------
   STEP 2 — AMOUNT SLIDER + COUNTER
   The Bebas Neue number dominates this step.
   On mobile: 64px — massive, fills the attention.
   On desktop: var(--fs-form-amount) — even larger via the overlay context.
   Quick-select pills below slider snap the value.
   Slider thumb: 32px on mobile, 26px on desktop.
   Track fill updates in real-time via JS setSliderFill().
   Counter transition: smooth opacity crossfade of digits.
---------------------------------------------------------- */

.form-amount-display {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: var(--sp-xs);
  margin-bottom: var(--sp-md);
}

.form-amount-currency {
  font-family: var(--f-display);
  font-size: var(--fs-display-md);
  color: var(--c-ochre);
  letter-spacing: var(--ls-display);
  line-height: 1;
  opacity: 0.72;
}

.form-amount-value {
  font-family: var(--f-display);
  font-size: var(--fs-form-amount);
  color: var(--c-ochre);
  letter-spacing: var(--ls-display);
  line-height: 1;
  transition: transform var(--dur-fast) var(--ease-spring),
              opacity  var(--dur-fast) var(--ease-smooth);
  display: inline-block;
}

.form-amount-value.is-updating {
  transform: scale(1.04) translateY(var(--ty-lift-md));
  will-change: transform, opacity;
}

/* Quick-select amount pills */
.form-amount-pills {
  display: flex;
  gap: var(--sp-xs);
  flex-wrap: wrap;
  justify-content: center;
  margin-top: var(--sp-md);
}

.form-amount-pill {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-body-xs);
  color: var(--t-dark-secondary);
  padding: var(--sp-xs) var(--sp-sm);
  border: var(--border-dark);
  border-radius: var(--r-full);
  background: var(--c-field-default);
  cursor: none;
  transition:
    border-color var(--dur-fast) var(--ease-smooth),
    background   var(--dur-fast) var(--ease-smooth),
    color        var(--dur-fast) var(--ease-smooth),
    transform    var(--dur-fast) var(--ease-spring);
  -webkit-tap-highlight-color: transparent;
}

.form-amount-pill:active,
.form-amount-pill.is-active {
  border-color: var(--c-border-ochre-strong);
  background: var(--c-ochre-glow);
  color: var(--c-ochre);
  transform: scale(0.96);
}

/* Custom slider — mobile-first (32px thumb) */
.form-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: var(--slider-track-h);
  border-radius: var(--r-full);
  outline: none;
  cursor: none;
  background: var(--c-field-default);
  margin: var(--sp-md) 0 var(--sp-xs);
}

.form-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: var(--slider-thumb-mob);
  height: var(--slider-thumb-mob);
  border-radius: var(--r-full);
  background: var(--c-ochre);
  box-shadow: var(--slider-thumb-shadow);
  cursor: none;
  transition:
    transform  var(--dur-fast) var(--ease-spring),
    box-shadow var(--dur-fast) var(--ease-smooth);
}

.form-slider:active::-webkit-slider-thumb {
  transform: scale(1.25);
  box-shadow: var(--slider-thumb-hover);
  will-change: transform;
}

.form-slider::-moz-range-thumb {
  width: var(--slider-thumb-mob);
  height: var(--slider-thumb-mob);
  border-radius: var(--r-full);
  border: none;
  background: var(--c-ochre);
  box-shadow: var(--slider-thumb-shadow);
  cursor: none;
}

/* Slider range labels */
.form-slider-labels {
  display: flex;
  justify-content: space-between;
  font-family: var(--f-body);
  font-size: var(--fs-body-xs);
  color: var(--t-dark-muted);
  margin-bottom: var(--sp-md);
}


/* ----------------------------------------------------------
   STEPS 3 + 4 — FLOATING LABEL FIELDS
   The gold standard of form field UX.
   Label sits centred in the field at rest.
   On focus OR filled: label rises to top-left at 10px,
   uppercased, letter-spaced, coloured ochre/green.
   The transform is on the label, not a height change.
   Zero layout shift. Zero janky reflow.
   Error messages appear below with colour and icon.
   Valid fields get a green right border flash.
   Input 52px height on mobile — fat, confident, unambiguous.
---------------------------------------------------------- */

.field-wrap {
  position: relative;
  margin-bottom: var(--sp-md);
}

.field-input {
  width: 100%;
  min-height: var(--field-height);
  padding: 22px var(--sp-sm) var(--sp-xs);
  background: var(--c-field-default);
  border: var(--border-dark);
  border-radius: var(--field-radius);
  color: var(--t-dark-primary);
  font-family: var(--f-body);
  font-size: var(--fs-body-md);
  font-weight: 400;
  line-height: 1;
  outline: none;
  transition:
    border-color var(--dur-fast) var(--ease-smooth),
    background   var(--dur-fast) var(--ease-smooth);
  -webkit-tap-highlight-color: transparent;
}

/* Prevent autofill from styling the field */
.field-input:-webkit-autofill,
.field-input:-webkit-autofill:hover,
.field-input:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 100px var(--c-midnight) inset;
  -webkit-text-fill-color: var(--t-dark-primary);
  caret-color: var(--t-dark-primary);
}

.field-label {
  position: absolute;
  left: var(--sp-sm);
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--f-body);
  font-size: var(--fs-body-sm);
  font-weight: 400;
  color: var(--t-dark-muted);
  pointer-events: none;
  transition:
    top          var(--dur-fast) var(--ease-smooth),
    font-size    var(--dur-fast) var(--ease-smooth),
    font-weight  var(--dur-fast) var(--ease-smooth),
    color        var(--dur-fast) var(--ease-smooth),
    letter-spacing var(--dur-fast) var(--ease-smooth),
    transform    var(--dur-fast) var(--ease-smooth);
}

/* Float: on focus or when value is present */
.field-input:focus ~ .field-label,
.field-input:not(:placeholder-shown) ~ .field-label {
  top: var(--sp-xs);
  transform: none;
  font-size: var(--field-label-size);
  font-weight: 600;
  letter-spacing: var(--field-label-ls);
  text-transform: uppercase;
  color: var(--c-green-hi);
}

/* Focus state */
.field-input:focus {
  border-color: var(--c-border-green);
  background: var(--c-field-focus);
}

/* Valid state */
.field-input.is-valid {
  border-color: var(--c-border-green);
  background: var(--c-field-valid);
}

.field-input.is-valid ~ .field-label {
  color: var(--c-green-hi);
}

/* Error state */
.field-input.is-error {
  border-color: var(--c-border-error);
  background: var(--c-field-error);
}

.field-input.is-error ~ .field-label {
  color: var(--c-error);
}

/* Error message */
.field-error {
  display: flex;
  align-items: center;
  gap: var(--sp-xs);
  font-family: var(--f-body);
  font-size: var(--fs-body-xs);
  color: var(--c-error);
  margin-top: var(--sp-xs);
  padding-left: var(--sp-xs);
  height: 0;
  overflow: hidden;
  opacity: 0;
  transition:
    height  var(--dur-fast) var(--ease-smooth),
    opacity var(--dur-fast) var(--ease-smooth);
}

.field-error.is-visible {
  height: auto;
  opacity: 1;
}

/* Success icon inside field — right side */
.field-success-icon {
  position: absolute;
  right: var(--sp-sm);
  top: 50%;
  transform: translateY(-50%) scale(0);
  color: var(--c-green-hi);
  opacity: 0;
  transition:
    transform var(--dur-fast) var(--ease-spring),
    opacity   var(--dur-fast) var(--ease-smooth);
}

.field-input.is-valid ~ .field-success-icon {
  transform: translateY(-50%) scale(1);
  opacity: 1;
}

/* ----------------------------------------------------------
   URGENCY + REVENUE PILLS (Step 3)
   Horizontal pill row for option selection.
   ASAP / 1–4 weeks / Just researching.
   Full-width each on mobile — easy tap surface.
   Selected: ochre fill. Others: ghost.
   Radio button behaviour — only one selectable.
---------------------------------------------------------- */

.form-pills {
  display: flex;
  flex-direction: column;
  gap: var(--sp-xs);
  margin-bottom: var(--sp-md);
}

.form-pill {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: var(--sp-sm) var(--sp-md);
  border: var(--border-dark);
  border-radius: var(--r-full);
  background: var(--c-field-default);
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-body-sm);
  color: var(--t-dark-secondary);
  cursor: none;
  text-align: center;
  transition:
    border-color var(--dur-fast) var(--ease-smooth),
    background   var(--dur-fast) var(--ease-smooth),
    color        var(--dur-fast) var(--ease-smooth),
    transform    var(--dur-fast) var(--ease-spring);
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}

.form-pill.is-selected {
  border-color: var(--c-border-ochre-strong);
  background: var(--c-ochre-glow);
  color: var(--c-ochre);
  transform: scale(1.02);
}

.form-pill:active {
  transform: scale(0.97);
}


/* ----------------------------------------------------------
   STEP NAVIGATION — MOBILE PINNED FOOTER
   "Continue" button always pinned to bottom of the sheet.
   Never floats with content — always in the thumb zone.
   Sits above any keyboard via keyboard-open adjustment.
   Back link: top-left of step, clearly secondary.
   Privacy note: between fields and continue button.
   The continue button pulses when all fields are complete
   via .is-ready class — draws the eye to the next action.
---------------------------------------------------------- */

.form-nav {
  position: sticky;
  bottom: 0;
  background: var(--c-midnight);
  padding: var(--sp-sm) 0 var(--sp-md);
  margin-top: var(--sp-md);
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
}

/* Gradient above the nav — separates from scrolled content */
.form-nav::before {
  content: '';
  position: absolute;
  top: var(--form-nav-grad-top);
  left: 0;
  right: 0;
  height: var(--form-nav-grad-h);
  background: linear-gradient(to bottom, transparent, var(--c-midnight));
  pointer-events: none;
}

.form-nav__continue {
  width: 100%;
  min-height: 56px;
  font-size: var(--fs-body-lg);
}

/* Pulse when all fields complete and button unclicked */
@keyframes form-cta-pulse {
  0%, 100% { box-shadow: var(--shadow-ochre-sm); }
  50%       { box-shadow: var(--shadow-ochre); }
}

.form-nav__continue.is-ready {
  animation: form-cta-pulse 2s var(--ease-in-out) infinite;
}

.form-nav__continue.is-ready:hover {
  animation: none;
}

.form-nav__back {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-xs);
  font-family: var(--f-body);
  font-weight: 500;
  font-size: var(--fs-body-sm);
  color: var(--t-dark-muted);
  background: none;
  border: none;
  cursor: none;
  padding: var(--sp-xs) 0;
  min-height: var(--btn-min-touch);
  align-self: flex-start;
  transition: color var(--dur-fast) var(--ease-smooth);
}

.form-nav__back:hover {
  color: var(--t-dark-secondary);
}

.form-privacy {
  font-family: var(--f-body);
  font-weight: 300;
  font-size: var(--fs-body-xs);
  color: var(--t-dark-muted);
  text-align: center;
  line-height: var(--lh-snug);
}

/* ----------------------------------------------------------
   SUCCESS + ERROR STATES
   Applied to the entire .form-sheet or .form-overlay.
   Success: midnight → green wash transition.
   Error: stays midnight, amber accent, phone prominent.
   Both preserve the form structure — no rebuild.
   JS swaps in the content div, CSS handles the atmosphere.
---------------------------------------------------------- */

.form-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--sp-xl) var(--sp-lg);
  gap: var(--sp-md);
  min-height: 320px;
}

.form-state__icon {
  width: var(--form-state-icon);
  height: var(--form-state-icon);
  border-radius: var(--r-full);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--sp-sm);
  transition: transform var(--dur-slow) var(--ease-spring);
}

.form-state--success .form-state__icon {
  background: var(--c-green-glow-strong);
  animation: state-icon-pop var(--dur-base) var(--ease-spring) forwards;
}

.form-state--error .form-state__icon {
  background: var(--c-error-glow);
}

@keyframes state-icon-pop {
  0%   { transform: scale(0); }
  70%  { transform: scale(1.15); }
  100% { transform: scale(1); }
}

.form-state__headline {
  font-family: var(--f-display);
  font-size: var(--fs-display-lg);
  letter-spacing: var(--ls-display);
  line-height: var(--lh-heading);
}

.form-state--success .form-state__headline {
  color: var(--c-green-hi);
}

.form-state--error .form-state__headline {
  color: var(--c-error);
}

.form-state__sub {
  font-family: var(--f-body);
  font-size: var(--fs-body-md);
  color: var(--t-dark-secondary);
  line-height: var(--lh-body);
  max-width: 36ch;
}

/* Green wash on success — background shifts subtly */
.form-sheet.form-success,
.form-overlay.form-success {
  background: var(--c-forest);
  transition: background var(--dur-slow) var(--ease-smooth);
}


/* ----------------------------------------------------------
   DESKTOP OVERLAY — FULL VIEWPORT TAKEOVER
   ≥780px only. Mobile never sees this.
   The overlay is the entire screen — it IS the moment.
   The card floats centred. Particles breathe behind it.
   Everything else ceases to exist while this is open.

   Architecture:
   .form-overlay        Fixed full-viewport container
   .form-overlay__bg    Particle field canvas (JS draws on this)
   .form-overlay__card  The floating form card
   .form-overlay__close X button — top right of card
   The progress BAR (not dots) sits atop the card.
   Liquid ochre fill via scaleX — not a jumping bar.
   
   Breakpoint behaviour:
   <780px:  display: none — mobile sheet takes over
   780px:   card max-width 540px
   1200px:  card max-width 560px
   1440px:  card max-width 580px — primary target
   1920px:  card max-width 600px
   2560px:  card max-width 620px
   Card never stretches beyond 620px regardless of viewport.
   Card never shrinks below 440px — content needs the room.
---------------------------------------------------------- */

.form-overlay {
  display: none;
}

@media (min-width: 780px) {
  .form-overlay {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    inset: 0;
    z-index: var(--z-overlay);
    padding: var(--sp-lg);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity var(--dur-base) var(--ease-smooth),
      visibility 0s linear var(--dur-base);
  }

  .form-overlay.is-open {
    opacity: 1;
    visibility: visible;
    pointer-events: all;
    transition: opacity var(--dur-base) var(--ease-smooth),
      visibility 0s linear 0s;
  }

  /* Dark backdrop — behind particle canvas */
  .form-overlay__bg {
    position: absolute;
    inset: 0;
    background: var(--c-overlay-heavy);
    z-index: 0;
  }

  /* Particle canvas — JS draws 40 RAF particles here */
  .form-overlay__canvas {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
  }

  /* The card — floats above everything */
  .form-overlay__card {
    position: relative;
    z-index: 2;
    width: 100%;
    max-width: var(--form-card-max);
    background: var(--c-midnight);
    border: var(--border-glass);
    border-radius: var(--r-xl);
    box-shadow: var(--shadow-2xl), 0 0 0 1px var(--c-glass-border);
    overflow: hidden;
    transform: scale(0.9) translateY(var(--ty-reveal-md));
    transition:
      transform var(--dur-slow) var(--ease-spring),
      box-shadow var(--dur-slow) var(--ease-smooth);
    will-change: transform;
  }

  .form-overlay.is-open .form-overlay__card {
    transform: scale(1) translateY(0);
    will-change: auto;
  }

  /* Ochre border pulse — card breathes while open */
  @keyframes overlay-border-pulse {
    0%, 100% { box-shadow: var(--shadow-2xl), 0 0 0 1px var(--c-glass-border); }
    50%       { box-shadow: var(--shadow-2xl), 0 0 0 1px var(--c-glass-border-active); }
  }

  .form-overlay.is-open .form-overlay__card {
    animation: overlay-border-pulse 3s var(--ease-in-out) infinite;
    animation-delay: var(--dur-slow);
  }

  .form-overlay.is-open .form-overlay__card:hover {
    animation: none;
    box-shadow: var(--shadow-2xl), 0 0 0 1px var(--c-glass-border-active);
  }

  /* Close button — top right */
  .form-overlay__close {
    position: absolute;
    top: var(--sp-md);
    right: var(--sp-md);
    z-index: 3;
    width: var(--btn-min-touch);
    height: var(--btn-min-touch);
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--t-dark-hairline);
    border: var(--border-dark);
    border-radius: var(--r-full);
    color: var(--t-dark-muted);
    cursor: none;
    transition:
      background  var(--dur-fast) var(--ease-smooth),
      color       var(--dur-fast) var(--ease-smooth),
      transform   var(--dur-fast) var(--ease-spring);
  }

  .form-overlay__close:hover {
    background: var(--c-error-glow);
    color: var(--c-error);
    transform: scale(1.1) rotate(90deg);
  }

  .form-overlay__close:active {
    transform: scale(0.92) rotate(90deg);
  }

  /* Card scroll — content overflows internally */
  .form-overlay__scroll {
    max-height: calc(90vh - var(--sp-2xl));
    overflow-y: auto;
    overflow-x: hidden;
    padding: var(--sp-xl) var(--sp-xl) var(--sp-lg);
    scrollbar-width: none;
  }

  .form-overlay__scroll::-webkit-scrollbar {
    display: none;
  }
}


/* ----------------------------------------------------------
   DESKTOP — LIQUID PROGRESS BAR
   Full-width bar at the top of the overlay card.
   Fills left to right via scaleX(0→1).
   transform-origin: left — grows from the left edge.
   The percentage label sits inside the fill — Bebas Neue.
   Step label sits above the bar.
   Between steps: the fill transitions smoothly.
   The bar NEVER jumps — only scale transforms. No width.
   
   Desktop only — inside the ≥780px breakpoint context.
   Mobile uses dots. The distinction is intentional.
   Desktop has horizontal space for a bar — mobile doesn't.
   The bar on desktop gives a more precise sense of progress.
   Dots on mobile work at a glance without reading a number.
---------------------------------------------------------- */

@media (min-width: 780px) {

  .form-progress {
    padding: var(--sp-md) var(--sp-xl) var(--sp-sm);
    border-bottom: var(--border-dark);
    margin-bottom: var(--sp-md);
  }

  .form-progress__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--sp-xs);
  }

  .form-progress__step-label {
    font-family: var(--f-body);
    font-weight: 600;
    font-size: var(--fs-eyebrow);
    letter-spacing: var(--ls-eyebrow);
    text-transform: uppercase;
    color: var(--t-dark-muted);
  }

  .form-progress__pct {
    font-family: var(--f-display);
    font-size: var(--fs-display-xs);
    letter-spacing: var(--ls-display);
    color: var(--c-ochre);
    line-height: 1;
  }

  /* Bar track */
  .form-progress__track {
    position: relative;
    height: var(--form-progress-h);
    background: var(--t-dark-hairline);
    border-radius: var(--r-full);
    overflow: hidden;
  }

  /* Liquid fill — scaleX only, transform-origin left */
  .form-progress__fill {
    position: absolute;
    inset: 0;
    background: var(--c-ochre);
    transform-origin: left;
    transform: scaleX(0);
    transition: transform var(--dur-slow) var(--ease-smooth);
    border-radius: var(--r-full);
  }

  /* Shimmer on the fill — subtle light running through it */
  .form-progress__fill::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(
      90deg,
      transparent 0%,
      var(--c-shimmer-light) 50%,
      transparent 100%
    );
    transform: translateX(-100%);
    animation: progress-shimmer 2s var(--ease-smooth) infinite;
    animation-delay: var(--dur-slow);
  }

  @keyframes progress-shimmer {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(300%); }
  }

  /* ----------------------------------------------------------
     DESKTOP — TILE GRID (STEP 1)
     3-column grid on desktop — not 2.
     7 tiles: 2 rows of 3, last row 1 tile centred.
     Larger tiles — more breathing room than mobile.
     Magnetic pull applied via JS (inline transform).
     Hover: green border glow + icon springs.
     Others dim on selection (same as mobile).
     Selected: ochre border, ochre glow, scale(1.04).
  ---------------------------------------------------------- */

  .form-tiles {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--sp-md);
    margin-inline: var(--sp-sm);
  }

  .form-tile {
    min-height: 80px;
    padding: var(--sp-md) var(--sp-sm);
    gap: var(--sp-sm);
  }

  /* Last tile centred — 3-col grid, 7 items: spans full row, max 33% width */
  .form-tile:last-child:nth-child(3n - 2),
  .form-tile:last-child:nth-child(3n - 1) {
    grid-column: 1 / -1;
    max-width: 33.333%;
    margin: 0 auto;
    width: 100%;
  }

  .form-tile__icon {
    width: var(--form-tile-icon-lg);
    height: var(--form-tile-icon-lg);
  }

  .form-tile__label {
    font-size: var(--fs-body-sm);
  }

  /* Desktop hover — touch devices never see this */
  .form-tile:hover:not(.is-selected) {
    border-color: var(--c-border-green);
    background: var(--c-green-glow);
    transform: translateY(var(--ty-lift-sm));
  }

  .form-tile:hover .form-tile__icon {
    color: var(--c-green-hi);
    transform: scale(1.1);
  }

  /* Desktop: selected tiles get slightly larger lift */
  .form-tile.is-selected {
    transform: scale(1.04) translateY(var(--ty-lift-sm));
  }

  /* ----------------------------------------------------------
     DESKTOP — AMOUNT COUNTER DIFFERENCES
     Same structure, larger Bebas number.
     Slot-machine digit effect — JS creates digit columns
     that scroll vertically. CSS sets the container.
     Each digit column: overflow hidden, height of one digit.
     Digits translate vertically to show the right number.
  ---------------------------------------------------------- */

  .form-amount-value {
    font-size: var(--fs-display-2xl);
  }

  .form-amount-slot {
    display: inline-flex;
    overflow: hidden;
    line-height: 1;
    height: 1em;
  }

  .form-amount-slot__col {
    display: flex;
    flex-direction: column;
    transition: transform var(--dur-base) var(--ease-spring);
    will-change: transform;
  }

  .form-amount-slot__col.is-done {
    will-change: auto;
  }

  .form-amount-slot__digit {
    display: block;
    line-height: 1;
    text-align: center;
  }

  /* Quick pills horizontal on desktop */
  .form-amount-pills {
    flex-wrap: wrap;
    gap: var(--sp-sm);
    justify-content: center;
    margin-inline: var(--sp-sm);
  }

  /* Slider: desktop thumb size */
  .form-slider::-webkit-slider-thumb {
    width: var(--slider-thumb);
    height: var(--slider-thumb);
  }

  .form-slider::-moz-range-thumb {
    width: var(--slider-thumb);
    height: var(--slider-thumb);
  }

  /* ----------------------------------------------------------
     DESKTOP — FIELDS + PILLS DIFFERENCES
     Pills go horizontal on desktop — 3 in a row.
     Fields maintain 52px height — consistency with mobile.
     The field padding increases slightly for desktop breathing.
  ---------------------------------------------------------- */

  .form-pills {
    flex-direction: row;
    gap: var(--sp-sm);
  }

  .form-pill {
    flex: 1;
    min-height: var(--btn-min-touch);
    font-size: var(--fs-body-xs);
    padding: var(--sp-sm) var(--sp-xs);
  }

  /* ----------------------------------------------------------
     DESKTOP — NAV FOOTER DIFFERENCES
     Not sticky — sits naturally below content.
     The card scrolls if needed, nav scrolls with it.
     Continue button: not full-width — sits right-aligned.
     Back: left side of the same row.
  ---------------------------------------------------------- */

  .form-nav {
    position: static;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    border-top: var(--border-dark);
    padding: var(--sp-md) 0 0;
    margin-top: var(--sp-lg);
  }

  .form-nav::before {
    display: none;
  }

  .form-nav__continue {
    width: auto;
    min-height: var(--btn-min-touch);
    font-size: var(--fs-body-md);
  }

  /* ----------------------------------------------------------
     DESKTOP — BREAKPOINT CARD WIDTH PROGRESSION
     Controlled entirely via max-width overrides.
     Each breakpoint adds 20px — proportional breathing.
     Never a jarring jump. Always a gentle expansion.
  ---------------------------------------------------------- */

  .form-overlay__card {
    max-width: 540px;
  }
}

@media (min-width: 1200px) {
  .form-overlay__card {
    max-width: 560px;
  }
}

@media (min-width: 1440px) {
  .form-overlay__card {
    max-width: 580px;
  }
}

@media (min-width: 1920px) {
  .form-overlay__card {
    max-width: 600px;
  }
}

@media (min-width: 2560px) {
  .form-overlay__card {
    max-width: 620px;
  }
}


/* ============================================================
   UNIT 1.8 — CALCULATOR COMPONENT SYSTEM
   Three calculators. One shared CSS architecture.
   Better than Apple. Built for conversion.

   The signature element: Live Ticker Result.
   When a value changes, the old number exits upward
   and the new number rises from below — like a Bloomberg
   terminal. Every interaction is an event, not a form update.

   Calc 1: Working Capital — loan amount, term, frequency toggle
   Calc 2: Equipment Finance — asset value, deposit, term, balloon
   Calc 3: Smart Matcher — product recommender with confidence score

   Desktop (≥780px): 55/45 grid, result panel sticky right
   Mobile (<780px):  1-col stacked, sticky result bar at bottom
   ============================================================ */

/* ----------------------------------------------------------
   CALCULATOR WRAPPER + SECTION
   Each calculator lives in a .calc-section on midnight bg.
   The inner .calc-container constrains the content width.
   Position relative — required for sticky result panel.
---------------------------------------------------------- */

.calc-section {
  position: relative;
  overflow: visible;
}

.calc-container {
  position: relative;
  width: 100%;
}

/* ----------------------------------------------------------
   CALCULATOR GRID — MOBILE FIRST
   Base: 1-column. Inputs above. Result below.
   ≥780px: 2-col, 55/45 split, result becomes sticky sidebar.
   ≥1200px: slight proportion shift — inputs get more room.
   align-items: start — panels size to their own content.
   gap increases with viewport — breathing room at scale.
---------------------------------------------------------- */

.calc-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-lg);
  align-items: start;
}

@media (min-width: 780px) {
  .calc-grid {
    grid-template-columns: 55fr 45fr;
    gap: var(--sp-xl);
    align-items: start;
  }
}

@media (min-width: 1200px) {
  .calc-grid {
    grid-template-columns: 58fr 42fr;
    gap: var(--sp-2xl);
  }
}

@media (min-width: 1440px) {
  .calc-grid {
    gap: var(--sp-2xl);
  }
}


/* ----------------------------------------------------------
   INPUTS PANEL
   Left column on desktop. Full-width on mobile.
   Each input group: label + control + value display.
   Section heading in Bebas Neue — establishes context.
   Input groups separated by --sp-lg — breathing room.
   No borders on the panel itself — inputs provide structure.
---------------------------------------------------------- */

.calc-inputs {
  display: flex;
  flex-direction: column;
  gap: var(--sp-lg);
}

.calc-heading {
  font-family: var(--f-display);
  font-size: var(--fs-display-md);
  letter-spacing: var(--ls-display);
  color: var(--t-dark-primary);
  line-height: var(--lh-heading);
  margin-bottom: var(--sp-xs);
}

.calc-input-group {
  display: flex;
  flex-direction: column;
  gap: var(--sp-xs);
}

/* CTA at bottom of calculator inputs */
.calc-inputs-cta {
  margin-top: var(--sp-sm);
  text-align: center;
}

.calc-input-label {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--t-dark-muted);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

/* Live value display beside label — updates as slider moves */
.calc-live-value {
  font-family: var(--f-display);
  font-size: var(--fs-display-xs);
  letter-spacing: var(--ls-display);
  color: var(--c-ochre);
  line-height: 1;
  transition: opacity var(--dur-fast) var(--ease-smooth);
}

.calc-live-value.is-updating {
  opacity: 0.6;
}

/* ----------------------------------------------------------
   CUSTOM SLIDER — THE SIGNATURE INPUT
   Track fill: CSS custom property --fill-pct (set by JS).
   JS: el.style.setProperty('--fill-pct', pct + '%')
   This updates instantly via the CSS variable cascade.
   Zero layout. Zero RAF. Zero jank.

   Green fill left of thumb. Ghost right.
   Thumb: ochre circle. Spring scale on grab.
   Magnetic snap: JS detects proximity to notable values,
   CSS handles the spring animation via --ease-spring.
   On notable value snap: thumb gets .is-snapping class —
   fires a brief scale(1.4 → 1.0) spring overshoot.

   Both ::-webkit-slider-thumb and ::-moz-range-thumb styled.
   iOS Safari: -webkit-appearance:none required on input.
   Firefox: appearance:none on input, separate moz pseudo.
---------------------------------------------------------- */

.calc-slider-wrap {
  position: relative;
  padding: var(--sp-sm) 0;
}

.calc-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: var(--slider-track-h);
  border-radius: var(--r-full);
  outline: none;
  cursor: none;
  background: linear-gradient(
    to right,
    var(--c-green) 0%,
    var(--c-green) var(--fill-pct, 0%),
    var(--t-dark-hairline) var(--fill-pct, 0%),
    var(--t-dark-hairline) 100%
  );
  transition: background var(--dur-instant) linear;
}

/* Webkit thumb — mobile size base */
.calc-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: var(--slider-thumb-mob);
  height: var(--slider-thumb-mob);
  border-radius: var(--r-full);
  background: var(--c-ochre);
  box-shadow: var(--slider-thumb-shadow);
  cursor: none;
  transition:
    transform  var(--dur-fast) var(--ease-spring),
    box-shadow var(--dur-fast) var(--ease-smooth);
  position: relative;
  z-index: 2;
}

.calc-slider:active::-webkit-slider-thumb {
  transform: scale(1.28);
  box-shadow: var(--slider-thumb-hover);
  will-change: transform;
}

/* Snap animation — JS adds .is-snapping, CSS fires spring */
.calc-slider.is-snapping::-webkit-slider-thumb {
  transform: scale(1.4);
  box-shadow: var(--shadow-ochre);
  transition:
    transform  var(--dur-base) var(--ease-spring),
    box-shadow var(--dur-base) var(--ease-smooth);
}

/* Firefox */
.calc-slider::-moz-range-thumb {
  width: var(--slider-thumb-mob);
  height: var(--slider-thumb-mob);
  border-radius: var(--r-full);
  border: none;
  background: var(--c-ochre);
  box-shadow: var(--slider-thumb-shadow);
  cursor: none;
  transition:
    transform  var(--dur-fast) var(--ease-spring),
    box-shadow var(--dur-fast) var(--ease-smooth);
}

.calc-slider:active::-moz-range-thumb {
  transform: scale(1.28);
  box-shadow: var(--slider-thumb-hover);
}

/* Firefox track */
.calc-slider::-moz-range-track {
  height: var(--slider-track-h);
  border-radius: var(--r-full);
  background: var(--t-dark-hairline);
}

.calc-slider::-moz-range-progress {
  height: var(--slider-track-h);
  border-radius: var(--r-full);
  background: var(--c-green);
}

/* Slider range endpoints */
.calc-slider-range {
  display: flex;
  justify-content: space-between;
  margin-top: var(--sp-xs);
  font-family: var(--f-body);
  font-weight: 400;
  font-size: var(--fs-body-xs);
  color: var(--t-dark-ghost);
}


/* ----------------------------------------------------------
   TERM PILLS — LOAN TERM SELECTOR
   6 pills: 12M, 24M, 36M, 48M, 60M, 72M.
   Horizontal row. Scrollable on very narrow screens.
   Selected: ochre bg, ochre border, midnight text.
   Hover (desktop): green tint — directional hint.
   Each pill: min 44px touch target always.
   Active selection fires a spring scale bounce.
---------------------------------------------------------- */

.calc-term-pills {
  display: flex;
  gap: var(--sp-xs);
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  padding-bottom: var(--sp-2xs);
}

.calc-term-pills::-webkit-scrollbar {
  display: none;
}

.calc-term-pill {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--btn-min-touch);
  padding: var(--sp-xs) var(--sp-sm);
  border: var(--border-dark);
  border-radius: var(--r-full);
  background: var(--c-field-default);
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-body-xs);
  color: var(--t-dark-secondary);
  cursor: none;
  white-space: nowrap;
  transition:
    border-color var(--dur-fast) var(--ease-smooth),
    background   var(--dur-fast) var(--ease-smooth),
    color        var(--dur-fast) var(--ease-smooth),
    transform    var(--dur-fast) var(--ease-spring);
  -webkit-tap-highlight-color: transparent;
}

.calc-term-pill.is-active {
  border-color: var(--c-border-ochre-strong);
  background: var(--c-ochre);
  color: var(--c-midnight);
  transform: scale(1.05);
}

.calc-term-pill:active:not(.is-active) {
  transform: scale(0.95);
}

@media (hover: hover) {
  .calc-term-pill:hover:not(.is-active) {
    border-color: var(--c-border-green);
    background: var(--c-green-glow);
    color: var(--c-green-hi);
  }
}

/* ----------------------------------------------------------
   TOGGLE — BALLOON PAYMENT / FREQUENCY SWITCH
   A custom toggle used for:
   - Balloon payment on/off (Equipment calc)
   - Weekly / Fortnightly / Monthly frequency (Working capital)
   The pill slides between options via translateX.
   The sliding pill is a single element moved by JS.
   Container is the track. Pill is the indicator.
   Options are text labels — not inputs.
   Entire toggle is keyboard accessible via JS.
---------------------------------------------------------- */

.calc-toggle {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
}

.calc-toggle-label {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--t-dark-muted);
}

/* Binary on/off toggle — Balloon payment */
.calc-toggle-switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: var(--calc-toggle-w);
  height: var(--calc-toggle-h);
  border-radius: var(--r-full);
  background: var(--t-dark-hairline);
  border: var(--border-dark);
  cursor: none;
  transition: background var(--dur-fast) var(--ease-smooth),
              border-color var(--dur-fast) var(--ease-smooth);
  -webkit-tap-highlight-color: transparent;
}

.calc-toggle-switch.is-on {
  background: var(--c-green);
  border-color: var(--c-border-green-strong);
}

.calc-toggle-thumb {
  position: absolute;
  left: var(--calc-toggle-pad);
  width: var(--calc-toggle-thumb);
  height: var(--calc-toggle-thumb);
  border-radius: var(--r-full);
  background: var(--t-dark-muted);
  transition: transform var(--dur-fast) var(--ease-spring),
              background var(--dur-fast) var(--ease-smooth);
}

.calc-toggle-switch.is-on .calc-toggle-thumb {
  transform: translateX(var(--calc-toggle-travel));
  background: var(--c-bone);
}

/* 3-way frequency selector */
.calc-freq-selector {
  position: relative;
  display: flex;
  background: var(--t-dark-hairline);
  border: var(--border-dark);
  border-radius: var(--r-full);
  padding: var(--calc-toggle-pad);
  gap: 0;
}

.calc-freq-option {
  position: relative;
  z-index: 1;
  flex: 1;
  text-align: center;
  padding: var(--sp-xs) var(--sp-sm);
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-body-xs);
  color: var(--t-dark-muted);
  cursor: none;
  border-radius: var(--r-full);
  transition: color var(--dur-fast) var(--ease-smooth);
  white-space: nowrap;
  min-height: var(--btn-min-touch);
  display: flex;
  align-items: center;
  justify-content: center;
  -webkit-tap-highlight-color: transparent;
}

.calc-freq-option.is-active {
  color: var(--c-midnight);
}

/* Sliding indicator behind active option */
.calc-freq-indicator {
  position: absolute;
  top: var(--calc-toggle-pad);
  bottom: var(--calc-toggle-pad);
  border-radius: var(--r-full);
  background: var(--c-ochre);
  transition: transform var(--dur-base) var(--ease-spring),
              width var(--dur-base) var(--ease-spring);
  z-index: 0;
  will-change: transform;
}

.calc-freq-indicator.is-done {
  will-change: auto;
}


/* ----------------------------------------------------------
   RESULT PANEL — DESKTOP
   Sticky right column. Floats beside the inputs.
   Midnight background — authoritative, premium.
   Ochre strong top border — full width, always visible.
   The panel feels like a financial instrument display.
   On first result: slides in from right (JS adds .is-visible).
   Subsequent updates: only the ticker values change.
   Disclaimer always visible at bottom — never scroll away.
   
   Desktop: sticky top = nav-height + sp-md.
   Mobile: this panel is hidden. Mobile uses .calc-mobile-bar.
---------------------------------------------------------- */

.calc-result-panel {
  display: none;
}

@media (min-width: 780px) {
  .calc-result-panel {
    display: flex;
    flex-direction: column;
    gap: var(--sp-md);
    background: var(--c-midnight);
    border: var(--border-dark);
    border-top: var(--border-ochre-strong);
    border-radius: var(--r-xl);
    padding: var(--sp-xl) var(--sp-lg);
    position: sticky;
    top: calc(var(--nav-height-desktop) + var(--sp-md));
    opacity: 0;
    transform: translateX(var(--tx-panel-enter));
    transition:
      opacity   var(--dur-slow) var(--ease-out),
      transform var(--dur-slow) var(--ease-spring);
  }

  .calc-result-panel.is-visible {
    opacity: 1;
    transform: translateX(0);
  }
}

@media (min-width: 1440px) {
  .calc-result-panel {
    padding: var(--sp-xl) var(--sp-xl);
  }
}

/* Panel header */
.calc-result-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: var(--sp-sm);
  border-bottom: var(--border-dark);
}

.calc-result-eyebrow {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--t-dark-muted);
}

/* Live badge — glows green when calc is active */
.calc-result-live {
  display: flex;
  align-items: center;
  gap: var(--sp-xs);
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--c-green-hi);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-smooth);
}

.calc-result-live.is-active {
  opacity: 1;
}

.calc-result-live__dot {
  width: var(--dot-size-pill);
  height: var(--dot-size-pill);
  border-radius: var(--r-full);
  background: var(--c-green-hi);
  animation: live-pulse 2s var(--ease-in-out) infinite;
}

@keyframes live-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%       { opacity: 0.5; transform: scale(0.7); }
}


/* ----------------------------------------------------------
   THE LIVE TICKER — SIGNATURE ANIMATION
   The most unique element on the entire site.
   When the repayment figure changes:
   — Old value exits upward (translateY(-100%) + opacity 0)
   — New value enters from below (translateY(100%) → 0)

   This is how Bloomberg terminals work.
   This is how Apple Watch activity rings feel.
   This is how a financial instrument behaves — not a form.

   Structure:
   .calc-ticker           Outer clip container (overflow: hidden)
   .calc-ticker__track    Inner element that holds both values
   .calc-ticker__current  Currently visible number
   .calc-ticker__next     Incoming number (invisible until swap)

   JS workflow:
   1. New value calculated
   2. JS puts new value in .calc-ticker__next
   3. JS adds .is-ticking to .calc-ticker
   4. CSS animation fires: current exits up, next enters up
   5. After animation: JS swaps values, removes .is-ticking

   Height of .calc-ticker = one line of the number font.
   This is set via --calc-ticker-h which JS calculates
   from the rendered font size and sets as a CSS property
   on the .calc-ticker element itself.
   Default fallback: 1.1em ensures something renders.
---------------------------------------------------------- */

.calc-ticker {
  overflow: hidden;
  position: relative;
  height: 1.1em;
  display: flex;
  align-items: center;
}

.calc-ticker__current {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  font-family: var(--f-display);
  font-size: var(--fs-display-2xl);
  letter-spacing: var(--ls-display);
  color: var(--c-ochre);
  line-height: 1;
  transition: none;
}

.calc-ticker__next {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  font-family: var(--f-display);
  font-size: var(--fs-display-2xl);
  letter-spacing: var(--ls-display);
  color: var(--c-ochre);
  line-height: 1;
  transform: translateY(100%);
  opacity: 0;
  transition: none;
}

/* Ticking: current exits up, next rises from below */
.calc-ticker.is-ticking .calc-ticker__current {
  animation: tick-exit var(--dur-base) var(--ease-in) forwards;
}

.calc-ticker.is-ticking .calc-ticker__next {
  animation: tick-enter var(--dur-base) var(--ease-out) forwards;
  animation-delay: var(--calc-ticker-gap);
}

@keyframes tick-exit {
  0%   { transform: translateY(0);     opacity: 1; }
  100% { transform: translateY(-100%); opacity: 0; }
}

@keyframes tick-enter {
  0%   { transform: translateY(100%); opacity: 0; }
  100% { transform: translateY(0);    opacity: 1; }
}

/* Period label beside the ticker */
.calc-ticker-period {
  font-family: var(--f-body);
  font-weight: 300;
  font-size: var(--fs-body-md);
  color: var(--t-dark-secondary);
  margin-top: var(--sp-xs);
}

/* Secondary result rows — total payable, interest etc. */
.calc-result-rows {
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
  padding: var(--sp-md) 0;
  border-top: var(--border-dark);
  border-bottom: var(--border-dark);
}

.calc-result-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-sm);
}

.calc-result-row__label {
  font-family: var(--f-body);
  font-size: var(--fs-body-sm);
  color: var(--t-dark-secondary);
  font-weight: 400;
}

.calc-result-row__value {
  font-family: var(--f-display);
  font-size: var(--fs-display-sm);
  letter-spacing: var(--ls-display);
  color: var(--t-dark-primary);
  line-height: 1;
  transition: opacity var(--dur-fast) var(--ease-smooth);
}

.calc-result-row__value.is-updating {
  opacity: 0.5;
}

/* Interest cost highlighted in green — not a warning */
.calc-result-row__value--interest {
  color: var(--c-green-hi);
}

/* ----------------------------------------------------------
   RESULT PANEL — DISCLAIMER
   Always visible at the bottom of the result panel.
   Figtree 300. Ghost opacity. Never scroll away.
   The legal note the Calculator spec requires.
   Separated by a border-top so it reads as a footer.
---------------------------------------------------------- */

.calc-result-disclaimer {
  font-family: var(--f-body);
  font-weight: 300;
  font-size: var(--fs-body-xs);
  color: var(--t-dark-ghost);
  line-height: var(--lh-body);
  padding-top: var(--sp-sm);
  border-top: var(--border-dark);
}


/* ----------------------------------------------------------
   RESULT CTA — THE CONVERSION MOMENT
   Immediately below the result panel content.
   Uses the actual calculated value in the copy (set by JS).
   The button pulses with breathing animation while the
   result is displayed and unfocused — drawing the eye.
   On hover: pulse stops, standard hover state takes over.
   On mobile: this CTA is inside the mobile sticky bar.
   2-field mini form below the button on desktop:
   name + phone, horizontally arranged, submit inline.
   On submit: replaces with success state (green).
   On error: phone number shown large below.
---------------------------------------------------------- */

.calc-cta-wrap {
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
}

.calc-cta-headline {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-body-sm);
  color: var(--t-dark-secondary);
  line-height: var(--lh-tight);
}

/* The CTA button — uses dynamic copy set by JS */
.calc-cta-btn {
  width: 100%;
  text-align: center;
}

/* Pulse while result visible and un-hovered */
.calc-cta-btn.is-ready {
  animation: calc-cta-pulse var(--dur-xxslow) var(--ease-in-out) infinite;
}

.calc-cta-btn.is-ready:hover {
  animation: none;
}

@keyframes calc-cta-pulse {
  0%, 100% { box-shadow: var(--shadow-ochre-sm); }
  50%       { box-shadow: var(--shadow-ochre-lg); }
}

/* Mini inline form inside result panel */
.calc-mini-form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-xs);
}

@media (min-width: 1200px) {
  .calc-mini-form {
    flex-direction: row;
    align-items: flex-end;
    gap: var(--sp-xs);
  }

  .calc-mini-form .field-wrap {
    flex: 1;
    margin-bottom: 0;
  }

  .calc-mini-form .btn {
    flex-shrink: 0;
  }
}

/* ----------------------------------------------------------
   MOBILE STICKY RESULT BAR
   Fixed to the bottom, above the mobile nav bar.
   Only visible below 780px.
   Shows primary repayment figure + period.
   Slide up on first calculator interaction.
   Tap the bar to scroll to the inline result section.
   The CTA button is inside the bar — always reachable.
   z-index sits above content but below mobile nav.
---------------------------------------------------------- */

.calc-mobile-bar {
  display: none;
}

@media (max-width: 779px) {
  .calc-mobile-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-sm);
    position: fixed;
    bottom: var(--mob-nav-height);
    left: 0;
    right: 0;
    z-index: var(--z-sticky);
    background: var(--c-forest);
    border-top: var(--border-ochre-strong);
    padding: var(--sp-sm) var(--container-px);
    transform: translateY(100%);
    transition: transform var(--dur-slow) var(--ease-spring);
  }

  .calc-mobile-bar.is-visible {
    transform: translateY(0);
  }

  .calc-mobile-bar__amount {
    display: flex;
    flex-direction: column;
    gap: var(--gap-micro);
  }

  .calc-mobile-bar__figure {
    font-family: var(--f-display);
    font-size: var(--fs-display-sm);
    letter-spacing: var(--ls-display);
    color: var(--c-ochre);
    line-height: 1;
  }

  .calc-mobile-bar__period {
    font-family: var(--f-body);
    font-size: var(--fs-body-xs);
    color: var(--t-dark-muted);
    font-weight: 300;
  }
}

/* ----------------------------------------------------------
   INLINE MOBILE RESULT — BELOW CALCULATOR INPUTS
   On mobile, after the slider section, a result card
   appears inline (not sticky — the sticky bar is the
   summary, this is the detail). Shows full breakdown.
   display: none until first calculation runs (JS adds
   .has-result to .calc-section).
   Same result-rows as desktop. Same disclaimer.
---------------------------------------------------------- */

.calc-inline-result {
  display: none;
  background: var(--c-forest);
  border: var(--border-dark);
  border-top: var(--border-ochre-strong);
  border-radius: var(--r-lg);
  padding: var(--sp-lg) var(--sp-md);
  flex-direction: column;
  gap: var(--sp-md);
  margin-top: var(--sp-md);
}

.calc-section.has-result .calc-inline-result {
  display: flex;
  animation: result-reveal var(--dur-slow) var(--ease-spring) forwards;
}

@keyframes result-reveal {
  0%   { opacity: 0; transform: translateY(var(--ty-reveal-sm)); }
  100% { opacity: 1; transform: translateY(0); }
}

@media (min-width: 780px) {
  .calc-inline-result {
    display: none !important;
  }
}


/* ----------------------------------------------------------
   SHARED CALC UTILITIES
   calc-input-row and calc-slider-labels used across pages.
   Defined here so they work everywhere design-system.css loads.
---------------------------------------------------------- */

.calc-input-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--sp-xs);
  max-width: 100%;
}

.calc-slider-labels {
  display: flex;
  justify-content: space-between;
  font-size: 10px;
  color: var(--t-dark-ghost);
  margin-top: 4px;
  letter-spacing: 0.06em;
}


/* ══════════════════════════════════════════════════════════
   EQUIPMENT FINANCE — FULL-WIDTH CALCULATOR SECTION
   Responsive two-column layout below the hero.
   Desktop 780px+: inputs left, results right (sticky).
   Mobile  <780px: stacked — inputs above results, full width.
   All four controls present on every breakpoint.
══════════════════════════════════════════════════════════ */

.ef-calc-section {
  overflow: hidden;
}

.ef-calc-section .ef-calc-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-xl);
  align-items: start;
}

.ef-calc-section .ef-calc-grid > * {
  min-width: 0;
}

@media (min-width: 780px) {
  .ef-calc-section .ef-calc-grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (min-width: 1200px) {
  .ef-calc-section .ef-calc-grid {
    gap: var(--sp-2xl);
  }
}

/* Inputs column */
.ef-calc-inputs {
  display: flex;
  flex-direction: column;
  gap: var(--sp-lg);
  min-width: 0;
  width: 100%;
}

.ef-calc-section-title {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--t-dark-muted);
}

/* Results column */
.ef-calc-results {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--sp-lg);
  width: 100%;
}

@media (min-width: 780px) {
  .ef-calc-results {
    position: sticky;
    top: 120px;
    padding: var(--sp-lg) 0;
  }
}

/* Large monthly repayment display */
.ef-calc-hero-amount {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 100%;
}

.ef-calc-hero-amount .calc-ticker {
  font-size: clamp(72px, 12vw, 120px);
  height: 1.1em;
  width: 100%;
}

.ef-calc-hero-amount .calc-ticker__current,
.ef-calc-hero-amount .calc-ticker__next {
  font-size: inherit;
  justify-content: center;
}

.ef-calc-hero-amount .calc-ticker-period {
  font-size: var(--fs-body-lg);
  color: var(--t-dark-secondary);
  margin-top: var(--sp-xs);
}

/* Three-column breakdown row */
.ef-calc-breakdown {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--sp-md);
  width: 100%;
  padding: var(--sp-md) 0;
  border-top: var(--border-dark);
  border-bottom: var(--border-dark);
}

.ef-calc-breakdown-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2xs);
  text-align: center;
}

.ef-calc-breakdown-label {
  font-family: var(--f-body);
  font-weight: 500;
  font-size: var(--fs-body-xs);
  letter-spacing: 0.04em;
  color: var(--t-dark-muted);
}

.ef-calc-breakdown-value {
  font-family: var(--f-display);
  font-size: var(--fs-display-sm);
  letter-spacing: var(--ls-display);
  color: var(--t-dark-primary);
  line-height: 1;
  transition: opacity var(--dur-fast) var(--ease-smooth);
}

.ef-calc-breakdown-value.is-updating {
  opacity: 0.5;
}

/* CTA inside results column */
.ef-calc-results .calc-cta-btn {
  width: 100%;
  max-width: 400px;
}

/* Microcopy below CTA */
.ef-calc-microcopy {
  font-family: var(--f-body);
  font-weight: 300;
  font-size: var(--fs-body-xs);
  color: var(--t-dark-ghost);
  line-height: var(--lh-body);
  text-align: center;
}

/* Pulse animation — fires when value changes */
@keyframes ef-result-pulse {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.05); }
  100% { transform: scale(1); }
}

.ef-calc-hero-amount.is-pulsing {
  animation: ef-result-pulse 200ms ease-out;
}

/* CTA text transition — smooth opacity change */
.ef-calc-results .calc-cta-btn.is-text-updating {
  opacity: 0.8;
  transition: opacity 80ms ease;
}


/* ══════════════════════════════════════════════════════════
   FUNDING CLOCK — BELOW HERO
   8 product tiles showing target turnaround times.
   Desktop 780px+: single row, 8 columns.
   Mobile  <780px: 4 columns, 2 rows.
══════════════════════════════════════════════════════════ */

.fclock {
  overflow: hidden;
}

/* Header */
.fclock__header {
  text-align: center;
  margin-bottom: var(--sp-lg);
  max-width: 640px;
  margin-left: auto;
  margin-right: auto;
}

.fclock__headline {
  font-family: var(--f-display);
  font-size: var(--fs-display-lg);
  letter-spacing: var(--ls-display);
  line-height: 1.05;
  color: var(--t-dark-primary);
  margin-bottom: var(--sp-xs);
  max-width: none;
  margin-left: auto;
  margin-right: auto;
  text-wrap: balance;
}

.fclock__sub {
  color: var(--t-dark-secondary);
  margin-bottom: var(--sp-sm);
  text-wrap: balance;
}

.fclock__perth-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-xs);
  font-family: var(--f-body);
  font-size: var(--fs-body-sm);
  font-weight: 500;
  color: var(--t-dark-muted);
  background: rgba(244, 239, 228, 0.06);
  border: 1px solid rgba(244, 239, 228, 0.1);
  border-radius: var(--r-full);
  padding: var(--sp-2xs) var(--sp-sm);
}

.fclock__perth-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--c-green-hi);
  flex-shrink: 0;
}

@media (prefers-reduced-motion: no-preference) {
  .fclock__perth-dot {
    animation: fclock-pulse 2s ease-in-out infinite;
  }
}

@keyframes fclock-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

/* Tile grid */
.fclock__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--sp-xs);
}

@media (min-width: 780px) {
  .fclock__grid {
    grid-template-columns: repeat(8, minmax(0, 1fr));
  }
}

/* Individual tile */
.fclock__tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  text-decoration: none;
  min-width: 0;
  padding: var(--sp-sm) var(--sp-xs);
  background: rgba(244, 239, 228, 0.06);
  border: 1px solid rgba(244, 239, 228, 0.1);
  border-top: 3px solid rgba(232, 160, 64, 0.5);
  border-radius: var(--r-sm);
  transition:
    transform var(--dur-normal) var(--ease-smooth),
    box-shadow var(--dur-normal) var(--ease-smooth),
    border-color var(--dur-normal) var(--ease-smooth);
}

@media (prefers-reduced-motion: no-preference) {
  .fclock__tile:hover {
    transform: translateY(-3px);
    box-shadow: 0 8px 24px rgba(232, 160, 64, 0.12);
    border-top-color: var(--c-ochre);
  }
}

.fclock__tile:focus-visible {
  outline: 2px solid var(--c-ochre);
  outline-offset: 2px;
}

/* Tile content */
.fclock__name {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-body-xs);
  letter-spacing: 0.02em;
  color: var(--t-dark-primary);
  line-height: 1.3;
  min-height: 2.6em;
  display: flex;
  align-items: center;
  overflow-wrap: break-word;
  word-break: break-word;
}

.fclock__divider {
  width: 20px;
  height: 1px;
  background: rgba(244, 239, 228, 0.12);
  margin: var(--sp-xs) 0;
}

.fclock__label {
  font-family: var(--f-body);
  font-weight: 400;
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--t-dark-muted);
  margin-bottom: var(--sp-2xs);
}

.fclock__day {
  font-family: var(--f-display);
  font-size: clamp(22px, 3vw, 32px);
  letter-spacing: var(--ls-display);
  line-height: 1;
  color: var(--c-ochre);
}

.fclock__time {
  font-family: var(--f-body);
  font-weight: 500;
  font-size: var(--fs-body-xs);
  color: var(--t-dark-secondary);
  margin-top: var(--sp-2xs);
}

/* ── Responsive tile tuning ── */

/* Mobile: scale headline for balanced centering */
@media (max-width: 779px) {
  .fclock__headline {
    font-size: clamp(26px, 7vw, 36px);
  }
}

/* Small phones: tighter padding */
@media (max-width: 385px) {
  .fclock__tile {
    padding: var(--sp-xs) 4px;
  }
  .fclock__name {
    font-size: 9px;
  }
  .fclock__day {
    font-size: 20px;
  }
}

@media (min-width: 480px) and (max-width: 779px) {
  .fclock__tile {
    padding: var(--sp-sm);
  }
  .fclock__day {
    font-size: clamp(24px, 4vw, 34px);
  }
}

@media (min-width: 780px) {
  .fclock__headline {
    font-size: var(--fs-display-xl);
  }
  .fclock__tile {
    padding: var(--sp-md) var(--sp-sm);
  }
  .fclock__day {
    font-size: clamp(26px, 2.2vw, 38px);
  }
}

@media (min-width: 1200px) {
  .fclock__tile {
    padding: var(--sp-md);
  }
  .fclock__day {
    font-size: clamp(30px, 2.4vw, 42px);
  }
}

@media (min-width: 1440px) {
  .fclock__day {
    font-size: 42px;
  }
}

/* CTA row */
.fclock__cta-row {
  text-align: center;
  margin-top: var(--sp-lg);
}

.fclock__disclaimer {
  font-family: var(--f-body);
  font-weight: 300;
  font-size: var(--fs-body-xs);
  color: var(--t-dark-ghost);
  line-height: var(--lh-body);
  max-width: 640px;
  margin: 0 auto var(--sp-md);
}

.fclock__buttons {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: var(--sp-sm);
  flex-wrap: wrap;
}


/* ----------------------------------------------------------
   SMART MATCHER — CALC 3
   The most powerful calculator on the site.
   Doesn't calculate a repayment — recommends a product.
   Every input change updates the recommendation live.

   Inputs: product icon tiles + revenue pills + timeline pills
   Output: recommended product in Bebas Neue 48px ochre
           + confidence score bar
           + weekly cost estimate + approval speed
           + 2-line plain English reason
           + dynamic CTA using the match

   The confidence bar is uniquely compelling:
   A green bar that scales from 0 to the match strength.
   "98% match — Equipment Finance" — like a search result.
   Users feel validated. They feel understood. They convert.
   
   Tiles reuse .form-tile classes — same system, no duplication.
   Revenue + timeline reuse .form-pill classes — same system.
   Only the result section is Matcher-specific.
---------------------------------------------------------- */

.calc-matcher-result {
  display: flex;
  flex-direction: column;
  gap: var(--sp-md);
  opacity: 0;
  transform: translateY(var(--ty-reveal-xs));
  transition:
    opacity   var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-spring);
  pointer-events: none;
}

.calc-matcher-result.is-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: all;
}

/* Match label */
.calc-matcher-label {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--t-dark-muted);
}

/* Confidence bar — the signature Smart Matcher element */
.calc-match-bar-wrap {
  display: flex;
  flex-direction: column;
  gap: var(--sp-xs);
}

.calc-match-bar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.calc-match-pct {
  font-family: var(--f-display);
  font-size: var(--fs-display-sm);
  letter-spacing: var(--ls-display);
  color: var(--c-green-hi);
  line-height: 1;
}

.calc-match-label {
  font-family: var(--f-body);
  font-size: var(--fs-body-xs);
  color: var(--t-dark-secondary);
  font-weight: 400;
}

.calc-match-track {
  height: var(--slider-track-h);
  background: var(--t-dark-hairline);
  border-radius: var(--r-full);
  overflow: hidden;
}

.calc-match-fill {
  height: 100%;
  background: var(--c-green);
  border-radius: var(--r-full);
  transform-origin: left;
  transform: scaleX(0);
  transition: transform var(--dur-slow) var(--ease-spring);
}

.calc-match-fill.is-filled {
  box-shadow: var(--shadow-green-sm);
}

/* Recommended product name */
.calc-match-product {
  font-family: var(--f-display);
  font-size: var(--fs-display-xl);
  letter-spacing: var(--ls-display);
  color: var(--c-ochre);
  line-height: var(--lh-heading);
  transition: opacity var(--dur-fast) var(--ease-smooth);
}

.calc-match-product.is-updating {
  opacity: 0.4;
}

/* Match detail grid — cost, speed, reason */
.calc-match-details {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-sm);
}

.calc-match-detail {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2xs);
  padding: var(--sp-sm);
  background: var(--c-field-default);
  border: var(--border-dark);
  border-radius: var(--r-md);
}

.calc-match-detail__label {
  font-family: var(--f-body);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--t-dark-ghost);
}

.calc-match-detail__value {
  font-family: var(--f-display);
  font-size: var(--fs-display-sm);
  letter-spacing: var(--ls-display);
  color: var(--t-dark-primary);
  line-height: 1;
}

/* Match reason — full width below the detail grid */
.calc-match-reason {
  font-family: var(--f-body);
  font-size: var(--fs-body-sm);
  color: var(--t-dark-secondary);
  line-height: var(--lh-body);
  font-style: italic;
  padding: var(--sp-sm);
  background: var(--c-green-glow);
  border: var(--border-green);
  border-radius: var(--r-md);
}

/* ----------------------------------------------------------
   DESKTOP SLIDER OVERRIDE — ≥780px
   Thumb shrinks to desktop size (26px).
   Hover state on thumb — enlarges on cursor proximity.
   The magnetic glow effect gets stronger on desktop.
   Cursor JS enhances the thumb interaction on pointer devices.
---------------------------------------------------------- */

@media (min-width: 780px) {
  .calc-slider::-webkit-slider-thumb {
    width: var(--slider-thumb);
    height: var(--slider-thumb);
  }

  .calc-slider::-moz-range-thumb {
    width: var(--slider-thumb);
    height: var(--slider-thumb);
  }

  .calc-slider::-webkit-slider-thumb:hover {
    transform: scale(1.2);
    box-shadow: var(--slider-thumb-hover);
  }
}

/* ----------------------------------------------------------
   FULL 7-BREAKPOINT COVERAGE
   Every breakpoint has at least one meaningful override.
   386px: base — all above is the base
   480px: term pills unwrap to horizontal row
   780px: grid activates, slider thumb shrinks, panel appears
   1200px: grid proportion shifts, mini form goes horizontal
   1440px: primary target — all at optimal proportions
   1920px: max-width caps — nothing stretches
   2560px: clamp values at ceiling
   
   The calc section itself doesn't need max-width — it lives
   inside the page .container which already constrains it.
   The result panel sticky position adjusts per breakpoint.
---------------------------------------------------------- */

/* 480px — term pills stop scrolling, all visible */
@media (min-width: 480px) {
  .calc-term-pills {
    overflow-x: visible;
    flex-wrap: wrap;
  }

  .calc-match-details {
    grid-template-columns: 1fr 1fr;
  }
}

/* 780px — covered by grid and result panel rules above */

/* 1200px — covered by grid and mini-form rules above */

/* 1440px — result panel padding increase */
@media (min-width: 1440px) {
  .calc-inputs {
    gap: var(--sp-xl);
  }
}

/* 1920px — nothing needed beyond container max-width */

/* 2560px — nothing needed beyond container max-width */


/* ============================================================
   UNIT 1.9 — NAVIGATION CSS
   The best nav ever built. Better than Apple.
   Not a claim — a standard that every rule below meets.

   DESKTOP (≥780px): Orbital Pill
   A floating glass pill that breathes at the top of every page.
   Transparent on load. Solidifies as the user scrolls.
   W mark + wordmark left. 4 links centre. Phone + CTA right.
   Services link opens a full-screen product overlay.
   Link hover: ochre colour + underline draws from left.
   Active page: static underline. No guessing where you are.

   MOBILE (≤779px): Bottom Navigation Bar
   iOS spatial computing aesthetic. 4 tabs.
   A single liquid ochre pill slides between active tabs.
   One DOM element. Pure translateX. Spring easing. Perfect.
   Call tab is always ochre — it never looks inactive.
   Services tab opens a bottom sheet with all 7 product tiles.
   ============================================================ */

/* ----------------------------------------------------------
   SHARED: SKIP LINK
   Already defined in unit 1.2. Nav is the first element
   after the skip link. This comment marks the boundary.
---------------------------------------------------------- */

/* ----------------------------------------------------------
   DESKTOP ORBITAL PILL — BASE (≥780px)
   The pill is hidden below 780px. Mobile uses bottom nav.
   Fixed position. Full-width context but pill is centred.
   The pill itself is max-width 1200px — not the full page.
   On 1440px it breathes. On 1920px it caps. On 2560px it caps.

   State: .is-transparent — top of page (initial)
   State: .is-scrolled   — past 80px scroll threshold
   State: .is-open       — services overlay is showing
   
   Transition: all state changes use CSS transitions only.
   JS adds/removes classes. CSS does all the visual work.
   No inline styles on the nav element itself from JS.
---------------------------------------------------------- */

.site-nav {
  display: none;
}

@media (min-width: 780px) {
  .site-nav {
    display: flex;
    align-items: center;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: var(--z-nav);
    height: var(--nav-height-desktop);
    padding: 0 var(--container-px);
    pointer-events: none;
  }

  /* The floating pill — centred, max-width constrained */
  .site-nav__pill {
    display: flex;
    align-items: center;
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    height: var(--nav-pill-h);
    padding: 0 var(--sp-md);
    border-radius: var(--r-full);
    pointer-events: all;

    /* Transparent state — dark tint ensures cream text is readable on any background.
       Midnight tint at 0.55 blends invisibly on dark hero pages and provides
       ~3.8:1 contrast ratio for cream text on light (bone) backgrounds. */
    background: rgba(12, 30, 24, 0.55);
    border: 1px solid rgba(244, 239, 228, 0.10);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);

    transition:
      background     var(--dur-base) var(--ease-smooth),
      border-color   var(--dur-base) var(--ease-smooth),
      box-shadow     var(--dur-base) var(--ease-smooth),
      backdrop-filter var(--dur-base) var(--ease-smooth);
  }

  /* Scrolled state — pill solidifies */
  .site-nav.is-scrolled .site-nav__pill {
    background: var(--c-surface-glass-solid);
    border-color: var(--c-glass-border);
    backdrop-filter: var(--nav-blur);
    -webkit-backdrop-filter: var(--nav-blur);
    box-shadow: var(--shadow-lg);
    animation: pill-breathe 4s var(--ease-in-out) infinite;
    animation-delay: var(--dur-slow);
  }

  /* Overlay open — pill dims, overlay takes focus */
  .site-nav.is-open .site-nav__pill {
    border-color: transparent;
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: none;
    animation: none;
  }

  /* Pill breathing — border glow pulses slowly */
  @keyframes pill-breathe {
    0%, 100% { border-color: var(--c-glass-border); }
    50%       { border-color: var(--c-glass-border-active); }
  }

  /* Pill layout: left / centre / right */
  .site-nav__left {
    display: flex;
    align-items: center;
    gap: var(--sp-sm);
    flex-shrink: 0;
  }

  .site-nav__centre {
    display: flex;
    align-items: center;
    gap: var(--sp-md);
    flex: 1;
    justify-content: center;
  }

  .site-nav__right {
    display: flex;
    align-items: center;
    gap: var(--sp-sm);
    flex-shrink: 0;
  }
}

@media (min-width: 1200px) {
  .site-nav__pill {
    max-width: 1200px;
    padding: 0 var(--sp-lg);
  }
}

@media (min-width: 1440px) {
  .site-nav__pill {
    max-width: 1360px;
    height: var(--nav-pill-h-lg);
  }
}

@media (min-width: 1920px) {
  .site-nav__pill {
    max-width: 1560px;
  }
}

@media (min-width: 2560px) {
  .site-nav__pill {
    max-width: 1760px;
  }
}


/* ----------------------------------------------------------
   DESKTOP — W MARK IN NAV
   SVG mark at 32px height. Wordmark in Bebas Neue beside it.
   The mark is an <svg> element — CSS controls size only.
   stroke colours are in the SVG attribute (style="stroke:var(--c-ochre)")
   per the Bible spec — CSS variables work in style= attributes.
   Clicking the mark navigates to home.
---------------------------------------------------------- */

@media (min-width: 780px) {
  .site-nav__mark {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    text-decoration: none;
    gap: var(--sp-xs);
  }

  .site-nav__mark svg {
    height: var(--nav-mark-h);
    width: auto;
    display: block;
  }

  .site-nav__wordmark {
    font-family: var(--f-display);
    font-size: var(--fs-wordmark);
    letter-spacing: var(--ls-wordmark);
    color: var(--t-dark-primary);
    line-height: 1;
    white-space: nowrap;
  }

  .site-nav__wordmark span {
    color: var(--c-ochre);
  }

  /* ----------------------------------------------------------
     DESKTOP — NAV LINKS
     Each link: Figtree 500, fs-body-sm, t-dark-secondary.
     On hover: colour → ochre + underline draws scaleX(0→1)
     The underline is a ::after pseudo, transform-origin: left.
     Active page (.is-active): underline static, colour ochre.
     On transparent nav: slightly brighter secondary.
     cursor: none — custom cursor handles the pointer.
  ---------------------------------------------------------- */

  .nav-link {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2xs);
    font-family: var(--f-body);
    font-weight: 500;
    font-size: var(--fs-body-sm);
    letter-spacing: var(--ls-nav);
    color: var(--t-dark-secondary);
    text-decoration: none;
    cursor: none;
    padding: var(--sp-xs) var(--sp-2xs);
    white-space: nowrap;
    transition: color var(--dur-fast) var(--ease-smooth);
  }

  /* Underline pseudo — scaleX from left on hover */
  .nav-link::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: var(--sp-2xs);
    right: var(--sp-2xs);
    height: var(--nav-underline-h);
    background: var(--c-ochre);
    transform-origin: left;
    transform: scaleX(0);
    transition: transform var(--dur-fast) var(--ease-out);
  }

  .nav-link:hover {
    color: var(--c-ochre);
  }

  .nav-link:hover::after {
    transform: scaleX(1);
  }

  .nav-link:focus-visible {
    outline: 2px solid var(--c-ochre);
    outline-offset: 3px;
    border-radius: var(--r-xs);
  }

  /* Active page — static underline, full ochre */
  .nav-link.is-active {
    color: var(--c-ochre);
  }

  .nav-link.is-active::after {
    transform: scaleX(1);
  }

  /* Services link — has a tiny chevron that rotates when overlay opens */
  .nav-link--services .nav-link__chevron {
    width: var(--nav-chevron);
    height: var(--nav-chevron);
    transition: transform var(--dur-fast) var(--ease-smooth);
    flex-shrink: 0;
  }

  .site-nav.is-open .nav-link--services .nav-link__chevron {
    transform: rotate(180deg);
  }

  /* ----------------------------------------------------------
     DESKTOP — RIGHT SIDE: PHONE + CTA
     Phone number: Figtree 600, ochre. Always a tel: link.
     Always visible on desktop. Never hidden at any breakpoint.
     CTA: btn--primary--sm — ochre button, smaller than hero.
  ---------------------------------------------------------- */

  .nav-phone {
    display: flex;
    align-items: center;
    gap: var(--sp-xs);
    font-family: var(--f-body);
    font-weight: 600;
    font-size: var(--fs-body-sm);
    letter-spacing: var(--ls-phone);
    color: var(--c-ochre);
    text-decoration: none;
    cursor: none;
    transition: opacity var(--dur-fast) var(--ease-smooth);
    white-space: nowrap;
  }

  .nav-phone:hover {
    opacity: 0.8;
  }

  .nav-phone:focus-visible {
    outline: 2px solid var(--c-ochre);
    outline-offset: 3px;
    border-radius: var(--r-xs);
  }

  .nav-phone__icon {
    width: var(--nav-phone-icon);
    height: var(--nav-phone-icon);
    flex-shrink: 0;
  }
}


/* ----------------------------------------------------------
   DESKTOP — FULL-SCREEN SERVICES OVERLAY
   The overlay covers the entire viewport.
   7 product cards arranged in a 3+3+1 grid.
   Cards fly in from below with staggered spring timing.
   Magnetic cursor: JS reads pointer position, applies
   inline transform to each card within ±12px range.
   CSS defines the base and the transition that makes
   the magnetic effect smooth — JS drives the actual transform.

   Open trigger: hover or click on "Services" nav link.
   Dismiss: mouse leaves overlay area OR Escape OR backdrop click.
   On dismiss: cards exit downward, overlay fades out.

   The backdrop sits BEHIND the nav pill — overlay opens
   beneath the nav so the pill stays accessible for closing.
   z-index: var(--z-modal-bg) — same as form overlay backdrop.
   Cards: var(--z-modal) — above the backdrop.
   The nav pill: var(--z-nav) = 900 — above everything.
---------------------------------------------------------- */

/* Hidden on mobile — desktop dropdown only */
.nav-dropdown {
  display: none;
  list-style: none;
  margin: 0;
  padding: 0;
}

/* ----------------------------------------------------------
   NAV SERVICES WRAP + SIMPLE DROPDOWN
   The .nav-services-wrap groups the button + dropdown list
   as one hover zone. CSS :hover opens the dropdown reliably.
   JS still manages aria-expanded and keyboard dismiss.
---------------------------------------------------------- */
@media (min-width: 780px) {

  /* Wrapper: relative parent for the dropdown */
  .nav-services-wrap {
    position: relative;
    display: flex;
    align-items: center;
  }

  /* Invisible hover bridge: connects button to dropdown panel */
  .nav-services-wrap::before {
    content: '';
    position: absolute;
    top: 100%;
    left: -8px;
    right: -8px;
    height: 12px;
    pointer-events: auto;
  }

  /* The dropdown list — two-column layout */
  .nav-dropdown {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-auto-flow: column;
    grid-template-rows: repeat(4, auto);
    position: absolute;
    top: calc(100% + 12px);
    left: 50%;
    transform: translateX(-50%);
    z-index: 850;
    min-width: 400px;
    background: var(--c-midnight);
    border: var(--border-dark);
    border-radius: var(--r-lg, 12px);
    box-shadow: var(--shadow-lg);
    padding: var(--sp-sm) 0;
    list-style: none;
    margin: 0;
    /* Hidden by default */
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateX(-50%) translateY(-8px);
    transition:
      opacity    200ms var(--ease-smooth),
      visibility 200ms var(--ease-smooth),
      transform  200ms var(--ease-spring);
  }

  /* Show on CSS hover or JS .is-open */
  .nav-services-wrap:hover .nav-dropdown,
  .nav-dropdown.is-open {
    opacity: 1;
    visibility: visible;
    pointer-events: all;
    transform: translateX(-50%) translateY(0);
  }

  /* Dropdown links */
  .nav-dropdown__link {
    display: block;
    padding: var(--sp-sm) var(--sp-md);
    font-family: var(--f-body);
    font-size: var(--fs-body-sm, 14px);
    font-weight: 500;
    color: var(--t-dark-secondary);
    text-decoration: none;
    white-space: nowrap;
    transition:
      color var(--dur-fast) var(--ease-smooth),
      background var(--dur-fast) var(--ease-smooth);
  }

  .nav-dropdown__link:hover {
    color: var(--c-ochre);
    background: var(--c-forest);
  }
}


/* ----------------------------------------------------------
   MOBILE — BOTTOM NAVIGATION BAR
   The best mobile nav ever built.
   Fixed bottom. Full width. 68px height.
   4 tabs: Home · Services · Calculate · Call.
   
   THE LIQUID INDICATOR:
   A single .mob-nav__indicator element — one ochre pill
   that slides between tab positions via translateX.
   JS calculates each tab's offsetLeft + offsetWidth / 2
   and moves the single pill to centre on the active tab.
   The pill width matches the active tab's label width + padding.
   One element. Pure transform. Spring easing. Never redraws.
   This is the iOS liquid tab bar — but premium.
   
   THE CALL TAB:
   Always ochre. Always raised 2px via translateY.
   A permanent glowing backdrop sits behind it.
   It is never inactive. It demands tap.
   
   Desktop: display: none — orbital pill takes over.
   Mobile: bottom nav is the entire navigation.
---------------------------------------------------------- */

.mob-nav {
  display: flex;
  align-items: center;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: var(--mob-nav-height);
  z-index: var(--z-bar);
  background: var(--c-midnight);
  border-top: var(--border-dark);
}

@media (min-width: 780px) {
  .mob-nav {
    display: none;
  }
}

/* Liquid indicator pill — single element, JS moves it */
.mob-nav__indicator {
  position: absolute;
  bottom: var(--mob-indicator-bot);
  height: var(--mob-indicator-h);
  border-radius: var(--r-full);
  background: var(--c-ochre-glow);
  border: var(--border-ochre);
  z-index: 0;
  transition:
    transform  var(--dur-base) var(--ease-spring),
    width      var(--dur-base) var(--ease-spring),
    left       var(--dur-base) var(--ease-spring);
  pointer-events: none;
}

/* Tab container */
.mob-nav__tabs {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  width: 100%;
  height: 100%;
  position: relative;
}

/* Individual tab */
.mob-nav__tab {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--mob-tab-gap);
  cursor: none;
  -webkit-tap-highlight-color: transparent;
  min-height: var(--mob-nav-height);
  transition: transform var(--dur-fast) var(--ease-spring);
}

.mob-nav__tab:active:not(.mob-nav__tab--call) {
  transform: scale(0.92);
}

/* Tab icon */
.mob-nav__icon {
  width: var(--mob-tab-icon);
  height: var(--mob-tab-icon);
  color: var(--t-dark-ghost);
  transition: color var(--dur-fast) var(--ease-smooth),
              transform var(--dur-fast) var(--ease-spring);
  flex-shrink: 0;
}

/* Tab label */
.mob-nav__label {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: var(--mob-label-size);
  letter-spacing: var(--mob-label-ls);
  text-transform: uppercase;
  color: var(--t-dark-ghost);
  line-height: 1;
  transition: color var(--dur-fast) var(--ease-smooth);
}

/* Active tab */
.mob-nav__tab.is-active .mob-nav__icon {
  color: var(--c-ochre);
  transform: translateY(var(--ty-lift-sm)) scale(1.1);
}

.mob-nav__tab.is-active .mob-nav__label {
  color: var(--c-ochre);
}

/* THE CALL TAB — permanently ochre, always alive */
.mob-nav__tab--call {
  transform: translateY(var(--ty-lift-sm));
}

.mob-nav__tab--call .mob-nav__icon {
  color: var(--c-ochre);
}

.mob-nav__tab--call .mob-nav__label {
  color: var(--c-ochre);
}

/* Glowing backdrop behind Call tab */
.mob-nav__call-glow {
  position: absolute;
  inset: 4px 8px;
  border-radius: var(--r-md);
  background: var(--c-ochre-glow);
  border: var(--border-ochre);
  z-index: 0;
  animation: call-tab-glow 3s var(--ease-in-out) infinite;
}

@keyframes call-tab-glow {
  0%, 100% { opacity: 0.6; }
  50%       { opacity: 1; }
}

.mob-nav__tab--call > *:not(.mob-nav__call-glow) {
  position: relative;
  z-index: 1;
}

.mob-nav__tab--call:active {
  transform: translateY(0) scale(0.95);
}


/* ----------------------------------------------------------
   MOBILE — SERVICES BOTTOM SHEET
   Slides up when Services tab is tapped.
   Same sheet architecture as the form overlay but
   purpose-built for service tile navigation.
   7 tiles in a 2-col grid — same .nav-service-tile system.
   Each tile navigates to the relevant service page.

   The sheet never uses display:none to hide/show.
   It's always in the DOM. translateY controls visibility.
   This prevents the reflow flash that display:none causes
   when the sheet opens for the first time.

   Swipe handle at top — same as form sheet.
   Backdrop behind sheet — same z-index hierarchy.
   Dismiss: swipe down · tap backdrop · tap any tile.
---------------------------------------------------------- */

.mob-services-sheet {
  position: fixed;
  bottom: var(--mob-nav-height);
  left: 0;
  right: 0;
  z-index: var(--z-modal);
  background: var(--c-midnight);
  border-radius: var(--r-2xl) var(--r-2xl) 0 0;
  border-top: var(--border-dark);
  border-left: var(--border-dark);
  border-right: var(--border-dark);
  max-height: 80vh;
  overflow: hidden;
  transform: translateY(calc(100% + var(--mob-nav-height)));
  transition: transform var(--dur-slow) var(--ease-spring);
  will-change: transform;
  pointer-events: none;
}

.mob-services-sheet.is-open {
  transform: translateY(0);
  will-change: auto;
  pointer-events: auto;
}

.mob-services-sheet.is-dragging {
  transition: none;
  will-change: transform;
}

@media (min-width: 780px) {
  .mob-services-sheet {
    display: none;
  }
}

/* Sheet handle */
.mob-services-sheet__handle {
  width: var(--form-handle-w);
  height: var(--dot-size-sm);
  background: var(--t-dark-ghost);
  border-radius: var(--r-full);
  margin: var(--sp-sm) auto var(--sp-xs);
  transition: background var(--dur-fast) var(--ease-smooth),
              transform  var(--dur-fast) var(--ease-smooth);
}

.mob-services-sheet.is-dragging .mob-services-sheet__handle {
  background: var(--t-dark-muted);
  transform: scaleX(0.85);
}

/* Sheet heading */
.mob-services-sheet__heading {
  padding: 0 var(--sp-md) var(--sp-sm);
  padding-right: calc(var(--sp-md) + var(--btn-min-touch));
  font-family: var(--f-display);
  font-size: var(--fs-display-sm);
  letter-spacing: var(--ls-display);
  color: var(--t-dark-primary);
  line-height: 1;
  border-bottom: var(--border-dark);
  margin-bottom: var(--sp-md);
}

.mob-services-sheet__close {
  position: absolute;
  top: var(--sp-lg);
  right: var(--sp-sm);
  width: var(--btn-min-touch);
  height: var(--btn-min-touch);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--t-dark-muted);
  cursor: none;
  -webkit-tap-highlight-color: transparent;
  transition: color var(--dur-fast) var(--ease-smooth),
              transform var(--dur-fast) var(--ease-spring);
}

.mob-services-sheet__close:active {
  transform: scale(0.88);
  color: var(--t-dark-secondary);
}

/* Service tiles grid */
.mob-services-sheet__grid {
  padding: 0 var(--sp-md) var(--sp-xl);
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-sm);
  overflow-y: auto;
  max-height: calc(80vh - var(--mob-sheet-header-h));
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

/* 7th tile centred — same as form tiles pattern */
.mob-service-tile:last-child:nth-child(odd) {
  grid-column: 1 / -1;
  max-width: 50%;
  margin: 0 auto;
  width: 100%;
}

/* Individual service tile */
.mob-service-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: var(--sp-xs);
  padding: var(--sp-md) var(--sp-sm);
  background: var(--c-forest);
  border: var(--border-dark);
  border-radius: var(--r-md);
  text-decoration: none;
  cursor: none;
  min-height: 80px;
  -webkit-tap-highlight-color: transparent;
  transition:
    transform    var(--dur-fast) var(--ease-spring),
    border-color var(--dur-fast) var(--ease-smooth),
    background   var(--dur-fast) var(--ease-smooth);
}

.mob-service-tile:active {
  transform: scale(0.96);
  border-color: var(--c-border-ochre);
  background: var(--c-ochre-glow);
}

.mob-service-tile svg {
  width: var(--form-tile-icon);
  height: var(--form-tile-icon);
  color: var(--c-green-hi);
  flex-shrink: 0;
}

.mob-service-tile span {
  font-family: var(--f-display);
  font-size: var(--fs-display-xs);
  letter-spacing: var(--ls-display);
  color: var(--t-dark-primary);
  line-height: var(--lh-heading);
}

/* Backdrop behind the sheet */
.mob-services-backdrop {
  position: fixed;
  inset: 0;
  bottom: var(--mob-nav-height);
  background: var(--c-overlay-mid);
  z-index: var(--z-modal-bg);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-smooth);
}

.mob-services-backdrop.is-open {
  opacity: 1;
  pointer-events: all;
}

@media (min-width: 780px) {
  .mob-services-backdrop {
    display: none;
  }
}


/* ============================================================
   UNIT 1.10 — MOBILE CTA BAR + STICKY CALCULATOR RESULT BAR
   The two most conversion-critical components on mobile.

   MOBILE CTA BAR:
   Always present below 780px. Every page. Every scroll.
   Sits above the bottom nav bar at bottom: var(--mob-nav-height).
   Left: phone call. Right: get funded. Split exactly 50/50.
   Both zones full-height tap targets — never smaller than 56px.
   Never hidden by page content. Only hidden by: form overlay,
   mobile nav overlay. Never by any other element.

   STICKY CALC RESULT BAR:
   Appears on first calculator interaction.
   Floats above both the CTA bar and bottom nav.
   Shows the primary figure + period + a CTA link.
   Slides up via translateY spring — native app feel.
   Tapping the bar scrolls to the inline result section.
   ============================================================ */

/* ----------------------------------------------------------
   MOBILE CTA BAR
   Hidden above 780px — desktop nav handles conversion there.
   Position: fixed. Bottom: mob-nav-height (sits above bottom nav).
   Height: mob-cta-height (56px — full touch target).
   background: midnight. Border-top: border-dark.
   Left half: phone CTA. Right half: primary button.
   The divider between them is a single border-right on the
   phone side — one element, no extra DOM nodes.
   z-index: var(--z-bar) — same level as bottom nav.
   Body padding already accounts for both bars via
   the .mob-nav-active class set in unit 1.2.
---------------------------------------------------------- */

.mob-cta-bar {
  display: none;
}

@media (max-width: 779px) {
  .mob-cta-bar {
    display: flex;
    align-items: stretch;
    position: fixed;
    bottom: var(--mob-nav-height);
    left: 0;
    right: 0;
    height: var(--mob-cta-height);
    z-index: var(--z-bar);
    background: var(--c-midnight);
    border-top: var(--border-mid);
    overflow: hidden;
  }

  /* Hidden state — slides down below bottom nav */
  .mob-cta-bar.is-hidden {
    transform: translateY(100%);
    pointer-events: none;
  }

  /* When form overlay is open — bar hides */
  body.form-open .mob-cta-bar {
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dur-fast) var(--ease-smooth);
  }

  /* PHONE HALF — left 50% */
  .mob-cta-bar__phone {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-xs);
    flex: 1;
    text-decoration: none;
    cursor: none;
    border-right: var(--border-dark);
    padding: 0 var(--sp-sm);
    -webkit-tap-highlight-color: transparent;
    transition:
      background var(--dur-instant) var(--ease-smooth),
      opacity    var(--dur-instant) var(--ease-smooth);
  }

  .mob-cta-bar__phone:active {
    background: var(--c-ochre-glow);
  }

  .mob-cta-bar__phone-icon {
    width: var(--nav-phone-icon);
    height: var(--nav-phone-icon);
    color: var(--c-ochre);
    flex-shrink: 0;
  }

  .mob-cta-bar__phone-number {
    font-family: var(--f-body);
    font-weight: 600;
    font-size: var(--fs-body-sm);
    letter-spacing: var(--ls-phone);
    color: var(--c-ochre);
    white-space: nowrap;
  }

  /* CTA HALF — right 50% */
  .mob-cta-bar__cta {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1;
    background: var(--c-ochre);
    cursor: none;
    border: none;
    font-family: var(--f-body);
    font-weight: 700;
    font-size: var(--fs-body-sm);
    letter-spacing: var(--ls-button);
    color: var(--c-midnight);
    -webkit-tap-highlight-color: transparent;
    transition:
      background var(--dur-instant) var(--ease-smooth),
      transform  var(--dur-instant) var(--ease-smooth);
    position: relative;
    overflow: hidden;
  }

  /* Shimmer on the CTA half — same as button shimmer */
  .mob-cta-bar__cta::before {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(
      105deg,
      transparent 20%,
      var(--c-shimmer-light) 50%,
      transparent 80%
    );
    transform: translateX(-110%);
    animation: mob-cta-shimmer 3s var(--ease-smooth) infinite;
    animation-delay: var(--dur-xxslow);
  }

  @keyframes mob-cta-shimmer {
    0%, 70% { transform: translateX(-110%); }
    85%      { transform: translateX(110%); }
    100%     { transform: translateX(110%); }
  }

  .mob-cta-bar__cta:active {
    background: var(--c-ochre-deep);
    transform: scale(0.98);
  }

  .mob-cta-bar__cta-text {
    position: relative;
    z-index: 1;
  }
}


/* ----------------------------------------------------------
   STICKY CALCULATOR RESULT BAR — MOBILE
   Floats above the CTA bar and bottom nav combined.
   bottom: calc(var(--mob-nav-height) + var(--mob-cta-height))
   Only appears below 780px.
   Only appears after first calculator interaction.
   JS adds .is-visible to slide it into view.
   Tapping the bar: smooth scrolls to the inline result section.
   Contains: primary result figure + period + a tap-to-scroll cue.
   A subtle border-top in ochre — matches the result card system.
   The bar itself is NOT a CTA button — the CTA bar below handles
   the conversion. This bar keeps the calculated number visible
   so the user's investment in adjusting sliders is never lost.
   Design: Forest bg. Ochre strong top border. Compact.
   Left: result figure + period. Right: scroll cue arrow.
   On pages without a calculator: bar never appears.
   z-index: var(--z-sticky) — below the CTA and bottom nav bars.
---------------------------------------------------------- */

@media (max-width: 779px) {
  .calc-sticky-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-sm);
    position: fixed;
    bottom: calc(var(--mob-nav-height) + var(--mob-cta-height));
    left: 0;
    right: 0;
    z-index: var(--z-sticky);
    background: var(--c-forest);
    border-top: var(--border-ochre-strong);
    padding: var(--sp-xs) var(--sp-md);
    transform: translateY(100%);
    transition: transform var(--dur-slow) var(--ease-spring);
    cursor: none;
    -webkit-tap-highlight-color: transparent;
  }

  .calc-sticky-bar.is-visible {
    transform: translateY(0);
  }

  /* When form overlay open — bar hides */
  body.form-open .calc-sticky-bar {
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dur-fast) var(--ease-smooth);
  }

  /* Left: result display */
  .calc-sticky-bar__result {
    display: flex;
    flex-direction: column;
    gap: var(--gap-micro);
    flex: 1;
    min-width: 0;
  }

  .calc-sticky-bar__label {
    font-family: var(--f-body);
    font-weight: 600;
    font-size: var(--fs-eyebrow);
    letter-spacing: var(--ls-eyebrow);
    text-transform: uppercase;
    color: var(--t-dark-muted);
    line-height: 1;
  }

  /* The primary figure — same Bebas Neue system */
  .calc-sticky-bar__figure {
    font-family: var(--f-display);
    font-size: var(--fs-display-md);
    letter-spacing: var(--ls-display);
    color: var(--c-ochre);
    line-height: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: opacity var(--dur-fast) var(--ease-smooth);
  }

  .calc-sticky-bar__figure.is-updating {
    opacity: 0.5;
  }

  .calc-sticky-bar__period {
    font-family: var(--f-body);
    font-weight: 300;
    font-size: var(--fs-body-xs);
    color: var(--t-dark-muted);
    line-height: 1;
  }

  /* Right: scroll cue — animated arrow pointing down */
  .calc-sticky-bar__cue {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-2xs);
    flex-shrink: 0;
  }

  .calc-sticky-bar__cue-text {
    font-family: var(--f-body);
    font-weight: 600;
    font-size: var(--fs-eyebrow);
    letter-spacing: var(--ls-eyebrow);
    text-transform: uppercase;
    color: var(--t-dark-muted);
    white-space: nowrap;
  }

  .calc-sticky-bar__cue-arrow {
    width: var(--nav-phone-icon);
    height: var(--nav-phone-icon);
    color: var(--t-dark-muted);
    animation: cue-bounce 2s var(--ease-in-out) infinite;
    flex-shrink: 0;
  }

  @keyframes cue-bounce {
    0%, 100% { transform: translateY(0); }
    50%       { transform: translateY(var(--cue-bounce-travel)); }
  }

  /* Active tap state — whole bar depresses */
  .calc-sticky-bar:active {
    background: var(--c-midnight);
  }
}

/* Desktop — this bar never appears */
@media (min-width: 780px) {
  .calc-sticky-bar {
    display: none;
  }
}


/* ----------------------------------------------------------
   BODY PADDING MANAGEMENT — MOBILE BARS
   When all three bars are active (bottom nav + CTA bar +
   sticky calc bar), the body needs enough bottom padding
   to ensure no page content is permanently hidden behind them.
   The .mob-nav-active class (set in unit 1.2) handles the
   base padding for the bottom nav.
   These classes stack on top of that for the additional bars.
   JS applies .has-cta-bar and .has-calc-bar on the body
   when each bar becomes visible.
   The padding uses calc() to combine the bar heights precisely.
   On desktop: no padding — orbital nav doesn't affect flow.
---------------------------------------------------------- */

@media (max-width: 779px) {
  body.has-cta-bar {
    padding-bottom: calc(var(--mob-nav-height) + var(--mob-cta-height));
  }

  body.has-cta-bar.has-calc-bar {
    padding-bottom: calc(
      var(--mob-nav-height) +
      var(--mob-cta-height) +
      var(--mob-calc-bar-h)
    );
  }
}

/* ----------------------------------------------------------
   EXIT INTENT MODAL
   Desktop only. Once per session. Mouse toward browser chrome.
   clientY < 20 triggers via JS.
   Overlay: rgba overlay-heavy fades in.
   Modal: spring entrance from scale(0.90) translateY(var(--modal-entrance-y)).
   2-field form: name + phone. Primary CTA fires form overlay.
   On submit success: form replaces with confirmation.
   Never shown on mobile. Never shown more than once.
   z-index: var(--z-overlay) — above everything except cursor.
   ---------------------------------------------------------- */

.exit-modal-overlay {
  display: none;
}

@media (min-width: 780px) {
  .exit-modal-overlay {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    inset: 0;
    z-index: var(--z-overlay);
    padding: var(--sp-xl);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity var(--dur-base) var(--ease-smooth),
      visibility 0s linear var(--dur-base);
  }

  .exit-modal-overlay.is-open {
    opacity: 1;
    visibility: visible;
    pointer-events: all;
    transition: opacity var(--dur-base) var(--ease-smooth),
      visibility 0s linear 0s;
  }

  .exit-modal-overlay__bg {
    position: absolute;
    inset: 0;
    background: var(--c-overlay-heavy);
  }

  .exit-modal {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 480px;
    background: var(--c-midnight);
    border: var(--border-ochre-strong);
    border-radius: var(--r-xl);
    padding: var(--sp-xl) var(--sp-xl) var(--sp-lg);
    box-shadow: var(--shadow-xl), var(--shadow-ochre);
    transform: scale(0.90) translateY(var(--modal-entrance-y));
    transition: transform var(--dur-slow) var(--ease-spring);
  }

  .exit-modal-overlay.is-open .exit-modal {
    transform: scale(1) translateY(0);
  }

  .exit-modal__close {
    position: absolute;
    top: var(--sp-md);
    right: var(--sp-md);
    width: var(--btn-min-touch);
    height: var(--btn-min-touch);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--t-dark-muted);
    cursor: none;
    border-radius: var(--r-full);
    background: var(--t-dark-hairline);
    border: var(--border-dark);
    transition:
      color      var(--dur-fast) var(--ease-smooth),
      background var(--dur-fast) var(--ease-smooth),
      transform  var(--dur-fast) var(--ease-spring);
  }

  .exit-modal__close:hover {
    color: var(--c-error);
    background: var(--c-error-glow);
    transform: rotate(90deg) scale(1.1);
  }

  .exit-modal__close:active {
    transform: rotate(90deg) scale(0.92);
  }

  .exit-modal__eyebrow {
    font-family: var(--f-body);
    font-weight: 600;
    font-size: var(--fs-eyebrow);
    letter-spacing: var(--ls-eyebrow);
    text-transform: uppercase;
    color: var(--c-ochre);
    margin-bottom: var(--sp-xs);
  }

  .exit-modal__headline {
    font-family: var(--f-display);
    font-size: var(--fs-display-lg);
    letter-spacing: var(--ls-display);
    color: var(--t-dark-primary);
    line-height: var(--lh-heading);
    margin-bottom: var(--sp-lg);
  }

  .exit-modal__fields {
    display: flex;
    flex-direction: column;
    gap: var(--sp-sm);
    margin-bottom: var(--sp-md);
  }

  .exit-modal__cta {
    width: 100%;
  }

  .exit-modal__privacy {
    font-family: var(--f-body);
    font-weight: 300;
    font-size: var(--fs-body-xs);
    color: var(--t-dark-ghost);
    text-align: center;
    margin-top: var(--sp-sm);
  }

  /* Success state — replaces form content */
  .exit-modal__success {
    text-align: center;
    padding: var(--sp-md) 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-md);
  }

  .exit-modal__success-headline {
    font-family: var(--f-display);
    font-size: var(--fs-display-md);
    letter-spacing: var(--ls-display);
    color: var(--c-green-hi);
    line-height: var(--lh-heading);
  }

  .exit-modal__success-sub {
    font-family: var(--f-body);
    font-size: var(--fs-body-md);
    color: var(--t-dark-secondary);
    line-height: var(--lh-body);
  }

  .exit-modal__success-phone {
    font-family: var(--f-display);
    font-size: var(--fs-display-sm);
    letter-spacing: var(--ls-display);
    color: var(--c-ochre);
    line-height: 1;
  }
}


/* ============================================================
   UNIT 1.11 — KEYFRAMES + PREFERS-REDUCED-MOTION
   The final unit. The global kill switch.

   PART A — ADDITIONAL KEYFRAMES
   Keyframes not already defined inline in component units.
   All animations: transform and opacity only.
   No width, height, top, left, padding, margin, background
   or any layout-triggering property in any keyframe loop.

   PART B — PREFERS-REDUCED-MOTION
   One block. Covers every animation, every transition,
   every parallax, every scroll behaviour.
   Duration collapses to 0.01ms — animations still complete,
   they just complete instantly. No broken JS state machines.
   will-change removed — no wasted GPU memory.
   cursor: auto restored — custom cursor JS also checks
   this media query and exits immediately if matched.
   ============================================================ */

/* ----------------------------------------------------------
   PART A — ADDITIONAL KEYFRAMES
   Page-level animations: fadeIn, scaleIn for modals/overlays.
   Scroll reveal: handled via CSS classes in unit 1.3.
   These complete the animation vocabulary of the site.
   Every property animated: transform or opacity only.
---------------------------------------------------------- */

/* General fade — opacity only, no transform */
@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes fade-out {
  from { opacity: 1; }
  to   { opacity: 0; }
}

/* Scale + fade — for modal/overlay entrances */
@keyframes scale-in-spring {
  0%   { opacity: 0; transform: scale(0.88); }
  60%  { opacity: 1; transform: scale(1.03); }
  100% { opacity: 1; transform: scale(1); }
}

@keyframes scale-out {
  from { opacity: 1; transform: scale(1);    }
  to   { opacity: 0; transform: scale(0.94); }
}

/* Slide up — for bottom sheets and sticky bars entering */
@keyframes slide-up {
  from { opacity: 0; transform: translateY(var(--ty-reveal-md)); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Slide down — for elements entering from above */
@keyframes slide-down {
  from { opacity: 0; transform: translateY(calc(-1 * var(--ty-reveal-md))); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Reveal from left — used for left-column scroll reveals */
@keyframes reveal-left {
  from { opacity: 0; transform: translateX(calc(-1 * var(--reveal-x))); }
  to   { opacity: 1; transform: translateX(0); }
}

/* Reveal from right — used for right-column scroll reveals */
@keyframes reveal-right {
  from { opacity: 0; transform: translateX(var(--reveal-x)); }
  to   { opacity: 1; transform: translateX(0); }
}

/* Reveal scale — used for stat cards, feature highlights */
@keyframes reveal-scale {
  from { opacity: 0; transform: scale(var(--reveal-scale)); }
  to   { opacity: 1; transform: scale(1); }
}

/* Reveal up — base scroll reveal, used by .reveal class in unit 1.3 */
@keyframes reveal-up {
  from { opacity: 0; transform: translateY(var(--reveal-y)); }
  to   { opacity: 1; transform: translateY(0); }
}

/* W mark SVG draw-on — stroke-dashoffset animation
   Applied to the SVG paths via JS adding .is-drawn class.
   The stroke-dasharray and stroke-dashoffset are set
   dynamically by JS based on the path's getTotalLength().
   This keyframe handles the opacity reveal only.
   The stroke-dashoffset transition is inline on the element. */
@keyframes mark-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Spin — loading spinner on buttons */
@keyframes spin {
  to { transform: rotate(360deg); }
}

/* Count up — stat counter digit entrance */
@keyframes count-digit-in {
  from { opacity: 0; transform: translateY(var(--ty-reveal-sm)); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Count suffix fade — the + or $M+ after the number */
@keyframes count-suffix-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Page transition — fade out on link click */
@keyframes page-exit {
  from { opacity: 1; }
  to   { opacity: 0; }
}

/* Page enter — fade in on page load */
@keyframes page-enter {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Checkmark draw — SVG stroke-dashoffset for form validation
   The path's stroke-dasharray is set equal to its length by JS.
   This keyframe animates stroke-dashoffset from length to 0.
   The actual values are set inline by JS — this is the template. */
@keyframes check-draw {
  from { stroke-dashoffset: 1; }
  to   { stroke-dashoffset: 0; }
}

/* ----------------------------------------------------------
   PART B — PREFERS-REDUCED-MOTION KILL SWITCH
   This block is the final rule in the entire file.
   It overrides every animation and transition everywhere.
   Duration: 0.01ms — not 0ms. At 0ms some JS timers break
   because they listen for transitionend/animationend events
   which never fire. At 0.01ms they fire almost immediately.
   
   Scroll-behaviour: auto — no smooth scrolling.
   Parallax: transform locked to translateY(0) always.
   Custom cursor: exits immediately if this media query matches —
   checked in cursor.js before any elements are created.
   
   This block deliberately does NOT use !important on most rules.
   Instead it targets specific animation classes and properties.
   Only transitions and animations get the 0.01ms treatment.
   Static transforms (like translateY on positioned elements)
   are left alone — they're layout, not animation.
   
   Exception: scroll-behavior uses !important because it's set
   on html and inherited — the override must win specificity.
---------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {

  /* Global animation + transition collapse */
  *,
  *::before,
  *::after {
    animation-duration:        0.01ms !important; /* intentional — near-zero, not 0, so JS animationend events still fire */
    animation-iteration-count: 1      !important;
    transition-duration:       0.01ms !important; /* intentional — near-zero, not 0, so JS transitionend events still fire */
    scroll-behavior:           auto   !important;
  }

  /* Scroll behaviour on html */
  html {
    scroll-behavior: auto !important;
  }

  /* Kill all named animations explicitly */
  .btn--loading::after,
  .calc-sticky-bar__cue-arrow,
  .mob-nav__call-glow,
  .calc-result-live__dot,
  .mob-cta-bar__cta::before,
  .form-progress__fill::after,
  .site-nav.is-scrolled .site-nav__pill,
  .form-nav__continue.is-ready,
  .calc-cta-btn.is-ready {
    animation: none !important;
  }

  /* Kill all transitions on interactive elements */
  .btn,
  .card,
  .card--product,
  .card--testimonial,
  .card--trust,
  .card--result,
  .nav-link,
  .nav-dropdown__link,
  .form-tile,
  .form-pill,
  .form-amount-pill,
  .calc-term-pill,
  .mob-nav__tab,
  .mob-service-tile,
  .mob-cta-bar__phone,
  .mob-cta-bar__cta {
    transition: none !important;
  }

  /* Kill will-change — no wasted GPU memory */
  * {
    will-change: auto !important;
  }

  /* Kill scroll reveals — show content immediately */
  .reveal,
  .reveal--left,
  .reveal--right,
  .reveal--scale,
  .reveal--fade {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  /* Kill hero load sequence — show immediately */
  .load-eyebrow,
  .load-headline,
  .load-sub,
  .load-cta,
  .load-trust,
  .load-stats,
  .load-visual {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  body.is-loaded .load-eyebrow,
  body.is-loaded .load-headline,
  body.is-loaded .load-sub,
  body.is-loaded .load-cta,
  body.is-loaded .load-trust,
  body.is-loaded .load-stats,
  body.is-loaded .load-visual {
    opacity: 1 !important;
    transform: none !important;
    transition-delay: 0.01ms !important; /* intentional — near-zero matches duration */
  }

  /* Kill hero word curtain reveal — show immediately */
  .t-hero-inner {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  /* Kill bottom sheet and form overlay spring entrances */
  .form-sheet,
  .form-overlay__card,
  .mob-services-sheet,
  .calc-sticky-bar,
  .mob-cta-bar {
    transition: none !important;
    transform: none !important;
  }

  /* Kill nav dropdown transition */
  .nav-dropdown {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  /* Kill result panel entrance */
  .calc-result-panel {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  /* Kill ticker animation — show result immediately */
  .calc-ticker__current,
  .calc-ticker__next {
    animation: none !important;
    transition: none !important;
  }

  /* Kill stat counter animation — numbers appear instantly */
  .stat-number {
    transition: none !important;
  }

  /* Kill form progress bar transition */
  .form-progress__fill {
    transition: none !important;
  }

  /* Kill Smart Matcher confidence bar fill */
  .calc-match-fill {
    transition: none !important;
  }

  /* Kill card diagonal sweep */
  .card::after {
    display: none !important;
  }

  /* Kill testimonial border draw */
  .card--testimonial::before,
  .card--testimonial:nth-child(2)::before,
  .card--testimonial:nth-child(3)::before {
    transform: scaleX(1) !important;
    transition: none !important;
  }

  /* Kill steps timeline draw + card reveal */
  .steps-grid::before {
    height: 100% !important;
    width: 80% !important;
    transition: none !important;
  }

  .step-card {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  /* Kill exit modal entrance */
  .exit-modal {
    transform: none !important;
    transition: none !important;
  }

  /* Kill counter update pulse */
  .stat-number.is-updating,
  .calc-result-amount.is-updating,
  .calc-result-product.is-updating,
  .calc-sticky-bar__figure.is-updating,
  .form-amount-value.is-updating {
    transform: none !important;
  }

  /* Kill mobile nav liquid indicator spring */
  .mob-nav__indicator {
    transition: none !important;
  }

  /* Kill parallax — W mark stays static */
  .hero-mark-parallax {
    transform: none !important;
  }

  /* Restore default cursor — custom cursor JS also exits early */
  body {
    cursor: auto !important;
  }

  button {
    cursor: pointer !important;
  }

  a {
    cursor: pointer !important;
  }

}

/* ----------------------------------------------------------
   HERO W-MARK — desktop draw + ambient animations
   1. One-time stroke-dashoffset draw on page load (~1.2 s).
      Ochre W draws left→right, then green V draws up from valley.
   2. Ambient: subtle opacity pulse on full mark (4 s),
      barely-visible drop-shadow breathe on green V (5.5 s).
      Deliberately out-of-sync so they never align.
---------------------------------------------------------- */

/* --- Stroke draw setup (desktop only) --- */
@media (min-width: 780px) {
  .hero-w-ochre {
    stroke-dasharray: 2500;
    stroke-dashoffset: 2500;
  }
  .hero-w-green {
    stroke-dasharray: 1200;
    stroke-dashoffset: 1200;
  }

  /* Draw plays once on load, then ambient loops take over */
  body.is-loaded .hero-w-ochre {
    animation: w-draw-ochre 0.75s ease-out 0.2s both;
  }
  body.is-loaded .hero-w-green {
    animation:
      w-draw-green 0.55s ease-out 0.65s both,
      w-green-glow 5.5s ease-in-out 1.8s infinite;
  }
  body.is-loaded .hero-visual .hero-w-mark {
    animation: w-mark-pulse 4s ease-in-out 1.5s infinite;
  }
}

/* --- Draw keyframes --- */
@keyframes w-draw-ochre {
  from { stroke-dashoffset: 2500; }
  to   { stroke-dashoffset: 0; }
}
@keyframes w-draw-green {
  from { stroke-dashoffset: 1200; }
  to   { stroke-dashoffset: 0; }
}

/* --- Ambient keyframes --- */
@keyframes w-mark-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.82; }
}
@keyframes w-green-glow {
  0%, 100% { filter: drop-shadow(0 0 0 rgba(30,132,73,0)); }
  50%      { filter: drop-shadow(0 0 8px rgba(30,132,73,0.3)); }
}

/* ----------------------------------------------------------
   SERVICE PAGE HERO — W BRAND MARK
   Absolutely positioned within hero <section>.
   Desktop ≥780: right-aligned, parallax via JS, subtle.
   Mobile  <780: watermark behind content, breathing + glow.
---------------------------------------------------------- */
.hero-w-brand {
  position: absolute;
  pointer-events: none;
  z-index: 0;
}
.hero-w-brand + .container,
.hero-w-brand ~ .container {
  position: relative;
  z-index: 1;
}

@media (min-width: 780px) {
  .hero-w-brand {
    top: 50%;
    right: 6%;
    width: clamp(420px, 36vw, 580px);
    transform: translateY(-50%);
    opacity: 0.4;
  }
  .hero-w-brand .hero-mark-glow { display: none; }

  /* Looping animation for W mark on all service pages */
  body.is-loaded .hero-w-brand .hero-w-mark {
    animation: w-brand-breathe 4s ease-in-out infinite;
  }
  body.is-loaded .hero-w-brand .hero-w-green {
    animation: w-brand-green-glow 5.5s ease-in-out 1.5s infinite;
  }
  body.is-loaded .hero-w-brand .hero-w-ochre {
    animation: w-brand-ochre-glow 6s ease-in-out 0.8s infinite;
  }

  /* Equipment finance — full-visibility W mark like index hero */
  .hero-w-brand--full {
    opacity: 1;
  }
  .hero-w-brand--full .hero-mark-glow { display: block; }
  .hero-w-brand--full .hero-w-ochre {
    stroke-dasharray: 2500;
    stroke-dashoffset: 2500;
  }
  .hero-w-brand--full .hero-w-green {
    stroke-dasharray: 1200;
    stroke-dashoffset: 1200;
  }
  body.is-loaded .hero-w-brand--full .hero-w-ochre {
    animation: w-draw-ochre 0.75s ease-out 0.2s both,
              w-brand-ochre-glow 6s ease-in-out 1.5s infinite;
  }
  body.is-loaded .hero-w-brand--full .hero-w-green {
    animation:
      w-draw-green 0.55s ease-out 0.65s both,
      w-green-glow 5.5s ease-in-out 1.8s infinite;
  }
  body.is-loaded .hero-w-brand--full .hero-w-mark {
    animation: w-mark-pulse 4s ease-in-out 1.5s infinite;
  }
}

@media (max-width: 779px) {
  .hero-w-brand {
    bottom: 10%;
    right: -10%;
    width: 55%;
    opacity: 0.10;
  }
  .hero-w-brand .hero-mark-glow { display: none; }
  .hero-w-brand .hero-w-mark {
    animation: w-brand-breathe 4s ease-in-out infinite;
  }
  .hero-w-brand .hero-w-green {
    animation: w-brand-green-glow 5.5s ease-in-out 1.5s infinite;
  }
}

@keyframes w-brand-breathe {
  0%, 100% { opacity: 0.82; }
  50%      { opacity: 1; }
}
@keyframes w-brand-green-glow {
  0%, 100% { filter: drop-shadow(0 0 0 rgba(30,132,73,0)); }
  50%      { filter: drop-shadow(0 0 8px rgba(30,132,73,0.3)); }
}
@keyframes w-brand-ochre-glow {
  0%, 100% { filter: drop-shadow(0 0 0 rgba(232,160,64,0)); }
  50%      { filter: drop-shadow(0 0 6px rgba(232,160,64,0.25)); }
}

/* --- Accessibility --- */
@media (prefers-reduced-motion: reduce) {
  .hero-w-mark   { animation: none !important; }
  .hero-w-ochre  { animation: none !important; stroke-dashoffset: 0 !important; }
  .hero-w-green  { animation: none !important; stroke-dashoffset: 0 !important; }
  .mobile-w-mark  { animation: none !important; }
  .mobile-w-green { animation: none !important; }
  .hero-w-brand .hero-w-mark  { animation: none !important; }
  .hero-w-brand .hero-w-ochre { animation: none !important; stroke-dashoffset: 0 !important; }
  .hero-w-brand .hero-w-green { animation: none !important; }
}

/* ============================================================
   END OF design-system.css
   Units 1.1 through 1.11 complete.
   270 CSS variables. Zero hardcoded values outside :root.
   Every component, every state, every breakpoint.
   wafinancehub.com.au · ABN 80 571 725 659
   ============================================================ */

