/* ============================================
   MIRENTHA — STYLESHEET (v3)
   Aesthetic: Clean, modern, confident, minimal.
   Teal + Coral palette, editorial surfaces, geometric
   sans-serif, generous whitespace, flat surfaces,
   pill-shaped CTAs, large rounded panels.
   ============================================ */

/* AUDIT 2026-04-16 FIX: <picture> defaults to display: inline, which
   collapses the wrapper to zero height. Every existing rule in this
   file targets the inner <img> with width: 100% / height: 100% / object-fit
   on the assumption that <img> is a direct child of the slot. Setting
   <picture> to display: contents removes it from the layout tree
   entirely — the <img> behaves as if it were a direct child of
   .service-image-slot / .work-image-slot / .about-image-col / .page-hero-bg
   without changing any of the slot rules. */
picture { display: contents; }

/* --- DESIGN TOKENS --- */
:root {
  /* Colours — Transformative Teal + Sunset Coral (spark) */
  --color-mint: #DFE3E7;
  --color-mint-light: #F0F4F8;
  --color-mint-pale: #F6FAFE;
  --color-green-dark: #171C1F;
  --color-green-deep: #0D1114;
  --color-accent: #006492;
  --color-accent-hover: #005478;
  --color-coral: #AE2F34;
  --color-dark-section: #171C1F;
  --color-text: #171C1F;
  --color-text-muted: #3F4850;
  --color-text-dim: #6F7881;
  --color-bg: #F6FAFE;
  --color-bg-warm: #F0F4F8;
  --color-bg-mint: #DFE3E7;
  --color-surface: #FFFFFF;
  --color-border: #DFE3E7;
  --color-border-light: #E8ECF0;
  --color-tag-bg: #EDF1F5;
  --color-sage-glow: #2D9CDB;

  /* Typography — single geometric sans-serif family */
  --font-display: 'Outfit', sans-serif;
  --font-body: 'Outfit', sans-serif;

  /* Spacing */
  --space-xs: 0.5rem;
  --space-sm: 1rem;
  --space-md: 1.5rem;
  --space-lg: 2.5rem;
  --space-xl: 4rem;
  --space-2xl: 6rem;
  --space-3xl: 8rem;
  --max-width: 1400px;
  --gutter: clamp(1.5rem, 4vw, 3rem);

  /* Surfaces */
  --radius-sm: 8px;
  --radius-md: 16px;
  --radius-lg: 20px;
  --radius-pill: 100px;

  /* Motion */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --transition: 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

/* FIX: Audit finding — skip-to-content link for keyboard/screen reader users */
.skip-to-content {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
  z-index: 10000;
  background: var(--color-accent);
  color: #fff;
  padding: 0.75rem 1.5rem;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 500;
  text-decoration: none;
}
.skip-to-content:focus {
  position: fixed;
  top: 1rem;
  left: 50%;
  transform: translateX(-50%);
  width: auto;
  height: auto;
  overflow: visible;
}

/* --- RESET --- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html {
  scroll-behavior: smooth;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Background here too (not just on body) so that if anything ever
     reveals the html box behind body — like the iOS Safari status-bar
     slot — it picks up the site's cream, not browser default gray. */
  background-color: var(--color-bg);
}
section[id] { scroll-margin-top: 80px; }
body {
  font-family: var(--font-body);
  font-size: clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
  line-height: 1.65;
  color: var(--color-text);
  background-color: var(--color-bg);
  /* `overflow-x: clip` (Safari 16+) prevents horizontal scrolling
     without promoting <body> into a fixed-element containing block —
     so the page is free to render behind the iOS Safari status bar
     the way `viewport-fit=cover` already allows it to. The previous
     `overflow-x: hidden` was the thing capping the page at the
     status-bar line. */
  overflow-x: clip;
  font-weight: 400;
}
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; transition: color var(--transition); }
ul { list-style: none; }
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--color-text);
}

/* --- SHARED --- */
.section-container { max-width: var(--max-width); margin: 0 auto; padding: 0 var(--gutter); }
.section-label {
  display: inline-block;
  font-family: var(--font-display);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #046591;
  margin-bottom: var(--space-md);
}
/* AUDIT 2026-04: Ration the gradient — section-title now solid dark by default.
   Gradient is reserved for signature moments only (hero H1, About H2, and
   .section-title--gradient opt-in), so the eye still treats it as special. */
.section-title {
  font-size: clamp(2rem, 1.4rem + 3vw, 3.5rem);
  font-weight: 400;
  color: var(--color-text);
  display: inline-block;
  width: 100%;
  margin-bottom: var(--space-md);
  line-height: 1.15;
  padding-bottom: 0.1em;
}
/* AUDIT 2026-04: Opt-in gradient variant for the two signature moments. */
.section-title--gradient {
  background: linear-gradient(to right, #b03333 0%, #046591 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
.section-intro {
  max-width: 640px;
  color: var(--color-text-muted);
  font-size: 1.05rem;
  font-weight: 300;
  line-height: 1.65;
}
.section-header { margin-bottom: var(--space-2xl); }

/* --- BUTTONS --- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  position: relative;
  font-family: var(--font-display);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  padding: 0.9rem 2rem;
  border-radius: var(--radius-pill);
  border: none;
  cursor: pointer;
  will-change: transform;
  transition: background 0.3s ease, color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
  white-space: nowrap;
}
.btn::after {
  content: '›';
  font-size: 1.1rem;
  font-weight: 300;
  transition: transform 0.3s ease;
}
.btn:hover::after { transform: translateX(3px); }
.btn-primary {
  background: linear-gradient(135deg, var(--color-accent), var(--color-sage-glow));
  color: #ffffff;
  box-shadow: 0 4px 14px rgba(0, 100, 146, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3);
}
.btn-primary:hover {
  background: linear-gradient(135deg, var(--color-accent-hover), #1E8AC4);
  box-shadow: 0 4px 14px rgba(0, 100, 146, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3), inset 0 0 40px rgba(255, 255, 255, 0.1);
}
.btn-outline {
  background: transparent;
  color: var(--color-text);
  border: 1.5px solid var(--color-border);
}
.btn-outline:hover {
  border-color: var(--color-accent);
  color: var(--color-green-dark);
}
.btn-full { width: 100%; }

/* --- NAV --- */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 1000;
  padding: 1rem 0;
  display: flex;
  justify-content: center;
  background: transparent;
  transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
/* scrolled state no longer adds a background bar */

/* --- NAV CONTAINER (pill, starts expanded — desktop only) --- */
/* 2026-05: Pill border now uses the brand gradient (teal → gold → coral,
   L→R). The previous attempt set a two-background stack — that bled the
   gradient through the translucent fill and read as "the whole pill is
   coloured." This version uses a ::before pseudo-element with
   mask-composite so the gradient is painted, then masked out everywhere
   except the 1.5px border ring. Result: gradient strictly on the edge,
   the translucent rgba(.88) fill + backdrop-filter glass is preserved. */
.nav-container {
  max-width: 940px;
  margin: 0 auto;
  padding: 0.55rem 2.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  border-radius: var(--radius-pill);
  background: rgba(246, 250, 254, 0.88);
  backdrop-filter: saturate(180%) blur(24px);
  -webkit-backdrop-filter: saturate(180%) blur(24px);
  border: none;
  box-shadow:
    0 2px 8px rgba(23, 28, 31, 0.06),
    0 8px 32px rgba(23, 28, 31, 0.08),
    inset 0 0.5px 0 rgba(255, 255, 255, 0.6);
  overflow: hidden;
  /* 2026-05-13 (perf): removed `will-change: max-width, padding`. Those
     are layout properties; will-change can't compositor-promote them
     and actually deopts the renderer (forces an extra layer + forces
     more frequent recalcs on a backdrop-filter element). At wide
     viewports the nav was the biggest contributor to scroll jank. */
  /* No transition on max-width/padding — JS scrubs these directly.
     Transitions only apply in .nav-collapsed for hover expand. */
  transition: box-shadow 0.35s ease;
}
.nav-container::before {
  content: '';
  position: absolute;
  inset: 0;
  /* 2026-05: Thinned from 1.5px → 1px and dropped the gradient stops to
     ~70% alpha. The full-saturation 1.5px ring read as a "design feature";
     thinner + slightly translucent makes the brand colours feel
     like considered hairline detail. */
  padding: 1px;                         /* = border thickness */
  border-radius: var(--radius-pill);
  background: linear-gradient(
    90deg,
    rgba(4, 101, 145, 0.70) 0%,
    rgba(212, 169, 58, 0.75) 50%,
    rgba(176, 51, 52, 0.70) 100%
  );
  -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;
  pointer-events: none;
  z-index: 1;
}

/* --- LOGO --- */
.nav-logo {
  display: flex; align-items: center; gap: 0.75rem;
  z-index: 10;
  position: relative;
  flex-shrink: 0;
  transition: gap 0.5s cubic-bezier(0.22, 1, 0.36, 1);
  -webkit-tap-highlight-color: transparent;
  outline: none;
}
.nav-logo-img {
  width: 52px; height: 52px; object-fit: contain;
  transition: transform 0.5s var(--ease-out);
}
/* (site-wordmark removed — now integrated into hero) */

/* --- NAV LINKS (shared base) --- */
.nav-links {
  display: flex; align-items: center;
  gap: clamp(1.2rem, 2.5vw, 2.25rem);
  overflow: hidden;
  width: 380px;
  /* 2026-05-13 (perf): removed `will-change: width, opacity, padding`.
     width + padding are layout properties — promoting them with
     will-change is a deopt, not an optimisation. Opacity alone isn't
     worth a permanent compositor layer either; the link group only
     animates inside the brief nav-collapse scrub window. */
  /* No transition — JS scrubs width/opacity directly.
     Transitions only apply in .nav-collapsed for hover expand. */
}
.nav-links a {
  font-family: var(--font-display);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  transition: color var(--transition), opacity 0.35s cubic-bezier(0.25, 1, 0.5, 1);
  white-space: nowrap;
}
.nav-links a:hover { color: var(--color-text); }

/* --- LINKS: visible by default, symmetric padding --- */
.nav-links-left,
.nav-links-right {
  opacity: 1;
  pointer-events: auto;
}
.nav-links-left { padding-right: 2rem; justify-content: flex-end; }
.nav-links-right { padding-left: 2rem; justify-content: flex-start; }

/* ============================================
   COLLAPSED STATE (on scroll) — pill shrinks
   ============================================ */
.site-header.nav-collapsed .nav-container {
  max-width: 72px;
  padding: 0.5rem 0.6rem;
  transition:
    max-width 0.55s cubic-bezier(0.25, 1, 0.5, 1),
    padding 0.55s cubic-bezier(0.25, 1, 0.5, 1),
    box-shadow 0.35s ease;
}
.site-header.nav-collapsed .nav-links-left,
.site-header.nav-collapsed .nav-links-right {
  width: 0;
  opacity: 0;
  pointer-events: none;
  padding: 0;
  transition:
    width 0.55s cubic-bezier(0.25, 1, 0.5, 1),
    opacity 0.4s cubic-bezier(0.25, 1, 0.5, 1),
    padding 0.55s cubic-bezier(0.25, 1, 0.5, 1);
}
.site-header.nav-collapsed .nav-links-left a,
.site-header.nav-collapsed .nav-links-right a {
  opacity: 0;
}

/* ============================================
   COLLAPSED + HOVER: pill expands symmetrically
   ============================================ */
.site-header.nav-collapsed .nav-container:hover {
  max-width: 940px;
  padding: 0.55rem 2.5rem;
}
.site-header.nav-collapsed .nav-container:hover .nav-links-left,
.site-header.nav-collapsed .nav-container:hover .nav-links-right {
  width: 380px;
  opacity: 1;
  pointer-events: auto;
}
.site-header.nav-collapsed .nav-container:hover .nav-links-left {
  padding-right: 2rem;
}
.site-header.nav-collapsed .nav-container:hover .nav-links-right {
  padding-left: 2rem;
}

/* Staggered link fade-in on expand */
.site-header.nav-collapsed .nav-container:hover .nav-links-left a,
.site-header.nav-collapsed .nav-container:hover .nav-links-right a {
  opacity: 1;
}
.site-header.nav-collapsed .nav-container:hover .nav-links-left a:nth-child(3) { transition-delay: 0.08s; }
.site-header.nav-collapsed .nav-container:hover .nav-links-left a:nth-child(2) { transition-delay: 0.14s; }
.site-header.nav-collapsed .nav-container:hover .nav-links-left a:nth-child(1) { transition-delay: 0.2s; }
.site-header.nav-collapsed .nav-container:hover .nav-links-right a:nth-child(1) { transition-delay: 0.08s; }
.site-header.nav-collapsed .nav-container:hover .nav-links-right a:nth-child(2) { transition-delay: 0.14s; }
.site-header.nav-collapsed .nav-container:hover .nav-links-right a:nth-child(3) { transition-delay: 0.2s; }

/* Subtle logo pulse on hover */
.site-header.nav-collapsed .nav-container:hover .nav-logo-img {
  transform: scale(1.08);
}

/* --- CTA in nav: plain text, same as other links --- */
.nav-links .nav-cta {
  padding: 0;
  background: none;
  color: var(--color-text-muted);
  border-radius: 0;
  letter-spacing: 0.15em;
  font-size: 0.75rem;
  font-weight: 500;
  box-shadow: none;
}
.nav-links .nav-cta:hover {
  background: none;
  color: var(--color-text);
  box-shadow: none;
  transform: none;
}
.nav-links .nav-cta::after {
  display: none;
}

/* --- MOBILE NAV (hidden on desktop) --- */
.nav-links-mobile {
  display: none;
}

/* --- MOBILE NAV TOGGLE --- */
.nav-toggle {
  display: none; flex-direction: column; gap: 6px;
  background: none; border: 1.5px solid var(--color-border);
  border-radius: var(--radius-sm); cursor: pointer;
  padding: 10px 9px;
  width: 42px; height: 42px;
  align-items: center; justify-content: center;
  z-index: 10;
}
.nav-toggle span {
  display: block; width: 18px; height: 1.5px;
  background: var(--color-text); transition: all var(--transition);
}
.nav-toggle.active span:nth-child(1) { transform: rotate(45deg) translate(4px, 5px); }
.nav-toggle.active span:nth-child(2) { opacity: 0; }
.nav-toggle.active span:nth-child(3) { transform: rotate(-45deg) translate(4px, -5px); }

/* --- MOBILE / TABLET OVERRIDES (pill disabled below 1024px) --- */
@media (max-width: 1024px) {
  .site-header {
    padding: 0.6rem var(--gutter);
    background: transparent;
    align-items: flex-start;
  }

  /* Hide the hamburger — logo pill is the trigger */
  .nav-toggle { display: none !important; }

  /* Nav container becomes the logo-only pill */
  .nav-container {
    max-width: none;
    width: auto;
    padding: 0.5rem 0.6rem;
    border-radius: var(--radius-pill);
    background: rgba(246, 250, 254, 0.92);
    backdrop-filter: saturate(180%) blur(24px);
    -webkit-backdrop-filter: saturate(180%) blur(24px);
    box-shadow:
      0 2px 8px rgba(23, 28, 31, 0.06),
      0 8px 32px rgba(23, 28, 31, 0.08),
      inset 0 0.5px 0 rgba(255, 255, 255, 0.6);
    overflow: visible;
    justify-content: center;
    will-change: auto;
    position: relative;
    cursor: pointer;
  }

  /* Prevent collapsed class from doing anything on mobile */
  .site-header.nav-collapsed .nav-container,
  .site-header.nav-collapsed .nav-container:hover {
    max-width: none;
    padding: 0.5rem 0.6rem;
    border-radius: var(--radius-pill);
    box-shadow:
      0 2px 8px rgba(23, 28, 31, 0.06),
      0 8px 32px rgba(23, 28, 31, 0.08),
      inset 0 0.5px 0 rgba(255, 255, 255, 0.6);
  }

  /* Hide desktop link groups entirely */
  .nav-links-left,
  .nav-links-right,
  .site-header.nav-collapsed .nav-links-left,
  .site-header.nav-collapsed .nav-links-right,
  .site-header.nav-collapsed .nav-container:hover .nav-links-left,
  .site-header.nav-collapsed .nav-container:hover .nav-links-right {
    display: none !important;
    width: 0 !important;
  }

  /* Logo — same size as collapsed desktop pill */
  .nav-logo-img {
    width: 52px; height: 52px;
    transition: transform 0.5s var(--ease-out);
  }
  /* Subtle pulse on hover to hint interactivity */
  .nav-container:hover .nav-logo-img {
    transform: scale(1.08);
  }

  /* ---- PILL DROPDOWN ---- */
  .nav-links-mobile {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    position: absolute;
    top: calc(100% + 0.6rem);
    left: 50%;
    min-width: 200px;
    width: max-content;
    padding: 0.5rem 0;
    border-radius: var(--radius-lg);
    background: rgba(246, 250, 254, 0.95);
    backdrop-filter: saturate(180%) blur(24px);
    -webkit-backdrop-filter: saturate(180%) blur(24px);
    box-shadow:
      0 4px 12px rgba(23, 28, 31, 0.08),
      0 12px 40px rgba(23, 28, 31, 0.12),
      inset 0 0.5px 0 rgba(255, 255, 255, 0.6);
    /* Closed state */
    opacity: 0;
    transform: translate(-50%, -8px) scale(0.96);
    transform-origin: top center;
    pointer-events: none;
    transition:
      opacity 0.3s cubic-bezier(0.16, 1, 0.3, 1),
      transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
    z-index: 999;
  }
  .nav-links-mobile.open {
    opacity: 1;
    transform: translate(-50%, 0) scale(1);
    pointer-events: auto;
  }
  .nav-links-mobile a {
    display: block;
    padding: 0.7rem 1.5rem;
    font-family: var(--font-display);
    font-size: 0.82rem;
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-align: center;
    color: var(--color-text-muted);
    transition: color var(--transition), background var(--transition);
    white-space: nowrap;
    opacity: 1; transform: none; max-width: none; width: auto;
  }
  .nav-links-mobile a:hover {
    color: var(--color-text);
    background: rgba(0, 100, 146, 0.05);
  }
  .nav-links-mobile .nav-cta {
    padding: 0.7rem 1.5rem;
    background: none;
    color: var(--color-accent);
    border: none;
    border-radius: 0;
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    box-shadow: none;
  }
  .nav-links-mobile .nav-cta::after {
    display: none;
  }
  .nav-links-mobile .nav-cta:hover {
    background: rgba(0, 100, 146, 0.05);
    color: var(--color-accent-hover);
    box-shadow: none;
    transform: none;
  }

  /* Staggered link fade-in when dropdown opens */
  .nav-links-mobile a {
    opacity: 0;
    transform: translateY(-6px);
    transition:
      opacity 0.25s cubic-bezier(0.16, 1, 0.3, 1),
      transform 0.25s cubic-bezier(0.16, 1, 0.3, 1),
      color var(--transition),
      background var(--transition);
  }
  .nav-links-mobile.open a {
    opacity: 1;
    transform: translateY(0);
  }
  .nav-links-mobile.open a:nth-child(1) { transition-delay: 0.03s; }
  .nav-links-mobile.open a:nth-child(2) { transition-delay: 0.06s; }
  .nav-links-mobile.open a:nth-child(3) { transition-delay: 0.09s; }
  .nav-links-mobile.open a:nth-child(4) { transition-delay: 0.12s; }
  .nav-links-mobile.open a:nth-child(5) { transition-delay: 0.15s; }
  .nav-links-mobile.open a:nth-child(6) { transition-delay: 0.18s; }

  /* Backdrop (light touch — just catches clicks outside) */
  .nav-backdrop {
    position: fixed; top: 0; left: 0; right: 0; bottom: 0;
    background: transparent;
    z-index: 998;
    opacity: 0; pointer-events: none;
    transition: opacity var(--transition);
  }
  .nav-backdrop.open { opacity: 1; pointer-events: auto; }
}

/* --- HERO --- */
.hero {
  position: relative;
  min-height: min(100vh, 900px);
  display: flex;
  align-items: center;
  overflow: hidden;
  background: var(--color-bg);
}

/* --- WEBGL SHADER CANVAS --- */
.hero-shader {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  opacity: 0.55;
  -webkit-mask-image: linear-gradient(to bottom,
    transparent 0%, rgba(0,0,0,0.05) 4%, rgba(0,0,0,0.15) 8%, rgba(0,0,0,0.4) 14%, rgba(0,0,0,0.7) 20%, black 28%,
    black 72%,
    rgba(0,0,0,0.7) 80%, rgba(0,0,0,0.4) 86%, rgba(0,0,0,0.15) 92%, rgba(0,0,0,0.05) 96%, transparent 100%);
  mask-image: linear-gradient(to bottom,
    transparent 0%, rgba(0,0,0,0.05) 4%, rgba(0,0,0,0.15) 8%, rgba(0,0,0,0.4) 14%, rgba(0,0,0,0.7) 20%, black 28%,
    black 72%,
    rgba(0,0,0,0.7) 80%, rgba(0,0,0,0.4) 86%, rgba(0,0,0,0.15) 92%, rgba(0,0,0,0.05) 96%, transparent 100%);
}
/* When shader is active, hide the CSS fallback orbs */
.hero.shader-active .hero-visual { opacity: 0; }

.hero-grain {
  position: fixed; top: 0; left: 0; right: 0; bottom: 0;
  opacity: 0.022; pointer-events: none; z-index: 3;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
  background-repeat: repeat;
}

/* --- CURSOR GLOW (lerp follower) --- */
.hero-cursor-glow {
  position: absolute;
  width: 400px;
  height: 400px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(45,156,219,0.12) 0%, rgba(0,100,146,0.06) 40%, transparent 70%);
  pointer-events: none;
  z-index: 2;
  transform: translate(-50%, -50%);
  opacity: 0;
  will-change: transform, opacity;
  mix-blend-mode: screen;
}

.hero-layout {
  position: relative;
  z-index: 4;
  max-width: var(--max-width);
  margin: 0 auto;
  padding: var(--space-3xl) var(--gutter);
  padding-bottom: var(--space-xl);
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: min(100vh, 900px);
}
.hero-content { max-width: 720px; }

/* --- HERO TITLE — gradient text --- */
.hero-title {
  font-size: clamp(2.5rem, 1.5rem + 4.5vw, 4.5rem);
  font-weight: 400;
  margin-bottom: var(--space-lg);
  line-height: 1.15;
  padding-bottom: 0.05em;
  background: linear-gradient(to right, #b03333 0%, #046591 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  display: inline-block;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
.hero-em {
  font-style: normal;
  font-family: var(--font-display);
  font-weight: 400;
}

.hero-actions {
  display: flex; gap: var(--space-sm); flex-wrap: wrap;
  margin-bottom: var(--space-lg);
}
.hero-sub {
  font-size: clamp(1rem, 0.9rem + 0.4vw, 1.15rem);
  color: var(--color-text-muted);
  max-width: 520px;
  font-weight: 300;
  line-height: 1.65;
}
/* --- HERO VISUAL: CSS FALLBACK ORBS (hidden when WebGL active) --- */
.hero-visual {
  position: absolute; top: 0; right: -5%; bottom: 0;
  width: 55%; z-index: 1; pointer-events: none;
  transition: opacity 0.5s ease;
}
.hero-orb {
  position: absolute;
  filter: blur(100px);
  will-change: transform;
  animation: morphBlob 14s ease-in-out infinite alternate;
}
.orb-1 {
  width: 520px; height: 520px;
  background: radial-gradient(circle at 30% 30%, #2D9CDB, var(--color-accent));
  opacity: 0.22; top: 5%; right: 0%;
  border-radius: 60% 40% 55% 45% / 55% 60% 40% 45%;
}
.orb-2 {
  width: 340px; height: 340px;
  background: radial-gradient(circle at 60% 40%, #D46A6E, #AE2F34);
  opacity: 0.10; top: 45%; right: 25%;
  border-radius: 45% 55% 40% 60% / 50% 45% 55% 50%;
  animation-duration: 18s;
  animation-direction: alternate-reverse;
}
.orb-3 {
  width: 240px; height: 240px;
  background: radial-gradient(circle at 50% 50%, #ffffff, #E0E8F0);
  opacity: 0.18; bottom: 12%; right: 8%;
  border-radius: 50% 60% 45% 55% / 55% 50% 60% 45%;
  animation-duration: 16s;
  animation-delay: -4s;
}
@keyframes morphBlob {
  0%   { border-radius: 60% 40% 55% 45% / 55% 60% 40% 45%; transform: translate(0, 0) scale(1); }
  25%  { border-radius: 45% 55% 50% 50% / 60% 40% 55% 45%; transform: translate(15px, -20px) scale(1.04); }
  50%  { border-radius: 50% 50% 40% 60% / 45% 55% 50% 50%; transform: translate(-10px, 15px) scale(0.97); }
  75%  { border-radius: 55% 45% 60% 40% / 50% 50% 45% 55%; transform: translate(8px, -8px) scale(1.02); }
  100% { border-radius: 40% 60% 50% 50% / 55% 45% 60% 40%; transform: translate(-5px, 10px) scale(1); }
}

/* --- NEURAL NET LINES --- */
.hero-net {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  pointer-events: none;
  overflow: visible;
}
.hero-net line {
  stroke-linecap: round;
}

/* --- FLOATING ACCENT SHAPES (parallax targets) --- */
.hero-shapes {
  position: absolute; inset: 0;
  z-index: 1; pointer-events: none;
  overflow: hidden;
}
.hero-shape {
  position: absolute;
  border-radius: 50%;
  will-change: transform;
  pointer-events: auto;
  cursor: default;
  transition: box-shadow 0.4s ease;
}
/* Invisible hit area — makes tiny dots easier to hover */
.hero-shape::before {
  content: '';
  position: absolute;
  inset: -14px;
  border-radius: 50%;
}
.hero-shape:hover {
  box-shadow: 0 0 20px rgba(0,100,146,0.3), 0 0 40px rgba(45,156,219,0.15);
}
/* No CSS animation on shapes — GSAP controls all transforms
   so hover scale doesn't conflict */
.shape-1  { width: 12px; height: 12px; background: var(--color-coral);    opacity: 0.35; top: 18%; left: 62%; }
.shape-2  { width: 8px;  height: 8px;  background: var(--color-accent);   opacity: 0.3;  top: 70%; left: 55%; }
.shape-3  { width: 18px; height: 18px; border: 2px solid rgba(45,156,219,0.25);  background: transparent; top: 30%; left: 78%; }
.shape-4  { width: 6px;  height: 6px;  background: var(--color-sage-glow); opacity: 0.4;  top: 55%; left: 72%; }
.shape-5  { width: 5px;  height: 5px;  background: var(--color-coral);    opacity: 0.25; top: 42%; left: 45%; }
.shape-6  { width: 10px; height: 10px; border: 1.5px solid rgba(0,100,146,0.2);  background: transparent; top: 12%; left: 50%; }
.shape-7  { width: 4px;  height: 4px;  background: var(--color-accent);   opacity: 0.3;  top: 82%; left: 65%; }
.shape-8  { width: 7px;  height: 7px;  background: var(--color-sage-glow); opacity: 0.2;  top: 25%; left: 88%; }
.shape-9  { width: 14px; height: 14px; border: 2px solid rgba(174,47,52,0.15);   background: transparent; top: 65%; left: 82%; }
.shape-10 { width: 5px;  height: 5px;  background: var(--color-coral);    opacity: 0.3;  top: 8%;  left: 72%; }
.shape-11 { width: 3px;  height: 3px;  background: var(--color-accent);   opacity: 0.35; top: 78%; left: 42%; }
.shape-12 { width: 8px;  height: 8px;  border: 1.5px solid rgba(45,156,219,0.2); background: transparent; top: 50%; left: 92%; }
.shape-13 { width: 6px;  height: 6px;  background: var(--color-coral);    opacity: 0.3;  top: 35%; left: 68%; }
.shape-14 { width: 4px;  height: 4px;  background: var(--color-accent);   opacity: 0.25; top: 15%; left: 40%; }
.shape-15 { width: 10px; height: 10px; border: 1.5px solid rgba(174,47,52,0.18); background: transparent; top: 88%; left: 55%; }
.shape-16 { width: 5px;  height: 5px;  background: var(--color-sage-glow); opacity: 0.3;  top: 60%; left: 38%; }
.shape-17 { width: 7px;  height: 7px;  background: var(--color-coral);    opacity: 0.2;  top: 22%; left: 92%; }
.shape-18 { width: 3px;  height: 3px;  background: var(--color-accent);   opacity: 0.35; top: 48%; left: 85%; }
.shape-19 { width: 12px; height: 12px; border: 2px solid rgba(0,100,146,0.15);   background: transparent; top: 75%; left: 78%; }
.shape-20 { width: 5px;  height: 5px;  background: var(--color-sage-glow); opacity: 0.25; top: 5%;  left: 58%; }

/* Hero buttons inherit the base .btn magnetic-friendly transition */

/* --- ACCESSIBILITY: Reduced motion --- */
@media (prefers-reduced-motion: reduce) {
  .hero-orb, .hero-shape { animation: none !important; }
  .hero-shader { display: none; }
  .hero-cursor-glow { display: none; }
}

@media (max-width: 1024px) {
  .hero-shapes { display: none; }
  .hero-cursor-glow { display: none; }
}



/* --- SERVICES --- */
/* AUDIT 2026-04: Services section now uses a subtle tonal surface shift
   instead of a hard 1px border (complies with DESIGN.md §2 "No-Line Rule").
   The alternating surface from `--color-bg` to `--color-bg-warm` provides
   structural separation without the templated border feel. */
.services { padding: var(--space-3xl) 0; background: var(--color-bg-warm); }
.services-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-md); }
/* AUDIT 2026-04 (revised 2026-04-16): Card rebuilt for editorial feel.
   - Padding bumped to --space-xl for breathing room
   - Image slot is now the hero element of each card (taller 4:3 aspect)
   - Hover: image zooms subtly, whole card lifts with a tinted shadow
   - Top accent line fades in on hover (retained from original)
   - Content spacing tuned for clearer hierarchy: number → image → title → body → link
   - 2026-05-12: Card sizing reverted to this original spec after the
     services pin was reworked to engage with the heading scrolled
     out of view (start: 'top 8%' on the grid), which gives the cards
     the full viewport height to play in. The reduced-size experiment
     from earlier in the day is no longer needed. */
.service-card {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  padding: var(--space-xl);
  transition: transform 0.35s var(--ease-out), box-shadow 0.35s var(--ease-out);
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.service-card::before {
  content: ''; position: absolute;
  top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg, var(--color-coral), var(--color-accent));
  opacity: 0; transition: opacity var(--transition);
}
.service-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 24px 56px rgba(23, 28, 31, 0.08);
}
.service-card:hover::before { opacity: 1; }
.service-card:hover .service-image-slot img { transform: scale(1.04); }

/* AUDIT 2026-04 (revised): Number indicator now feels like an editorial
   by-line rather than a raw "01". The mono rule + uppercase + wide
   letter-spacing reads as intentional typographic craft. */
.service-number {
  font-family: var(--font-display);
  font-size: 0.7rem; font-weight: 500;
  color: var(--color-coral);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  margin-bottom: var(--space-md);
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}
.service-number::before {
  content: '';
  width: 1.5rem;
  height: 1px;
  background: var(--color-coral);
  opacity: 0.6;
}

/* AUDIT 2026-04 (revised): 4:3 image slot (was 3:2). Taller aspect gives
   each card a stronger editorial "plate" and makes the illustrations
   breathe. Slight inner zoom on hover for premium feel.
   2026-05-12: restored to 4:3 after the pin engagement position was
   moved high enough that the full card now fits in viewport. */
.service-image-slot {
  margin-bottom: var(--space-lg);
  border-radius: var(--radius-md);
  overflow: hidden;
  aspect-ratio: 4/3;
}
.service-image-slot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s var(--ease-out);
}
/* Work cards keep their 3:2 ratio — applied directly on that element
   rather than via shared selector (was: .service-image-slot img, .work-image-slot img). */
.work-image-slot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  aspect-ratio: 3/2;
}

.service-title {
  font-size: 1.6rem; font-weight: 400;
  color: var(--color-text); margin-bottom: var(--space-sm);
  letter-spacing: -0.015em;
  line-height: 1.2;
}
.service-desc {
  color: var(--color-text-muted);
  font-size: 0.95rem; font-weight: 300;
  line-height: 1.75;
  margin-bottom: var(--space-md);
  flex-grow: 1;
}
@media (max-width: 1100px) { .services-grid { grid-template-columns: repeat(2, 1fr); gap: var(--space-md); } }
/* Mobile carousel shared pattern — applied via media query below */


/* --- PROCESS --- */
/* AUDIT 2026-04: Removed top/bottom 1px borders (DESIGN.md §2 "No-Line Rule").
   Section separation is now purely tonal: services (bg-warm) → process
   (mint-pale) → work (bg). The eye reads the shift cleanly without the
   templated divider line. */
.process {
  padding: var(--space-3xl) 0;
  background: var(--color-mint-pale);
  position: relative;
  overflow: hidden;
}
.process::before {
  content: '';
  position: absolute;
  inset: 0;
  background: url('Idea_Launch.webp') center / cover no-repeat;
  opacity: 0.06;
  pointer-events: none;
}
.process > .section-container { position: relative; z-index: 1; }
.process-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; }
.process-step { padding: var(--space-lg) var(--space-md); position: relative; }
.step-marker { display: flex; flex-direction: column; align-items: center; margin-bottom: var(--space-md); }
.step-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px; border-radius: 50%;
  border: 1.5px solid var(--color-accent);
  font-family: var(--font-display);
  font-size: 0.78rem; font-weight: 600;
  color: var(--color-green-deep);
  margin-bottom: var(--space-sm);
  transition: all var(--transition);
  background: var(--color-surface);
}
.process-step:hover .step-num {
  background: var(--color-accent);
  color: #ffffff;
  border-color: var(--color-accent);
}
/* AUDIT 2026-04: step-line changed from a single 1px line to a soft gradient
   fade (teal → transparent) so it reads as "flow" not "divider". */
.step-line {
  width: 1px; height: 32px;
  background: linear-gradient(to bottom, var(--color-accent), transparent);
  opacity: 0.35;
}
/* AUDIT 2026-04: mid-tier typography bump — was 1.1rem, now 1.5rem. */
.step-content h3 {
  font-size: 1.5rem; font-weight: 400;
  color: var(--color-text); margin-bottom: var(--space-xs);
  text-align: center;
  letter-spacing: -0.01em;
}
.step-content p {
  color: var(--color-text-muted);
  font-size: 0.9rem; font-weight: 300;
  text-align: center; line-height: 1.7;
}
@media (max-width: 1000px) {
  .process-grid { grid-template-columns: repeat(2, 1fr); }
}
/* Process mobile carousel handled in shared block below */

/* --- WHAT WE BUILD --- */
.work { padding: var(--space-3xl) 0; background: var(--color-bg); }
/* AUDIT 2026-04: removed outer container border and inner card borders
   (DESIGN.md §2 "No-Line Rule"). Work-grid is now pure rhythm, with a subtle
   tonal shift on card hover instead of a border change. Extra padding dropped. */
.work-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-md);
}
.work-card {
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-surface);
  transition: transform 0.25s var(--ease-out), box-shadow 0.25s var(--ease-out);
}
.work-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 20px 48px rgba(23, 28, 31, 0.06);
}
.work-image-slot { aspect-ratio: 3/2; overflow: hidden; }
.work-info { padding: var(--space-md) var(--space-lg); }
.work-tag {
  display: inline-block;
  font-family: var(--font-display);
  font-size: 0.65rem; font-weight: 500;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: #046591;
  background: rgba(4, 101, 145, 0.08);
  padding: 0.25rem 0.7rem;
  border-radius: var(--radius-pill);
  margin-bottom: var(--space-xs);
}
/* AUDIT 2026-04: mid-tier typography bump — was 1.15rem, now 1.5rem. */
.work-info h3 { font-size: 1.5rem; font-weight: 400; color: var(--color-text); margin-bottom: var(--space-xs); letter-spacing: -0.01em; }
.work-info p { color: var(--color-text-muted); font-size: 0.9rem; font-weight: 300; line-height: 1.7; }
@media (max-width: 1100px) { .work-grid { grid-template-columns: repeat(2, 1fr); } }

/* --- ABOUT --- */
/* AUDIT 2026-04: Removed top/bottom 1px borders (DESIGN.md §2).
   Section separation is handled by the tonal step from work (bg) → about (bg-warm). */
.about {
  padding: var(--space-3xl) 0;
  background: var(--color-bg-warm);
}
.about-layout {
  display: grid;
  /* 2026-05: Text on the LEFT, M construct on the RIGHT. Ratio tuned
     from 1.4fr 1fr → 1.2fr 1fr so the M reads a touch bigger while the
     text column narrows slightly to keep clear of it. */
  grid-template-columns: 1.2fr 1fr;
  gap: var(--space-2xl);
  align-items: center;  /* construct sits centred vertically against the text block */
}
@media (max-width: 1000px) and (min-width: 801px) {
  /* Tablet: scale the same shift through — was 1.6fr 1fr → 1.4fr 1fr. */
  .about-layout { grid-template-columns: 1.4fr 1fr; gap: var(--space-lg); }
}
/* AUDIT 2026-04 (revised 2026-04-16): Image is now a true column-fill,
   not a fixed aspect ratio. The image column grows with the text column's
   height, and Studio.webp object-covers to fill it. No more mismatched-height
   jank between columns. */
.about-image-col {
  position: relative;
  min-height: 100%;
}
.about-image-col img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: var(--radius-lg);
  display: block;
}
.about-text-col {
  display: flex;
  flex-direction: column;
}
.about-body p { color: var(--color-text-muted); font-weight: 300; margin-bottom: var(--space-sm); font-size: 1rem; line-height: 1.75; }
.about-body em { color: var(--color-accent); font-style: italic; }
.about-cta {
  margin-top: var(--space-lg);
  align-self: flex-start;  /* Button hugs left, doesn't stretch */
}
/* AUDIT 2026-04 (revised 2026-04-16, v4): Compact inline row. Nowrap so
   the stats stay on a single line. Value and label sit inline ("15+ years
   regulated delivery") rather than stacked, which removes the visual
   weight and keeps everything on one row even on narrow desktops. */
.about-stats {
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: clamp(1.25rem, 2.5vw, 2.5rem);
  margin: var(--space-2xl) auto 0;
  padding: 0;
  flex-wrap: nowrap;
}
.stat {
  display: inline-flex;
  align-items: baseline;
  gap: 0.5rem;
  white-space: nowrap;
  padding: 0;
  text-align: left;
}
.stat-value {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 500;
  color: var(--color-text);
  letter-spacing: -0.01em;
  line-height: 1;
  display: inline-block;
}
.stat-label {
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 400;
  color: var(--color-text-muted);
  letter-spacing: 0.02em;
  text-transform: none;
  white-space: nowrap;
}
@media (max-width: 800px) {
  .about-layout { grid-template-columns: 1fr; gap: var(--space-xl); }
  .about-image-col { max-width: 100%; width: 100%; min-height: auto; }
  .about-image-col img { aspect-ratio: 3/4; }  /* portrait on mobile */
  .about-stats { flex-wrap: wrap; gap: 1rem 1.5rem; justify-content: center; }
}
@media (max-width: 480px) {
  .about-stats { flex-direction: column; gap: 0.75rem; align-items: center; }
  .stat { white-space: normal; }
}

/* --- FAQ --- */
.faq { padding: var(--space-3xl) 0; background: var(--color-bg); }
.faq-layout { display: grid; grid-template-columns: 1fr 1.5fr; gap: clamp(var(--space-lg), 4vw, var(--space-2xl)); align-items: start; }
.faq-intro { color: var(--color-text-muted); font-size: 1rem; font-weight: 300; margin-top: var(--space-sm); }
.faq-list { display: flex; flex-direction: column; }
/* AUDIT 2026-04: Removed 1px divider (DESIGN.md §5 "Forbid divider lines").
   Items now separate via spacing + subtle hover tint as the doc prescribes. */
.faq-item {
  border-radius: var(--radius-md);
  transition: background var(--transition);
  padding: 0 var(--space-sm);
  margin: 0 calc(-1 * var(--space-sm));
}
.faq-item:hover { background: rgba(0, 100, 146, 0.03); }
.faq-item[open] { background: rgba(0, 100, 146, 0.04); }
.faq-item summary {
  padding: var(--space-md) 0; cursor: pointer;
  font-family: var(--font-display);
  font-size: 1.05rem; font-weight: 400;
  color: var(--color-text);
  list-style: none;
  display: flex; align-items: center;
  justify-content: space-between; gap: var(--space-sm);
  transition: color var(--transition);
}
.faq-item summary:hover { color: var(--color-green-dark); }
.faq-item summary::after {
  content: '+';
  font-size: 1.4rem; font-weight: 300;
  color: var(--color-accent);
  transition: transform var(--transition);
  flex-shrink: 0;
}
.faq-item[open] summary::after { transform: rotate(45deg); color: var(--color-coral); }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-answer { padding-bottom: var(--space-md); }
.faq-answer p { color: var(--color-text-muted); font-size: 0.95rem; font-weight: 300; line-height: 1.8; }
@media (max-width: 800px) { .faq-layout { grid-template-columns: 1fr; gap: var(--space-xl); } }

/* --- CONTACT --- */
/* AUDIT 2026-04: Removed 1px top border (DESIGN.md §2). Tonal step
   from faq (bg) → contact (bg-warm) provides the separation. */
.contact {
  padding: var(--space-3xl) 0;
  background: var(--color-bg-warm);
}
.contact-layout { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(var(--space-lg), 4vw, var(--space-2xl)); align-items: start; }
.contact-text p {
  color: var(--color-text-muted);
  font-weight: 300;
  margin-bottom: var(--space-lg);
  font-size: 1.05rem; line-height: 1.75;
}
/* AUDIT 2026-04-16: Promoted from inline styles in contact.html. The
   contact page reuses the .contact section but needs a slightly different
   heading treatment (it acts as a page-level intro, not a section title). */
.contact-text h2 {
  font-size: clamp(1.5rem, 1rem + 2vw, 2.5rem);
  font-weight: 400;
  color: var(--color-text);
  margin-bottom: var(--space-lg);
  line-height: 1.2;
}
.contact-text .contact-meta {
  margin-top: var(--space-lg);
  font-size: 0.95rem;
}
.contact-email {
  display: inline-block;
  font-family: var(--font-display);
  font-size: 1.1rem; font-weight: 400;
  color: var(--color-green-dark);
  border-bottom: 1px solid var(--color-mint);
  padding-bottom: 2px;
  transition: all var(--transition);
}
.contact-email:hover { color: var(--color-coral); border-color: var(--color-coral); }
.contact-form { display: flex; flex-direction: column; gap: var(--space-md); }
.form-group { display: flex; flex-direction: column; gap: 0.375rem; }
.form-group label {
  font-family: var(--font-display);
  font-size: 0.78rem; font-weight: 400;
  color: var(--color-text-muted);
  letter-spacing: 0.02em;
}
.form-group input, .form-group textarea {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 1rem; font-weight: 300;
  padding: 0.9rem 1.1rem;
  transition: border-color var(--transition), box-shadow var(--transition);
  outline: none; resize: vertical;
}
/* FIX: Audit finding — styled select to match existing form inputs */
.form-group select {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 0.75rem 1rem;
  font-family: var(--font-body);
  font-size: 0.95rem;
  color: var(--color-text);
  transition: border-color var(--transition), box-shadow var(--transition);
  outline: none;
  cursor: pointer;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%236F7881' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  padding-right: 2.5rem;
}
.form-group select:focus {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 2px rgba(0, 100, 146, 0.15);
}
.form-group input:focus, .form-group textarea:focus {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 2px rgba(0, 100, 146, 0.15);
}
.form-group input::placeholder, .form-group textarea::placeholder { color: var(--color-text-dim); }
@media (max-width: 800px) { .contact-layout { grid-template-columns: 1fr; } }

/* --- FOOTER --- */
/* AUDIT 2026-04: Removed 1px top border (DESIGN.md §2). Footer uses a
   slightly deeper tonal shift (bg-mint) so it reads as "ground level"
   without a line. */
.site-footer {
  padding: var(--space-2xl) 0 var(--space-lg);
  background: var(--color-bg-mint);
}
.footer-container { max-width: var(--max-width); margin: 0 auto; padding: 0 var(--gutter); }
.footer-top {
  display: flex; justify-content: space-between; flex-wrap: wrap;
  gap: var(--space-2xl); margin-bottom: var(--space-2xl);
}
.footer-wordmark {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 400;
  letter-spacing: -0.02em;
  background: linear-gradient(to right, #b03333 0%, #046591 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  display: inline-block;
}
.footer-wordmark .logo-blue { color: inherit; -webkit-text-fill-color: inherit; }
.footer-wordmark .accent { color: inherit; -webkit-text-fill-color: inherit; }
.footer-tagline {
  color: var(--color-text-dim);
  font-size: 0.9rem; font-weight: 300;
  margin-top: var(--space-sm); line-height: 1.6;
}
.footer-links { display: flex; gap: clamp(var(--space-lg), 4vw, var(--space-2xl)); flex-wrap: wrap; }
.footer-col { display: flex; flex-direction: column; gap: 0.5rem; }
.footer-col h4 {
  font-family: var(--font-display);
  font-size: 0.68rem; font-weight: 500;
  letter-spacing: 0.15em; text-transform: uppercase;
  color: var(--color-text-dim);
  margin-bottom: var(--space-xs);
}
.footer-col a {
  font-family: var(--font-display);
  font-size: 0.9rem; font-weight: 300;
  color: var(--color-text-muted);
}
.footer-col a:hover { color: var(--color-text); }
/* AUDIT 2026-04: Removed 1px border — spacing alone does the job.
   (DESIGN.md §5 "Cards & Lists: forbid divider lines.") */
.footer-bottom {
  padding-top: var(--space-md);
}
.footer-bottom p {
  font-family: var(--font-display);
  font-size: 0.7rem; font-weight: 400;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--color-text-dim);
}
@media (max-width: 600px) { .footer-top { flex-direction: column; gap: var(--space-xl); } }


/* ============================================
   LEGAL PAGES (Privacy Policy, Terms)
   ============================================ */
.legal-page {
  padding: calc(var(--space-3xl) + 80px) 0 var(--space-3xl);
  background: var(--color-bg);
  min-height: 100vh;
}
.legal-header {
  margin-bottom: var(--space-xl);
}
.legal-updated {
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 300;
  color: var(--color-text-dim);
  margin-top: var(--space-sm);
}
.legal-body {
  max-width: 780px;
}
.legal-body h2 {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 500;
  color: var(--color-text);
  margin-top: var(--space-lg);
  margin-bottom: var(--space-sm);
  letter-spacing: -0.01em;
}
.legal-body p {
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 300;
  line-height: 1.75;
  color: var(--color-text-muted);
  margin-bottom: var(--space-sm);
}
.legal-body a {
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.legal-body a:hover {
  color: var(--color-accent-hover);
}
.legal-body strong {
  font-weight: 500;
  color: var(--color-text);
}
.legal-body code {
  font-size: 0.85em;
  background: var(--color-bg-warm);
  padding: 0.15em 0.4em;
  border-radius: 4px;
  font-family: monospace;
}


/* ============================================
   MOBILE CAROUSELS — shared horizontal-scroll pattern
   ============================================ */
@media (max-width: 640px) {
  .services-grid,
  .work-grid,
  .process-grid,
  .service-process .process-grid {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    gap: var(--space-md);
    padding-bottom: var(--space-md);
    scrollbar-width: none;
  }
  .services-grid::-webkit-scrollbar,
  .work-grid::-webkit-scrollbar,
  .process-grid::-webkit-scrollbar,
  .service-process .process-grid::-webkit-scrollbar {
    display: none;
  }
  .service-card,
  .work-card {
    flex: 0 0 85%;
    scroll-snap-align: center;
  }
  .process-step,
  .service-process .process-step {
    flex: 0 0 80%;
    scroll-snap-align: center;
  }
  .process-grid,
  .service-process .process-grid {
    gap: 0;
  }
  .step-content h3, .step-content p { text-align: center; }
}
/* (Highlights mobile carousel moved after base .highlights-grid styles to fix CSS cascade) */

/* ============================================
   MOBILE CAROUSEL SCROLL INDICATORS
   ============================================ */
.scroll-dots {
  display: none;
}
@media (max-width: 640px) {
  .scroll-dots {
    display: flex;
    justify-content: center;
    gap: 0.5rem;
    padding-top: var(--space-xs);
  }
  .scroll-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--color-border);
    border: none;
    padding: 0;
    cursor: pointer;
    transition: background 0.25s, transform 0.25s;
  }
  .scroll-dot.is-active {
    background: var(--color-accent);
    transform: scale(1.25);
  }
}


/* ============================================
   COOKIE CONSENT BANNER
   Rendered as a CENTERED MODAL at every breakpoint.
   Why: bottom-pinned banners get clipped by browser
   chrome (iOS Chrome's bottom URL bar overlay, some
   desktop browsers' download/notification trays) and
   a top banner pushes the page content down. A
   centred floating card with a soft dim-the-page
   backdrop sidesteps all of that and is the
   conventional cookie-consent pattern users expect.
   ============================================ */
.cookie-banner {
  position: fixed;
  /* Centered card layout — works at every viewport size. */
  top: 50%;
  left: 50%;
  right: auto;
  bottom: auto;
  width: min(calc(100vw - 2 * var(--space-md)), 520px);
  max-width: 520px;
  z-index: 9999;
  background: var(--color-green-dark);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--radius-md, 14px);
  padding: var(--space-md) var(--space-lg, 1.75rem);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45),
              0 0 0 100vmax rgba(8, 22, 30, 0.45);
  /* Hidden state: centred but scaled down + invisible + click-through */
  transform: translate(-50%, -50%) scale(0.94);
  opacity: 0;
  pointer-events: none;
  transition: transform 0.32s cubic-bezier(0.22, 1, 0.36, 1),
              opacity 0.25s ease-out;
  /* `clip-path` lets the giant outer box-shadow act as a soft
     dim-the-page backdrop without us needing an extra DOM element. */
  clip-path: inset(-100vmax round var(--radius-md, 14px));
}
.cookie-banner.is-visible {
  transform: translate(-50%, -50%) scale(1);
  opacity: 1;
  pointer-events: auto;
}
.cookie-banner-inner {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-sm);
  text-align: center;
}
.cookie-banner-text {
  font-family: var(--font-body);
  font-size: 0.88rem;
  font-weight: 300;
  color: rgba(255, 255, 255, 0.82);
  line-height: 1.6;
  margin: 0;
}
.cookie-banner-text a {
  color: rgba(255, 255, 255, 0.95);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.cookie-banner-text a:hover {
  color: #fff;
}
.cookie-banner-actions {
  display: flex;
  justify-content: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.cookie-btn {
  font-family: var(--font-display);
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  padding: 0.6rem 1.4rem;
  border-radius: var(--radius-pill, 50px);
  border: none;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}
.cookie-btn-accept {
  background: var(--color-accent);
  color: #fff;
}
.cookie-btn-accept:hover {
  background: var(--color-accent-hover);
}
.cookie-btn-decline {
  background: transparent;
  color: rgba(255, 255, 255, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.15);
}
.cookie-btn-decline:hover {
  color: rgba(255, 255, 255, 0.9);
  border-color: rgba(255, 255, 255, 0.3);
}
@media (max-width: 600px) {
  /* On phones, tighten the modal and bump tap targets. */
  .cookie-banner {
    width: min(calc(100vw - 2 * var(--space-md)), 420px);
    max-width: 420px;
    padding: var(--space-md);
  }
  .cookie-banner-text {
    font-size: 0.82rem;
    line-height: 1.55;
  }
  .cookie-banner-actions {
    width: 100%;
    gap: 0.6rem;
  }
  .cookie-btn {
    /* Larger tap target on mobile — Apple/Google guidance is 44px+. */
    padding: 0.75rem 1.4rem;
    min-height: 44px;
    /* Prevent iOS double-tap-zoom delay on the button. */
    touch-action: manipulation;
  }
}


/* ============================================
   SCROLL-SCRUBBED ANIMATION SUPPORT
   JS directly sets transform/opacity every frame.
   NO CSS transitions on scrubbed elements — they
   would fight the JS and cause mushy lag.
   ============================================ */

/* --- SCROLL PROGRESS BAR --- */
.scroll-progress {
  position: fixed;
  top: 0; left: 0;
  height: 3px;
  width: 0%;
  background: linear-gradient(90deg, var(--color-accent), var(--color-coral));
  z-index: 10000;
  pointer-events: none;
  /* No transition — JS drives width directly */
}

/* --- NAV HIDE/SHOW (disabled — pill replaces this) --- */

/* --- NAV ACTIVE LINK INDICATOR --- */
.nav-links a.active {
  color: var(--color-text);
}
.nav-links a {
  position: relative;
}
.nav-links a::after {
  content: '';
  position: absolute;
  bottom: -4px; left: 50%;
  width: 0; height: 1.5px;
  background: var(--color-accent);
  transition: width 0.3s var(--ease-out), left 0.3s var(--ease-out);
}
.nav-links a.active::after,
.nav-links a:hover::after {
  width: 100%; left: 0;
}
@media (max-width: 1024px) {
  .nav-links a::after { display: none; }
}

/* --- SCRUBBED ELEMENTS: will-change kept minimal ---
   Too many will-change layers hurts performance (each creates a
   GPU compositing layer). Only promote elements that animate
   continuously. Section headers, stats, etc. animate once on
   scroll-in and don't need permanent promotion. */
.hero-orb,
.service-card,
.process-step {
  will-change: transform, opacity;
}
.work-card {
  /* 2026-05-13 (perf): dropped `filter` from will-change. The blur-to-
     sharp scroll-scrub on .work-card was the single most expensive
     paint operation on the homepage at wide viewports — `filter: blur`
     on a card-sized compositor layer costs proportional to area, and
     animate() was setting it every scroll frame. Filter removed from
     animate() (scripts.js) and from will-change here so the cards no
     longer reserve a filter buffer. */
  will-change: transform, opacity;
}

/* --- INTERACTIVE ELEMENTS: always clickable even during scroll fade --- */
.hero-actions,
.btn,
.faq-item summary,
.contact-form button,
.contact-form input,
.contact-form textarea {
  pointer-events: auto !important;
}

/* Cards still need border-color transition for hover */
.service-card,
.work-card {
  transition: border-color var(--transition), transform 0.2s ease-out;
}

/* --- FAQ SMOOTH OPEN/CLOSE --- */
.faq-answer {
  animation: faqOpen 0.35s var(--ease-out);
}
@keyframes faqOpen {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* --- PAGE HERO (text left, faded background image right) --- */
.page-hero {
  position: relative;
  padding: clamp(7rem, 14vw, 10rem) 0 clamp(4rem, 8vw, 6rem);
  background: var(--color-bg);
  overflow: hidden;
}
.page-hero .page-hero-bg {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 100%;
  z-index: 0;
  pointer-events: none;
}
.page-hero .page-hero-bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center right;
  -webkit-mask-image: linear-gradient(to right, transparent 15%, rgba(0,0,0,0.08) 40%, rgba(0,0,0,0.18) 70%, rgba(0,0,0,0.22) 100%);
  mask-image: linear-gradient(to right, transparent 15%, rgba(0,0,0,0.08) 40%, rgba(0,0,0,0.18) 70%, rgba(0,0,0,0.22) 100%);
}
.page-hero .section-container {
  position: relative; z-index: 2;
  max-width: var(--max-width);
}
.page-hero-text {
  max-width: 560px;
}
.page-hero .section-label {
  margin-bottom: var(--space-md);
}
.page-hero .section-title {
  margin-bottom: var(--space-md);
  font-size: clamp(2.2rem, 1.4rem + 3.5vw, 3.8rem);
}
.page-hero .section-intro {
  font-size: 1.15rem;
  color: var(--color-text-muted);
  max-width: 520px;
  font-weight: 300;
  line-height: 1.7;
}
.page-hero .hero-actions {
  display: flex; gap: var(--space-sm); flex-wrap: wrap;
  margin-top: var(--space-lg);
}
@media (max-width: 800px) {
  .page-hero {
    padding: clamp(6rem, 10vw, 8rem) 0 clamp(3rem, 6vw, 4rem);
  }
  .page-hero .section-title {
    font-size: clamp(1.8rem, 1rem + 3vw, 2.8rem);
  }
  .page-hero .page-hero-bg img {
    -webkit-mask-image: linear-gradient(to bottom, transparent 10%, rgba(0,0,0,0.1) 50%, rgba(0,0,0,0.15) 100%);
    mask-image: linear-gradient(to bottom, transparent 10%, rgba(0,0,0,0.1) 50%, rgba(0,0,0,0.15) 100%);
  }
}


/* --- SERVICE HIGHLIGHTS (3-card grid, numbered) --- */
.service-highlights {
  padding: var(--space-3xl) 0;
  background: var(--color-bg);
}
.highlights-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-md);
}
/* AUDIT 2026-04: highlight-card border removed — uses tonal-layered shadow
   on hover instead (DESIGN.md §4 "Ambient Shadows"). */
.highlight-card {
  background: var(--color-surface);
  border-radius: var(--radius-lg);
  padding: var(--space-lg);
  transition: all var(--transition);
  position: relative;
  overflow: hidden;
}
.highlight-card::before {
  content: ''; position: absolute;
  top: 0; left: 0; right: 0; height: 3px;
  background: linear-gradient(90deg, var(--color-coral), var(--color-accent));
  opacity: 0; transition: opacity var(--transition);
}
.highlight-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 20px 48px rgba(23, 28, 31, 0.06);
}
.highlight-card:hover::before { opacity: 1; }
.highlight-card::after {
  content: '';
  position: absolute;
  top: 0; right: 0; bottom: 0; width: 100%;
  background-position: center center;
  background-size: cover;
  background-repeat: no-repeat;
  opacity: 0.12;
  pointer-events: none;
  /* no directional fade — even coverage */
}
/* Highlight card backgrounds — first declaration is the PNG fallback for older
   browsers; the second uses image-set() to serve WebP where supported, with
   PNG as the in-set fallback. Saves ~90% bytes per image in modern browsers. */
.highlight-card--responsive::after { background-image: url('IWD_Responsive.webp'); }
.highlight-card--seo::after        { background-image: url('IWD_SEO.webp'); }
.highlight-card--custom::after     { background-image: url('IWD_Custom.webp'); }
.highlight-card--clean::after      { background-image: url('CAD_Clean.webp'); }
.highlight-card--scalable::after   { background-image: url('CAD_Scalable.webp'); }
.highlight-card--secure::after     { background-image: url('CAD_Secure.webp'); }
.highlight-card--smart::after      { background-image: url('ML_Smart.webp'); }
.highlight-card--flexible::after   { background-image: url('ML_Flexible.webp'); }
.highlight-card--production::after { background-image: url('ML_Production.webp'); }
.highlight-card > * { position: relative; z-index: 1; }
.highlight-number {
  font-family: var(--font-display);
  font-size: 0.72rem; font-weight: 500;
  color: var(--color-accent);
  letter-spacing: 0.1em;
  margin-bottom: var(--space-md);
}
/* AUDIT 2026-04: mid-tier typography bump — was 1.2rem, now 1.55rem. */
.highlight-card h3 {
  font-size: 1.55rem; font-weight: 400;
  color: var(--color-text); margin-bottom: var(--space-sm);
  letter-spacing: -0.01em;
}
/* AUDIT 2026-04: highlight-number now coral to match service-number (coral
   "spark" for numbered moments, DESIGN.md §2). */
.highlight-card .highlight-number { color: var(--color-coral); }
.highlight-card p {
  color: var(--color-text-muted);
  font-size: 0.95rem; font-weight: 300;
  line-height: 1.75; margin: 0;
}
/* --- HIGHLIGHTS: mobile horizontal scroll carousel --- */
@media (max-width: 900px) {
  .highlights-grid {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    gap: var(--space-md);
    padding-bottom: var(--space-md);
    scrollbar-width: none;
  }
  .highlights-grid::-webkit-scrollbar { display: none; }
  .highlight-card {
    flex: 0 0 85%;
    scroll-snap-align: center;
  }
}

/* --- SERVICE PROCESS (on service pages — alternating bg + background image) --- */
/* AUDIT 2026-04: Removed top/bottom 1px borders (DESIGN.md §2). */
.service-process {
  padding: var(--space-3xl) 0;
  background: var(--color-mint-pale);
  position: relative;
  overflow: hidden;
}
.service-process::before {
  content: '';
  position: absolute;
  inset: 0;
  background: url('Idea_Launch.webp') center / cover no-repeat;
  opacity: 0.06;
  pointer-events: none;
}
.service-process > .section-container {
  position: relative;
  z-index: 1;
}

/* --- CTA SECTION (dark, immersive) --- */
.cta-section {
  padding: var(--space-3xl) 0;
  background: linear-gradient(160deg, #0D1114 0%, #171C1F 50%, #1E2A32 100%);
  position: relative;
  overflow: hidden;
}
.cta-section .cta-orb {
  position: absolute; border-radius: 50%; filter: blur(120px); pointer-events: none;
}
.cta-section .cta-orb-1 {
  width: 300px; height: 300px;
  background: radial-gradient(circle, #2D9CDB, var(--color-accent));
  opacity: 0.1; top: -20%; left: 10%;
}
.cta-section .cta-orb-2 {
  width: 200px; height: 200px;
  background: radial-gradient(circle, #D46A6E, #AE2F34);
  opacity: 0.06; bottom: -10%; right: 15%;
}
.cta-content {
  max-width: 640px;
  margin: 0 auto;
  text-align: center;
  position: relative;
  z-index: 2;
}
.cta-content h2 {
  font-size: clamp(1.75rem, 1.3rem + 2vw, 2.5rem);
  margin-bottom: var(--space-md);
  background: linear-gradient(to right, #e8e8e8 0%, #ffffff 40%, #2D9CDB 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  display: inline-block;
  width: 100%;
  padding-bottom: 0.1em;
}
.cta-content p {
  color: rgba(255, 255, 255, 0.55);
  font-size: 1.05rem;
  font-weight: 300;
  line-height: 1.75;
  margin-bottom: var(--space-lg);
}
.cta-content .btn-outline {
  border-color: rgba(255, 255, 255, 0.2);
  color: rgba(255, 255, 255, 0.8);
}
.cta-content .btn-outline:hover {
  border-color: var(--color-accent);
  color: #ffffff;
}

/* --- SERVICE PAGES RESPONSIVE --- */
@media (max-width: 1024px) {
  .service-process .process-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
/* Service page process mobile carousel handled in shared block below */


/* --- NAV CURRENT PAGE INDICATOR --- */
.nav-current {
  color: var(--color-accent) !important;
}
.nav-links-mobile .nav-current {
  color: var(--color-accent) !important;
}


/* ============================================
   AUDIT 2026-04: ADDITIONS
   All new styles from the April 2026 design audit
   live in this block so they can be removed or
   toggled cleanly. Every rule is annotated with
   the audit finding it addresses.
   ============================================ */

/* AUDIT 2026-04: Nav CTA in coral — was muted grey, losing the brand spark
   on the primary conversion surface. Coral matches DESIGN.md "Tertiary"
   button role (human / high-emotion actions). */
.nav-links .nav-cta {
  color: var(--color-coral);
  font-weight: 600;
}
.nav-links .nav-cta:hover {
  color: var(--color-coral);
  opacity: 0.8;
}

/* AUDIT 2026-04 (revised 2026-04-16): Chevron shows on MOBILE ONLY.
   Previous attempt showed it in the desktop collapsed pill, but the chevron
   was a flex child of .nav-logo with a 0.75rem gap — that made flex-centring
   in the 72px collapsed container use the combined (img + chevron) width,
   pushing the logo image left of centre. Fix: chevron lives only on mobile,
   where the logo pill has room to breathe and the chevron serves as an
   explicit "tap to expand menu" hint. On desktop the pill's changing shape
   and hover behaviour is sufficient discoverability. */
.nav-chevron {
  display: none;
  position: absolute;
  left: calc(100% + 0.35rem);
  top: 50%;
  transform: translateY(-50%);
  font-size: 0.6rem;
  opacity: 0.5;
  color: var(--color-coral);
  transition: transform 0.3s var(--ease-out), opacity 0.3s ease;
  pointer-events: none;
}
@media (max-width: 1024px) {
  /* AUDIT 2026-04-16: On mobile the chevron read as visual noise next to the
     logo (coral ▾, 0.6rem, opacity 0.5 = "odd looking small red down arrow"
     per user report). The hamburger button at top-right is the established
     menu affordance — no second hint needed. Chevron stays defined above in
     case we want to reintroduce it, but it's suppressed on the breakpoint
     where it was previously shown. */
  .nav-logo { position: relative; }
  .nav-chevron { display: none; }
}

/* AUDIT 2026-04: Hero scroll cue — users were landing on a full-viewport
   hero with no signal that content continues below. A small "Scroll" text
   + chevron in Outfit 500 / uppercase / 0.65rem, fading in after 2s. */
.hero-scroll-cue {
  position: absolute;
  left: 50%;
  bottom: 2rem;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-display);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  opacity: 0;
  transition: opacity 0.6s ease;
  z-index: 5;
  pointer-events: none;
}
.hero-scroll-cue.is-visible { opacity: 0.7; }
.hero-scroll-cue .cue-line {
  width: 1px;
  height: 28px;
  background: linear-gradient(to bottom, var(--color-coral), transparent);
  animation: cueDrop 2.4s cubic-bezier(0.7, 0, 0.3, 1) infinite;
}
@keyframes cueDrop {
  0%   { transform: scaleY(0); transform-origin: top; opacity: 0; }
  40%  { transform: scaleY(1); transform-origin: top; opacity: 1; }
  60%  { transform: scaleY(1); transform-origin: bottom; opacity: 1; }
  100% { transform: scaleY(0); transform-origin: bottom; opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-scroll-cue .cue-line { animation: none; }
}

/* AUDIT 2026-04 (revised 2026-04-16): Asymmetric services layout removed.
   The staggered-margin uneven-column trick read as misaligned rather than
   editorial. The balanced 3-up grid with premium card craft (see .service-card
   block above) delivers the "intentional" feel without the jitter. The
   .services-grid--asymmetric class is no longer used in markup — leaving
   this comment as a trail for anyone grep-ing for the audit. */

/* AUDIT 2026-04: Coral arrow inline link — replaces the weak ".btn-outline
   Learn more" secondary buttons on service cards with an editorial text
   link that earns more attention than the previous pill while feeling less
   SaaS-boilerplate. Uses coral to reinforce brand spark. */
.arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: var(--space-md);
  font-family: var(--font-display);
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--color-coral);
  text-decoration: none;
  transition: gap 0.25s var(--ease-out), color 0.25s;
  padding: 0.2rem 0;
  border-bottom: 1px solid transparent;
  width: fit-content;
}
.arrow-link::after {
  content: '→';
  font-size: 1rem;
  transition: transform 0.25s var(--ease-out);
}
.arrow-link:hover {
  gap: 0.7rem;
  color: var(--color-accent);
}
.arrow-link:hover::after { transform: translateX(2px); }

/* AUDIT 2026-04: Principles section — social proof / trust block between
   Work and About. Three opinionated one-liners that show taste. Addresses
   the audit's "missing: social proof, anywhere" finding. Laid out
   asymmetrically: heading left, principles right in an editorial
   two-column grid. */
.principles {
  padding: var(--space-3xl) 0;
  background: var(--color-bg);
  position: relative;
}

/* ===== Brand mark inside the About image column ========================
   2026-05: The drafting-table M construct lives in the .about-image-col
   slot, replacing the old Studio.webp. Acts as a *demonstration* of the
   "Better thinking. Better software." claim in the adjacent text — the
   mark itself is shown as something carefully constructed from guides
   and tick marks, not generated. scripts.js drives the build via scroll
   progress through the About section. (The .pc-* class names are kept
   from earlier iterations; renaming churns JS without changing behaviour.)
   ======================================================================= */
.about-image-col--construct {
  display: flex;
  align-items: center;
  justify-content: center;
  /* No min-height stretch — let the construct sit at its natural size.
     The grid's align-items: center vertically centres it against the
     taller text column. No padding so the M sits tight in its slot. */
  min-height: auto;
  padding: 0;
}
.about-construct-svg {
  width: 100%;
  height: auto;
  display: block;
  /* viewBox is cropped to 1150 × 1090 in the HTML — close to 1:1.
     Match that ratio here so the column doesn't add letterbox. */
  aspect-ratio: 1150 / 1090;
  overflow: visible;
}
@media (max-width: 900px) {
  /* Hide the M construct on mobile. With the about-layout collapsing
     to a single column, the M ended up isolated below the founder copy
     and didn't read well. Mobile users get the founder bio + stats
     card; desktop keeps the construct in the right-hand column. */
  .about-image-col--construct {
    display: none;
  }
}
.pc-guides line,
.pc-guides path,
.pc-guides circle {
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.pc-tick      { stroke-width: 1.2 !important; }
.pc-crosshair { stroke-width: 1.4 !important; }
.pc-label {
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 22px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  fill: var(--color-accent);
}
.pc-stroke {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  /* Default initial state — hidden until JS scrub (desktop) or CSS
     keyframes (mobile, via .is-playing) reveal. Without this, the M
     renders fully on first paint before JS executes, causing a brief
     flash that catches the eye. Paths have pathLength="1" so this
     hides them via the normalised 0..1 dash space. */
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  opacity: 0;
}
.pc-stroke-teal      { stroke: #046081; stroke-width: 186; }
.pc-stroke-teal-dark { stroke: #03506a; stroke-width: 178; }
.pc-stroke-gold-lt   { stroke: #d5a73f; stroke-width: 178; }
.pc-stroke-gold      { stroke: #c08c30; stroke-width: 186; }
/* Guides default hidden (matches strokes). */
.pc-guides > * { opacity: 0; }
.pc-dot {
  fill: #e05e4f;
  /* Default hidden. JS animates via the SVG `r` attribute (desktop)
     or CSS transform: scale (mobile, see mobile @media block). */
  opacity: 0;
}
@media (max-width: 700px) {
  /* On small screens the dimension labels become too cramped to read —
     hide them and let the M strokes carry the moment. */
  .pc-label { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  /* No animation — render the peak resolved state directly. */
  .pc-stroke { stroke-dasharray: none !important; stroke-dashoffset: 0 !important; opacity: 0.70; }
  .pc-guides > * { opacity: 0.14; }
  .pc-dot { opacity: 1; transform: scale(1); }
}

/* ===========================================================
   MOBILE — auto-play the M construction when the About section
   enters the viewport. scripts.js attaches an IntersectionObserver
   to .about-image-col--construct and adds the .is-playing class
   when it scrolls into view; these keyframes then run once, in
   sequence, exactly mirroring the desktop scroll-driven timeline.
   Animation-fill-mode: forwards holds the settled state.
   =========================================================== */
@media (max-width: 900px) {
  /* Initial hidden state on mobile. JS scrub (ScrollTrigger) overrides
     these via inline style as the user scrolls. The .is-playing CSS
     keyframes (further down) only kick in as a fallback when GSAP
     fails to load.

     IMPORTANT: do NOT set `transform: scale(0)` here. The JS scrub
     animates the dot via the SVG `r` attribute, not CSS transform —
     a default `transform: scale(0)` would persist throughout the
     scroll and scale the dot to nothing even when `r=70`, making
     the dot permanently invisible on mobile. transform-box +
     transform-origin are kept so the keyframe fallback (which DOES
     use transform: scale) scales around the dot's own centre. */
  .pc-stroke {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    opacity: 0;
  }
  .pc-guides > * { opacity: 0; }
  .pc-dot {
    opacity: 0;
    transform-box: fill-box;
    transform-origin: 50% 50%;
  }

  /* Stroke 1 — teal leg. Hidden from 0% to 8% of the cycle,
     opacity ramps to 0.70 around 10%, dashoffset reaches 0 at
     22%, settles to 0.45 by 78%. Mirrors scripts.js range [0.08,0.22]
     for desktop scrub. */
  /* No settle phase — M holds at peak opacity once built. */
  @keyframes pcBuildStroke1 {
    0%, 8%  { stroke-dashoffset: 1; opacity: 0; }
    11%     { opacity: 0.70; }
    22%     { stroke-dashoffset: 0; opacity: 0.70; }
    100%    { stroke-dashoffset: 0; opacity: 0.70; }
  }
  @keyframes pcBuildStroke2 {
    0%, 18% { stroke-dashoffset: 1; opacity: 0; }
    21%     { opacity: 0.70; }
    34%     { stroke-dashoffset: 0; opacity: 0.70; }
    100%    { stroke-dashoffset: 0; opacity: 0.70; }
  }
  @keyframes pcBuildStroke3 {
    0%, 30% { stroke-dashoffset: 1; opacity: 0; }
    33%     { opacity: 0.70; }
    46%     { stroke-dashoffset: 0; opacity: 0.70; }
    100%    { stroke-dashoffset: 0; opacity: 0.70; }
  }
  @keyframes pcBuildStroke4 {
    0%, 42% { stroke-dashoffset: 1; opacity: 0; }
    45%     { opacity: 0.70; }
    58%     { stroke-dashoffset: 0; opacity: 0.70; }
    100%    { stroke-dashoffset: 0; opacity: 0.70; }
  }
  @keyframes pcBuildDot {
    0%, 56% { transform: scale(0); opacity: 0; }
    62%     { transform: scale(1.15); opacity: 1; } /* back-out overshoot */
    66%     { transform: scale(1); opacity: 1; }
    100%    { transform: scale(1); opacity: 1; }
  }
  @keyframes pcBuildGuides {
    0%      { opacity: 0; }
    8%      { opacity: 0.14; }
    100%    { opacity: 0.14; }
  }

  /* When .is-playing is added by the IntersectionObserver, kick off
     all six animations. 5s duration (slower than the desktop pin) +
     alternate direction + infinite — so the M builds slowly, holds,
     then "undraws" itself in reverse, then rebuilds, in a continuous
     loop. Mesmerising brand mark on mobile. */
  .about-image-col--construct.is-playing .pc-stroke-teal      { animation: pcBuildStroke1 5s cubic-bezier(0.45, 0, 0.25, 1) infinite alternate; }
  .about-image-col--construct.is-playing .pc-stroke-teal-dark { animation: pcBuildStroke2 5s cubic-bezier(0.45, 0, 0.25, 1) infinite alternate; }
  .about-image-col--construct.is-playing .pc-stroke-gold-lt   { animation: pcBuildStroke3 5s cubic-bezier(0.45, 0, 0.25, 1) infinite alternate; }
  .about-image-col--construct.is-playing .pc-stroke-gold      { animation: pcBuildStroke4 5s cubic-bezier(0.45, 0, 0.25, 1) infinite alternate; }
  .about-image-col--construct.is-playing .pc-dot              { animation: pcBuildDot 5s ease-out infinite alternate; }
  .about-image-col--construct.is-playing .pc-guides > *       { animation: pcBuildGuides 5s ease-out infinite alternate; }
}
.principles-layout {
  display: grid;
  grid-template-columns: 1fr 1.5fr;
  gap: clamp(var(--space-lg), 5vw, var(--space-2xl));
  align-items: start;
}
.principles-header .section-title { font-size: clamp(1.8rem, 1.2rem + 2.5vw, 3rem); }
.principles-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xl);
}
.principle {
  display: grid;
  grid-template-columns: 3rem 1fr;
  gap: var(--space-md);
  align-items: start;
}
.principle-number {
  font-family: var(--font-display);
  font-size: 0.72rem; font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--color-coral);
  padding-top: 0.35rem;
}
.principle-body h3 {
  font-size: 1.45rem;
  font-weight: 400;
  color: var(--color-text);
  margin-bottom: var(--space-xs);
  letter-spacing: -0.01em;
  line-height: 1.3;
}
.principle-body p {
  color: var(--color-text-muted);
  font-weight: 300;
  font-size: 1rem;
  line-height: 1.75;
}
@media (max-width: 900px) {
  .principles-layout { grid-template-columns: 1fr; gap: var(--space-xl); }
  .principle { grid-template-columns: 2.5rem 1fr; gap: var(--space-sm); }
}

/* AUDIT 2026-04: Smooth FAQ open/close — closes animate as well as open. */
.faq-answer-inner {
  overflow: hidden;
}

/* ═══════════════════════════════════════════════
   AUDIT 2026-04-16: HERO COMET + STRAPLINE
   The brand-mark moment. Canvas sits above the
   shader but below the content layer. Pointer-none
   throughout (ambient, not interactive).
   ═══════════════════════════════════════════════ */
.hero-comet {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1.2s ease;
}
.hero-comet.is-ready {
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  .hero-comet { display: none; }
}

/* Hero strapline — a small kerned brand mark above the H1.
   Three-part composition: left rule, "Mirentha", right rule.
   Feels editorial; gives the hero a "title card" rhythm. */
.hero-strapline {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: var(--space-md);
  opacity: 0;
  transform: translateY(6px);
  animation: strapReveal 1.1s cubic-bezier(0.2, 0.9, 0.25, 1) 0.3s forwards;
}
/* AUDIT 2026-04-16 (v2): Strapline text now uses the brand blue→coral
   gradient via background-clip: text — mirroring the hero H1's treatment
   at a smaller scale. The flanking rules follow the same gradient so
   the whole composition reads as one coherent brand mark. */
.hero-strapline-text {
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  white-space: nowrap;
  background: linear-gradient(90deg, #046591 0%, #b03333 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent; /* fallback colour just in case */
}
.hero-strapline-rule {
  display: inline-block;
  width: 2.25rem;
  height: 1px;
  opacity: 0.6;
  /* Left rule fades FROM transparent INTO teal (leading into the text) */
  background: linear-gradient(90deg, transparent 0%, #046591 100%);
}
.hero-strapline-rule:last-child {
  /* Right rule fades FROM coral (continuing the text colour) INTO transparent */
  background: linear-gradient(90deg, #b03333 0%, transparent 100%);
}
@keyframes strapReveal {
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-strapline {
    animation: none;
    opacity: 1;
    transform: none;
  }
}

/* AUDIT 2026-04: Stat values get coral highlight option — used for the
   "15+ yrs" stat to bring the "human spark" into the about rail. */
.stat-value--coral { color: var(--color-coral); }

/* ===========================================================
   2026-05: HERO PLOTTER — replaces the comet-era visual stack.
   Five layered topographic contour lines drawn from a sine-sum
   field; cursor proximity warps them via a Gaussian "warm front."
   Drawn by plotter.js. The old .hero-shader / .hero-visual /
   .hero-orb / .hero-comet rules earlier in this file no longer
   match any markup (the elements are gone from index.html) and
   can be deleted in a later cleanup pass.
   =========================================================== */
.hero-plotter {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* 2026-05: was z-index: 10 (from the Stage 02 Plotter preview, where
     the hero-layout didn't have its own z-index). On the real site the
     hero-layout sits at z-index: 4, so a plotter above 4 draws the
     contour lines OVER the buttons and breaks the entrance animation.
     z-index: 1 puts it behind the cursor glow, grain, and content. */
  z-index: 1;
  pointer-events: none;
  /* 2026-05: Horizontal mask gradient so the contour lines fade on the
     left where the H1, buttons, and sub-copy live. Lines aren't hidden
     completely (that would feel arbitrary) — they sit at ~25% on the
     far left and ramp to full strength by mid-hero. Tune the percentages
     to taste; lower starting opacity = quieter text area. */
  -webkit-mask-image: linear-gradient(
    to right,
    rgba(0, 0, 0, 0.22) 0%,
    rgba(0, 0, 0, 0.45) 28%,
    rgba(0, 0, 0, 0.80) 50%,
    #000 65%
  );
          mask-image: linear-gradient(
    to right,
    rgba(0, 0, 0, 0.22) 0%,
    rgba(0, 0, 0, 0.45) 28%,
    rgba(0, 0, 0, 0.80) 50%,
    #000 65%
  );
}
/* Mobile: the text column fills the whole width, so the mask would
   just hide most of the hero. Drop it on small screens — the lines
   are already faint enough at narrow viewports. */
@media (max-width: 780px) {
  .hero-plotter {
    -webkit-mask-image: none;
            mask-image: none;
  }
}
.hero-plotter path.plot-contour {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

/* Editorial corner readout — mono numbers in top-right, faint.
   Quiet "studio with a system" touch. Hidden on mobile. */
.hero-plotter-readout {
  position: absolute;
  top: 6rem;
  right: 2rem;
  z-index: 40;
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 0.65rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  text-align: right;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  pointer-events: none;
  opacity: 0;
}
.hero-plotter-readout b   { color: var(--color-text); font-weight: 500; }
.hero-plotter-readout .val { color: var(--color-coral); }

@media (max-width: 780px) {
  .hero-plotter-readout { display: none; }
  /* Topmost contour gets a hair thinner on small screens so the
     H1 reads cleanly without contour weight competing. */
  .hero-plotter path.plot-contour[data-layer="0"] { stroke-width: 1.2; }
}
