/* ==========================================================================
   Cognexa Website — "The Automation Line"
   Shared stylesheet. Design tokens mirror the Cognexa Dashboard.
   Use variables, never raw hex in page markup.

   CONTRACT NOTE (motion): CSS NEVER pre-hides content. All reveal from-states
   are created at runtime by GSAP (scroll.js uses gsap.from patterns). With JS
   disabled, or with .no-3d / reduced motion, every element below is fully
   visible and readable by default.

   Layering: fixed #scene-canvas at --z-canvas (0), page content at
   --z-content (1), nav at --z-nav (100), overlays (skip link, mobile menu)
   at/near --z-overlay (200).
   ========================================================================== */

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

/* --------------------------------------------------------------------------
   Self-hosted web fonts (perf fix — removes fonts.googleapis.com and
   fonts.gstatic.com from the critical path).
   Ported 1:1 from the Google Fonts css2 response for
   Inter:wght@400;500;600;700 + Space+Grotesk:wght@500;600;700 (latin and
   latin-ext subsets only), preserving each block's exact unicode-range.
   Google serves ONE variable woff2 per family+subset shared by every weight
   (identical gstatic URLs across weights), so all weight blocks of a subset
   reference the same local file — the browser fetches it once and instances
   the requested weight, exactly as the hosted CSS behaved.
   Files live in ../assets/fonts/ (paths relative to this stylesheet).
   -------------------------------------------------------------------------- */

/* Inter latin-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../assets/fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Inter latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../assets/fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Inter latin-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../assets/fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Inter latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../assets/fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Inter latin-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../assets/fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Inter latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../assets/fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Inter latin-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../assets/fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Inter latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../assets/fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Space Grotesk latin-ext */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../assets/fonts/space-grotesk-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Space Grotesk latin */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../assets/fonts/space-grotesk-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Space Grotesk latin-ext */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../assets/fonts/space-grotesk-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Space Grotesk latin */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../assets/fonts/space-grotesk-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Space Grotesk latin-ext */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../assets/fonts/space-grotesk-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Space Grotesk latin */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../assets/fonts/space-grotesk-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* --------------------------------------------------------------------------
   CLS fix — metric-compatible fallback fonts.
   Inter and Space Grotesk load from Google Fonts with display=swap; the swap
   from the default fallback reflows text and was the main source of mobile
   layout shift. These local-Arial overrides use published metric adjustments
   so fallback text occupies (almost) the same space as the web fonts, making
   the swap visually near-lossless. They are inserted into the font stacks
   below, immediately after the web-font names.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: 'Inter Fallback';
  src: local('Arial');
  size-adjust: 107%;
  ascent-override: 90%;
  descent-override: 22.5%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Space Grotesk Fallback';
  src: local('Arial');
  size-adjust: 106%;
  ascent-override: 93%;
  descent-override: 27.5%;
  line-gap-override: 0%;
}

:root {
  /* Surfaces */
  --bg-primary: #0f1117;
  --bg-secondary: #1a1d27;
  --bg-card: #222533;
  --bg-hover: #2a2e3f;
  --border-color: #2e3347;

  /* Text */
  --text-primary: #e8eaf0;
  --text-secondary: #8b8fa3;
  --text-muted: #5a5e72;

  /* Accents */
  --accent-blue: #4a7cff;
  --accent-blue-hover: #3a6aee;
  --accent-green: #34d399;
  --accent-orange: #fb923c;
  --accent-red: #f87171;
  --accent-purple: #a78bfa;

  /* Shape & motion */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --shadow-card: 0 2px 8px rgba(0, 0, 0, 0.3);
  --transition-fast: 150ms ease;

  /* Layout */
  --nav-height: 64px;
  --content-max: 1120px;

  /* Type */
  --font-body: 'Inter', 'Inter Fallback', system-ui, -apple-system, sans-serif;
  --font-display: 'Space Grotesk', 'Space Grotesk Fallback', var(--font-body);

  /* Glows */
  --glow-blue: 0 0 40px rgba(74, 124, 255, 0.35);
  --glow-green: 0 0 40px rgba(52, 211, 153, 0.3);
  --glow-purple: 0 0 40px rgba(167, 139, 250, 0.3);

  /* Rhythm & layers */
  --section-pad: clamp(80px, 12vh, 140px);
  --z-canvas: 0;
  --z-content: 1;
  --z-nav: 100;
  --z-overlay: 200;

  /* Accent system — scroll.js swaps [data-accent] on <html>; stations carry
     their own data-accent so each section is correctly tinted even w/o JS. */
  --accent-current: var(--accent-blue);
  --accent-soft: rgba(74, 124, 255, 0.25);
  --glow-current: var(--glow-blue);
}

[data-accent="blue"] {
  --accent-current: var(--accent-blue);
  --accent-soft: rgba(74, 124, 255, 0.25);
  --glow-current: var(--glow-blue);
}
[data-accent="green"] {
  --accent-current: var(--accent-green);
  --accent-soft: rgba(52, 211, 153, 0.22);
  --glow-current: var(--glow-green);
}
[data-accent="purple"] {
  --accent-current: var(--accent-purple);
  --accent-soft: rgba(167, 139, 250, 0.22);
  --glow-current: var(--glow-purple);
}

/* ==========================================================================
   Base
   ========================================================================== */

html {
  scroll-behavior: smooth;
  color-scheme: dark;
  overflow-x: clip; /* huge display type / ghost numbers never cause page-level x-scroll */
}

body {
  font-family: var(--font-body);
  background-color: var(--bg-primary);
  color: var(--text-primary);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
  text-wrap: balance;
}

h1 { font-size: clamp(2.5rem, 7vw, 4.5rem); }
h2 { font-size: clamp(2rem, 5vw, 3.25rem); }
h3 { font-size: 1.25rem; }

p { max-width: 62ch; }

img { max-width: 100%; height: auto; display: block; }

a { color: var(--accent-blue); text-decoration: none; }
/* Hover keeps the AA-compliant resting blue (5.05:1); affordance via underline */
a:hover { color: var(--accent-blue); text-decoration: underline; }

button, input, textarea, select { font: inherit; color: inherit; }

a, button, .btn, .nav-toggle, label[for], summary { cursor: pointer; }

:focus-visible {
  outline: 2px solid var(--accent-blue);
  outline-offset: 3px;
}

::selection {
  background: var(--accent-current);
  color: var(--bg-primary);
}

/* Anchor targets land clear of the fixed nav */
section[id], article[id] { scroll-margin-top: calc(var(--nav-height) + 12px); }

main, .site-footer {
  position: relative;
  z-index: var(--z-content);
}

.container {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: 0 24px;
}

/* ==========================================================================
   Utilities
   ========================================================================== */

.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: fixed;
  top: 16px; left: 16px;
  z-index: var(--z-overlay);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 10px 20px;
  background: var(--accent-blue);
  color: var(--bg-primary);
  font-weight: 600;
  border-radius: var(--radius-sm);
  box-shadow: var(--glow-blue);
}
.skip-link:hover { color: var(--bg-primary); }
.skip-link:not(:focus):not(:focus-within) {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
  min-height: 0;
}

.eyebrow {
  display: block;
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent-current);
  transition: color 400ms ease;
  margin-bottom: 16px;
}

.section-sub {
  color: var(--text-secondary);
  font-size: 1.05rem;
  max-width: 46ch;
  margin-top: 14px;
}

/* Headings that sit directly over the live particle canvas keep a soft dark
   halo so bright particles passing behind never wash the text out (the canvas
   itself is never dimmed). */
.work h2,
.work .section-sub,
.contact h2,
.contact .section-sub,
.process h2 {
  text-shadow:
    0 2px 24px rgba(15, 17, 23, 0.95),
    0 0 10px rgba(15, 17, 23, 0.85);
}

/* Glass panel — used only where text sits over busy canvas areas.
   Solid fallback first; translucent + blur where supported. */
.glass,
.station-inner,
.process-step,
.metric {
  background: rgba(34, 37, 51, 0.92);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}

@supports ((backdrop-filter: blur(16px)) or (-webkit-backdrop-filter: blur(16px))) {
  .glass,
  .station-inner,
  .process-step,
  .metric {
    background: rgba(34, 37, 51, 0.55);
    -webkit-backdrop-filter: blur(16px) saturate(1.2);
    backdrop-filter: blur(16px) saturate(1.2);
  }
}

/* ==========================================================================
   Canvas layering + no-3d fallback
   ========================================================================== */

#scene-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: var(--z-canvas);
  pointer-events: none;
  display: block;
}

body.no-3d #scene-canvas { display: none; }

/* Gradient backdrop when the 3D scene is off (no WebGL, reduced motion)
   or JS never ran at all. */
body.no-3d,
body:not(.js-enabled) {
  background-color: var(--bg-primary);
}
/* Gradients live on a fixed pseudo-layer, not background-attachment: fixed,
   which defeats composited scrolling (and is buggy on iOS Safari). */
body.no-3d::before,
body:not(.js-enabled)::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(closest-side at 18% 12%, rgba(74, 124, 255, 0.08), transparent),
    radial-gradient(closest-side at 85% 38%, rgba(167, 139, 250, 0.08), transparent),
    radial-gradient(closest-side at 28% 88%, rgba(52, 211, 153, 0.06), transparent);
}

/* ==========================================================================
   Navigation
   ========================================================================== */

.site-nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--nav-height);
  background: rgba(15, 17, 23, 0.94);
  border-bottom: 1px solid var(--border-color);
  z-index: var(--z-nav);
}

@supports ((backdrop-filter: blur(12px)) or (-webkit-backdrop-filter: blur(12px))) {
  .site-nav {
    background: rgba(15, 17, 23, 0.72);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
  }
}

.site-nav .container {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

/* If the header has no inner .container, lay the header itself out */
.site-nav:not(:has(.container)) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 24px;
}

.nav-brand {
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--text-primary);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.nav-brand:hover { color: var(--accent-blue); }

/* Scroll progress bar — scroll.js writes --scroll-progress (0..1) on <html>.
   Driven by transform only; background recolors with the active accent. */
.nav-progress {
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: var(--accent-current);
  transform: scaleX(var(--scroll-progress, 0));
  transform-origin: 0 50%;
  transition: background-color 400ms ease;
  pointer-events: none;
}

/* Burger — mobile only, needs JS to work, so hidden until .js-enabled */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-primary);
  flex-shrink: 0;
}
.nav-toggle:hover { color: var(--accent-blue); border-color: var(--border-color); }
.nav-toggle svg { width: 24px; height: 24px; stroke: currentColor; }
body.nav-open .nav-toggle { color: var(--accent-blue); }

/* Nav links — shared */
#nav-menu ul { list-style: none; }
#nav-menu a:not(.btn) {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--text-secondary);
  font-size: 0.9rem;
  font-weight: 500;
  transition: color var(--transition-fast);
}
#nav-menu a:not(.btn):hover { color: var(--text-primary); }

/* --- Mobile (default, <900px) ------------------------------------------- */
body.js-enabled .nav-toggle { display: inline-flex; }

/* No JS on mobile: the toggle can't work — render the menu as a static
   wrapped row under the brand instead of hiding the primary nav. */
@media (max-width: 899.98px) {
  body:not(.js-enabled) .site-nav,
  body:not(.js-enabled) .site-nav:not(:has(.container)) {
    position: static;
    height: auto;
    flex-wrap: wrap;
    padding: 10px 24px;
  }
  body:not(.js-enabled) #nav-menu {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 20px;
    width: 100%;
    padding-bottom: 6px;
  }
}

body.js-enabled #nav-menu {
  position: fixed;
  top: var(--nav-height);
  left: 0; right: 0;
  z-index: var(--z-nav);
  max-height: calc(100vh - var(--nav-height));
  overflow-y: auto;
  padding: 12px 24px 24px;
  background: rgba(15, 17, 23, 0.96);
  border-bottom: 1px solid var(--border-color);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity 250ms ease, transform 250ms ease, visibility 0s linear 250ms;
}
@supports ((backdrop-filter: blur(16px)) or (-webkit-backdrop-filter: blur(16px))) {
  body.js-enabled #nav-menu {
    background: rgba(15, 17, 23, 0.85);
    -webkit-backdrop-filter: blur(16px);
    backdrop-filter: blur(16px);
  }
}
body.js-enabled.nav-open #nav-menu {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 250ms ease, transform 250ms ease;
}
body.js-enabled #nav-menu ul {
  display: flex;
  flex-direction: column;
}
body.js-enabled #nav-menu a:not(.btn) {
  display: flex;
  min-height: 48px;
  padding: 12px 8px;
  font-size: 1.05rem;
  border-bottom: 1px solid var(--border-color);
}
body.js-enabled #nav-menu li:last-child a:not(.btn) { border-bottom: 0; }
body.js-enabled #nav-menu .btn {
  width: 100%;
  justify-content: center;
  margin-top: 16px;
}

/* Nav CTA living outside the menu is hidden on small screens (menu carries one) */
@media (max-width: 639.98px) {
  .site-nav .container > .btn,
  .site-nav > .btn { display: none; }
}

/* --- Desktop (≥900px) ---------------------------------------------------- */
@media (min-width: 900px) {
  .nav-toggle,
  body.js-enabled .nav-toggle { display: none; }

  body:not(.js-enabled) #nav-menu,
  #nav-menu {
    display: flex;
    align-items: center;
    gap: 28px;
    position: static;
    max-height: none;
    overflow: visible;
    padding: 0;
    background: transparent;
    border: 0;
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  body.js-enabled #nav-menu {
    position: static;
    padding: 0;
    background: transparent;
    border: 0;
    opacity: 1;
    visibility: visible;
    transform: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  #nav-menu ul,
  body.js-enabled #nav-menu ul {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 28px;
  }
  body.js-enabled #nav-menu a:not(.btn) {
    display: inline-flex;
    min-height: 44px;
    padding: 0;
    font-size: 0.9rem;
    border-bottom: 0;
  }
  body.js-enabled #nav-menu .btn { width: auto; margin-top: 0; }
}

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 11px 22px;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast),
              border-color var(--transition-fast), box-shadow var(--transition-fast),
              transform var(--transition-fast);
}

/* Dark label on accent-blue: 5.0:1 vs 3.7:1 for white — AA compliant. */
.btn-primary {
  background: var(--accent-blue);
  color: var(--bg-primary);
}
/* Hover keeps the AA-passing #4a7cff bg (dark text 5.0:1); the hover cue is
   the lift + glow — #3a6aee would drop text contrast to 4.0:1. */
.btn-primary:hover,
.btn-primary:focus-visible {
  background: var(--accent-blue);
  color: var(--bg-primary);
  transform: translateY(-1px);
  box-shadow: var(--glow-blue);
}
.btn-primary:active { transform: translateY(0); box-shadow: none; }

.btn-ghost {
  background: transparent;
  color: var(--text-secondary);
  border-color: var(--border-color);
}
.btn-ghost:hover,
.btn-ghost:focus-visible {
  color: var(--text-primary);
  background: var(--bg-hover);
  border-color: var(--text-muted);
}

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: calc(var(--nav-height) + 48px) 0 120px;
}

.hero-inner {
  position: relative;
  z-index: var(--z-content);
  max-width: 860px;
  margin: 0 auto;
  padding: 0 24px;
}

.hero h1 {
  margin: 0 auto 24px;
  color: var(--text-primary);
}

.hero-accent {
  background: linear-gradient(92deg, var(--accent-blue) 10%, var(--accent-purple) 90%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .hero-accent { background: none; color: var(--accent-blue); }
}

.hero-sub {
  color: var(--text-secondary);
  font-size: clamp(1.05rem, 2vw, 1.25rem);
  /* 34.066em == 54ch in loaded Inter (ch = 0.63086em), but em does not change
     when the web font swaps in. With 54ch the fallback-font ch (~0.595em) made
     the shrink-to-fit .hero-inner grow ~38px on font load — the measured
     desktop CLS source. Same rendered width, no swap reflow. */
  max-width: 34.066em;
  margin: 0 auto 36px;
}

.hero-actions {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
}
.hero-actions .btn { padding: 13px 26px; font-size: 1rem; }

.hero-trust {
  margin-top: 20px;
  font-size: 0.85rem;
  color: var(--text-secondary);
  letter-spacing: 0.02em;
}

.scroll-cue {
  position: absolute;
  bottom: 28px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: var(--text-secondary);
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.18em;
}
.scroll-cue:hover { color: var(--text-primary); text-decoration: none; }
.scroll-cue svg {
  width: 18px;
  height: 18px;
  stroke: currentColor;
  animation: cue-bob 1.8s ease-in-out infinite;
}

@keyframes cue-bob {
  0%, 100% { transform: translateY(0); opacity: 0.9; }
  50%      { transform: translateY(6px); opacity: 0.45; }
}

/* ==========================================================================
   Stations (services)
   ========================================================================== */

.stations { position: relative; }

.station {
  position: relative;
  min-height: 150vh;
  padding: 0 clamp(24px, 5vw, 64px);
}

/* Sticky full-viewport stage that flex-centers the glass panel while its
   station scrolls past. No top:50% + translateY(-50%) trick — that transform
   also applies at the panel's natural flow position and drags it up into the
   previous section before the sticky range begins. */
.station-stage {
  position: sticky;
  top: 0;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* GSAP only ever animates the panel's CHILDREN — never the panel itself. */
.station-inner {
  max-width: 640px;
  padding: clamp(28px, 5vw, 48px);
}

/* Everything in the panel stacks above the ghost number */
.station-inner > * {
  position: relative;
  z-index: 1;
}

/* Ghost station numbers — huge outlined Space Grotesk behind the heading.
   scroll.js adds a y-parallax scrub tween; positioning here uses top/right
   only (no transform) so GSAP owns the transform channel. */
.station-ghost,
.station-num,
.ghost-num {
  position: absolute;
  z-index: 0;
  top: -0.45em;
  right: 0;
  font-family: var(--font-display);
  font-size: clamp(6rem, 18vw, 14rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.04em;
  color: rgba(74, 124, 255, 0.1); /* fallback where text-stroke unsupported */
  pointer-events: none;
  user-select: none;
}
@supports (-webkit-text-stroke: 2px red) {
  .station-ghost,
  .station-num,
  .ghost-num {
    color: transparent;
    -webkit-text-stroke: 2px var(--accent-soft);
  }
}

.station h2 {
  color: var(--text-primary);
  margin-bottom: 18px;
  font-size: clamp(2rem, 5vw, 3.25rem);
}

.station p {
  color: var(--text-secondary);
  max-width: 52ch;
}

.station-list {
  list-style: none;
  display: grid;
  gap: 10px;
  margin: 22px 0 6px;
}
.station-list li {
  position: relative;
  padding-left: 24px;
  color: var(--text-secondary);
}
.station-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.65em;
  width: 12px;
  height: 2px;
  border-radius: 1px;
  background: var(--accent-current);
  transition: background-color 400ms ease;
}

.station-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  margin-top: 18px;
  font-weight: 600;
  color: var(--accent-current);
  transition: color 400ms ease;
  text-underline-offset: 5px;
}
.station-link:hover,
.station-link:focus-visible {
  color: var(--accent-current);
  text-decoration: underline;
}

/* Alternate panels left/right on wide screens so the formations get room */
@media (min-width: 900px) {
  .station-inner { margin-right: auto; }
  .station:nth-of-type(even) .station-inner { margin-left: auto; margin-right: 0; }
}

/* ==========================================================================
   Process — the conveyor
   ========================================================================== */

.process {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--section-pad) 24px;
}

.process h2 {
  width: 100%;
  max-width: var(--content-max);
  margin: 0 auto 40px;
}

/* Baseline (no JS / no-3d / reduced motion): horizontal scroll-snap strip
   with a visible thin scrollbar. scroll.js takes over on the full experience
   and drives .process-track x while #process is pinned. */
.process-viewport {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
  scroll-padding-left: 24px;
  padding-bottom: 18px;
  scrollbar-width: thin;
  scrollbar-color: var(--border-color) var(--bg-secondary);
}
.process-viewport::-webkit-scrollbar { height: 8px; }
.process-viewport::-webkit-scrollbar-track {
  background: var(--bg-secondary);
  border-radius: 4px;
}
.process-viewport::-webkit-scrollbar-thumb {
  background: var(--border-color);
  border-radius: 4px;
}
.process-viewport::-webkit-scrollbar-thumb:hover { background: var(--bg-hover); }

/* While the ring is transform-animated every scroll frame, re-sampling a
   blurred backdrop per frame over the live canvas is the page's most expensive
   GPU path — use the solid surface instead (setDim keeps text readable). */
body.js-enabled:not(.no-3d) .process-step {
  background: rgba(34, 37, 51, 0.92);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.process-track {
  display: flex;
  gap: 32px;
  padding: 8px 2px;
  width: max-content;
}

/* Image cards — shared by the mobile strip and the desktop ring */
.process-step {
  position: relative;
  flex: 0 0 auto;
  width: min(300px, 78vw);
  aspect-ratio: 3 / 4;
  padding: 0;
  overflow: hidden;
  scroll-snap-align: center;
}

.process-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.process-step-content {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 64px 22px 22px;
  background: linear-gradient(to top, rgba(15, 17, 23, 0.94) 40%, rgba(15, 17, 23, 0));
}

/* ==== Circular 3D ring (desktop, full experience only) ==================== */
@media (min-width: 900px) {
  body.js-enabled:not(.no-3d) .process { overflow: hidden; }

  body.js-enabled:not(.no-3d) .process-viewport {
    overflow: visible;
    scroll-snap-type: none;
    padding-bottom: 0;
    height: 500px;
    perspective: 1600px;
  }

  body.js-enabled:not(.no-3d) .process-track {
    position: relative;
    display: block;
    width: 100%;
    height: 100%;
    padding: 0;
    transform-style: preserve-3d;
    will-change: transform;
  }

  /* scroll.js positions each card: rotateY(i * 72deg) translateZ(radius) */
  body.js-enabled:not(.no-3d) .process-track .process-step {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 300px;
    height: 400px;
    margin: -200px 0 0 -150px;
    aspect-ratio: auto;
    will-change: transform, opacity;
  }

  body.js-enabled:not(.no-3d) .process-step::before { display: none; }

  /* LED strip: a faint continuous blue→purple rim plus one brighter segment
     slowly traveling the perimeter. Masked to a 1.5px ring so it reads as
     edge lighting, not a glow bath. (Replaces the strip-mode connector
     arrow, which is display:none'd via ::before above.) */
  body.js-enabled:not(.no-3d) .process-step::after {
    content: "";
    position: absolute;
    inset: 0;
    top: 0; right: 0; bottom: 0; left: 0;
    width: auto; height: auto;
    margin: 0;
    border: 0;
    border-radius: var(--radius-lg);
    padding: 1.5px;
    background:
      conic-gradient(from var(--led-angle, 0deg),
        rgba(200, 214, 255, 0.85) 0deg,
        rgba(74, 124, 255, 0.4) 40deg,
        transparent 80deg 360deg),
      linear-gradient(135deg,
        rgba(74, 124, 255, 0.38),
        rgba(167, 139, 250, 0.30) 45%,
        rgba(52, 211, 153, 0.22) 75%,
        rgba(74, 124, 255, 0.38));
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask-composite: exclude;
    transform: none;
    pointer-events: none;
    z-index: 2;
    animation: led-run 8s linear infinite;
  }

  body.js-enabled:not(.no-3d) .process-track .process-step {
    box-shadow: 0 0 22px rgba(74, 124, 255, 0.10), var(--shadow-card);
  }
}

/* Registered property lets the conic angle interpolate; browsers without
   @property simply show the static gradient rim — still an LED edge. */
@property --led-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

@keyframes led-run {
  to { --led-angle: 360deg; }
}

/* Conveyor connectors: line + arrowhead across each gap */
.process-step:not(:last-child)::before {
  content: "";
  position: absolute;
  top: 50%;
  right: -32px;
  width: 32px;
  height: 2px;
  margin-top: -1px;
  background: var(--border-color);
}
.process-step:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 50%;
  right: -23px;
  width: 9px;
  height: 9px;
  border-top: 2px solid var(--border-color);
  border-right: 2px solid var(--border-color);
  transform: translateY(-50%) rotate(45deg);
}

.process-num {
  display: block;
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.08em;
  margin-bottom: 10px;
  background: linear-gradient(120deg, var(--accent-blue), var(--accent-purple));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .process-num { background: none; color: var(--accent-blue); }
}

.process-step h3 {
  font-size: 1.35rem;
  margin-bottom: 8px;
  color: var(--text-primary);
}
.process-step-content > p:not(.process-num) {
  color: var(--text-secondary);
  font-size: 0.9rem;
  line-height: 1.5;
}

/* ==========================================================================
   Work
   ========================================================================== */

.work {
  max-width: var(--content-max);
  margin-inline: auto;
  padding: var(--section-pad) 24px;
}

.work .section-sub { margin-bottom: 48px; }

.work-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: 24px;
  perspective: 900px;
}
@media (min-width: 900px) {
  .work-grid { grid-template-columns: repeat(2, 1fr); } /* 2×2 on desktop */
}

.work-card {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  box-shadow: var(--shadow-card);
  transform-style: preserve-3d; /* scroll.js pointer tilt (pointer:fine only) */
}

.work-card img,
.work-card .work-media {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  transition: transform 500ms ease, opacity 650ms linear;
}

/* Crossfade looper (main.js adds body.work-loops + a stacked twin copy;
   whichever copy holds .is-front is visible). Without JS the single video
   stays fully visible. */
.work-media-twin {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
}
body.work-loops .work-card .work-media:not(.is-front) { opacity: 0; }
@media (hover: hover) and (pointer: fine) {
  .work-card:hover img,
  .work-card:hover .work-media { transform: scale(1.04); }
}

/* Gated view link — stretched over the card; pill sits top-right */
.work-view {
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
}
.work-view:hover { text-decoration: none; }

.work-view-pill {
  position: absolute;
  top: 14px;
  right: 14px;
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 7px 14px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-primary);
  background: rgba(15, 17, 23, 0.78);
  border: 1px solid var(--border-color);
  border-radius: 999px;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast),
              background var(--transition-fast);
}
.work-view:hover .work-view-pill,
.work-view:focus-visible .work-view-pill {
  border-color: var(--accent-blue);
  box-shadow: var(--glow-blue);
  background: rgba(15, 17, 23, 0.92);
}

.work-note {
  margin-top: 28px;
  color: var(--text-secondary);
  font-size: 0.9rem;
  text-shadow: 0 1px 12px rgba(15, 17, 23, 0.9);
}

.work-card figcaption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 56px 22px 20px;
  background: linear-gradient(to top, rgba(15, 17, 23, 0.92) 30%, rgba(15, 17, 23, 0));
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--text-primary);
  letter-spacing: -0.01em;
}
.work-card .work-name { display: block; }
.work-card .work-tag,
.work-card figcaption small {
  display: block;
  margin-top: 2px;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.85rem;
  color: var(--text-secondary);
  letter-spacing: 0;
}

/* ==========================================================================
   Metrics
   ========================================================================== */

/* The four .metric tiles are direct children of the section — the section
   itself is the grid. (sr-only h2 is absolutely positioned; no track.) */
.metrics {
  display: grid;
  grid-template-columns: repeat(2, 1fr); /* 2-col mobile */
  gap: 16px;
  max-width: var(--content-max);
  margin-inline: auto;
  padding: var(--section-pad) 24px;
}
.metrics h2 { grid-column: 1 / -1; }

@media (min-width: 900px) {
  .metrics {
    grid-template-columns: repeat(4, 1fr); /* 4-col desktop */
    gap: 24px;
  }
}

.metric {
  padding: 30px 18px;
  text-align: center;
}

.metric-value {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 6vw, 4rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}

.metric-label {
  display: block;
  margin-top: 10px;
  font-size: 0.9rem;
  color: var(--text-secondary);
  text-wrap: balance;
}

/* ==========================================================================
   Contact
   ========================================================================== */

.contact {
  max-width: 720px;
  margin-inline: auto;
  padding: var(--section-pad) 24px;
}

.contact .section-sub { color: var(--text-secondary); }

#contact-form { margin-top: 40px; }

#contact-form label {
  display: block;
  margin: 22px 0 8px;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--text-primary);
}
#contact-form .form-field:first-child label { margin-top: 0; }

#contact-form abbr[title] {
  color: var(--accent-current);
  text-decoration: none;
  border: 0;
  cursor: help;
}

#contact-form input,
#contact-form textarea {
  display: block;
  width: 100%;
  min-height: 48px; /* ≥44px touch target */
  padding: 12px 14px;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  transition: border-color var(--transition-fast), background var(--transition-fast);
}
#contact-form textarea {
  min-height: 150px;
  resize: vertical;
}
#contact-form input::placeholder,
#contact-form textarea::placeholder { color: var(--text-muted); }

#contact-form input:focus,
#contact-form textarea:focus {
  border-color: var(--accent-blue);
  background: var(--bg-primary);
}
/* Visible focus ring comes from the global :focus-visible rule */

#contact-form [aria-invalid="true"] { border-color: var(--accent-red); }

.field-error {
  display: block;
  margin-top: 8px;
  font-size: 0.875rem;
  color: var(--accent-red);
}

#contact-form button[type="submit"],
#contact-form .btn {
  width: 100%;
  margin-top: 30px;
}
@media (min-width: 640px) {
  #contact-form button[type="submit"],
  #contact-form .btn { width: auto; }
}

.form-note {
  margin-top: 16px;
  color: var(--accent-green);
  font-size: 0.95rem;
}

.form-hint {
  margin-top: 16px;
  font-size: 0.875rem;
  color: var(--text-secondary);
}

.contact-alt {
  margin-top: 32px;
  color: var(--text-secondary);
}
.contact-alt a {
  color: var(--accent-current);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 4px;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

/* ==========================================================================
   Intake overlay — CTA implosion questionnaire.
   JS-only UI: opened by main.js; the #contact form is the no-JS fallback,
   so it is hidden once JS is running.
   ========================================================================== */

/* Hide ONLY the no-JS fallback form — never the whole section.
   Googlebot executes JS, so `body.js-enabled .contact` used to put the
   entire <section id="contact"> (heading, intro copy, WhatsApp link and
   tel: link) into the rendered DOM as display:none, which Google
   explicitly discounts — while 44 sitewide links pointed into it. */
body.js-enabled .contact-form { display: none; }

/* Primary CTA shown in place of the fallback form once JS is running.
   Hidden without JS, where the real form is already visible. */
.contact-cta { margin-top: var(--space-lg, 2rem); }
body:not(.js-enabled) .contact-cta { display: none; }

/* Scroll lock lives on <html>: our `html { overflow-x: clip }` stops the
   body's overflow from propagating to the viewport, so body-only hidden
   never actually locked the page. */
html.intake-open,
body.intake-open { overflow: hidden; }

.intake {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  overflow-y: auto;
  outline: none; /* focus anchor via tabindex="-1"; no ring on the dialog */
}

/* Backdrop lives on its own fixed layer so its 300ms fade never multiplies
   with the form's GSAP burst alpha (the form must pop on its own curve).
   Translucent: the particle scene stays visible behind the questions. */
.intake::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(circle at 50% 42%,
    rgba(15, 17, 23, 0.35),
    rgba(15, 17, 23, 0.9) 72%);
  opacity: 0;
  transition: opacity 300ms ease;
}
.intake.is-open::before { opacity: 1; }

/* Closing: fade the content out with the backdrop. (Opening state has no
   transition on the shell, so the reveal stays instant for the burst.) */
.intake:not(.is-open) .intake-shell {
  opacity: 0;
  transition: opacity 300ms ease;
}

.intake-shell {
  min-height: 100%;
  max-width: 780px;
  margin: 0 auto;
  padding: 10px 24px 72px;
  display: flex;
  flex-direction: column;
}

.intake-chrome {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 56px;
}

.intake-brand {
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--text-primary);
}

.intake-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
}
.intake-close:hover {
  color: var(--text-primary);
  border-color: var(--border-color);
}

.intake-progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: rgba(46, 51, 71, 0.5);
}
.intake-progress-bar {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--accent-blue), var(--accent-purple));
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 350ms ease;
}

#intake-form {
  margin: auto 0;
  padding-top: 6vh;
}

.intake-step { display: none; }
.intake-step.active {
  display: block;
  animation: intake-in 480ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
/* During the big-bang reveal the whole form scales from the center —
   the step's own slide-in would fight it. */
.intake.is-bursting .intake-step.active { animation: none; }
@keyframes intake-in {
  from { opacity: 0; transform: translateY(34px); }
  to   { opacity: 1; transform: none; }
}

fieldset.intake-step {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}

.intake-meta {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-bottom: 30px;
  color: var(--text-secondary);
  font-size: 0.9rem;
}
.intake-back {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 44px;
  background: none;
  border: 0;
  padding: 0;
  color: var(--text-secondary);
  font-weight: 500;
}
.intake-back:hover { color: var(--text-primary); }
.intake-step[data-step="1"] .intake-back { visibility: hidden; }

.intake-num {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--accent-current);
  margin-bottom: 10px;
}

.intake-q {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 4.5vw, 2.75rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--text-primary);
  text-shadow: 0 2px 24px rgba(15, 17, 23, 0.95);
  margin-bottom: 10px;
}
/* Float keeps the legend in source order (after the Back/count row) instead
   of the browser hoisting it to the top of the fieldset. */
legend.intake-q {
  float: left;
  width: 100%;
  padding: 0;
}
legend.intake-q + * { clear: both; }

.intake-sub {
  color: var(--text-secondary);
  text-shadow: 0 1px 12px rgba(15, 17, 23, 0.9);
}

/* Match on what a control ISN'T, not on a whitelist of types: a new
   question (tel, url, number…) picks the styling up automatically instead
   of silently falling back to the unstyled browser default. */
#intake-form input:not([type="checkbox"]):not([type="radio"]),
#intake-form textarea {
  display: block;
  width: 100%;
  margin-top: 26px;
  padding: 16px 18px;
  font-size: 1.15rem;
  background: rgba(26, 29, 39, 0.78);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  transition: border-color var(--transition-fast);
}
#intake-form input:focus,
#intake-form textarea:focus { border-color: var(--accent-blue); }
#intake-form textarea { min-height: 140px; resize: vertical; }
#intake-form ::placeholder { color: var(--text-muted); }
#intake-form [aria-invalid="true"] { border-color: var(--accent-red); }

.intake-options {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-top: 28px;
}
@media (max-width: 639.98px) {
  .intake-options { grid-template-columns: 1fr; }
}

.intake-option {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 56px;
  padding: 14px 18px;
  background: rgba(34, 37, 51, 0.78);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  cursor: pointer;
  color: var(--text-primary);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.intake-option:hover { border-color: var(--text-muted); }
.intake-option:focus-within {
  outline: 2px solid var(--accent-blue);
  outline-offset: 3px;
}
.intake-option input {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  accent-color: var(--accent-blue);
  cursor: pointer;
}
.intake-option:has(input:checked) {
  border-color: var(--accent-blue);
  box-shadow: var(--glow-blue);
}

.intake-source { margin-top: 22px; }
.intake-source label {
  display: block;
  margin-bottom: 8px;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--text-primary);
}
#intake-form select {
  display: block;
  width: 100%;
  min-height: 48px;
  padding: 12px 14px;
  font-size: 1rem;
  background: rgba(26, 29, 39, 0.78);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  cursor: pointer;
}
#intake-form select:focus { border-color: var(--accent-blue); }

.intake-actions {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 30px;
}
.intake-hint {
  color: var(--text-secondary);
  font-size: 0.85rem;
}

.intake-success .intake-num {
  color: var(--accent-green);
  font-size: 2.2rem;
}

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer {
  border-top: 1px solid var(--border-color);
  padding: 56px 24px 40px;
  text-align: center;
  font-size: 0.9rem;
  color: var(--text-secondary);
  background: var(--bg-primary);
}

.site-footer .nav-brand,
.footer-brand {
  display: inline-flex;
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--text-primary);
}

.site-footer p { margin: 10px auto 0; max-width: 60ch; }

.site-footer nav,
.site-footer ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px 8px;
  list-style: none;
  margin: 24px 0;
}
.site-footer nav a,
.site-footer ul a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 8px 12px;
  color: var(--text-secondary);
  transition: color var(--transition-fast);
}
.site-footer nav a:hover,
.site-footer ul a:hover { color: var(--text-primary); }

.site-footer small,
.footer-copy {
  display: block;
  margin-top: 8px;
  font-size: 0.85rem;
  color: var(--text-secondary);
}

/* ==========================================================================
   FAQ — homepage accordion (native details/summary; works without JS)
   ========================================================================== */

.faq {
  max-width: 820px;
  margin-inline: auto;
  padding: var(--section-pad) 24px;
}

.faq h2 {
  margin-bottom: 12px;
  text-shadow: 0 2px 24px rgba(15, 17, 23, 0.95), 0 0 10px rgba(15, 17, 23, 0.85);
}

.faq .section-sub { margin-bottom: 36px; }

.faq-item {
  background: rgba(34, 37, 51, 0.78);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  margin-bottom: 12px;
  overflow: hidden;
}

.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 56px;
  padding: 16px 20px;
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--text-primary);
  cursor: pointer;
  list-style: none;
  transition: color var(--transition-fast);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "+";
  flex-shrink: 0;
  font-size: 1.4rem;
  font-weight: 500;
  color: var(--accent-current);
  transition: transform 200ms ease;
}
.faq-item[open] summary::after { transform: rotate(45deg); }
.faq-item summary:hover { color: var(--accent-blue); }

.faq-item p {
  padding: 0 20px 18px;
  color: var(--text-secondary);
  max-width: none;
}
.faq-item a { font-weight: 600; }

/* ==========================================================================
   Static subpages (blog) — no 3D scene, gradient backdrop, light and fast
   ========================================================================== */

body.page-static {
  background-color: var(--bg-primary);
}
body.page-static::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(closest-side at 18% 12%, rgba(74, 124, 255, 0.08), transparent),
    radial-gradient(closest-side at 85% 38%, rgba(167, 139, 250, 0.08), transparent),
    radial-gradient(closest-side at 28% 88%, rgba(52, 211, 153, 0.06), transparent);
}
body.page-static main {
  padding-top: calc(var(--nav-height) + 48px);
}

/* Blog index */
.blog-index {
  max-width: var(--content-max);
  margin-inline: auto;
  padding: 48px 24px var(--section-pad);
}
.blog-index > h1 { margin-bottom: 10px; }
.blog-index > .section-sub { margin-bottom: 44px; }

.blog-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: 20px;
}

.blog-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 0 24px 28px;
  background: rgba(34, 37, 51, 0.78);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  overflow: hidden; /* clip the thumbnail to the card's rounded corners */
  transition: border-color var(--transition-fast), transform var(--transition-fast),
              box-shadow var(--transition-fast);
}

/* Card thumbnail. Fixed aspect + explicit width/height attrs in the markup
   keep the grid from reflowing as images arrive (CLS). */
.blog-card-media {
  display: block;
  /* Bleed back over the card's 24px side padding. max-width must be cleared
     explicitly — the global `img { max-width: 100% }` reset otherwise clamps
     this back to the content box and leaves a gap down the right edge. */
  width: calc(100% + 48px);
  max-width: none;
  margin: 0 -24px 16px;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: var(--bg-secondary);
}
.blog-card:hover {
  border-color: var(--accent-blue);
  transform: translateY(-2px);
  box-shadow: var(--glow-blue);
  text-decoration: none;
}
.blog-card h2 {
  font-size: 1.25rem;
  line-height: 1.3;
  color: var(--text-primary);
}
.blog-card p { color: var(--text-secondary); font-size: 0.95rem; }
.blog-card .blog-card-meta {
  margin-top: auto;
  padding-top: 8px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--accent-blue);
}

/* Article hero. Sits between the meta line and the answer block; decorative
   support for the topic rather than information, so alt text stays short. */
.post-hero {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  margin: 8px 0 28px;
  background: var(--bg-secondary);
}

/* Article pages */
.post {
  max-width: 760px;
  margin-inline: auto;
  padding: 40px 24px var(--section-pad);
}

/* Visible breadcrumb trail. Mirrors the BreadcrumbList JSON-LD on each page —
   Google treats a visible trail and the markup as corroborating each other, and
   it gives deep pages a real path back to the money pages. */
.breadcrumb {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-bottom: 20px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
.breadcrumb a {
  color: var(--text-secondary);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.breadcrumb a:hover,
.breadcrumb a:focus-visible { color: var(--accent-blue); }
.breadcrumb [aria-current="page"] { color: var(--text-muted); }

/* 404 page */
.error-links {
  list-style: none;
  margin: 32px 0;
  padding: 0;
  text-align: left;
  max-width: 640px;
  margin-inline: auto;
}
.error-links li {
  padding: 14px 0;
  border-bottom: 1px solid var(--border-color);
  color: var(--text-secondary);
}
.error-links li:last-child { border-bottom: 0; }
.error-links a {
  color: var(--accent-blue);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 4px;
}
.error-help {
  color: var(--text-secondary);
  max-width: 640px;
  margin-inline: auto;
}
.error-help a {
  color: var(--accent-blue);
  text-decoration: underline;
  text-underline-offset: 4px;
}

.post-eyebrow {
  display: block;
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent-blue);
  margin-bottom: 16px;
}

.post h1 {
  font-size: clamp(2rem, 5vw, 3rem);
  margin-bottom: 14px;
}

.post-meta {
  color: var(--text-muted);
  font-size: 0.9rem;
  margin-bottom: 36px;
  color: var(--text-secondary);
}

.post h2 {
  font-size: clamp(1.4rem, 3vw, 1.8rem);
  margin: 44px 0 14px;
}
.post h3 {
  font-size: 1.15rem;
  margin: 30px 0 10px;
}

.post p,
.post li {
  color: var(--text-secondary);
  font-size: 1.02rem;
  line-height: 1.75;
  max-width: none;
}
.post p { margin-bottom: 16px; }

.post ul,
.post ol {
  margin: 0 0 16px;
  padding-left: 24px;
}
.post li { margin-bottom: 8px; }

.post strong { color: var(--text-primary); }

.post blockquote {
  margin: 24px 0;
  padding: 16px 22px;
  border-left: 3px solid var(--accent-blue);
  background: rgba(34, 37, 51, 0.6);
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  color: var(--text-primary);
}

.post .post-answer {
  padding: 18px 22px;
  margin-bottom: 28px;
  background: rgba(74, 124, 255, 0.08);
  border: 1px solid rgba(74, 124, 255, 0.35);
  border-radius: var(--radius-md);
  color: var(--text-primary);
}

.post-cta {
  margin: 48px 0;
  padding: 30px 28px;
  background: rgba(34, 37, 51, 0.78);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
}
.post-cta h2 { margin: 0 0 8px; font-size: 1.35rem; }
.post-cta p { margin-bottom: 18px; }

.post-sources {
  margin-top: 56px;
  padding-top: 24px;
  border-top: 1px solid var(--border-color);
}
.post-sources h2 {
  font-size: 0.85rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--text-secondary);
  margin: 0 0 12px;
}
.post-sources ol {
  padding-left: 20px;
  margin: 0;
}
.post-sources li {
  font-size: 0.9rem;
  color: var(--text-muted);
  color: var(--text-secondary);
  margin-bottom: 6px;
}

/* ==========================================================================
   Reduced motion
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .scroll-cue svg { animation: none; }
  .btn-primary:hover { transform: none; }
  .work-card img,
  .work-card:hover img { transform: none; }
}

/* ==========================================================================
   Print
   ========================================================================== */

@media print {
  #scene-canvas,
  .nav-toggle,
  .nav-progress,
  .scroll-cue,
  .skip-link,
  .station-ghost,
  .station-num,
  .ghost-num { display: none !important; }

  body {
    background: #fff !important;
    color: #000 !important;
  }

  .site-nav {
    position: static;
    background: #fff;
    border-bottom: 1px solid #ccc;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  .hero { min-height: auto; padding: 40px 0; }
  .hero-accent,
  .process-num {
    background: none;
    color: #000;
  }

  .station { min-height: auto; padding: 24px 0; }
  .station-stage {
    position: static;
    min-height: auto;
    display: block;
  }
  .station-inner {
    position: static;
    transform: none;
    background: #fff;
    border-color: #ddd;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  .glass,
  .process-step,
  .metric,
  .work-card {
    background: #fff;
    border-color: #ddd;
    box-shadow: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  .process { min-height: auto; }
  .process-viewport { overflow: visible; }
  .process-track { flex-wrap: wrap; width: auto; }

  .hero-sub,
  .section-sub,
  .station p,
  .station-list li,
  .process-step p,
  .metric-label,
  .site-footer,
  .site-footer nav a { color: #333 !important; }

  a { color: #000; text-decoration: underline; }
}

/* ==========================================================================
   Local prose section (#local .local-seo) — appended.
   Content-depth section between #metrics and #faq. Reuses the FAQ container
   rhythm (820px column, section padding) and the same translucent card +
   text-halo treatments so it sits over the live particle canvas without
   washing out. Mobile-first; single column works down to 360px.
   ========================================================================== */

.local-seo {
  max-width: 820px;
  margin-inline: auto;
  padding: var(--section-pad) 24px;
}

/* Same soft dark halo used by .faq h2 over the canvas */
.local-seo h2 {
  margin-bottom: 12px;
  text-shadow: 0 2px 24px rgba(15, 17, 23, 0.95), 0 0 10px rgba(15, 17, 23, 0.85);
}

.local-seo .section-sub { margin-bottom: 28px; }

.local-intro,
.local-outro {
  color: var(--text-secondary);
  text-shadow: 0 2px 24px rgba(15, 17, 23, 0.95), 0 0 10px rgba(15, 17, 23, 0.85);
}
.local-intro { margin-bottom: 28px; }
.local-outro { margin-top: 28px; }

/* Cards match the .faq-item glass surface */
.local-block {
  background: rgba(34, 37, 51, 0.78);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  padding: 20px;
}
.local-block + .local-block { margin-top: 12px; }

@media (min-width: 640px) {
  .local-block { padding: 24px; }
}

.local-block h3 {
  margin-bottom: 8px;
  color: var(--text-primary);
}

.local-block p { color: var(--text-secondary); }

.local-block a,
.local-outro a { font-weight: 600; }

@media print {
  .local-block {
    background: #fff;
    border-color: #ddd;
  }
  .local-intro,
  .local-outro,
  .local-block p { color: #333 !important; text-shadow: none; }
}

/* ==========================================================================
   Reading run (#local, #faq) — the quiet sections after the set-pieces.
   Both used to be 820px columns centred in the viewport, which put them
   squarely on top of the particle machine: the globe got sliced in half by
   the cards and read as an accident rather than a decision.

   Now they take a 640px column on alternating sides — #local left, #faq
   right, continuing the rhythm the stations established — and js/scroll.js
   parks the machine in the strip each one leaves free, dimmed, so it reads
   as deliberate ambience you can actually see whole.

   Below 1100px there is no strip worth parking in, so both stay centred and
   the machine simply dims further instead (see READING_DIM in scroll.js).
   ========================================================================== */
@media (min-width: 1100px) {
  .local-seo,
  .faq {
    /* 640px of prose + the 24px gutters the base rule already pads */
    max-width: 688px;
  }
  .local-seo { margin-inline: clamp(24px, 5vw, 64px) auto; }
  .faq { margin-inline: auto clamp(24px, 5vw, 64px); }
}

/* Footer contact line (index footer): phone + email links get comfortable
   tap targets on touch screens, matching the footer nav pattern. */
.footer-contact a {
  display: inline-block;
  padding: 8px 4px;
}

/* Locality line under the footer contact details. Quiet by design — it exists
   for the local-SEO/NAP signal, not to compete with the phone and email.
   --text-secondary, NOT --text-muted: muted is 2.95:1 on this background and
   fails AA for copy, where secondary is 5.89:1. */
.footer-locality {
  margin-top: 2px;
  font-size: 0.85rem;
  color: var(--text-secondary);
}

/* Two-button CTA row. Adjacent .btn elements have no margin of their own, and
   at 360px the pair must wrap rather than overflow. */
.post-cta-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 18px;
}

/* ==========================================================================
   Article comparison tables
   ========================================================================== */

/* The wrapper scrolls sideways, never <body>. At the 360px floor a four-column
   comparison table is far wider than the viewport, and letting the page scroll
   horizontally breaks the nav and every section below it. tabindex="0" is set
   on the wrapper in the markup so keyboard users can reach the scroll region;
   the focus ring below is what makes that reachability visible. */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: 0 0 24px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: rgba(34, 37, 51, 0.55);
}
.table-scroll:focus-visible {
  outline: 2px solid var(--accent-blue);
  outline-offset: 2px;
}

.post table {
  width: 100%;
  min-width: 580px;
  border-collapse: collapse;
  font-size: 0.94rem;
  line-height: 1.6;
}
.post caption {
  caption-side: top;
  padding: 14px 16px 2px;
  text-align: left;
  font-size: 0.85rem;
  /* --text-secondary, not --text-muted: muted fails AA for copy on this
     background, same reasoning as .footer-locality. */
  color: var(--text-secondary);
}
.post th,
.post td {
  padding: 12px 16px;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--border-color);
  color: var(--text-secondary);
}
.post thead th {
  color: var(--text-primary);
  font-weight: 600;
  background: var(--bg-secondary);
}
.post tbody th[scope="row"] {
  color: var(--text-primary);
  font-weight: 600;
  min-width: 150px;
}
.post tbody tr:last-child th,
.post tbody tr:last-child td { border-bottom: 0; }

/* ==========================================================================
   Founder photo (about.html).
   Portrait crop, so it is width-capped rather than full-bleed — at .post's
   760px measure a full-width portrait would push the bios two screens down.
   ========================================================================== */
.founders {
  margin: 28px 0;
  text-align: center;
}

.founders-photo {
  width: 100%;
  max-width: 420px;
  height: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-color);
}

.founders figcaption {
  margin-top: 12px;
  font-size: 0.85rem;
  /* --text-secondary, not --text-muted: muted fails AA for copy. */
  color: var(--text-secondary);
}

/* --- Article CTA contact line ---------------------------------------------
   Appended: `.post-cta-contact` was in the pillar-page markup with no rule, so
   the phone/WhatsApp line rendered at body size and inherited `.post-cta p`'s
   18px bottom margin, leaving dead space under the card. Scoped to `.post-cta`
   so it cannot leak into ordinary article paragraphs. --text-secondary, not
   --text-muted: muted fails AA for copy. */
.post-cta .post-cta-contact {
  margin-top: 16px;
  margin-bottom: 0;
  font-size: 0.9rem;
  color: var(--text-secondary);
}
