/* ==========================================================================
   Arkio. — design system
   ========================================================================== */

@font-face {
  font-family: 'Gilroy';
  src: url('../fonts/GilroyExtraBold.ttf') format('truetype');
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}

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

:root {
  --red: #BD001F;
  --red-dark: #8F0018;
  --red-soft: rgba(189, 0, 31, 0.08);
  --red-soft-2: rgba(189, 0, 31, 0.16);
  --white: #FFFFFF;
  --off-white: #FAFAFA;
  --paper: #F2F0EE;
  --off-black: #0D0D0D;
  --grey: #6B6B6B;
  --grey-light: #DEDBDA;
  --grey-lighter: #EFEDEC;

  --radius: 16px;
  --radius-sm: 10px;
  --radius-pill: 999px;
  --container: 1200px;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

  --font-display: 'Gilroy', 'Public Sans', sans-serif;
  --font-body: 'Public Sans', sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, monospace;

  --shadow-card: 0 2px 8px -4px rgba(13, 13, 13, 0.06);
  --shadow-card-hover: 0 20px 40px -20px rgba(13, 13, 13, 0.22);
}

html { scroll-behavior: smooth; }

body {
  background: var(--off-white);
  color: var(--off-black);
  font-family: var(--font-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

body.intro-active { overflow: hidden; height: 100vh; }

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; }
button { font: inherit; background: none; border: none; }

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.05em;
  color: var(--off-black);
}

h1 { font-size: clamp(2.6rem, 5.4vw, 4.6rem); }
h2 { font-size: clamp(1.9rem, 3.2vw, 2.7rem); margin-bottom: 0.9rem; max-width: 620px; }
h3 { font-size: 1.15rem; letter-spacing: -0.02em; margin-bottom: 0.5rem; }

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

:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 3px;
  border-radius: 4px;
}

.text-accent { color: var(--red); }

.skip-link {
  position: absolute;
  top: -48px;
  left: 24px;
  z-index: 10001;
  background: var(--red);
  color: var(--white);
  font-weight: 700;
  font-size: 0.9rem;
  padding: 0.7rem 1.2rem;
  border-radius: var(--radius-sm);
  transition: top 0.2s var(--ease);
}
.skip-link:focus { top: 12px; }

/* Shared base card look. Defined early so component-specific classes
   (.industry-card, .price-card, .price-card-featured, .contact-form)
   can compose on top of it later in the cascade and still win on any
   property they override. */
.card {
  background: var(--white);
  border: 1px solid var(--grey-light);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
}

.section-sub {
  color: var(--grey);
  max-width: 540px;
  margin: 0 0 3.6rem;
  font-size: 1.02rem;
  line-height: 1.65;
}
.section-sub em { color: var(--off-black); font-style: normal; font-weight: 600; }

.required-mark { color: var(--red); margin-left: 2px; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 50px;
  padding: 0.9rem 1.9rem;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.97rem;
  border: 1.5px solid transparent;
  cursor: pointer;
  touch-action: manipulation;
  /* No box-shadow in this list: shadow interpolation repaints the pill
     every frame of the 0.3s hover, which stutters alongside the hero's
     pointer parallax. The translateY lift carries the motion instead. */
  transition: transform 0.3s var(--ease), background 0.25s var(--ease), color 0.25s var(--ease), border-color 0.25s var(--ease);
  white-space: nowrap;
}
.btn-primary {
  position: relative;
  overflow: hidden;
  background: var(--red);
  color: var(--white);
  box-shadow: 0 10px 24px -12px rgba(189, 0, 31, 0.55);
}
/* Specular shine that sweeps across on hover */
.btn-primary::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 40%;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, 0.35), transparent);
  transform: translateX(-160%) skewX(-18deg);
  pointer-events: none;
}
.btn-primary:hover::after {
  transform: translateX(320%) skewX(-18deg);
  transition: transform 0.7s var(--ease);
}
.btn-primary:hover {
  background: var(--red-dark);
  transform: translateY(-2px);
}
.btn-primary:active { transform: translateY(0) scale(0.98); }

.btn-ghost {
  position: relative;
  overflow: hidden;
  background: transparent;
  border-color: var(--grey-light);
  color: var(--off-black);
}
/* Same specular sweep as the primary button, tinted red so it reads
   on the ghost's light hover fill */
.btn-ghost::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 40%;
  background: linear-gradient(105deg, transparent, rgba(189, 0, 31, 0.16), transparent);
  transform: translateX(-160%) skewX(-18deg);
  pointer-events: none;
}
.btn-ghost:hover::after {
  transform: translateX(320%) skewX(-18deg);
  transition: transform 0.7s var(--ease);
}
.btn-ghost:hover { border-color: var(--red); background: var(--red-soft); color: var(--red); transform: translateY(-2px); }
.btn-ghost:active { transform: translateY(0) scale(0.98); }

.btn-pill {
  position: relative;
  overflow: hidden;
  background: var(--white);
  color: var(--red);
  min-height: 44px;
  padding: 0.6rem 1.5rem;
  font-size: 0.92rem;
}
/* The header pill gets the primary's shine sweep too — white light
   crossing the black hover fill */
.btn-pill::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 40%;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, 0.4), transparent);
  transform: translateX(-160%) skewX(-18deg);
  pointer-events: none;
}
.btn-pill:hover::after {
  transform: translateX(320%) skewX(-18deg);
  transition: transform 0.7s var(--ease);
}
.btn-pill:hover { background: var(--off-black); color: var(--white); transform: translateY(-2px); }
.btn-pill:active { transform: translateY(0) scale(0.97); }
.header-cta-arrow {
  display: inline-block;
  width: 0;
  margin-left: 0;
  overflow: hidden;
  opacity: 0;
  transition: width 0.25s var(--ease), margin-left 0.25s var(--ease), opacity 0.2s var(--ease);
}
.header-cta:hover .header-cta-arrow { width: 0.9em; margin-left: 0.4em; opacity: 1; }

.btn-block { width: 100%; }

/* ==========================================================================
   INTRO LOADER
   ========================================================================== */
.intro-loader {
  position: fixed;
  inset: 0;
  background: var(--red);
  z-index: 9998;
  transform: translateY(0);
  transition: transform 0.5s var(--ease);
}
.intro-loader.wipe { transform: translateY(-100%); }

.intro-logo-wrap {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  transition: transform 0.5s var(--ease);
}
.intro-logo-wrap.to-header {
  transform: translate(var(--dx, 0), var(--dy, 0)) scale(var(--scale, 0.4));
}
.intro-logo {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2.2rem, 6vw, 3.6rem);
  letter-spacing: -0.05em;
  color: var(--white);
  white-space: nowrap;
}
.intro-logo .ch {
  display: inline-block;
  opacity: 0;
  transform: translateY(6px);
  animation: charIn 0.3s ease-out forwards;
  animation-delay: calc(var(--i) * 60ms);
}
.intro-logo .ch.dot {
  animation: dotBounce 0.4s var(--ease-spring) forwards;
  animation-delay: calc(var(--i) * 60ms);
}
@keyframes charIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes dotBounce {
  0%   { opacity: 0; transform: scale(0); }
  55%  { opacity: 1; }
  70%  { transform: scale(1.3); }
  100% { opacity: 1; transform: scale(1); }
}

/* ---------- Header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--red);
}
/* Page scroll progress — thin white line along the header's bottom edge */
.header-progress {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2px;
  background: rgba(255, 255, 255, 0.9);
  transform: scaleX(0);
  transform-origin: left;
  will-change: transform;
  pointer-events: none;
}
.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 1rem;
  padding-bottom: 1rem;
  gap: 1.5rem;
}
.logo {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.25rem;
  letter-spacing: -0.05em;
  color: var(--white);
  /* Visible by default so the header logo never depends on JS succeeding —
     the intro script hides it explicitly, only once it has committed to
     running the hand-off animation, and always restores it afterwards. */
  opacity: 1;
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}
.logo:hover { transform: translateY(-1px); }
.logo-dot {
  display: inline-block;
  color: var(--white);
  transition: transform 0.3s var(--ease);
}
.logo:hover .logo-dot { transform: scale(1.35); }
.logo-dot { animation: logoDotPulse 2.6s ease-in-out infinite; }
@keyframes logoDotPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}
.logo-footer { opacity: 1; color: var(--off-white); }
.logo-footer .logo-dot { animation: none; }

.nav {
  display: flex;
  gap: 2rem;
  margin-left: auto;
  margin-right: 1.6rem;
}
.nav a {
  position: relative;
  font-size: 0.94rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.8);
  padding: 0.3rem 0;
  transition: color 0.25s var(--ease), transform 0.25s var(--ease);
}
.nav a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 100%;
  height: 2px;
  background: var(--white);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.3s var(--ease);
}
.nav a:hover { color: var(--white); transform: translateY(-1px); }
.nav a.active { color: var(--white); }
.nav a.active::after { transform: scaleX(1); }

.nav-toggle {
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  cursor: pointer;
  transition: background 0.25s var(--ease), transform 0.25s var(--ease);
}
.nav-toggle:hover { background: rgba(255, 255, 255, 0.12); }
.nav-toggle:active { transform: scale(0.92); }
.nav-toggle span {
  width: 20px;
  height: 2px;
  background: var(--white);
  border-radius: 2px;
  transition: transform 0.3s var(--ease), opacity 0.3s var(--ease);
}
/* hamburger -> X, driven by the aria-expanded state main.js already sets */
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ---------- Hero ---------- */
.hero { position: relative; padding: 5rem 0 6rem; overflow: hidden; }
.hero-inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1.32fr 0.92fr;
  gap: 3.5rem;
  align-items: center;
}

/* Animated gradient mesh — base layer behind all hero content. Felt, not
   seen: large, heavily-blurred, low-opacity red washes that drift slowly.
   Only transform is animated (GPU-friendly); blur is a static filter. */
.hero-mesh {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  will-change: transform; /* JS cursor-parallax nudges the whole layer */
}
/* Fine dot-grid texture — gives the drifting colour a fixed reference
   plane so the motion actually registers, and adds craft up close. */
.hero-dots {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: radial-gradient(rgba(13, 13, 13, 0.07) 1px, transparent 1px);
  background-size: 26px 26px;
  -webkit-mask-image: radial-gradient(ellipse 75% 70% at 42% 38%, black 0%, transparent 100%);
  mask-image: radial-gradient(ellipse 75% 70% at 42% 38%, black 0%, transparent 100%);
}
.mesh-blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(60px);
  background: radial-gradient(circle, rgba(189, 0, 31, 0.38) 0%, rgba(189, 0, 31, 0) 70%);
}
.mesh-blob-1 { width: 620px; height: 620px; left: -140px; top: -180px; }
.mesh-blob-2 {
  width: 520px; height: 520px; right: -120px; top: -100px;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.28) 0%, rgba(189, 0, 31, 0) 70%);
}
.mesh-blob-3 {
  width: 680px; height: 680px; left: 12%; bottom: -320px;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.34) 0%, rgba(189, 0, 31, 0) 70%);
}
.mesh-blob-4 {
  width: 440px; height: 440px; right: 8%; bottom: -220px;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.42) 0%, rgba(189, 0, 31, 0) 70%);
}
.mesh-blob-1 { animation: meshDrift1 24s ease-in-out infinite; }
.mesh-blob-2 { animation: meshDrift2 30s ease-in-out infinite; animation-delay: -8s; }
.mesh-blob-3 { animation: meshDrift3 26s ease-in-out infinite; animation-delay: -15s; }
.mesh-blob-4 { animation: meshDrift4 20s ease-in-out infinite; animation-delay: -4s; }
/* Multi-waypoint wander — each blob traces an irregular loop rather than
   a straight back-and-forth, so the field never settles into a visible
   ping-pong rhythm. */
@keyframes meshDrift1 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  28% { transform: translate(48px, -28px) scale(1.07); }
  55% { transform: translate(64px, -58px) scale(1.02); }
  80% { transform: translate(18px, -20px) scale(0.96); }
}
@keyframes meshDrift2 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  30% { transform: translate(-44px, 26px) scale(0.95); }
  58% { transform: translate(-58px, 52px) scale(1.05); }
  82% { transform: translate(-16px, 30px) scale(0.98); }
}
@keyframes meshDrift3 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  26% { transform: translate(30px, 40px) scale(1.05); }
  54% { transform: translate(58px, 50px) scale(0.97); }
  78% { transform: translate(26px, 14px) scale(1.03); }
}
@keyframes meshDrift4 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  32% { transform: translate(-40px, -26px) scale(0.96); }
  60% { transform: translate(-60px, -44px) scale(1.06); }
  84% { transform: translate(-22px, -12px) scale(1); }
}

.status-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 1rem;
  border: 1px solid var(--grey-light);
  border-radius: var(--radius-pill);
  /* Solid backing so this reads as a clean opaque chip sitting above the
     mesh, not a transparent label that picks up its tint. */
  background: var(--off-white);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--off-black);
  margin-bottom: 1.8rem;
  transition: border-color 0.25s var(--ease), transform 0.25s var(--ease), background 0.25s var(--ease);
}
.status-chip:hover {
  border-color: var(--red);
  background: var(--red-soft);
  transform: translateY(-1px);
}
/* Arrow hint — cancels its own flex-gap contribution at rest (negative
   margin equal to the chip's gap) so it reads as truly hidden, then
   grows in on hover: the chip visibly becomes "go somewhere", not just
   a colour swap. Same reveal language as .booking-link elsewhere. */
.status-chip-arrow {
  margin-left: -0.6rem;
  opacity: 0;
  color: var(--red);
  font-weight: 700;
  transition: margin-left 0.25s var(--ease), opacity 0.2s var(--ease);
}
.status-chip:hover .status-chip-arrow { margin-left: 0; opacity: 1; }
.status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--red);
  box-shadow: 0 0 0 3px var(--red-soft-2);
  flex-shrink: 0;
  transition: transform 0.25s var(--ease-spring), box-shadow 0.25s var(--ease);
}
/* On hover the pulse quickens and the ring flashes wider — the dot
   reads as "live" rather than idly blinking */
.status-chip:hover .status-dot {
  animation-duration: 0.85s;
  transform: scale(1.2);
  box-shadow: 0 0 0 5px var(--red-soft-2);
}
.status-dot { animation: pulseDot 2.4s ease-in-out infinite; }
@keyframes pulseDot {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

.hero h1 {
  margin-bottom: 1.5rem;
  font-size: clamp(2.9rem, 5.6vw, 4.7rem);
  line-height: 1.04;
}
.hero-sub { color: var(--grey); font-size: 1.12rem; max-width: 470px; margin-bottom: 2.2rem; }
.hero-actions { display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 3.2rem; }

/* Spec-sheet stats: hairline rule, big display numbers over mono
   uppercase labels — the same instrument voice as the section rails */
.hero-stats {
  display: flex;
  gap: 2.4rem;
  flex-wrap: wrap;
  padding-top: 1.4rem;
  border-top: 1px solid var(--grey-light);
  max-width: 560px;
}
.hero-stats li { display: flex; flex-direction: column; gap: 0.3rem; }
.hero-stats strong {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.75rem;
  color: var(--off-black);
  letter-spacing: -0.03em;
  line-height: 1;
  transition: color 0.25s var(--ease);
}
/* Hovering a stat springs its figure up and flashes it brand-red; the
   counted stats also re-roll their numbers (JS) so the 48 spins up again */
.hero-stats li:hover strong {
  color: var(--red);
  animation: statPop 0.5s var(--ease-spring);
}
@keyframes statPop {
  0%, 100% { transform: none; }
  40% { transform: translateY(-5px) scale(1.07); }
}
.hero-stats li {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--grey);
}
/* Compact label variant — swapped in by the mobile media query, where
   the full label wraps and breaks the single-line stat row. */
.stat-label-short { display: none; }


/* hero visual — browser mockup cycling through three industry states.
   Sized and offset so it reads as a supporting detail beside the
   headline, not a mirrored second column. */
.hero-visual {
  position: relative;
  /* Fixed width, not max-width: without an explicit width, this box
     shrink-wraps to its content's natural size — and since the URL bar
     text and card labels differ in length per cycling state, the whole
     card would visibly resize and shift left/right every ~4s. */
  width: min(400px, 100%);
  margin-left: auto;
  margin-top: 1rem;
  margin-right: 0.5rem;
  will-change: transform; /* JS pointer-tilt */
}
.browser-frame {
  background: var(--white);
  border: 1px solid rgba(13, 13, 13, 0.08);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow-card-hover);
  transform: rotate(1.5deg);
  transition: transform 0.4s var(--ease);
}
.hero-visual:hover .browser-frame { transform: rotate(0.4deg) translateY(-3px); }
/* Shared ground shadow — anchors browser and phone to one surface so
   the pair reads as a single staged composition, not two floating cards */
.hero-visual-shadow {
  position: absolute;
  left: -8%;
  right: 4%;
  bottom: -44px;
  height: 34px;
  background: radial-gradient(ellipse 50% 100% at 50% 50%, rgba(13, 13, 13, 0.16), transparent 70%);
  filter: blur(6px);
  pointer-events: none;
}
.browser-bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0.85rem 1rem;
  border-bottom: 1px solid var(--grey-lighter);
}
/* Cycle progress — fills across each industry state's 4s on screen */
.mockup-progress {
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 100%;
  height: 2px;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: left;
  will-change: transform;
}
/* Real (muted) traffic lights — instantly reads "browser", not "card" */
.bdot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
}
.bdot-r { background: #F09A93; }
.bdot-y { background: #F2CE8A; }
.bdot-g { background: #9BD6A5; }
.url-lock {
  width: 11px;
  height: 11px;
  margin-left: 0.7rem;
  margin-right: -0.4rem;
  color: #3E9C5C; /* https green — the one colour a padlock should be */
  flex-shrink: 0;
}
.browser-url {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin-left: 0.8rem;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--grey);
  background: var(--grey-lighter);
  padding: 0.25rem 0.7rem;
  border-radius: var(--radius-pill);
  transition: opacity 0.25s ease;
}
/* Tiny favicon in the URL pill — takes each client's brand colour */
.url-fav {
  width: 8px;
  height: 8px;
  border-radius: 2.5px;
  background: var(--grey-light);
  flex-shrink: 0;
  transition: background 0.35s var(--ease);
}
[data-persona="trades"] .url-fav { background: #F2A93B; }
[data-persona="fitness"] .url-fav { background: #C8F169; }
[data-persona="restaurant"] .url-fav { background: #35502F; }
[data-persona="local"] .url-fav { background: #0E7C7B; }
.browser-body { position: relative; padding: 1.5rem; display: flex; flex-direction: column; gap: 1.2rem; }

/* The builder's cursor — travels between elements as they land, then
   clicks the CTA. Motion is eased between JS waypoints. */
.mockup-cursor {
  position: absolute;
  z-index: 3;
  left: 0;
  top: 0;
  width: 15px;
  height: 15px;
  opacity: 0;
  pointer-events: none;
  /* Travel via transform: left/top would re-run layout every frame of
     the 0.55s glide; translate stays on the compositor. JS drives
     --cx/--cy in px; the click squeeze rides the same transform. */
  transform: translate(var(--cx, 0px), var(--cy, 0px)) scale(var(--cs, 1));
  transition: transform 0.55s cubic-bezier(0.45, 0.05, 0.35, 1), opacity 0.3s ease;
  filter: drop-shadow(0 2px 4px rgba(13, 13, 13, 0.35));
}
.mockup-cursor.click { --cs: 0.8; transition-duration: 0.15s, 0.3s; }
/* Click ripple */
.mockup-cursor::after {
  content: "";
  position: absolute;
  left: -4px;
  top: -4px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid rgba(189, 0, 31, 0.65);
  opacity: 0;
  transform: scale(0.4);
}
.mockup-cursor.click::after { animation: cursorRipple 0.5s var(--ease) forwards; }
@keyframes cursorRipple {
  0% { opacity: 1; transform: scale(0.4); }
  100% { opacity: 0; transform: scale(1.6); }
}

/* Build canvas — the site assembling itself from placed blocks.
   Each .blk drops in from above and settles (staggered via --i) while
   the browser-bar progress line fills; then the layout holds "live"
   and the loop rebuilds. Driven by .assemble / .resetting on the canvas. */
.build-canvas {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  height: 248px;
  overflow: hidden;
  transition: opacity 0.3s var(--ease);
}
.build-canvas.resetting { opacity: 0; }

/* .blk is purely the animation carrier — visuals live on the mini-site
   primitives below, so each client's page can look like real design
   rather than grey placeholder bars. */
.blk { display: block; opacity: 0; }
.build-canvas.assemble .blk {
  animation: blockIn 0.55s var(--ease-spring) both;
  animation-delay: calc(var(--i) * 130ms);
}
@keyframes blockIn {
  0% { opacity: 0; transform: translateY(-30px) scale(0.9) rotate(-1.5deg); }
  70% { opacity: 1; transform: translateY(3px) scale(1.01) rotate(0.4deg); }
  100% { opacity: 1; transform: none; }
}

/* ---- Mini-site primitives ---- */
.m-nav { display: flex; align-items: center; justify-content: space-between; width: 100%; }
.m-nav-center { justify-content: center; }
.m-logo {
  font-family: var(--font-body);
  font-weight: 800;
  font-size: 10px;
  letter-spacing: 0.12em;
}
.m-navlinks { font-size: 8px; font-weight: 600; color: #98A0AC; }
.m-navpill {
  font-size: 8.5px;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: var(--radius-pill);
}
.m-split { display: flex; gap: 0.9rem; align-items: stretch; }
.m-copy {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 0.5rem;
}
.m-stars { font-size: 8.5px; font-weight: 700; color: #F2A93B; letter-spacing: 0.04em; }
.m-stars em { font-style: normal; font-weight: 600; color: #8A93A3; }
.m-head {
  font-family: var(--font-body);
  font-weight: 800;
  font-size: 14.5px;
  line-height: 1.18;
  letter-spacing: -0.01em;
}
.m-photo { width: 104px; border-radius: 8px; object-fit: cover; }
.m-row3 { display: flex; gap: 0.5rem; width: 100%; }
.m-chip {
  flex: 1;
  text-align: center;
  font-size: 8.5px;
  font-weight: 700;
  padding: 6px 0;
  border-radius: 7px;
}
.m-center { align-self: center; text-align: center; }

/* Editorial micro-detail — the difference between "wireframe" and
   "real site" at miniature scale: eyebrows, subcopy, secondary links,
   floating proof cards. Colours are scoped per persona below. */
.m-eyebrow {
  font-family: var(--font-mono);
  font-size: 6px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.m-sub { font-size: 7.5px; line-height: 1.5; font-weight: 500; }
.m-ctarow { display: flex; align-items: center; gap: 9px; }
.m-ghostlink {
  font-size: 7.5px;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 2px;
  white-space: nowrap;
}
/* Photo column with an overlapping review card — layered depth reads
   as designed, not placed */
.m-photowrap { position: relative; width: 118px; flex-shrink: 0; }
.m-photowrap .m-photo { width: 100%; height: 100%; min-height: 100px; }
.m-review {
  position: absolute;
  left: -16px;
  bottom: 6px;
  width: 100px;
  display: flex;
  flex-direction: column;
  gap: 1.5px;
  padding: 5px 7px;
  border-radius: 6px;
  background: #FFFFFF;
  box-shadow: 0 7px 18px -6px rgba(27, 42, 65, 0.4);
  font-size: 6.2px;
  line-height: 1.35;
  font-weight: 600;
}
.m-review b { font-size: 5.5px; letter-spacing: 0.08em; }
.m-review em { font-style: normal; font-size: 5.5px; font-weight: 600; }
/* Service cards: icon tile + label + one-line sub */
.m-svc {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2.5px;
  padding: 6px 7px;
  border-radius: 7px;
  font-size: 7.5px;
  font-weight: 700;
}
.m-svc i {
  width: 13px;
  height: 13px;
  border-radius: 4px;
  display: grid;
  place-items: center;
  margin-bottom: 1px;
}
.m-svc i svg { width: 8px; height: 8px; }
.m-svc em { font-style: normal; font-weight: 500; font-size: 6.3px; }
/* Class cards: live "spots left" dot under the time */
.m-class em {
  font-style: normal;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 6px;
  font-weight: 600;
}
.m-spot { width: 4px; height: 4px; border-radius: 50%; display: inline-block; }
/* Restaurant ornament — hairline rule with a rotated diamond */
.m-orn { position: relative; width: 46px; height: 1px; margin: 3px auto 0; }
.m-orn::after {
  content: "";
  position: absolute;
  left: 50%;
  top: -2.5px;
  width: 5px;
  height: 5px;
  transform: translateX(-50%) rotate(45deg);
}
/* Shop banner with a badge pinned to it, and product cards */
.m-bannerwrap { position: relative; width: 100%; }
.m-bannerbadge {
  position: absolute;
  left: 7px;
  bottom: 7px;
  font-family: var(--font-mono);
  font-size: 5.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  padding: 2.5px 5px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.94);
}
.m-prod {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2.5px;
  font-size: 7px;
  font-weight: 700;
}
.m-prod i { display: block; height: 30px; border-radius: 6px; }
.m-prod em {
  font-style: normal;
  font-family: var(--font-mono);
  font-size: 6.3px;
  font-weight: 600;
}

/* Fitness: full-bleed photo hero with oversized display type */
.m-fithero { position: relative; width: 100%; height: 118px; border-radius: 9px; overflow: hidden; }
.m-fithero img { width: 100%; height: 100%; object-fit: cover; }
.m-fitoverlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-start;
  gap: 6px;
  padding: 10px 12px;
  background: linear-gradient(180deg, rgba(10, 10, 12, 0.05), rgba(10, 10, 12, 0.74));
}
.m-fithead {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 21px;
  line-height: 0.95;
  letter-spacing: -0.01em;
  color: #FFFFFF;
}
.m-classes { display: flex; gap: 0.5rem; width: 100%; }
.m-class {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px 8px;
  border-radius: 7px;
  font-size: 8px;
  font-weight: 600;
}
.m-class b { font-family: var(--font-mono); font-size: 9px; }

/* Restaurant: serif voice, centred, dotted-leader menu */
.m-serif { font-family: Georgia, 'Times New Roman', serif; font-style: italic; letter-spacing: 0; }
.m-logo.m-serif { font-weight: 600; font-size: 12px; }
.m-est { font-family: var(--font-mono); font-size: 7.5px; font-weight: 600; letter-spacing: 0.16em; }
.m-resthead { display: flex; flex-direction: column; align-items: center; gap: 4px; text-align: center; }
.m-resthead .m-head { font-size: 18px; font-weight: 500; }
.m-menu { display: flex; flex-direction: column; gap: 5px; width: 100%; padding: 0 4px; }
.m-dish { display: flex; align-items: baseline; gap: 6px; font-size: 9px; font-weight: 600; }
.m-dish i { flex: 1; border-bottom: 1px dotted #C9BFA8; transform: translateY(-2px); }
.m-dish b { font-family: var(--font-mono); font-weight: 600; }
.m-thumb { flex: 1; min-width: 0; height: 36px; border-radius: 7px; object-fit: cover; }

/* Local: photo banner storefront with live hours */
.m-banner { width: 100%; height: 60px; border-radius: 9px; object-fit: cover; }
.m-localrow { display: flex; align-items: center; justify-content: space-between; width: 100%; }
.m-hours { font-size: 9.5px; font-weight: 600; }
.m-hours b {
  display: block;
  font-family: var(--font-mono);
  font-size: 7.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-bottom: 1px;
}

.blk-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: fit-content;
  padding: 0 12px;
  height: 25px;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 9.5px;
  white-space: nowrap;
}
/* The cursor's click lands — the CTA responds with a squeeze, played via
   JS (el.animate(), see scheduleCursor in main.js) rather than a CSS
   class. Toggling a class here would change .blk-cta's `animation`
   shorthand from one entry to two, and browsers restart the *whole*
   declaration when the list itself changes — including blockIn's
   animation-delay, during which `fill: both` backward-fills its 0%
   keyframe (opacity: 0). The CTA would vanish for the length of that
   delay on every single cycle. Web Animations run on a separate
   timeline from CSS animations, so this can't touch blockIn at all,
   restart or otherwise. */

/* ---- Persona identities ----
   Each little site wears its own brand — nothing borrows Arkio's red,
   so the mockups read as four different clients' builds. The browser
   body itself takes the client's background colour. */
.browser-body { transition: background 0.35s var(--ease); }

/* Trades: navy + amber, workwear colours, review-led */
[data-persona="trades"] .browser-body,
[data-persona="trades"] .phone-screen { background: #F5F7FB; }
[data-persona="trades"] .m-logo { color: #1B2A41; }
[data-persona="trades"] .m-navpill { background: #FCEBCB; color: #8A5E11; }
[data-persona="trades"] .m-head { color: #16233A; }
[data-persona="trades"] .m-chip { background: #FFFFFF; border: 1px solid #DCE4EF; color: #31415C; box-shadow: 0 4px 10px -6px rgba(27, 42, 65, 0.3); }
[data-persona="trades"] .blk-cta { background: #F2A93B; color: #1B2A41; box-shadow: 0 8px 18px -8px rgba(242, 169, 59, 0.75); }
[data-persona="trades"] .m-eyebrow { color: #B07A17; }
[data-persona="trades"] .m-sub { color: #5C6B84; }
[data-persona="trades"] .m-ghostlink { color: #1B2A41; }
[data-persona="trades"] .m-review { color: #31415C; }
[data-persona="trades"] .m-review b { color: #F2A93B; }
[data-persona="trades"] .m-review em { color: #8A93A3; }
[data-persona="trades"] .m-svc { background: #FFFFFF; border: 1px solid #DCE4EF; color: #16233A; box-shadow: 0 4px 10px -6px rgba(27, 42, 65, 0.3); }
[data-persona="trades"] .m-svc i { background: #FCEBCB; color: #8A5E11; }
[data-persona="trades"] .m-svc em { color: #8A93A3; }

/* Fitness: near-black + electric lime, big type over photography */
[data-persona="fitness"] .browser-body,
[data-persona="fitness"] .phone-screen { background: #131316; }
[data-persona="fitness"] .m-logo { color: #C8F169; }
[data-persona="fitness"] .m-navlinks { color: #6E6E76; }
[data-persona="fitness"] .m-class { background: #1D1D21; border: 1px solid #2C2C31; color: #B9BDC7; }
[data-persona="fitness"] .m-class b { color: #C8F169; }
[data-persona="fitness"] .blk-cta { background: #C8F169; color: #101010; box-shadow: 0 8px 18px -8px rgba(200, 241, 105, 0.5); }
[data-persona="fitness"] .m-eyebrow { color: #C8F169; }
[data-persona="fitness"] .m-ghostlink { color: #EDEFF3; }
[data-persona="fitness"] .m-class em { color: #7C7F89; }
[data-persona="fitness"] .m-spot { background: #C8F169; box-shadow: 0 0 4px rgba(200, 241, 105, 0.8); }
[data-persona="fitness"] .m-navpill { background: #C8F169; color: #101010; }

/* Restaurant: warm cream + forest green, serif menu voice */
[data-persona="restaurant"] .browser-body,
[data-persona="restaurant"] .phone-screen { background: #FAF5EC; }
[data-persona="restaurant"] .m-logo { color: #35502F; }
[data-persona="restaurant"] .m-est { color: #8A7F63; }
[data-persona="restaurant"] .m-head { color: #2C2418; }
[data-persona="restaurant"] .m-dish { color: #3A3226; }
[data-persona="restaurant"] .blk-cta { background: #35502F; color: #FAF5EC; box-shadow: 0 8px 18px -8px rgba(53, 80, 47, 0.6); }
[data-persona="restaurant"] .m-navlinks { color: #8A7F63; }
[data-persona="restaurant"] .m-ghostlink { color: #35502F; }
[data-persona="restaurant"] .m-orn { background: #C9BFA8; }
[data-persona="restaurant"] .m-orn::after { background: #FAF5EC; border: 1px solid #8A7F63; }
[data-persona="restaurant"] .m-dish em { font-style: normal; font-size: 6.3px; color: #8A7F63; font-weight: 500; }

/* Local & independent: teal + fresh white, hours-led */
[data-persona="local"] .browser-body,
[data-persona="local"] .phone-screen { background: #F2F8F7; }
[data-persona="local"] .m-logo { color: #0E7C7B; letter-spacing: 0.04em; font-size: 11px; }
[data-persona="local"] .m-navlinks { color: #7FA3A1; }
[data-persona="local"] .m-head { color: #123A39; font-size: 12.5px; font-weight: 700; }
[data-persona="local"] .m-hours { color: #3E5654; }
[data-persona="local"] .m-hours b { color: #0E7C7B; }
[data-persona="local"] .blk-cta { background: #0E7C7B; color: #FFFFFF; box-shadow: 0 8px 18px -8px rgba(14, 124, 123, 0.6); }
[data-persona="local"] .m-ghostlink { color: #0E7C7B; }
[data-persona="local"] .m-bannerbadge { color: #0E7C7B; }
[data-persona="local"] .m-navpill { background: #DCEEED; color: #0E7C7B; }
[data-persona="local"] .m-prod { color: #123A39; }
[data-persona="local"] .m-prod i { border: 1px solid rgba(14, 124, 123, 0.14); }
[data-persona="local"] .m-prod em { color: #0E7C7B; }

/* ---- Phone preview — the same client build, mobile-first ----
   Overlaps the browser's lower-left corner at a counter-rotation, so the
   pair reads as one responsive project shown on two devices. */
.phone-shell {
  position: absolute;
  left: -58px;
  bottom: -30px;
  width: 118px;
  z-index: 2;
  padding: 5px;
  border-radius: 19px;
  background: linear-gradient(160deg, #26262B, #0B0B0D 55%);
  border: 1px solid rgba(255, 255, 255, 0.16);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.22),
    0 26px 48px -16px rgba(13, 13, 13, 0.48);
  transform: rotate(-4deg);
  transition: transform 0.4s var(--ease);
}
.hero-visual:hover .phone-shell { transform: rotate(-1.5deg) translateY(-4px); }
/* Side button nub */
.phone-shell::after {
  content: "";
  position: absolute;
  right: -2.5px;
  top: 56px;
  width: 2.5px;
  height: 26px;
  border-radius: 0 2px 2px 0;
  background: #2E2E33;
}
.phone-screen {
  position: relative;
  height: 212px;
  border-radius: 14px;
  overflow: hidden;
  background: #F5F7FB;
  display: flex;
  flex-direction: column;
  transition: background 0.35s var(--ease);
}
.phone-notch {
  position: absolute;
  top: 4px;
  left: 50%;
  transform: translateX(-50%);
  width: 32px;
  height: 8px;
  border-radius: 5px;
  background: #0B0B0D;
  z-index: 3;
}
.phone-statusbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 9px 0;
  font-family: var(--font-mono);
  font-size: 5.5px;
  font-weight: 600;
  color: rgba(127, 127, 127, 0.85);
}
.phone-sig { display: inline-flex; align-items: flex-end; gap: 1.5px; }
.phone-sig i {
  width: 2px;
  border-radius: 1px;
  background: rgba(127, 127, 127, 0.85);
}
.phone-sig i:nth-child(1) { height: 3px; }
.phone-sig i:nth-child(2) { height: 4.5px; }
.phone-sig i:nth-child(3) { height: 6px; }
.phone-canvas {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 7px 8px 10px;
  overflow: hidden;
  transition: opacity 0.3s var(--ease);
}
.phone-canvas.resetting { opacity: 0; }
/* Mobile blocks land just after their desktop counterparts — the
   responsive view assembling in the desktop build's wake */
.phone-canvas.assemble .blk {
  animation: blockIn 0.55s var(--ease-spring) both;
  animation-delay: calc(0.4s + var(--i) * 130ms);
}
.phone-home {
  position: absolute;
  bottom: 3px;
  left: 50%;
  transform: translateX(-50%);
  width: 30px;
  height: 3px;
  border-radius: 2px;
  background: rgba(127, 127, 127, 0.5);
  z-index: 3;
}
/* Phone-scale type — same primitives, mobile sizes */
.p-nav { display: flex; align-items: center; justify-content: space-between; width: 100%; }
.phone-canvas .m-logo { font-size: 6.5px; }
.phone-canvas .m-logo.m-serif { font-size: 8px; }
.phone-canvas .m-stars { font-size: 6px; }
.phone-canvas .m-head { font-size: 9px; line-height: 1.2; }
.phone-canvas .m-head.m-serif { font-size: 10px; text-align: center; }
.phone-canvas .m-dish { font-size: 6.5px; }
.phone-canvas .m-hours { font-size: 7px; }
.phone-canvas .m-hours b { font-size: 5.5px; }
.phone-canvas .m-class { font-size: 6px; padding: 4px 6px; }
.phone-canvas .m-class b { font-size: 7px; }
.phone-canvas .blk-cta { height: 17px; padding: 0 8px; font-size: 6.5px; }
.phone-canvas .m-eyebrow { font-size: 5px; }
.phone-canvas .m-sub { font-size: 6.3px; }
.phone-canvas .m-ghostlink { font-size: 6.3px; }
.phone-canvas .m-orn { width: 34px; margin-top: 1px; }
.phone-canvas .m-fitoverlay .m-eyebrow { font-size: 4.5px; }
.p-img { width: 100%; height: 58px; border-radius: 6px; object-fit: cover; }
.p-fithero { height: 72px; border-radius: 6px; }
.phone-canvas .m-fithead { font-size: 12px; }
.phone-canvas .m-fitoverlay { padding: 6px 7px; gap: 3px; }
.p-burger {
  position: relative;
  width: 9px;
  height: 7px;
  color: #98A0AC;
}
.p-burger::before {
  content: "";
  position: absolute;
  inset: 0;
  border-top: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
}
[data-persona="fitness"] .p-burger { color: #6E6E76; }
[data-persona="local"] .p-burger { color: #7FA3A1; }

.hero-visual-tag {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 1.2rem;
  padding-left: 76px; /* clear of the overlapping phone */
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--grey);
}
.hero-visual-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--red);
}
.hero-visual-dot { animation: pulseDot 1.6s ease-in-out infinite; }

/* ---------- Sections ---------- */
.section { padding: 7.5rem 0; scroll-margin-top: 88px; }
.section-alt { background: var(--paper); }

/* ---------- Process (black prestige stage + liquid-glass strip gallery) ----------
   The same black-and-red ambient stage as the Pricing section —
   charcoal radial depth, red ember glows, drifting mesh blobs and a
   faint dot grid — with the step strips rendered as liquid glass. */
.process-section {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(circle at 18% 4%, rgba(255, 255, 255, 0.05), transparent 42%),
    radial-gradient(circle at 84% 10%, rgba(189, 0, 31, 0.26), transparent 46%),
    radial-gradient(circle at 8% 74%, rgba(189, 0, 31, 0.22), transparent 46%),
    radial-gradient(ellipse 120% 62% at 50% 106%, rgba(189, 0, 31, 0.42), transparent 68%),
    radial-gradient(ellipse 130% 100% at 50% 30%, #1a1416 0%, #0a0a0b 82%);
  padding-top: 4.5rem;
  padding-bottom: 4rem;
}
.process-mesh {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
/* Same drifting colour recipe as the pricing stage */
.process-blob-1 {
  width: 440px; height: 440px; left: -110px; top: 18%;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.44) 0%, rgba(189, 0, 31, 0) 70%);
  animation: meshDrift3 26s ease-in-out infinite;
}
.process-blob-2 {
  width: 380px; height: 380px; right: -90px; bottom: 6%;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.48) 0%, rgba(189, 0, 31, 0) 70%);
  animation: meshDrift2 30s ease-in-out infinite;
  animation-delay: -10s;
}
.process-blob-3 {
  width: 400px; height: 400px; left: 50%; margin-left: -200px; top: 30%;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.32) 0%, rgba(189, 0, 31, 0) 70%);
  animation: meshDrift1 24s ease-in-out infinite;
  animation-delay: -6s;
}
.process-dots {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: radial-gradient(rgba(255, 255, 255, 0.06) 1px, transparent 1px);
  background-size: 26px 26px;
  -webkit-mask-image: radial-gradient(ellipse 70% 65% at 50% 55%, black 0%, transparent 100%);
  mask-image: radial-gradient(ellipse 70% 65% at 50% 55%, black 0%, transparent 100%);
}
/* Timecode gridlines — faint verticals, like frame marks on a timeline,
   fading out toward the section's edges */
.process-grid {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.05) 0 1px, transparent 1px 130px);
  -webkit-mask-image: radial-gradient(ellipse 80% 90% at 50% 46%, black 0%, transparent 96%);
  mask-image: radial-gradient(ellipse 80% 90% at 50% 46%, black 0%, transparent 96%);
}
/* The playhead of time — a soft band of red light crossing the stage
   left to right, resting a beat before each pass */
.process-scan {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.process-scan::before {
  content: "";
  position: absolute;
  top: -12%;
  bottom: -12%;
  left: 0;
  width: 34%;
  background: linear-gradient(90deg, transparent, rgba(189, 0, 31, 0.17) 45%, rgba(237, 90, 110, 0.1) 58%, transparent);
  filter: blur(20px);
  transform: translateX(-130%) skewX(-8deg);
  animation: scanSweep 14s ease-in-out infinite;
}
@keyframes scanSweep {
  0% { transform: translateX(-130%) skewX(-8deg); }
  62%, 100% { transform: translateX(430%) skewX(-8deg); }
}

.process-section .container { position: relative; z-index: 1; }

/* Editorial split header: timecode eyebrow + title on the left, the
   sub anchored to the baseline on the right — the timecode language
   of the strips starts here. */
.process-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 3rem;
  margin-bottom: 2.8rem;
}
.process-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: #ED5A6E;
  margin-bottom: 1rem;
}
.process-eyebrow::after {
  content: "";
  width: 36px;
  height: 1px;
  background: rgba(237, 90, 110, 0.5);
}
.process-section h2 { color: var(--white); margin-bottom: 0; max-width: none; }
.process-section .section-sub {
  color: rgba(255, 255, 255, 0.78);
  max-width: 320px;
  margin: 0 0 0.4em;
  text-align: left;
}
/* Sub waits for the headline words to land */
.process-section .section-sub.reveal { transition-delay: 0.45s; }

/* Stage: gallery + timeline rail share one centred width, floating on
   a breathing pool of red light — same ambience language as the pie */
.process-stage { position: relative; width: fit-content; margin: 0 auto; }
.process-stage::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 126%;
  height: 122%;
  transform: translate(-50%, -53%);
  border-radius: 50%;
  background: radial-gradient(ellipse, rgba(189, 0, 31, 0.3) 0%, rgba(189, 0, 31, 0.1) 46%, rgba(189, 0, 31, 0) 72%);
  filter: blur(32px);
  pointer-events: none;
  animation: pieGlowBreathe 7s ease-in-out infinite;
}
.strip-gallery, .process-rail { position: relative; z-index: 1; }

/* 48-hour timeline rail — a live instrument under the strips: the red
   fill advances to the active step's timecode and completes to LIVE
   when Launch is open. */
.process-rail { margin-top: 1.7rem; }
.rail-track {
  position: relative;
  height: 2px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.14);
}
.rail-fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 0;
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(189, 0, 31, 0.65), #ED5A6E);
  box-shadow: 0 0 12px rgba(189, 0, 31, 0.7);
  transition: width 0.6s var(--ease);
}
.rail-fill::after {
  content: "";
  position: absolute;
  right: -4px;
  top: 50%;
  width: 8px;
  height: 8px;
  margin-top: -4px;
  border-radius: 50%;
  background: #ED5A6E;
  box-shadow: 0 0 10px rgba(237, 90, 110, 0.9);
}
.rail-ticks {
  position: relative;
  margin-top: 0.7rem;
  height: 1.1em;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: rgba(255, 255, 255, 0.4);
}
.rail-tick {
  position: absolute;
  transform: translateX(-50%);
  transition: color 0.3s var(--ease);
}
.rail-tick[data-index="0"] { transform: none; }
.rail-tick.is-active { color: var(--white); }
.rail-tick-end { right: 0; transform: none; color: rgba(255, 255, 255, 0.55); }

.strip-gallery {
  display: flex;
  gap: 6px;
  width: fit-content;
  margin: 0 auto;
  padding: 0.5rem 0 1rem;
}
/* Liquid glass: translucent, blurred and saturated so the dunes bend
   through it, with a hairline glass edge and a specular top sheen. */
.strip-item {
  position: relative;
  width: 64px;
  height: 330px;
  flex-shrink: 0;
  border-radius: var(--radius);
  border: 1px solid rgba(255, 255, 255, 0.32);
  overflow: hidden;
  cursor: pointer;
  background: rgba(255, 255, 255, 0.12);
  backdrop-filter: blur(18px) saturate(160%);
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45), 0 12px 36px rgba(20, 0, 4, 0.35);
  transition: width 0.5s var(--ease), transform 0.2s var(--ease), border-color 0.3s var(--ease), background 0.3s var(--ease);
}
.strip-item::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 42%;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0));
  pointer-events: none;
  z-index: 1;
}
/* Ambient aura drifting inside each strip — every step glows from its
   own corner so the glass never reads as flat panels */
.strip-item::after {
  content: "";
  position: absolute;
  inset: -30%;
  pointer-events: none;
  background: radial-gradient(circle at var(--ax, 50%) var(--ay, 80%), rgba(189, 0, 31, 0.5), transparent 58%);
  filter: blur(26px);
  opacity: 0.6;
  animation: stripAura 9s ease-in-out infinite;
}
.strip-step-1 { --ax: 32%; --ay: 82%; }
.strip-step-2 { --ax: 68%; --ay: 24%; }
.strip-step-2::after { animation-delay: -3s; }
.strip-step-3 { --ax: 40%; --ay: 40%; }
.strip-step-3::after { animation-delay: -5.5s; }
.strip-step-4 { --ax: 62%; --ay: 74%; }
.strip-step-4::after { animation-delay: -7.5s; }
@keyframes stripAura {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(5%, -6%) scale(1.1); }
}
/* On hover the aura stops drifting, brightens, and follows the pointer
   (the JS feeds --ax/--ay) — the contact form's glass-glow behaviour */
.strip-item:hover::after {
  opacity: 0.95;
  animation-play-state: paused;
  transition: opacity 0.35s var(--ease);
}
/* Keep the strip's content above its aura */
.strip-label, .strip-scene, .strip-overlay { z-index: 1; }

/* ---- Step scenes ----
   Each open strip stages a crafted artefact of that step — the actual
   enquiry, the approved direction, the code, the live site — in the
   site's own visual language instead of stock photography. Fixed to
   the expanded width so nothing reflows while the strip animates. */
.strip-scene {
  position: absolute;
  top: 1.5rem;
  left: 0;
  width: 450px;
  padding: 0 1.6rem;
  opacity: 0;
  transform: translateY(-12px);
  transition: opacity 0.4s var(--ease), transform 0.5s var(--ease-spring);
  transition-delay: 0s;
  pointer-events: none;
}
.strip-item.is-active .strip-scene { opacity: 1; transform: none; transition-delay: 0.18s; }

.scene-card {
  border-radius: 12px;
  background: rgba(10, 5, 7, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.16);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 12px 30px rgba(0, 0, 0, 0.35);
  padding: 0.9rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
.scene-tag {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: #ED5A6E;
}
/* Brief: the enquiry that starts the clock */
.scene-field {
  display: flex;
  gap: 0.7rem;
  align-items: baseline;
  font-size: 0.78rem;
  color: rgba(255, 255, 255, 0.88);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  padding-bottom: 0.35rem;
}
.scene-field:last-child { border-bottom: none; padding-bottom: 0; }
.scene-field b {
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 0.6rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.45);
  width: 58px;
  flex-shrink: 0;
}
/* Design: type, palette and wireframe on one board */
.scene-board-row { display: flex; align-items: center; gap: 1.1rem; }
.scene-type {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 2rem;
  line-height: 1;
  color: var(--white);
  letter-spacing: -0.04em;
}
.scene-swatches { display: flex; gap: 0.35rem; }
.scene-swatches i {
  width: 18px;
  height: 18px;
  border-radius: 6px;
  background: var(--c, #fff);
  border: 1px solid rgba(255, 255, 255, 0.25);
}
.scene-wire {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.scene-wire b, .scene-wire u, .scene-wire s {
  display: block;
  height: 5px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.35);
}
.scene-wire b { width: 72%; height: 8px; }
.scene-wire u { width: 100%; background: rgba(255, 255, 255, 0.18); }
.scene-wire s { width: 46%; background: rgba(237, 90, 110, 0.75); height: 7px; }
/* Each time Design opens, the board assembles itself: the type specimen
   lands first, the palette chips pop in one by one, then the wireframe
   bars draw themselves left to right. */
.strip-item.is-active .scene-type {
  animation: sceneRise 0.5s var(--ease-spring) 0.3s backwards;
}
.strip-item.is-active .scene-swatches i {
  animation: swatchPop 0.45s var(--ease-spring) backwards;
}
.strip-item.is-active .scene-swatches i:nth-child(1) { animation-delay: 0.45s; }
.strip-item.is-active .scene-swatches i:nth-child(2) { animation-delay: 0.57s; }
.strip-item.is-active .scene-swatches i:nth-child(3) { animation-delay: 0.69s; }
.strip-item.is-active .scene-wire b,
.strip-item.is-active .scene-wire u,
.strip-item.is-active .scene-wire s {
  transform-origin: left center;
  animation: wireDraw 0.5s var(--ease) backwards;
}
.strip-item.is-active .scene-wire b { animation-delay: 0.75s; }
.strip-item.is-active .scene-wire u:nth-of-type(1) { animation-delay: 0.87s; }
.strip-item.is-active .scene-wire u:nth-of-type(2) { animation-delay: 0.97s; }
.strip-item.is-active .scene-wire s { animation-delay: 1.07s; }
@keyframes sceneRise {
  from { opacity: 0; transform: translateY(8px) scale(0.85); }
  to { opacity: 1; transform: none; }
}
@keyframes swatchPop {
  from { opacity: 0; transform: scale(0.3); }
  to { opacity: 1; transform: none; }
}
@keyframes wireDraw {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}
/* Build: the editor, mid-keystroke */
.code-line { display: flex; gap: 0.4rem; align-items: center; }
.code-indent { padding-left: 1rem; }
.code-line s {
  display: block;
  width: var(--w, 40px);
  height: 6px;
  border-radius: 3px;
  background: var(--c, rgba(255, 255, 255, 0.35));
}
.code-caret {
  width: 2px;
  height: 12px;
  background: #ED5A6E;
  animation: caretBlink 1s steps(1) infinite;
}
@keyframes caretBlink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}
/* Each time Build opens, the editor types itself out: every line wipes in
   left to right on a stepped clock, like keystrokes landing. */
.strip-item.is-active .scene-code .code-line {
  animation: lineType 0.45s steps(9) backwards;
}
.strip-item.is-active .scene-code .code-line:nth-of-type(1) { animation-delay: 0.35s; }
.strip-item.is-active .scene-code .code-line:nth-of-type(2) { animation-delay: 0.75s; }
.strip-item.is-active .scene-code .code-line:nth-of-type(3) { animation-delay: 1.15s; }
.strip-item.is-active .scene-code .code-line:nth-of-type(4) { animation-delay: 1.55s; }
@keyframes lineType {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0 0 0); }
}
/* Launch: the site, live and already working */
.live-row { display: flex; align-items: center; gap: 0.5rem; }
.live-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #4CD964;
  box-shadow: 0 0 8px rgba(76, 217, 100, 0.8);
  animation: pulseDot 2s ease-in-out infinite;
}
.live-row b {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: var(--white);
}
.live-row em {
  font-family: var(--font-mono);
  font-style: normal;
  font-size: 0.66rem;
  color: rgba(255, 255, 255, 0.55);
}
.live-spark {
  width: 100%;
  height: 34px;
}
.live-spark polyline {
  fill: none;
  stroke: #ED5A6E;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* The graph draws itself each time Launch opens */
.strip-item.is-active .live-spark polyline {
  stroke-dasharray: 200;
  stroke-dashoffset: 200;
  animation: sparkDraw 1.1s var(--ease) 0.35s forwards;
}
@keyframes sparkDraw { to { stroke-dashoffset: 0; } }
.live-stats { display: flex; gap: 1.2rem; }
.live-stats span {
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
}
.live-stats b {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 0.95rem;
  color: var(--white);
}
.strip-item:hover { border-color: rgba(255, 255, 255, 0.65); background: rgba(255, 255, 255, 0.16); }
.strip-item:active { transform: scale(0.97); }
.strip-item.is-active {
  width: 450px;
  cursor: default;
  border-color: rgba(255, 255, 255, 0.5);
}
.strip-item:focus-visible { outline: 2px solid rgba(255, 255, 255, 0.85); outline-offset: 3px; }

/* Vertical timestamp label on collapsed strips */
.strip-label {
  position: absolute;
  top: 1.1rem;
  left: 50%;
  transform: translateX(-50%);
  writing-mode: vertical-rl;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.8);
  white-space: nowrap;
  transition: opacity 0.25s var(--ease);
}
.strip-item.is-active .strip-label { opacity: 0; }

/* Overlay is fixed at the expanded width so its text never reflows or
   squishes while the strip's width animates. */
.strip-overlay {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 450px;
  padding: 1.6rem;
  background: linear-gradient(to top, rgba(30, 0, 6, 0.55) 20%, rgba(30, 0, 6, 0) 100%);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s var(--ease);
}
.strip-item.is-active .strip-overlay { opacity: 1; }

.strip-num {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.92);
  margin-bottom: 0.45rem;
}
.strip-overlay h3 { font-size: 1.4rem; margin-bottom: 0.35rem; color: var(--white); }
.strip-overlay p { color: rgba(255, 255, 255, 0.85); font-size: 0.93rem; max-width: 380px; }

/* Staggered rise-in for the active step's copy */
.strip-num,
.strip-overlay h3,
.strip-overlay p {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.45s var(--ease), transform 0.45s var(--ease-spring);
}
.strip-item.is-active .strip-num { opacity: 1; transform: none; transition-delay: 0.15s; }
.strip-item.is-active .strip-overlay h3 { opacity: 1; transform: none; transition-delay: 0.25s; }
.strip-item.is-active .strip-overlay p { opacity: 1; transform: none; transition-delay: 0.35s; }

/* ---------- Industries (interactive pie) ----------
   Four donut segments, one per industry. Highlighting a segment explodes
   it outward with a glow while a 3D icon card flies toward the viewer in
   the liquid-glass hub, and the glass panel below describes the industry. */
.industries-pie-section { position: relative; overflow: hidden; }
.pie-mesh {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.industries-blob-1 {
  width: 430px; height: 430px; left: 50%; margin-left: -370px; top: 26%;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.18) 0%, rgba(189, 0, 31, 0) 70%);
  animation: meshDrift1 24s ease-in-out infinite;
}
.industries-blob-2 {
  /* Kept clear of the section's bottom edge: the glow's radius must fade
     to transparent before the overflow boundary, or it gets cut off in a
     hard line where the next section starts. */
  width: 380px; height: 380px; right: 50%; margin-right: -390px; bottom: 28%;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.16) 0%, rgba(189, 0, 31, 0) 70%);
  animation: meshDrift2 30s ease-in-out infinite;
  animation-delay: -9s;
}
.industries-pie-section .container { position: relative; z-index: 1; }

/* Editorial split header, mirroring the Process section's rhythm */
.industries-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 3rem;
  margin-bottom: 2.6rem;
}
.industries-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: var(--red);
  margin-bottom: 1rem;
}
.industries-eyebrow::after {
  content: "";
  width: 36px;
  height: 1px;
  background: rgba(189, 0, 31, 0.35);
}
.industries-head h2 { margin-bottom: 0; max-width: none; }
.industries-head .section-sub { max-width: 470px; margin: 1.1rem 0 0; }

/* Two columns: description panel + rail left, pie right — top-aligned
   so the disc sits level with the panel rather than sinking below it */
.pie-layout {
  display: grid;
  grid-template-columns: 1.02fr 0.98fr;
  gap: 3.5rem;
  align-items: start;
}
/* Lift the disc so its centre sits level with the photo panel — it
   floats up into the open space beside the header. */
.pie-stage { margin-top: -158px; }
.pie-link { margin-top: 1.6rem; }

/* Industry rail — the same instrument as the process timeline: a
   hairline track whose glowing fill slides across as the pie's active
   segment moves, with clickable industry ticks beneath. */
.pie-copy { min-width: 0; }
.pie-rail { margin-top: 1.6rem; max-width: 520px; }
.pie-rail .rail-track { background: rgba(13, 13, 13, 0.12); }
.pie-rail-ticks {
  position: relative;
  margin-top: 0.65rem;
  height: 1.3em;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.pie-rail-tick {
  position: absolute;
  transform: translateX(-50%);
  color: var(--grey);
  cursor: pointer;
  padding: 0;
  white-space: nowrap;
  transition: color 0.25s var(--ease);
}
.pie-rail-tick[data-industry="trades"] { transform: none; }
.pie-rail-tick[data-industry="local"] { transform: translateX(-100%); }
.pie-rail-tick:hover { color: var(--red); }
.pie-rail-tick.is-active { color: var(--red); }
.pie-stage {
  position: relative;
  width: min(440px, 88vw);
  aspect-ratio: 1;
  justify-self: center;
  will-change: transform; /* JS cursor tilt */
  /* Resting 3D perspective — the JS cursor tilt modulates around this */
  transform: perspective(900px) rotateX(26deg);
  transform-style: preserve-3d;
}
/* Floating layer — the whole disc (faces, walls, shadow, hub) drifts
   gently up and down so the chart reads as a hovering object even at
   rest. Lives inside the stage so the JS cursor tilt composes with it. */
.pie-float {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  animation: pieBob 7s ease-in-out infinite;
}
@keyframes pieBob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-9px); }
}
/* Red ambience pooled around the whole disc — sits behind the chart
   and breathes slowly, replacing the old grey ground shadow. */
.pie-glow {
  position: absolute;
  inset: -16%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.42) 0%, rgba(189, 0, 31, 0.16) 50%, rgba(189, 0, 31, 0) 74%);
  filter: blur(30px);
  pointer-events: none;
  animation: pieGlowBreathe 6s ease-in-out infinite;
}
@keyframes pieGlowBreathe {
  0%, 100% { opacity: 0.75; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.05); }
}
/* Extruded underside — each wedge's wall path carries its own swept
   bands (outer arc, inner arc, radial cut faces) and explodes with
   exactly the same transform as its top face, so face and wall stay
   welded along every edge. */
.depth-seg {
  transform-box: view-box;
  transform-origin: 50% 50%;
  transition: transform 0.45s var(--ease-spring);
}
.depth-seg.is-active {
  transform: translate(var(--ex, 0px), var(--ey, 0px)) scale(1.02);
}
.pie-svg { width: 100%; height: 100%; display: block; overflow: visible; }

/* Specular sheen over the top faces — never intercepts the pointer */
.pie-sheen { pointer-events: none; }


.pie-seg {
  cursor: pointer;
  outline: none;
  transform-box: view-box;
  transform-origin: 50% 50%;
  transition: transform 0.45s var(--ease-spring), filter 0.35s var(--ease);
}
.pie-seg path {
  stroke: rgba(255, 255, 255, 0.55);
  stroke-width: 1.5;
  transition: fill 0.3s var(--ease);
}
/* Quiet industry mark on each wedge — a whisper, not a label */
.seg-icon { pointer-events: none; }
.seg-icon path {
  fill: none;
  stroke: rgba(255, 255, 255, 0.5);
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: stroke 0.3s var(--ease);
}
/* ---- Entrance choreography ----
   When the section scrolls into view: the whole disc rises up out of
   its glow, the wedges sweep in clockwise from the centre with a
   springy overshoot — each wall arriving welded to its face — and the
   glass hub pops in last, once the disc is assembled. */
.pie-layout.in-view .pie-float {
  animation: pieFloatIn 0.9s var(--ease) backwards, pieBob 7s ease-in-out 0.9s infinite;
}
@keyframes pieFloatIn {
  from { opacity: 0; transform: translateY(52px); }
  to { opacity: 1; transform: translateY(0); }
}
.pie-layout.in-view .pie-seg,
.pie-layout.in-view .depth-seg {
  animation: segIn 0.7s var(--ease) backwards;
}
.pie-layout.in-view .pie-seg[data-industry="trades"],
.pie-layout.in-view .depth-seg[data-industry="trades"] { animation-delay: 0.2s; }
.pie-layout.in-view .pie-seg[data-industry="fitness"],
.pie-layout.in-view .depth-seg[data-industry="fitness"] { animation-delay: 0.34s; }
.pie-layout.in-view .pie-seg[data-industry="restaurant"],
.pie-layout.in-view .depth-seg[data-industry="restaurant"] { animation-delay: 0.48s; }
.pie-layout.in-view .pie-seg[data-industry="local"],
.pie-layout.in-view .depth-seg[data-industry="local"] { animation-delay: 0.62s; }
@keyframes segIn {
  0% { opacity: 0; transform: scale(0.4) rotate(-20deg); }
  70% { opacity: 1; transform: scale(1.045) rotate(2.5deg); }
  100% { opacity: 1; transform: none; }
}
/* The active segment keeps its breathing glow alongside the entrance
   (the entrance shorthand would otherwise knock the pulse out) */
.pie-layout.in-view .pie-seg.is-active {
  animation: segIn 0.7s var(--ease) 0.2s backwards, segGlowPulse 3.2s ease-in-out 1.1s infinite;
}
/* Sheen and hub wait for the wedges to land */
.pie-layout.in-view .pie-sheen { animation: sheenIn 0.6s var(--ease) 0.9s backwards; }
@keyframes sheenIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
.pie-layout.in-view .pie-hub { animation: hubIn 0.7s var(--ease-spring) 0.95s backwards; }
@keyframes hubIn {
  from { opacity: 0; transform: scale(0.55); }
  to { opacity: 1; transform: none; }
}
/* Highlighted segment: explode outward along its bisector + red glow */
.pie-seg.is-active,
.pie-seg:hover,
.pie-seg:focus-visible {
  transform: translate(var(--ex, 0), var(--ey, 0)) scale(1.02);
  filter: brightness(1.12) drop-shadow(0 0 22px rgba(189, 0, 31, 0.55));
}
/* The held-open segment's glow breathes while it waits */
.pie-seg.is-active {
  animation: segGlowPulse 3.2s ease-in-out infinite;
}
@keyframes segGlowPulse {
  0%, 100% { filter: brightness(1.12) drop-shadow(0 0 22px rgba(189, 0, 31, 0.55)); }
  50% { filter: brightness(1.17) drop-shadow(0 0 34px rgba(189, 0, 31, 0.75)); }
}
.pie-seg.is-active .seg-icon path { stroke: rgba(255, 255, 255, 0.85); }
.pie-seg:focus-visible path { stroke: var(--white); stroke-width: 2.5; }

/* Liquid-glass hub — the donut hole */
.pie-hub {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 42%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.16);
  backdrop-filter: blur(16px) saturate(160%);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, 0.55);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55), 0 12px 40px rgba(13, 13, 13, 0.12);
  transform-style: preserve-3d;
}
.pie-hub::before {
  content: "";
  position: absolute;
  inset: -18px;
  z-index: -1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.4), transparent 70%);
  filter: blur(20px);
  animation: glowBreathe 5s ease-in-out infinite;
}
/* The 3D icon card that flies toward the screen */
.hub-card {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  opacity: 0;
  transform: translateZ(-240px) rotateX(24deg);
  transform-style: preserve-3d;
  transition: transform 0.6s var(--ease-spring), opacity 0.4s var(--ease);
  pointer-events: none;
}
/* Floats above the tilted disc, counter-rotated to face the viewer */
.hub-card.is-active { opacity: 1; transform: translateZ(48px) rotateX(-26deg); }
.hub-icon {
  width: 62px;
  height: 62px;
  border-radius: 16px;
  display: grid;
  place-items: center;
  background: linear-gradient(160deg, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.42));
  border: 1px solid rgba(255, 255, 255, 0.75);
  box-shadow: 0 10px 26px rgba(189, 0, 31, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.85);
  color: var(--red);
}
.hub-icon svg { width: 34px; height: 34px; }
/* Active icon floats gently, like it's suspended in the glass */
.hub-card.is-active .hub-icon { animation: hubFloat 3.2s ease-in-out infinite; }
@keyframes hubFloat {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-7px); }
}

/* Description panel — the same black prestige stage as the Pricing
   section: near-black base with red radial glows and a faint dot grid,
   so the industry blocks read as a piece of that room. */
.pie-desc-panel {
  position: relative;
  width: 100%;
  max-width: 520px;
  min-height: 178px;
  border-radius: var(--radius);
  background:
    radial-gradient(circle at 84% 10%, rgba(189, 0, 31, 0.3), transparent 48%),
    radial-gradient(circle at 8% 88%, rgba(189, 0, 31, 0.24), transparent 48%),
    radial-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px),
    radial-gradient(ellipse 130% 100% at 50% 30%, #1a1416 0%, #0a0a0b 82%);
  background-size: 100% 100%, 100% 100%, 16px 16px, 100% 100%;
  border: 1px solid rgba(255, 255, 255, 0.18);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.14),
    0 16px 44px rgba(13, 13, 13, 0.3),
    0 0 46px rgba(189, 0, 31, 0.2);
  /* 3D plane: the JS cursor tilt rotates the whole block as one flat
     piece — children carry no Z of their own, so nothing parallaxes
     apart during motion. */
  transform: perspective(800px);
  will-change: transform;
}
/* Card swap: a crisp 2D crossfade-and-slide. The text never rotates in
   3D during the swap (rotated live text rasterises blurry mid-motion),
   the outgoing card drops instantly beneath the incoming one, and the
   incoming card slides in flat as one piece. */
.pie-desc {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 1.2rem;
  padding: 1.1rem 1.6rem 1.1rem 1.1rem;
  transform: translateX(18px);
  opacity: 0;
  transition: transform 0.4s var(--ease), opacity 0.1s var(--ease);
  pointer-events: none;
}
.pie-desc.is-active {
  transform: none;
  opacity: 1;
  z-index: 1;
  pointer-events: auto;
  transition: transform 0.45s var(--ease-spring), opacity 0.18s var(--ease);
}
/* Photo medallion — flat on the card's plane so it moves as one piece
   with the text (a real Z offset parallaxes ahead of the card during
   motion and reads as a detached block); the deep shadow carries the
   raised look instead. */
.pie-desc-img {
  flex-shrink: 0;
  width: 96px;
  height: 96px;
  border-radius: calc(var(--radius) - 6px);
  object-fit: cover;
  object-position: center;
  border: 1px solid rgba(255, 255, 255, 0.3);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 12px 28px rgba(0, 0, 0, 0.55);
}
.pie-desc-text {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
}
.pie-desc-name { font-size: 1.35rem; margin: 0 0 0.3rem; color: var(--white); }
.pie-desc-text p { color: rgba(255, 255, 255, 0.72); font-size: 0.96rem; max-width: 380px; }
/* What actually ships for this industry — mono chips that swap with the
   card, so the panel answers "what would ours include?" at a glance */
.pie-desc-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.8rem;
}
.pie-desc-tags span {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.78);
  padding: 0.32rem 0.62rem;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.06);
  white-space: nowrap;
}
/* ---------- Pricing ---------- */
/* Prestige black stage — the same ambient treatment as the Growth card
   and the reference: charcoal radial depth, a red ember rising from the
   base, a whisper of top light. */
.pricing-section {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(circle at 18% 4%, rgba(255, 255, 255, 0.05), transparent 42%),
    radial-gradient(circle at 84% 10%, rgba(189, 0, 31, 0.26), transparent 46%),
    radial-gradient(circle at 8% 74%, rgba(189, 0, 31, 0.22), transparent 46%),
    radial-gradient(ellipse 120% 62% at 50% 106%, rgba(189, 0, 31, 0.42), transparent 68%),
    radial-gradient(ellipse 130% 100% at 50% 30%, #1a1416 0%, #0a0a0b 82%);
  padding-top: 4.5rem;
  padding-bottom: 4rem;
}
/* White, centred header on the black stage */
.pricing-section h2 {
  color: var(--white);
  text-align: center;
  margin-left: auto;
  margin-right: auto;
  /* Sized to hold the headline on a single line on desktop */
  max-width: none;
  font-size: clamp(1.8rem, 2.9vw, 2.4rem);
}
.pricing-section .section-sub {
  color: rgba(255, 255, 255, 0.72);
  text-align: center;
  margin-left: auto;
  margin-right: auto;
  margin-bottom: 2.4rem;
}
/* Sub waits for the headline words to land */
.pricing-section .section-sub.reveal { transition-delay: 0.45s; }
.pricing-mesh {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
/* Colour behind the cards for the glass rims to refract */
.pricing-blob-1 {
  width: 440px; height: 440px; left: -110px; top: 18%;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.44) 0%, rgba(189, 0, 31, 0) 70%);
  animation: meshDrift3 26s ease-in-out infinite;
}
.pricing-blob-2 {
  width: 380px; height: 380px; right: -90px; bottom: 6%;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.48) 0%, rgba(189, 0, 31, 0) 70%);
  animation: meshDrift2 30s ease-in-out infinite;
  animation-delay: -10s;
}
.pricing-blob-3 {
  width: 400px; height: 400px; left: 50%; margin-left: -200px; top: 30%;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.32) 0%, rgba(189, 0, 31, 0) 70%);
  animation: meshDrift1 24s ease-in-out infinite;
  animation-delay: -6s;
}
/* Dot-grid texture — same ambient craft layer as the hero, centred on
   the cards so the drifting mesh colour has a fixed plane to move against */
.pricing-dots {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: radial-gradient(rgba(255, 255, 255, 0.06) 1px, transparent 1px);
  background-size: 26px 26px;
  -webkit-mask-image: radial-gradient(ellipse 70% 65% at 50% 55%, black 0%, transparent 100%);
  mask-image: radial-gradient(ellipse 70% 65% at 50% 55%, black 0%, transparent 100%);
}
.pricing-section .container { position: relative; z-index: 1; }

.pricing-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
  align-items: stretch;
  max-width: 980px;
  margin: 0 auto;
}
/* Compact button sizing to match the smaller cards */
.pricing-grid .btn { min-height: 46px; padding: 0.7rem 1.4rem; font-size: 0.9rem; }
/* The wrapper carries all hover motion (lift + cursor tilt, set by JS).
   Transforming the card itself would create a stacking context and pull
   its glass rim above the card face — the wrapper keeps the rim intact. */
.price-card-wrap {
  position: relative;
  transition: transform 0.35s var(--ease);
  will-change: transform;
}
.price-card-wrap:hover { z-index: 2; }
.price-card {
  position: relative;
  height: 100%;
  padding: 1.9rem 1.6rem;
  display: flex;
  flex-direction: column;
  transition: box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
}
/* Liquid-glass rim — a translucent, blurred frame floating around each
   card, refracting the mesh colour behind it. The card body stays solid
   for legibility; the outline carries the glass. */
.price-card::before {
  content: "";
  position: absolute;
  inset: -6px;
  z-index: -1;
  border-radius: calc(var(--radius) + 6px);
  background: rgba(255, 255, 255, 0.16);
  backdrop-filter: blur(16px) saturate(160%);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, 0.55);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55), 0 12px 40px rgba(13, 13, 13, 0.1);
  pointer-events: none;
  transition: background 0.3s var(--ease), border-color 0.3s var(--ease);
}
.price-card:hover::before {
  background: rgba(255, 255, 255, 0.26);
  border-color: rgba(255, 255, 255, 0.9);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55), 0 20px 52px rgba(13, 13, 13, 0.16);
}
.price-card:hover { box-shadow: var(--shadow-card-hover); }

/* Ambient glow around each card — breathes softly at idle; on hover it
   brightens and follows the cursor (--mx/--my set from JS), so the glow
   concentrates wherever the pointer is. Sits behind the glass rim. */
.price-card::after {
  content: "";
  position: absolute;
  inset: -12px;
  z-index: -2;
  border-radius: calc(var(--radius) + 12px);
  background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 50%), rgba(189, 0, 31, 0.5), transparent 70%);
  filter: blur(20px);
  opacity: 0.2;
  animation: glowBreathe 5s ease-in-out infinite;
  transition: opacity 0.35s var(--ease);
  pointer-events: none;
}
.price-card:hover::after { opacity: 0.9; animation: none; }
@keyframes glowBreathe {
  0%, 100% { opacity: 0.14; }
  50% { opacity: 0.3; }
}

/* Growth: prestige red interior — deep brand-red depth, a brighter rose
   ember breathing along the bottom edge, and a whisper of dot texture.
   The one warm card on the black stage: unmistakably the hero option. */
.price-card-featured {
  background:
    radial-gradient(circle at 22% 6%, rgba(255, 255, 255, 0.16), transparent 42%),
    radial-gradient(rgba(255, 255, 255, 0.07) 1px, transparent 1px),
    radial-gradient(ellipse 130% 70% at 50% 108%, rgba(255, 77, 102, 0.5), transparent 68%),
    radial-gradient(ellipse 120% 100% at 50% 28%, #C41732 0%, #6E0010 82%);
  background-size: 100% 100%, 16px 16px, 190% 150%, 100% 100%;
  background-position: 0 0, 0 0, 50% 100%, 0 0;
  border-color: rgba(255, 255, 255, 0.4);
  color: var(--white);
  animation: emberDrift 9s ease-in-out infinite alternate;
}
@keyframes emberDrift {
  0% { background-position: 0 0, 0 0, 28% 100%, 0 0; }
  100% { background-position: 0 0, 0 0, 72% 100%, 0 0; }
}
.price-card-featured .price-tier,
.price-card-featured .price-figure { color: var(--white); }
.price-card-featured .price-desc { color: rgba(255,255,255,0.82); }
.price-card-featured .price-features li { color: rgba(255,255,255,0.88); }
.price-card-featured .price-features li::before {
  color: var(--white);
  border-color: rgba(255, 255, 255, 0.5);
  background: rgba(255, 255, 255, 0.12);
}
.price-card.price-card-featured:hover .price-features li::before {
  background: var(--white);
  color: var(--red);
  border-color: var(--white);
}
/* Inverted badge + CTA so they pop against the red interior */
.price-card-featured .price-badge { background: var(--white); color: var(--red); }
.price-card-featured .btn-primary {
  background: var(--white);
  color: var(--red);
  box-shadow: 0 10px 26px -10px rgba(20, 0, 4, 0.5);
}
.price-card-featured .btn-primary:hover { background: var(--off-black); color: var(--white); }

.price-badge {
  position: absolute;
  top: -13px;
  left: 2rem;
  background: var(--red);
  color: var(--white);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.35rem 0.8rem;
  border-radius: var(--radius-pill);
}
/* Card header: tier name left, billing-cadence chip right — one scannable
   row, so the big figure below owns the card's focal point alone */
.price-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.8rem;
  margin-bottom: 1rem;
}
.price-tier { font-family: var(--font-display); font-weight: 800; font-size: 1.15rem; letter-spacing: -0.03em; margin-bottom: 0; }
.price-kind {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--grey);
  padding: 0.3rem 0.65rem;
  border: 1px solid var(--grey-light);
  border-radius: var(--radius-pill);
  white-space: nowrap;
}
.price-card-featured .price-kind {
  color: rgba(255, 255, 255, 0.92);
  border-color: rgba(255, 255, 255, 0.45);
}
.price-figure { font-family: var(--font-display); font-weight: 800; font-size: 2.2rem; letter-spacing: -0.03em; margin-bottom: 0.7rem; }
.price-desc { color: var(--grey); font-size: 0.9rem; margin-bottom: 1.2rem; }
.price-features {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  margin-bottom: 1.5rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--grey-light);
  flex-grow: 1;
}
.price-card-featured .price-features { border-top-color: rgba(255, 255, 255, 0.28); }
.price-features li {
  font-size: 0.92rem;
  color: var(--off-black);
  padding-left: 1.65rem;
  position: relative;
}
/* Check-in-circle bullets — outlined at rest, filling solid red (or
   inverting to white on the Growth card) when the card is hovered */
.price-features li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0.12em;
  width: 16px;
  height: 16px;
  display: grid;
  place-items: center;
  font-size: 0.58rem;
  font-weight: 800;
  line-height: 1;
  color: var(--red);
  border: 1px solid rgba(189, 0, 31, 0.4);
  border-radius: 50%;
  background: rgba(189, 0, 31, 0.07);
  transition: background 0.25s var(--ease), color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.price-card:hover .price-features li::before {
  background: var(--red);
  color: var(--white);
  border-color: var(--red);
}
/* Features cascade in as the card scrolls into view */
.price-card-wrap.reveal .price-features li {
  opacity: 0;
  transform: translateY(9px);
  transition: opacity 0.45s var(--ease), transform 0.5s var(--ease-spring);
  transition-delay: calc(0.3s + var(--li, 0) * 70ms);
}
.price-card-wrap.reveal.in-view .price-features li { opacity: 1; transform: none; }
.price-features li:nth-child(1) { --li: 0; }
.price-features li:nth-child(2) { --li: 1; }
.price-features li:nth-child(3) { --li: 2; }
.price-features li:nth-child(4) { --li: 3; }
.price-features li:nth-child(5) { --li: 4; }
.price-features li:nth-child(6) { --li: 5; }

/* ---------- Testimonials ----------
   A light glass panel over soft red ambience: the quote rises in word by
   word with the key phrase in brand red, framed by oversized quote marks,
   attribution following once the words land. */
.testimonial-section { position: relative; overflow: hidden; padding: 5rem 0; }
.testimonial-mesh {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.t-blob-1 {
  width: 360px; height: 360px; left: 10%; top: 14%;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.18) 0%, rgba(189, 0, 31, 0) 70%);
  animation: meshDrift1 26s ease-in-out infinite;
}
.t-blob-2 {
  width: 400px; height: 400px; right: 8%; bottom: 16%;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.16) 0%, rgba(189, 0, 31, 0) 70%);
  animation: meshDrift2 30s ease-in-out infinite;
  animation-delay: -8s;
}
.testimonial-section .container {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: center;
}
.testimonial-card {
  position: relative;
  max-width: 780px;
  margin: 0;
  padding: 3rem 3.4rem 2.5rem;
  text-align: center;
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid rgba(255, 255, 255, 0.85);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    0 18px 50px rgba(13, 13, 13, 0.08),
    0 0 60px rgba(189, 0, 31, 0.1);
}
/* Framing quotation marks */
.testimonial-card::before,
.testimonial-card::after {
  font-family: var(--font-display);
  font-size: 5rem;
  line-height: 1;
  color: rgba(189, 0, 31, 0.22);
  position: absolute;
  pointer-events: none;
}
.testimonial-card::before { content: "\201C"; top: 0.8rem; left: 1.4rem; }
.testimonial-card::after { content: "\201D"; bottom: -0.8rem; right: 1.4rem; }

/* Five stars pop in one after another as the card enters view — the
   opening beat before the quote's words start rising. */
.testimonial-stars {
  display: flex;
  justify-content: center;
  gap: 0.35rem;
  margin-bottom: 1.2rem;
}
.testimonial-stars span {
  color: var(--red);
  font-size: 1.1rem;
  line-height: 1;
  opacity: 0;
  transform: scale(0.3);
  transition: opacity 0.3s var(--ease), transform 0.45s var(--ease-spring);
  transition-delay: calc(0.15s + var(--si, 0) * 90ms);
}
.testimonial-card.in-view .testimonial-stars span { opacity: 1; transform: none; }

/* One weight step below the display headlines — a spoken voice, not a
   shouted one. Body face at bold, near-neutral tracking. */
.testimonial-quote {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: clamp(1.25rem, 2.4vw, 1.7rem);
  letter-spacing: -0.01em;
  line-height: 1.48;
  color: var(--off-black);
  margin-bottom: 1.7rem;
}
.testimonial-quote .hl { color: var(--red); font-style: normal; }

.testimonial-attrib {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.5s var(--ease), transform 0.55s var(--ease-spring);
  transition-delay: 0.8s;
}
.testimonial-card.in-view .testimonial-attrib { opacity: 1; transform: none; }
.testimonial-avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: linear-gradient(150deg, var(--red), var(--red-dark));
  color: var(--white);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 0.82rem;
  letter-spacing: 0.02em;
  box-shadow: 0 6px 16px -6px rgba(189, 0, 31, 0.55);
  flex-shrink: 0;
}
.testimonial-who { text-align: left; font-size: 0.88rem; color: var(--grey); }
.testimonial-who strong { display: block; color: var(--off-black); font-size: 0.95rem; }

/* Project footer — the client's live domain (same green pulse as the
   Launch scene) beside the delivery claim, landing last of all. */
.testimonial-meta {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.9rem;
  margin-top: 1.7rem;
  padding-top: 1.25rem;
  border-top: 1px solid rgba(13, 13, 13, 0.09);
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--grey);
  opacity: 0;
  transition: opacity 0.6s var(--ease) 1.15s;
}
.testimonial-card.in-view .testimonial-meta { opacity: 1; }
.testimonial-meta .live-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  text-transform: none;
  letter-spacing: 0.03em;
}
.testimonial-meta .live-chip-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #4CD964;
  box-shadow: 0 0 8px rgba(76, 217, 100, 0.8);
  animation: pulseDot 2s ease-in-out infinite;
}
.testimonial-meta-sep { width: 1px; height: 12px; background: rgba(13, 13, 13, 0.16); }

/* ---------- FAQ ---------- */
/* Same warm ambient accent layer as the Testimonial section — the light
   paper base stays, with soft red washes drifting behind the content so
   the section reads as part of the same room as its neighbours. */
.faq-section { position: relative; overflow: hidden; }
.faq-mesh {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.faq-blob-1 {
  width: 400px; height: 400px; right: 6%; top: 10%;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.18) 0%, rgba(189, 0, 31, 0) 70%);
  animation: meshDrift2 28s ease-in-out infinite;
}
.faq-blob-2 {
  width: 360px; height: 360px; left: -60px; bottom: 14%;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.16) 0%, rgba(189, 0, 31, 0) 70%);
  animation: meshDrift1 32s ease-in-out infinite;
  animation-delay: -12s;
}
.faq-section .container { position: relative; z-index: 1; }

.faq-layout {
  display: grid;
  grid-template-columns: 300px 1fr;
  gap: 4rem;
  align-items: start;
}
.faq-head { position: sticky; top: 110px; }
.faq-eyebrow {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  color: var(--red);
  margin-bottom: 0.9rem;
}
.faq-head h2 { margin-bottom: 0.9rem; }
.faq-head .section-sub { margin-bottom: 2rem; max-width: none; }
.faq-prompt {
  border-radius: var(--radius);
  border: 1px solid var(--grey-light);
  background: var(--white);
  padding: 1.3rem 1.4rem;
}
.faq-prompt p { font-size: 0.9rem; color: var(--grey); margin-bottom: 0.4rem; }
.faq-prompt a {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.96rem;
  color: var(--off-black);
  transition: color 0.25s var(--ease), gap 0.25s var(--ease);
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.faq-prompt a:hover { color: var(--red); gap: 0.6rem; }

.faq-list { max-width: 760px; counter-reset: faq-count; }
.faq-item { border-bottom: 1px solid var(--grey-light); counter-increment: faq-count; }
.faq-question {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.5rem 0;
  text-align: left;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--off-black);
  cursor: pointer;
}
.faq-question::before {
  content: counter(faq-count, decimal-leading-zero);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--red);
  padding-right: 1.1rem;
  margin-right: 1.1rem;
  border-right: 1px solid var(--grey-light);
  flex-shrink: 0;
  transition: border-color 0.25s var(--ease);
}
.faq-question span:first-of-type { flex: 1; }
.faq-question:hover { color: var(--red); }
.faq-question:hover::before { border-color: var(--red); }
.faq-icon {
  position: relative;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  transition: transform 0.3s var(--ease), color 0.25s var(--ease);
}
.faq-icon::before, .faq-icon::after {
  content: "";
  position: absolute;
  background: currentColor;
  border-radius: 2px;
  transition: background 0.25s var(--ease);
}
.faq-icon::before { top: 9px; left: 2px; width: 16px; height: 2px; }
.faq-icon::after { top: 2px; left: 9px; width: 2px; height: 16px; }
/* The plus rotates into a close × when its answer is open */
.faq-question[aria-expanded="true"] .faq-icon { transform: rotate(45deg); }
.faq-question[aria-expanded="true"] .faq-icon::before,
.faq-question[aria-expanded="true"] .faq-icon::after { background: var(--red); }

.faq-answer {
  display: grid;
  grid-template-rows: 0fr;
  overflow: hidden;
  transition: grid-template-rows 0.35s var(--ease);
}
.faq-answer > p {
  overflow: hidden;
  min-height: 0;
  color: var(--grey);
  font-size: 0.98rem;
  line-height: 1.65;
  max-width: 640px;
}
.faq-item.open .faq-answer { grid-template-rows: 1fr; }
.faq-item.open .faq-answer > p { padding-bottom: 1.6rem; }

/* ---------- Contact ---------- */
.contact-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 3.5rem; align-items: start; }
.contact-details { margin-top: 2rem; }
.contact-details li {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding: 1.1rem 0;
  border-bottom: 1px solid var(--grey-light);
}
.contact-details li strong {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--grey);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.contact-details li a, .contact-details li span { color: var(--off-black); width: fit-content; }
.contact-details li a { transition: color 0.2s var(--ease); }
.contact-details li a:hover { color: var(--red); }

.booking-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 2rem;
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--off-black);
  border-bottom: 2px solid var(--red);
  padding-bottom: 3px;
  transition: color 0.2s var(--ease), gap 0.2s var(--ease);
}
.booking-link:hover { color: var(--red); gap: 0.75rem; }

.contact-form { padding: 2.25rem; display: flex; flex-direction: column; gap: 1.25rem; }
.form-row { display: flex; flex-direction: column; gap: 0.45rem; }
.form-row label { font-size: 0.85rem; color: var(--grey); font-weight: 600; }
.form-row input, .form-row textarea, .form-row select {
  background: var(--off-white);
  border: 1px solid var(--grey-light);
  border-radius: var(--radius-sm);
  padding: 0.85rem 1rem;
  min-height: 48px;
  color: var(--off-black);
  font-family: var(--font-body);
  font-size: 0.95rem;
  resize: vertical;
  transition: border-color 0.25s var(--ease), box-shadow 0.25s var(--ease);
}
.form-row input:hover, .form-row textarea:hover, .form-row select:hover { border-color: var(--grey); }
.form-row input:focus, .form-row textarea:focus, .form-row select:focus {
  outline: none;
  border-color: var(--red);
  box-shadow: 0 0 0 4px var(--red-soft);
}
.form-success {
  display: none;
  color: var(--red);
  font-size: 0.9rem;
  text-align: center;
  font-weight: 600;
}
.form-success.visible { display: block; }

/* ---------- Contact: prestige dark stage ----------
   The closing conversion moment gets the same black-and-red ambience as
   Pricing, flowing straight into the off-black footer. The form becomes
   a liquid-glass panel with a cursor-tracked glow. */
.contact-section {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(circle at 16% 8%, rgba(255, 255, 255, 0.04), transparent 40%),
    radial-gradient(circle at 88% 82%, rgba(189, 0, 31, 0.15), transparent 44%),
    radial-gradient(circle at 6% 60%, rgba(189, 0, 31, 0.1), transparent 42%),
    radial-gradient(ellipse 130% 100% at 50% 24%, #141114 0%, #070708 84%);
  padding-top: 4.5rem;
  padding-bottom: 4rem;
}
.contact-mesh {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.contact-blob-1 {
  width: 420px; height: 420px; left: -100px; top: 12%;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.24) 0%, rgba(189, 0, 31, 0) 70%);
  animation: meshDrift1 26s ease-in-out infinite;
}
.contact-blob-2 {
  width: 460px; height: 460px; right: -120px; bottom: 10%;
  background: radial-gradient(circle, rgba(189, 0, 31, 0.28) 0%, rgba(189, 0, 31, 0) 70%);
  animation: meshDrift2 32s ease-in-out infinite;
  animation-delay: -11s;
}
.contact-section .contact-grid { position: relative; z-index: 1; }

/* White copy column */
.contact-section h2 { color: var(--white); }
.contact-section .section-sub { color: rgba(255, 255, 255, 0.75); margin-bottom: 1.2rem; }
.contact-chip {
  border-color: rgba(255, 255, 255, 0.28);
  background: rgba(255, 255, 255, 0.08);
  color: var(--white);
  margin-bottom: 0.6rem;
}
.contact-section .contact-details { margin-top: 1.4rem; }
.contact-section .contact-details li { border-bottom-color: rgba(255, 255, 255, 0.16); padding: 0.8rem 0; }
.contact-section .booking-link { margin-top: 1.4rem; }
.contact-section .contact-details li strong { color: rgba(255, 255, 255, 0.55); }
.contact-section .contact-details li a,
.contact-section .contact-details li span { color: var(--white); }
.contact-section .contact-details li a:hover { color: #ED5A6E; }
.contact-section .booking-link { color: var(--white); }
.contact-section .booking-link:hover { color: #ED5A6E; }
.contact-section .required-mark { color: #ED5A6E; }

/* Liquid-glass form panel */
.contact-section .contact-form {
  position: relative;
  padding: 1.7rem;
  gap: 1rem;
  background: rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  border: 1px solid rgba(255, 255, 255, 0.3);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35), 0 24px 60px rgba(0, 0, 0, 0.45);
}
/* Cursor-tracked glow behind the glass (--mx/--my set by JS) */
.contact-section .contact-form::before {
  content: "";
  position: absolute;
  inset: -14px;
  z-index: -1;
  border-radius: calc(var(--radius) + 14px);
  background: radial-gradient(280px circle at var(--mx, 70%) var(--my, 30%), rgba(189, 0, 31, 0.45), transparent 70%);
  filter: blur(22px);
  opacity: 0.25;
  transition: opacity 0.35s var(--ease);
  pointer-events: none;
}
.contact-section .contact-form:hover::before { opacity: 0.8; }

/* Mono micro-labels — the site's utility-label voice */
.contact-section .form-row label {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
  transition: color 0.25s var(--ease);
}
.contact-section .form-row:focus-within label { color: var(--white); }

/* Glass fields */
.contact-section .form-row input,
.contact-section .form-row textarea,
.contact-section .form-row select {
  min-height: 42px;
  padding: 0.65rem 0.9rem;
  background: rgba(255, 255, 255, 0.07);
  border-color: rgba(255, 255, 255, 0.22);
  color: var(--white);
  caret-color: #ED5A6E;
}
.contact-section .form-row input:hover,
.contact-section .form-row textarea:hover,
.contact-section .form-row select:hover { border-color: rgba(255, 255, 255, 0.45); }
.contact-section .form-row input:focus,
.contact-section .form-row textarea:focus,
.contact-section .form-row select:focus {
  border-color: #ED5A6E;
  background: rgba(255, 255, 255, 0.11);
  box-shadow: 0 0 0 4px rgba(189, 0, 31, 0.28);
}
.contact-section .form-row select option { color: var(--off-black); }

/* Fields rise in one after another once the panel scrolls into view */
.contact-section .contact-form .form-row,
.contact-section .contact-form .btn-block {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.5s var(--ease), transform 0.55s var(--ease-spring);
}
.contact-section .contact-form.in-view .form-row:nth-child(1) { opacity: 1; transform: none; transition-delay: 0.15s; }
.contact-section .contact-form.in-view .form-row:nth-child(2) { opacity: 1; transform: none; transition-delay: 0.24s; }
.contact-section .contact-form.in-view .form-row:nth-child(3) { opacity: 1; transform: none; transition-delay: 0.33s; }
.contact-section .contact-form.in-view .form-row:nth-child(4) { opacity: 1; transform: none; transition-delay: 0.42s; }
.contact-section .contact-form.in-view .btn-block { opacity: 1; transform: none; transition-delay: 0.52s; }

/* Send -> success sequence */
.contact-section .btn-block.sending { opacity: 0.7; pointer-events: none; }
.contact-section .form-success {
  color: var(--white);
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
}
.contact-section .form-success.visible {
  display: flex;
  animation: successPop 0.5s var(--ease-spring);
}
.success-check {
  width: 22px;
  height: 22px;
  color: #ED5A6E;
  flex-shrink: 0;
}
.success-check path {
  stroke-dasharray: 26;
  stroke-dashoffset: 26;
}
.form-success.visible .success-check path {
  animation: checkDraw 0.5s var(--ease) 0.15s forwards;
}
@keyframes successPop {
  0% { opacity: 0; transform: translateY(10px) scale(0.9); }
  100% { opacity: 1; transform: none; }
}
@keyframes checkDraw { to { stroke-dashoffset: 0; } }

/* ---------- Footer ---------- */
.site-footer { background: var(--off-black); padding: 3.5rem 0; }
.footer-inner { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 1.4rem; }
.footer-nav { display: flex; gap: 1.6rem; flex-wrap: wrap; }
.footer-nav a { color: rgba(255,255,255,0.65); font-size: 0.9rem; font-weight: 600; transition: color 0.2s var(--ease); }
.footer-nav a:hover { color: var(--white); }

.footer-social { display: flex; gap: 0.7rem; }
.footer-social a {
  width: 42px;
  height: 42px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: 50%;
  color: rgba(255,255,255,0.7);
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease), transform 0.25s var(--ease);
}
.footer-social a:hover { color: var(--white); border-color: var(--red); background: var(--red); transform: translateY(-2px); }
.footer-social svg { width: 17px; height: 17px; }

.footer-copy { color: rgba(255,255,255,0.5); font-size: 0.82rem; width: 100%; text-align: center; margin-top: 0.6rem; }

/* ---------- Split-word text ----------
   Any .split-words element has its text split into word spans by JS; each
   word rises in on its own beat when the element scrolls into view. The
   element's own reveal fade is disabled so the words carry the entrance. */
.split-words.reveal { opacity: 1; transform: none; transition: none; }
.split-words .w {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.7em);
  transition: opacity 0.5s var(--ease), transform 0.6s var(--ease-spring);
  transition-delay: calc(var(--wi) * 80ms);
}
.split-words.in-view .w { opacity: 1; transform: none; }
/* Faster stagger for long passages (e.g. quotes) */
.split-fast .w { transition-delay: calc(var(--wi) * 35ms); }

/* ---------- Scroll reveal ---------- */
.reveal, .hero-reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
/* Settle to `none`, not translateY(0): a zero translate still counts as a
   transform and leaves a stacking context on every revealed element, which
   breaks any child that relies on z-index:-1 painting behind its parent
   (e.g. the pricing cards' glass rims). */
.reveal.in-view, .hero-reveal.in-view {
  opacity: 1;
  transform: none;
}
/* Once the entrance has finished (JS adds .settled a beat after
   .in-view), release the 0.7s entrance transition — otherwise it
   hijacks every later change: hover states run in slow motion and the
   hero's per-frame cursor tilt trails the pointer by ~700ms. */
.reveal.settled, .hero-reveal.settled { transition: none; }
/* Interaction transitions these elements own, re-stated post-settle
   (the blanket `transition: none` above would otherwise win the cascade) */
.status-chip.settled { transition: border-color 0.25s var(--ease), transform 0.25s var(--ease), background 0.25s var(--ease); }
.price-card-wrap.settled { transition: transform 0.35s var(--ease); }

/* Shared stagger pattern for any grid of reveal cards — applied via the
   .stagger-grid class so adding a new grid, or a new item to an existing
   one (up to 6), gets consistent staggering for free instead of needing
   its own nth-child block. */
.stagger-grid > .reveal:nth-child(1) { transition-delay: 0s; }
.stagger-grid > .reveal:nth-child(2) { transition-delay: 0.06s; }
.stagger-grid > .reveal:nth-child(3) { transition-delay: 0.12s; }
.stagger-grid > .reveal:nth-child(4) { transition-delay: 0.18s; }
.stagger-grid > .reveal:nth-child(5) { transition-delay: 0.24s; }
.stagger-grid > .reveal:nth-child(6) { transition-delay: 0.3s; }


/* ---------- Responsive ---------- */
@media (max-width: 960px) {
  .hero-inner { grid-template-columns: 1fr; }
  /* Stacked hero: extra bottom room for the phone's downward overlap */
  .hero-visual { margin: 1.6rem auto 0; }
  .contact-grid { grid-template-columns: 1fr; }
  .pricing-grid { grid-template-columns: 1fr; max-width: 420px; margin: 0 auto; }
  /* Stacked order follows how the desktop layout reads left-to-right:
     copy/heading, then the donut illustration, then the industry card
     + tab row + link that sit below it in the same column on desktop. */
  .pie-layout { grid-template-columns: 1fr; gap: 2.5rem; }
  .pie-stage { margin-top: 0; order: -1; }
  .pie-desc-panel { max-width: 100%; }

  /* Stacked order: heading block, then the full accordion list, then
     the "ask us directly" prompt at the very bottom. .faq-prompt lives
     inside .faq-head in the markup (it's sticky-positioned alongside
     the heading on desktop) — display:contents flattens that wrapper
     so the prompt can be reordered independently of its own heading. */
  .faq-layout { grid-template-columns: 1fr; gap: 2rem; }
  .faq-head { position: static; display: contents; }
  .faq-list { order: 1; }
  .faq-prompt { order: 2; margin-top: 1.5rem; }

  /* Stacked order: heading + intro, then the form (the priority
     action), then contact details below it. .contact-details and
     .booking-link live inside .contact-copy alongside the heading on
     desktop — same display:contents flattening as the FAQ prompt. */
  .contact-copy { display: contents; }
  .contact-form { order: 1; }
  .contact-details { order: 2; margin-top: 1.5rem; }
  .booking-link { order: 3; }

  .process-head { flex-direction: column; align-items: flex-start; gap: 1.1rem; }
  .process-section .section-sub { margin: 0; }
  .industries-head { flex-direction: column; align-items: flex-start; gap: 1.1rem; }
  .industries-head .section-sub { margin: 0; }
}

@media (max-width: 720px) {
  .nav { display: none; }
  .header-cta { padding: 0.55rem 1.2rem; font-size: 0.85rem; }
  .nav-toggle { display: flex; }

  .nav.nav-open {
    display: flex;
    flex-direction: column;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--red-dark);
    padding: 1.2rem 24px 1.6rem;
    gap: 1.2rem;
    margin: 0;
  }
  /* Grow the tap area to the 44px touch-target minimum without
     changing the link's visual size or spacing (desktop untouched). */
  .nav.nav-open a { padding: 10px 0; margin: -10px 0; }

  /* Keep the 4-step timeline reading left-to-right like desktop —
     stacking it vertically breaks the "timeline" metaphor. All 4 steps
     stay visible at once (no scrolling): the 3 collapsed rails compress
     to thin slivers and the active step takes the rest of the row,
     same relationship as desktop just narrowed proportionally. */
  .process-stage { width: 100%; }
  .strip-gallery { width: 100%; margin: 0; gap: 5px; }
  /* Desktop's height (330px) was tuned for a 450px-wide active card;
     kept as-is here it towers over the now-narrow strips. Match the
     shorter, squarer proportions of a compact mobile card instead —
     collapsed and active strips still share one height, same as desktop. */
  .strip-item, .strip-item.is-active { height: 230px; }
  .strip-item { width: 10%; }
  .strip-item.is-active { width: 62%; }
  /* .strip-overlay is fixed to the desktop active width (450px) so its
     text never reflows during that card's width transition — at the
     mobile active width that's wider than the card itself, so the
     description clips at the strip's overflow:hidden edge. Match it to
     the strip's own (percentage) width instead. */
  .strip-overlay { width: 100%; padding: 1.1rem; }
  /* No room for the staged scenes at this width; the number/title/
     description alone carry each step */
  .strip-scene { display: none; }
  /* The rail's tick labels are positioned by percentage across a track
     sized for the ~660px desktop width — at mobile width "00:47" and
     "48:00 — LIVE" collide. Drop the two middle ticks so only the
     start and end labels show, with room to breathe. */
  .rail-tick[data-index="1"],
  .rail-tick[data-index="2"],
  .rail-tick[data-index="3"] { display: none; }

  /* .pie-desc is absolutely positioned with inset:0 for the desktop
     crossfade, which forces its height to match the panel's min-height
     regardless of content — on narrow screens the image+text+tags
     overflow that box uncontained. Switch to a normal-flow show/hide so
     the panel grows to fit whichever card is active. */
  .pie-desc-panel { min-height: 196px; height: auto; }
  .pie-desc {
    position: static;
    display: none;
    gap: 0.85rem;
    padding: 1rem;
    align-items: flex-start;
    opacity: 1;
    transform: none;
  }
  .pie-desc.is-active { display: flex; }
  .pie-desc-img { width: 64px; height: 64px; }
  .pie-desc-text p { max-width: none; }

  /* Invisible expanded hit area — the visible label stays the same
     size/position (still centered via its own transform), this just
     grows what's actually tappable to a comfortable touch target. */
  .pie-rail-tick::after {
    content: "";
    position: absolute;
    inset: -14px -10px;
  }

  .section { padding: 5rem 0; }
  .hero { padding: 2rem 0 2.2rem; }
  /* Stats stay one row of three equal centred columns (desktop is a
     left-aligned wrapping row). gap:0 — the flex:1 columns already
     space themselves evenly, an extra gap just reads as a misaligned
     hole between the first divider-width and the columns beneath. */
  .hero-stats {
    order: 3;
    flex-wrap: nowrap;
    gap: 0;
    padding-top: 1.1rem;
    max-width: none;
  }
  .hero-stats li { flex: 1 1 0; align-items: center; gap: 0.25rem; text-align: center; font-size: 0.6rem; letter-spacing: 0.05em; }
  .hero-stats strong { font-size: 1.35rem; }
  .stat-label-full { display: none; }
  .stat-label-short { display: inline; }

  /* Desktop's h1 clamp floors out at 46.4px here — still the biggest
     text on the page, but big enough that "Websites that work" wraps
     into 3-4 lines instead of the compact two-line headline it should
     read as (one of the main things making mobile feel sprawling
     instead of composed). One consistent ~1.2rem beat between every
     hero block keeps the section reading as one composed screen. */
  .hero h1 { font-size: 2rem; line-height: 1.1; margin-bottom: 0.8rem; }
  .status-chip { margin-bottom: 1.2rem; }
  .hero-sub { font-size: 1rem; margin-bottom: 1.2rem; }

  /* Mobile hero order: eyebrow, headline and subcopy first, then the
     mockup, then the CTAs, then the stat row — matching how the
     two-column desktop hero reads left (copy) then right (mockup).
     .hero-actions/.hero-stats live inside .hero-copy in the markup;
     display:contents flattens that wrapper so each child can be
     reordered individually against the sibling .hero-visual. */
  .hero-copy { display: contents; }
  /* Mobile hero visual: the same desktop browser-building animation with
     the phone overlapping its corner — just scaled to fit the column, no
     white backing card. Only transform is the desktop tilt, kept. The
     secondary detail tiers are dropped so the mockup stays compact and
     the whole hero reads as one short screen, not a tall panel. */
  .hero-visual {
    order: 1;
    width: min(330px, calc(100% - 16px));
    margin: 0 auto 1.6rem;
  }
  .m-row3, .m-photowrap, .m-menu, .m-classes { display: none; }
  .browser-bar { padding: 0.55rem 0.7rem; }
  .browser-body { padding: 0.85rem; gap: 0.7rem; }
  /* Fixed canvas + screen heights, same as desktop's model: auto-height
     made the whole mockup (and the phone especially) visibly grow and
     shrink as each persona's content swapped in. Locked sizes keep the
     animation one steady shape; content differences play out inside. */
  .build-canvas { height: 148px; gap: 0.55rem; }
  .phone-shell { left: -8px; bottom: -16px; width: 78px; padding: 4px; }
  .phone-screen { height: 154px; }
  /* Tighter mini-content so every persona fits the locked screen; the
     eyebrow/stars micro-rows are sub-legible at this scale and push the
     tallest persona (trades) past the fixed screen — every phone reads
     as the same nav → image → headline → CTA stack instead. */
  .phone-canvas { gap: 4px; padding: 5px 6px 7px; }
  .phone-canvas .m-eyebrow, .phone-canvas .m-stars { display: none; }
  .p-img { height: 28px; }
  .p-fithero { height: 40px; }
  .hero-visual-tag { justify-content: center; padding-left: 0; margin-top: 0.7rem; font-size: 0.68rem; }

  .hero-actions { order: 2; gap: 0.7rem; margin-bottom: 1.4rem; }
  .hero-actions .btn { min-height: 50px; width: 100%; }

  /* Meta footer stacks; the hairline separator only makes sense in a row */
  .testimonial-meta { flex-direction: column; gap: 0.55rem; }
  .testimonial-meta-sep { display: none; }
  .testimonial-meta > span:last-child { white-space: nowrap; }

  /* Bump the dark-theme contact fields and footer social icons up to
     the 44px touch-target minimum (both sit a couple px under it). */
  .contact-section .form-row input,
  .contact-section .form-row textarea,
  .contact-section .form-row select { min-height: 44px; }
  .footer-social a { width: 44px; height: 44px; }
}
