/* Smart Web Labs: site.css
   Order: fonts, tokens, base, layout, components, sections, motion.
   All motion lives in one gated block near the end, so reduced motion and
   the footer switch only have to switch one thing off. */

/* ---------- Fonts (SIL Open Font Licence, self-hosted, Latin subset) ---------- */

@font-face {
  font-family: "Funnel Display";
  src: url("/assets/fonts/funnel-display-latin-wght-normal.woff2") format("woff2");
  font-weight: 300 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist";
  src: url("/assets/fonts/geist-latin-wght-normal.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist Mono";
  src: url("/assets/fonts/geist-mono-latin-wght-normal.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Metric-matched fallbacks, from tools/font-metrics.py. Arial covers Windows,
   macOS and iOS; Roboto covers Android. */
@font-face {
  font-family: "Geist Fallback";
  src: local("Arial"), local("ArialMT");
  font-weight: 100 549;
  size-adjust: 104.3%; ascent-override: 96.36%; descent-override: 28.28%; line-gap-override: 0%;
}
@font-face {
  font-family: "Geist Fallback";
  src: local("Arial Bold"), local("Arial-BoldMT");
  font-weight: 550 900;
  size-adjust: 104.3%; ascent-override: 96.36%; descent-override: 28.28%; line-gap-override: 0%;
}
@font-face {
  font-family: "Geist Fallback Android";
  src: local("Roboto");
  size-adjust: 104.93%; ascent-override: 95.78%; descent-override: 28.11%; line-gap-override: 0%;
}
@font-face {
  font-family: "Funnel Display Fallback";
  src: local("Arial Bold"), local("Arial-BoldMT");
  font-weight: 300 800;
  size-adjust: 101.12%; ascent-override: 98.89%; descent-override: 24.72%; line-gap-override: 0%;
}
@font-face {
  font-family: "Funnel Display Fallback Android";
  src: local("Roboto Bold"), local("Roboto-Bold");
  font-weight: 300 800;
  size-adjust: 108.2%; ascent-override: 92.42%; descent-override: 23.1%; line-gap-override: 0%;
}
@font-face {
  font-family: "Geist Mono Fallback";
  src: local("Courier New"), local("CourierNewPSMT");
  size-adjust: 99.98%; ascent-override: 100.52%; descent-override: 29.5%; line-gap-override: 0%;
}

/* Animatable number for the card spotlight. */
@property --glow {
  syntax: "<number>";
  inherits: false;
  initial-value: 0;
}

/* ---------- Tokens ---------- */

:root {
  --bg-0: #07070A;
  --bg-1: #0E0E13;
  --bg-2: #15151C;
  --line: rgba(255, 255, 255, 0.09);
  --line-strong: rgba(255, 255, 255, 0.16);
  --text-1: #F5F3EE;
  --text-2: #C9C6BE;
  --text-3: #8F8C85;
  --gold-300: #FEFE74;
  --gold-400: #FEED1F;
  --gold-500: #F0C100;
  --gold-600: #DE9200;
  --gold-700: #984F00;
  --cyan: #7FF8FB;
  --lavender: #E7B4FC;
  --ink: #1A1200;
  --danger: #FF9C8A;

  --metal: linear-gradient(135deg, #FEFE74 0%, #FEED1F 24%, #F0C100 58%, #DE9200 100%);
  --spectrum: linear-gradient(90deg, #F0C100, #7FF8FB, #E7B4FC);
  --accent: var(--gold-500);

  --font-display: "Funnel Display", "Funnel Display Fallback", "Funnel Display Fallback Android", Arial, sans-serif;
  --font-body: "Geist", "Geist Fallback", "Geist Fallback Android", Arial, sans-serif;
  --font-mono: "Geist Mono", "Geist Mono Fallback", ui-monospace, "Courier New", monospace;

  --fs-body: clamp(1.0625rem, 1.02rem + 0.18vw, 1.125rem);
  --fs-small: 0.9375rem;
  --fs-lab: 0.75rem;
  --fs-lede: clamp(1.125rem, 1.03rem + 0.45vw, 1.375rem);
  --fs-h1: clamp(2.75rem, 1.55rem + 5.3vw, 5.75rem);
  --fs-h2: clamp(2rem, 1.45rem + 2.4vw, 3.5rem);
  --fs-h3: clamp(1.25rem, 1.12rem + 0.55vw, 1.5rem);

  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --radius: 14px;
  /* Never less than the notch or rounded corners on a phone held sideways
     (the page uses viewport-fit=cover). */
  --pad: max(clamp(20px, 5.5vw, 72px), env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
  --content: 1240px;
  --section: clamp(4rem, 10vw, 9rem);
  --header-h: 64px;
  --dock-h: 0px;
}

@media (min-width: 1024px) {
  :root { --header-h: 76px; --fs-lab: 0.8125rem; }
}
@media (max-width: 767.98px) {
  :root { --dock-h: calc(64px + env(safe-area-inset-bottom, 0px)); }
}
/* A phone held sideways has little height: a slimmer header and bottom bar
   leave about two thirds of the screen for the page. */
@media (max-width: 767.98px) and (max-height: 440px) and (orientation: landscape) {
  :root { --header-h: 56px; --dock-h: calc(57px + env(safe-area-inset-bottom, 0px)); }
}

[data-accent="cyan"] { --accent: var(--cyan); }
[data-accent="gold"] { --accent: var(--gold-500); }
[data-accent="lavender"] { --accent: var(--lavender); }

/* ---------- Base ---------- */

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

html {
  color-scheme: dark;
  background: var(--bg-0);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--header-h) + 1.5rem);
  scroll-padding-bottom: calc(var(--dock-h) + 1rem);
  hanging-punctuation: first;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg-0);
  color: var(--text-2);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.68;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  padding-bottom: var(--dock-h);
}

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

h1, h2, h3, h4 {
  margin: 0;
  color: var(--text-1);
  font-family: var(--font-display);
  font-weight: 680;
  letter-spacing: -0.03em;
  line-height: 1.05;
  text-wrap: balance;
}
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); line-height: 1.1; font-weight: 650; }

p { margin: 0 0 1em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }
ul, ol { margin: 0; padding: 0; }
strong { color: var(--text-1); font-weight: 600; }

a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
a:hover { color: var(--text-1); }

:focus-visible {
  outline: 2px solid var(--gold-500);
  outline-offset: 2px;
  border-radius: 6px;
}
:focus:not(:focus-visible) { outline: none; }

::selection { background: rgba(240, 193, 0, 0.32); color: var(--text-1); }

address { font-style: normal; }
button { font: inherit; color: inherit; }

.container {
  width: min(100% - 2 * var(--pad), var(--content));
  margin-inline: auto;
}

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

/* Keeps names such as "Form W-9" from breaking at the hyphen. */
.nowrap { white-space: nowrap; }

.skip-link {
  position: fixed;
  top: 0.75rem; left: 0.75rem;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  border-radius: 999px;
  background: var(--metal);
  color: var(--ink);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-200%);
}
.skip-link:focus-visible { transform: none; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.icon {
  --s: 20;
  width: calc(var(--s) * 1px);
  height: calc(var(--s) * 1px);
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: calc(36 / var(--s));
  stroke-linecap: round;
  stroke-linejoin: round;
}
.icon--16 { --s: 16; }
.icon--24 { --s: 24; }

/* ---------- Type helpers ---------- */

.lab {
  margin: 0;
  color: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--fs-lab);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}
.lab--accent { color: var(--accent); }

.lede {
  max-width: 62ch;
  color: var(--text-1);
  font-size: var(--fs-lede);
  line-height: 1.6;
}

.prose { max-width: 68ch; }
.prose a, .link {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--accent) 45%, transparent);
}
.prose a:hover, .link:hover { color: var(--text-1); text-decoration-color: currentColor; }

/* Inline, so a long label wraps with the arrow after its last word. The
   vertical padding widens the tap area without changing the line. */
.text-link {
  padding-block: 0.55rem;
  color: var(--text-1);
  font-weight: 600;
  line-height: 1.5;
  text-decoration: none;
}
.text-link:hover { color: var(--text-1); text-decoration: underline; text-decoration-color: var(--accent); }
.text-link .icon { display: inline-block; margin-left: 0.4rem; vertical-align: -0.2em; color: var(--accent); }
/* The last word and the arrow wrap together, so the arrow is never alone on a line. */
.text-link__end { white-space: nowrap; }

/* ---------- Buttons ---------- */

.btn {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  min-height: 48px;
  padding: 0.7rem 1.4rem;
  overflow: hidden;
  border: 1px solid transparent;
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.005em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.btn--primary {
  background: var(--metal);
  color: var(--ink);
  box-shadow: inset 0 0 0 1px rgba(254, 254, 116, 0.35), 0 10px 34px -12px rgba(240, 193, 0, 0.55);
}
.btn--primary:hover { color: var(--ink); }
.btn--primary::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(105deg, transparent 30%, rgba(255, 255, 255, 0.6) 50%, transparent 70%);
  transform: translateX(-130%);
}
.btn--secondary {
  border-color: var(--line-strong);
  background: transparent;
  color: var(--text-1);
}
.btn--secondary:hover { border-color: rgba(255, 255, 255, 0.34); background: rgba(255, 255, 255, 0.04); }
.btn--sm { min-height: 44px; padding: 0.55rem 1.15rem; font-size: 0.9375rem; }
.btn--block { width: 100%; }
.btn .icon { margin-inline: -0.1rem; }

.btn-row { display: flex; flex-wrap: wrap; gap: 0.75rem; }

/* Phone layout (below 768 px, where the bottom bar shows): every group of
   call-to-action buttons stacks, and each button spans the full content width
   at the same height and type size, primary and secondary alike. */
@media (max-width: 767.98px) {
  .btn-row { display: grid; grid-template-columns: minmax(0, 1fr); width: 100%; }
  .btn-row > .btn, .form__actions > .btn {
    width: 100%;
    min-width: 0;
    min-height: 48px;
    padding-inline: 1.25rem;
    font-size: 1rem;
  }
  .form__actions { display: grid; grid-template-columns: minmax(0, 1fr); }
}

/* ---------- Header ---------- */

.progress {
  position: fixed;
  inset: 0 0 auto;
  z-index: 61;
  height: 2px;
  background: var(--spectrum);
  transform: scaleX(0);
  transform-origin: 0 50%;
  pointer-events: none;
}

.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 60;
  height: var(--header-h);
  pointer-events: none;
  view-transition-name: site-header;
}
.site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(14, 14, 19, 0.94);
  border-bottom: 1px solid var(--line);
  transition: opacity 300ms var(--ease-out), transform 300ms var(--ease-out);
}
/* Transparent at the top of the page from the first frame; site.js adds
   data-scrolled after the first scroll. Without scripts it stays solid. */
@media (scripting: enabled) {
  .site-header:not([data-scrolled])::before { opacity: 0; }
}
.site-header[data-scrolled]::before { transform: translateY(-10px); }

.site-header__bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 1rem;
  height: 100%;
  transition: transform 300ms var(--ease-out);
}
.site-header[data-scrolled] .site-header__bar { transform: translateY(-5px); }
.site-header__bar > * { pointer-events: auto; }

.brand {
  display: block;
  flex: none;
  margin-right: auto;
  border-radius: 4px;
  transform-origin: 0 50%;
  transition: transform 300ms var(--ease-out);
}
.brand img {
  width: clamp(204px, calc(100vw - 2 * var(--pad) - 68px), 250px);
}
.site-header[data-scrolled] .brand { transform: scale(0.92); }

.nav { display: none; }
.nav__list { display: flex; align-items: center; gap: 0.25rem; list-style: none; }
.nav__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  min-height: 44px;
  padding: 0 0.85rem;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--text-2);
  font-size: 0.9375rem;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
}
.nav__link:hover { color: var(--text-1); }
.nav__link[aria-current="page"], .nav__link[data-active] { color: var(--text-1); }
.nav__link[aria-current="page"]::after, .nav__link[data-active]::after {
  content: "";
  position: absolute;
  left: 0.85rem; right: 0.85rem; bottom: 4px;
  height: 2px;
  border-radius: 2px;
  background: var(--spectrum);
}
.nav__link .icon { transition: transform 200ms var(--ease-out); }
/* A strip under the Services button spans the gap to its panel, so a pointer
   moving down to the panel never leaves the button on the way. */
.nav__btn::before { content: ""; position: absolute; top: 100%; left: 0; right: 0; height: 12px; }
.nav__btn:has(+ .nav-panel:popover-open) { color: var(--text-1); }
.nav__btn:has(+ .nav-panel:popover-open) .icon { transform: rotate(180deg); }

.header__cta { display: none; }

.menu-btn {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 0.45rem;
  min-height: 44px;
  min-width: 44px;
  padding: 0 0.9rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: transparent;
  color: var(--text-1);
  font-size: 0.9375rem;
  font-weight: 500;
  cursor: pointer;
}
@media (max-width: 379.98px) {
  .menu-btn, .menu__close { padding: 0; justify-content: center; }
  .menu-btn span, .menu__close span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
/* From 380 px the menu button shows its label, so the logo leaves room for
   the whole button instead of squeezing it. */
@media (min-width: 380px) and (max-width: 767.98px) {
  .site-header .brand img { width: clamp(204px, calc(100vw - 2 * var(--pad) - 118px), 250px); }
}

@media (min-width: 768px) {
  .brand img { width: 278px; }
  .header__cta { display: inline-flex; }
}
@media (min-width: 1024px) {
  .nav { display: block; }
  .menu-btn { display: none; }
  .header__cta { margin-left: 0.75rem; }
}

/* Popovers: reset the UA box, keep its display rules. */
[popover] {
  margin: 0;
  padding: 0;
  border: 0;
  color: var(--text-2);
  background: none;
  inset: auto;
  overflow: visible;
}

/* Services panel (desktop). */
.nav-panel {
  position: fixed;
  top: calc(var(--header-h) - 6px);
  left: 50%;
  translate: -50% 0;
  width: min(900px, 100vw - 2 * var(--pad));
  padding: 0.5rem;
  border: 1px solid var(--line-strong);
  border-radius: 18px;
  background: var(--bg-1);
  box-shadow: 0 30px 80px -24px rgba(0, 0, 0, 0.8);
}
:root:has(.site-header[data-scrolled]) .nav-panel { top: calc(var(--header-h) - 16px); }

.svc-list { display: grid; gap: 0.5rem; list-style: none; }
.nav-panel .svc-list { grid-template-columns: repeat(3, 1fr); }
.svc { position: relative; }
.svc a {
  position: relative;
  display: grid;
  align-content: start;
  gap: 0.4rem;
  height: 100%;
  padding: 1.1rem 1.15rem 1.2rem;
  border-radius: 12px;
  color: var(--text-1);
  text-decoration: none;
}
.svc a::before {
  content: "";
  position: absolute;
  top: 0; left: 1.15rem; right: 1.15rem;
  height: 1px;
  background: linear-gradient(90deg, var(--accent), transparent);
  opacity: 0.8;
}
.svc a:hover { background: rgba(255, 255, 255, 0.04); }
.svc__lab { color: var(--accent); }
.svc__name { font-family: var(--font-display); font-size: 1.1875rem; font-weight: 650; letter-spacing: -0.02em; line-height: 1.15; }
.svc__desc { color: var(--text-3); font-size: var(--fs-small); line-height: 1.5; }
.svc--build { --accent: var(--cyan); }
.svc--grow { --accent: var(--gold-500); }
.svc--automate { --accent: var(--lavender); }

/* Full-screen menu (phones and tablets). */
.menu {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100dvh;
  max-width: none;
  max-height: none;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--bg-0);
}
.menu:popover-open { display: grid; grid-template-rows: auto 1fr auto; }
/* The logo and Close stay at the top when a long menu scrolls on a short
   screen. The pinned top and bottom paint their background out to the
   screen edges, so nothing scrolling underneath shows in the gutters. */
.menu__top { position: sticky; top: 0; z-index: 2; display: flex; align-items: center; justify-content: space-between; min-height: var(--header-h); background: var(--bg-0); }
.menu__top, .menu__contact { box-shadow: 0 0 0 100vmax var(--bg-0); clip-path: inset(0 -100vmax); }
.menu__top .brand img { width: clamp(204px, calc(100vw - 2 * var(--pad) - 68px), 250px); }
.menu__close {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 0.45rem;
  min-height: 44px;
  min-width: 44px;
  padding: 0 0.9rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: transparent;
  font-size: 0.9375rem;
  font-weight: 500;
  cursor: pointer;
}
.menu__body { display: grid; align-content: start; gap: 1.5rem; padding-block: 1rem 1.5rem; }
.menu .svc-list { gap: 0; }
.menu .svc a { gap: 0.25rem; padding: 0.75rem 0 0.8rem; border-radius: 0; }
.menu .svc a::before { left: 0; right: 30%; }
.menu .svc__name { font-size: 1.375rem; }
.menu__links { display: grid; list-style: none; border-top: 1px solid var(--line); }
.menu__links a {
  display: flex;
  align-items: center;
  min-height: 52px;
  border-bottom: 1px solid var(--line);
  color: var(--text-1);
  font-family: var(--font-display);
  font-size: 1.375rem;
  font-weight: 650;
  letter-spacing: -0.02em;
  text-decoration: none;
}
.menu__links a[aria-current="page"] { color: var(--accent); }
/* Stays in view at the bottom of the menu, even when the menu scrolls. */
.menu__contact {
  position: sticky;
  bottom: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.5rem;
  padding-block: 0.75rem calc(0.75rem + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--line);
  background: var(--bg-0);
}
.menu__contact a {
  display: grid;
  justify-items: center;
  gap: 0.35rem;
  min-height: 64px;
  padding: 0.6rem 0.25rem;
  border-radius: 12px;
  background: var(--bg-1);
  color: var(--text-1);
  font-size: 0.875rem;
  font-weight: 500;
  text-decoration: none;
}
:root:has(.menu:popover-open) { overflow: hidden; }
/* A phone held sideways: shorter contact buttons leave more room for the links. */
@media (max-height: 440px) and (orientation: landscape) {
  .menu__contact { padding-block: 0.5rem calc(0.5rem + env(safe-area-inset-bottom, 0px)); }
  .menu__contact a { display: flex; align-items: center; justify-content: center; gap: 0.5rem; min-height: 48px; padding-block: 0; }
}

/* ---------- Sections ---------- */

main { display: block; }
.section { position: relative; padding-block: var(--section); }
.section--raised { background: var(--bg-1); }
.section--tight { padding-block: calc(var(--section) * 0.6); }
.section__head { display: grid; gap: 1.1rem; max-width: 50rem; margin-bottom: clamp(2.25rem, 4.5vw, 3.75rem); }
.section__head .lede { margin-top: 0.25rem; }
.section__foot { margin-top: clamp(1.75rem, 3vw, 2.5rem); }

/* Sections below the fold skip layout and paint until they're near the
   viewport. `auto` remembers each section's real height once it's seen. */
.below, .site-footer { content-visibility: auto; contain-intrinsic-size: auto 1100px; }
.cta-band.below { contain-intrinsic-size: auto 360px; }
.site-footer { contain-intrinsic-size: auto 900px; }

.divider {
  height: 1px;
  background: var(--spectrum);
  opacity: 0.6;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
}

/* ---------- Cards ---------- */

.card {
  position: relative;
  padding: clamp(1.35rem, 2.4vw, 1.85rem);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background:
    radial-gradient(520px circle at var(--mx, 50%) var(--my, -30%), color-mix(in srgb, var(--accent) calc(var(--glow) * 9%), transparent), transparent 70%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.01));
  transition: --glow 400ms var(--ease-out), border-color 300ms var(--ease-out);
}
.card::before, .card::after {
  content: "";
  position: absolute;
  top: -1px; left: var(--radius); right: var(--radius);
  height: 1px;
  pointer-events: none;
}
.card::before { background: linear-gradient(90deg, transparent, var(--accent) 25%, var(--accent) 75%, transparent); opacity: 0.55; }
.card::after { background: var(--spectrum); opacity: 0; box-shadow: 0 0 12px rgba(240, 193, 0, 0.35); transition: opacity 350ms var(--ease-out); }
.card:focus-within::after { opacity: 1; }
@media (hover: hover) and (pointer: fine) {
  .card:hover { --glow: 1; border-color: var(--line-strong); }
  .card:hover::after { opacity: 1; }
}

.stretched::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.stretched:focus-visible { outline: none; }
.card:has(.stretched:focus-visible) { outline: 2px solid var(--gold-500); outline-offset: 2px; }

/* ---------- Home hero ---------- */

.hero {
  position: relative;
  isolation: isolate;
  overflow: clip;
  padding-top: calc(var(--header-h) + clamp(2.25rem, 6vw, 5.5rem));
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
}
.hero__bg { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.hero__grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, 0.035) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, 0.035) 1px, transparent 1px);
  background-size: 56px 56px;
  background-position: center -1px;
  -webkit-mask-image: radial-gradient(ellipse 85% 75% at 50% 30%, #000 25%, transparent 78%);
  mask-image: radial-gradient(ellipse 85% 75% at 50% 30%, #000 25%, transparent 78%);
}
.hero__light {
  position: absolute;
  width: max(520px, 58vw);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--c), transparent);
  opacity: 0.16;
  will-change: transform;
}
.hero__light--gold { --c: rgb(240 193 0 / 0.7); top: -22%; left: -14%; }
.hero__light--cyan { --c: rgb(127 248 251 / 0.55); top: -8%; right: -20%; }
.hero__light--lavender { --c: rgb(231 180 252 / 0.6); bottom: -38%; left: 28%; }
/* Service pages: two fields, both in the page's accent. */
.hero__light--one { top: -34%; right: -16%; }
.hero__light--two { bottom: -52%; left: -18%; opacity: 0.1; }
.hero--accent .hero__light { --c: color-mix(in srgb, var(--accent) 60%, transparent); }

/* Phones: eyebrow, headline, buttons, then the coordinates. Wider screens
   put the coordinates top right, level with the eyebrow. */
.hero__inner { display: grid; grid-template-columns: minmax(0, 1fr); }
.hero__inner > * { grid-column: 1 / -1; }
.hero__eyebrow { margin-bottom: clamp(1.25rem, 2.5vw, 1.75rem); color: var(--text-2); }
.hero__coords { order: 1; margin-top: 1.5rem; color: var(--text-3); white-space: pre-wrap; }
.hero__inner > .tiles, .hero__inner > .toc { order: 2; }
@media (min-width: 768px) {
  .hero__inner { grid-template-columns: minmax(0, 1fr) auto; column-gap: 2rem; }
  .hero__eyebrow { grid-column: 1; grid-row: 1; }
  .hero__coords { grid-column: 2; grid-row: 1; order: 0; margin-top: 0; text-align: right; }
}

.hero__title { font-size: var(--fs-h1); font-weight: 700; line-height: 0.98; letter-spacing: -0.035em; text-wrap: initial; }
.hero__line { display: block; }
.hero__word { display: inline-block; white-space: nowrap; }
.hero__word--cyan { color: var(--cyan); }
.hero__word--gold { color: var(--gold-500); }
.hero__word--lavender { color: var(--lavender); }
.hero__desc {
  display: block;
  max-width: 34ch;
  margin-top: clamp(1rem, 2vw, 1.4rem);
  color: var(--text-1);
  font-family: var(--font-body);
  font-size: clamp(1.125rem, 1rem + 0.6vw, 1.5rem);
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.35;
  text-wrap: balance;
}
.hero__lede { max-width: 58ch; margin-top: clamp(1.1rem, 2vw, 1.5rem); color: var(--text-2); font-size: var(--fs-lede); line-height: 1.6; }
.hero__actions { margin-top: clamp(1.5rem, 3vw, 2.25rem); }

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .hero__sheen {
    background: linear-gradient(100deg, var(--gold-500) 0 42%, var(--gold-300) 50%, var(--gold-500) 58% 100%) 100% 0 / 300% 100%;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}

/* Service tiles */
.tiles { display: grid; gap: 0.75rem; margin-top: clamp(2.25rem, 5.5vw, 4.25rem); list-style: none; }
/* Phones: a small diagram beside the label, then the title at full width. */
.tile { display: grid; grid-template-columns: 1fr 88px; grid-template-areas: "lab art" "title title" "text text"; align-items: center; gap: 0.5rem 1rem; }
.tile__art { grid-area: art; width: 88px; height: auto; color: var(--accent); }
.tile__lab { grid-area: lab; align-self: center; color: var(--accent); }
.tile__title { grid-area: title; margin: 0; color: var(--text-1); font-family: var(--font-display); font-size: 1.3125rem; font-weight: 650; letter-spacing: -0.02em; line-height: 1.15; }
.tile__title a { text-decoration: none; }
.tile__text { grid-area: text; margin-top: 0.35rem; color: var(--text-2); font-size: var(--fs-small); line-height: 1.55; }
.tile--build { --accent: var(--cyan); }
.tile--grow { --accent: var(--gold-500); }
.tile--automate { --accent: var(--lavender); }
@media (min-width: 900px) {
  .tiles { grid-template-columns: repeat(3, 1fr); gap: 1rem; }
  .tile { grid-template-columns: 1fr; grid-template-areas: "art" "lab" "title" "text"; gap: 0.5rem; }
  .tile__art { width: 100%; margin-bottom: 0.9rem; }
}

/* SVG line art (tiles and diagrams) */
.art { overflow: visible; }
.art .ln { fill: none; stroke: currentColor; stroke-width: var(--sw, 1.4); stroke-linecap: round; stroke-linejoin: round; }
.art .fa { fill: none; stroke: rgba(255, 255, 255, 0.13); stroke-width: var(--sw-faint, 1); stroke-linecap: round; }
.art .fl { fill: currentColor; fill-opacity: 0.12; stroke: none; }
.art .dt { fill: currentColor; stroke: none; }
.art .nd { fill: var(--bg-0); stroke: currentColor; stroke-width: var(--sw, 1.4); }
.art .lit { fill-opacity: 0; }
.art .traveller { opacity: 0; }
@media (max-width: 899.98px) {
  .tile__art { --sw: 3.2; --sw-faint: 2.2; }
}
.art .ln2 { stroke-opacity: 0.45; }
.tile--build .art, .art--build { --loop: 7s; }
.tile--grow .art, .art--grow { --loop: 6.5s; }
.tile--automate .art, .art--automate { --loop: 8s; }
.art .d1 { --d: 140; }
.art .d2 { --d: 280; }
.art .d3 { --d: 420; }
.art .d4 { --d: 560; }
.art .d5 { --d: 700; }
.art .d6 { --d: 840; }
.art .d7 { --d: 980; }
/* Node lights follow the travelling dot: it reaches each node at 53%,
   62%, 71% and 80% of the 8 s loop. */
.art .n1 { --d: 4240; }
.art .n2 { --d: 4960; }
.art .n3 { --d: 5680; }
.art .n4 { --d: 6400; }

/* On this page */
.toc { margin-top: clamp(2rem, 4vw, 3rem); padding-top: 1.25rem; border-top: 1px solid var(--line); }
.toc__inner { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1.25rem; }
.toc__list { display: flex; flex-wrap: wrap; gap: 0.25rem 1.25rem; list-style: none; }
.toc__list a {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  color: var(--text-2);
  font-size: var(--fs-small);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.toc__list a:hover { color: var(--text-1); border-bottom-color: var(--accent); }

/* ---------- Capability marquee ---------- */

.marquee { position: relative; border-block: 1px solid var(--line); background: var(--bg-1); }
.marquee__inner { display: grid; gap: 0.9rem; padding-block: 1.4rem; }
.marquee__label { text-align: center; }
.marquee__viewport { overflow: hidden; }
.marquee__track { display: flex; justify-content: center; }
.marquee__list { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.35rem 0; list-style: none; padding-inline: var(--pad); }
.marquee__list li { display: inline-flex; align-items: center; color: var(--text-2); font-size: var(--fs-small); font-weight: 500; white-space: nowrap; }
.marquee__list li::after {
  content: "";
  width: 4px; height: 4px;
  margin-inline: 1.1rem;
  border-radius: 50%;
  background: var(--gold-500);
  opacity: 0.75;
}
.marquee__list--copy { display: none; }

/* ---------- Client voices (testimonial marquee above the footer) ----------
   One row of cards. Without motion (reduced motion, the footer switch, no
   scripts) it is a sideways scroller with snap points; with motion it
   glides steadily to the left (see the motion section below). */

.voices {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: clamp(4.25rem, 9vw, 7.5rem);
  background: var(--bg-0);
}
.voices.below { contain-intrinsic-size: auto 800px; }
.voices::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold-500) 28%, var(--cyan) 50%, var(--lavender) 72%, transparent);
  opacity: 0.5;
}
.voices__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(38% 55% at 10% 0%, rgba(127, 248, 251, 0.07), transparent 70%),
    radial-gradient(42% 60% at 50% 4%, rgba(240, 193, 0, 0.085), transparent 72%),
    radial-gradient(38% 55% at 90% 0%, rgba(231, 180, 252, 0.07), transparent 70%);
}
.voices__head { display: grid; justify-items: center; gap: 0.85rem; margin-bottom: clamp(2.25rem, 5vw, 3.5rem); text-align: center; }
.voices__head h2 { max-width: 18ch; text-wrap: balance; }
.voices__lede { max-width: 50ch; margin: 0; color: var(--text-2); text-wrap: balance; }
.voices__rows { display: grid; gap: 0.5rem; }
.voices__viewport {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--pad);
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}
.voices__viewport:focus-visible { outline: 2px solid var(--gold-500); outline-offset: -2px; border-radius: 12px; }
.voices__track { display: flex; width: max-content; }
/* Room above for the hover lift and below for the cards' shadow. */
.voices__list { display: flex; gap: 1.25rem; padding: 0.4rem var(--pad) 1.6rem; list-style: none; }
.voices__list--copy { display: none; }

.voice { --c: var(--gold-500); display: flex; width: clamp(17.5rem, 80vw, 25.5rem); scroll-snap-align: start; }
.voice--build { --c: var(--cyan); }
.voice--automate { --c: var(--lavender); }
.voice__figure {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 1.35rem;
  width: 100%;
  margin: 0;
  padding: 1.55rem 1.55rem 1.35rem;
  border: 1px solid var(--line);
  border-radius: 20px;
  background:
    radial-gradient(120% 80% at 0% 0%, color-mix(in srgb, var(--c) 10%, transparent), transparent 60%),
    linear-gradient(180deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0.012)),
    var(--bg-1);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 26px 56px -38px rgba(0, 0, 0, 0.95);
}
/* A hairline of the card's service colour along the top edge. */
.voice__figure::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 1.55rem;
  right: 1.55rem;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--c), transparent);
  opacity: 0.85;
}
.voice__tag { position: absolute; top: 1.55rem; right: 1.55rem; margin: 0; color: var(--c); }
.voice__quote { flex: 1; margin: 0; }
/* The opening quotation mark is decoration; the empty alternative text keeps
   screen readers from announcing it. */
.voice__quote::before {
  content: "\201C";
  content: "\201C" / "";
  display: block;
  height: 2.25rem;
  margin-bottom: 0.55rem;
  color: var(--c);
  font-family: var(--font-display);
  font-size: 4.25rem;
  font-weight: 700;
  line-height: 1;
}
.voice__quote p { color: var(--text-1); font-size: 1rem; line-height: 1.65; text-wrap: pretty; }
.voice__by { display: flex; align-items: center; gap: 0.85rem; padding-top: 1.15rem; border-top: 1px solid var(--line); }
.voice__avatar {
  position: relative;
  display: grid;
  place-items: center;
  flex: none;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 32% 26%, rgba(255, 255, 255, 0.6), transparent 46%),
    linear-gradient(140deg, color-mix(in srgb, var(--c) 78%, #fff), var(--c));
  box-shadow: 0 0 0 2px var(--bg-1), 0 0 0 3px color-mix(in srgb, var(--c) 55%, transparent), 0 10px 22px -10px color-mix(in srgb, var(--c) 75%, transparent);
  color: var(--ink);
  font-family: var(--font-display);
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}
/* A photo covers the initials, which stay underneath in case it can't load. */
.voice__avatar img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  background: var(--bg-2);
}
.voice__who { display: grid; gap: 0.15rem; min-width: 0; }
.voice__name { color: var(--text-1); font-size: 0.9375rem; font-weight: 600; line-height: 1.3; }
.voice__role { color: var(--text-3); font-size: 0.8125rem; line-height: 1.4; }
@media (min-width: 768px) {
  .voice__quote p { font-size: 1.0625rem; }
}
@media (hover: hover) and (pointer: fine) {
  .voice__figure:hover { border-color: color-mix(in srgb, var(--c) 38%, var(--line)); }
}

/* ---------- The system ---------- */

.journey { margin: 0 0 clamp(2.5rem, 5vw, 4rem); }
.journey__track { position: relative; display: grid; list-style: none; }
.journey__stage { position: relative; z-index: 1; display: flex; align-items: center; gap: 0.85rem; color: var(--text-1); font-family: var(--font-mono); font-size: var(--fs-lab); font-weight: 500; letter-spacing: 0.13em; text-transform: uppercase; }
.journey__node { width: 14px; height: 14px; flex: none; border: 1.5px solid var(--text-1); border-radius: 50%; background: var(--bg-0); }
.journey__move { position: relative; padding: 1rem 0 1rem 2.4rem; color: var(--text-2); font-size: var(--fs-small); line-height: 1.5; }
.journey__move::before { content: ""; position: absolute; left: 6px; top: -2px; bottom: -2px; width: 2px; border-radius: 2px; background: var(--c); }
.journey__move .lab { display: block; margin-bottom: 0.2rem; color: var(--c); }
.journey__move--gold { --c: var(--gold-500); }
.journey__move--cyan { --c: var(--cyan); }
.journey__move--lavender { --c: var(--lavender); }
.journey__caption { max-width: 68ch; margin-top: 1.5rem; color: var(--text-3); font-size: var(--fs-small); }

@media (min-width: 900px) {
  .journey__track { grid-template-columns: auto 1fr auto 1fr auto 1fr auto; align-items: start; }
  /* One spectrum line from the first node to the last. */
  .journey__track::before { content: ""; position: absolute; left: 7px; right: 7px; top: 6px; height: 2px; border-radius: 2px; background: var(--spectrum); }
  .journey__stage { flex-direction: column; align-items: center; gap: 0.75rem; }
  .journey__stage:first-child { align-items: flex-start; }
  .journey__stage:last-child { align-items: flex-end; }
  .journey__move { padding: 1.75rem 1rem 0; text-align: center; }
  .journey__move::before { display: none; }
}

.panels { display: grid; gap: 1rem; list-style: none; }
@media (min-width: 900px) { .panels { grid-template-columns: repeat(3, 1fr); } }
.panel { display: grid; align-content: start; gap: 0.85rem; }
.panel h3 { margin-top: 0.15rem; }
.panel p:not(.lab) { margin: 0; color: var(--text-2); font-size: var(--fs-small); line-height: 1.62; }
.panel .text-link { margin-top: auto; padding-top: 0.75rem; }
.taglist { display: flex; flex-wrap: wrap; gap: 0.4rem; list-style: none; }
.taglist li { padding: 0.28rem 0.65rem; border: 1px solid var(--line); border-radius: 999px; color: var(--text-2); font-size: 0.8125rem; line-height: 1.3; }

/* ---------- Editorial ---------- */

.editorial { display: grid; gap: clamp(1.5rem, 4vw, 4rem); }
.editorial__head { display: grid; gap: 1.1rem; align-content: start; }
.editorial__body p { max-width: 68ch; }
@media (min-width: 1024px) {
  .editorial { grid-template-columns: 5fr 7fr; }
  .editorial__head { position: sticky; top: calc(var(--header-h) + 2.5rem); }
}

/* ---------- Call-to-action band ---------- */

.cta-band { position: relative; padding-block: clamp(3rem, 7vw, 5rem); border-block: 1px solid var(--line); background: var(--bg-1); overflow: clip; }
.cta-band::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  background: var(--spectrum);
  opacity: 0.55;
}
.cta-band__inner { display: grid; gap: 1.5rem; align-items: center; }
.cta-band__title { margin: 0.6rem 0 0.75rem; color: var(--text-1); font-family: var(--font-display); font-size: clamp(1.625rem, 1.3rem + 1.4vw, 2.375rem); font-weight: 680; letter-spacing: -0.03em; line-height: 1.08; text-wrap: balance; }
.cta-band p:not(.cta-band__title):not(.lab) { max-width: 56ch; }
@media (min-width: 900px) {
  .cta-band__inner { grid-template-columns: 1fr auto; gap: 3rem; }
}

/* ---------- Process timeline ---------- */

.steps { position: relative; display: grid; gap: 0; list-style: none; }
.step { position: relative; display: grid; align-content: start; gap: 0.45rem; padding: 0 0 2.25rem 2.5rem; }
.step:last-child { padding-bottom: 0; }
/* Phones: each step draws the segment down to the next marker. */
.step:not(:last-child)::before, .step:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 7px; top: 18px; bottom: -3px;
  width: 1px;
}
.step::before { background: var(--line-strong); }
.step::after { background: var(--accent); transform-origin: 50% 0; }
.step__marker {
  position: absolute;
  left: 0; top: 3px;
  width: 15px; height: 15px;
  border: 1.5px solid var(--accent);
  border-radius: 50%;
  background: var(--bg-0);
  box-shadow: 0 0 0 4px var(--bg-0);
}
.step__marker::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--accent); }
.step__meta { color: var(--accent); }
.step h3 { font-size: 1.25rem; }
.step p:not(.lab) { color: var(--text-2); font-size: var(--fs-small); line-height: 1.62; }
/* Desktop: one line across all five markers. */
@media (min-width: 1024px) {
  .steps { grid-template-columns: repeat(5, 1fr); gap: 1.5rem; }
  .steps::before, .steps::after { content: ""; position: absolute; left: 0; right: 0; top: 7px; height: 1px; }
  .steps::before { background: var(--line-strong); }
  .steps::after { background: var(--accent); transform-origin: 0 50%; }
  .step:not(:last-child)::before, .step:not(:last-child)::after { display: none; }
  .step { padding: 2.25rem 0 0; }
  .step__marker { top: 0; }
}

/* ---------- Features ---------- */

.features { display: grid; gap: 1rem; list-style: none; }
@media (min-width: 700px) { .features { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .features { grid-template-columns: repeat(3, 1fr); } }
.feature { display: grid; align-content: start; gap: 0.8rem; }
.feature__icon { display: grid; place-items: center; width: 44px; height: 44px; border: 1px solid var(--line-strong); border-radius: 12px; color: var(--accent); }
.feature h3 { font-size: 1.25rem; }
.feature p:not(.lab) { color: var(--text-2); font-size: var(--fs-small); line-height: 1.62; }
.proof-note { max-width: 72ch; margin-top: 1.75rem; padding-left: 1rem; border-left: 1px solid var(--accent); color: var(--text-2); font-size: var(--fs-small); }

/* ---------- Audience and key facts ---------- */

.audience { display: grid; gap: 1rem; list-style: none; }
@media (min-width: 900px) { .audience { grid-template-columns: repeat(3, 1fr); } }
.audience__item { display: grid; align-content: start; gap: 0.8rem; padding-top: 1.25rem; border-top: 1px solid var(--line-strong); }
.audience__item h3 { font-size: 1.25rem; }
.audience__item p:not(.lab) { color: var(--text-2); font-size: var(--fs-small); line-height: 1.62; }
.audience__links { display: grid; gap: 0.1rem; list-style: none; }

.facts { margin-top: clamp(2.5rem, 5vw, 4rem); }
.facts__head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; }
.facts__head :is(h2, h3) { font-size: 1.25rem; }
.facts__list { display: grid; margin: 0; border-top: 1px solid var(--line); }
.facts__row { display: grid; gap: 0.15rem; padding: 0.85rem 0; border-bottom: 1px solid var(--line); }
.facts__row dt { color: var(--text-3); font-family: var(--font-mono); font-size: var(--fs-lab); letter-spacing: 0.13em; text-transform: uppercase; }
.facts__row dd { margin: 0; color: var(--text-1); }
.facts__row a { text-decoration: none; }
/* A 44 px tall tap area around each link, without moving the text. */
.facts__row dd a { display: inline-block; padding-block: 11px; margin-block: -11px; }
.facts__row a:hover { text-decoration: underline; }
/* Two columns of facts from tablet width, each label above its value; labels
   move beside their values only once each column is wide enough for both. */
@media (min-width: 760px) {
  .facts__list { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 2.5rem; }
}
@media (min-width: 1200px) {
  .facts__row { grid-template-columns: 10.5rem minmax(0, 1fr); gap: 1rem; align-items: baseline; }
}

/* ---------- Questions ---------- */

.faq { display: grid; max-width: 56rem; border-top: 1px solid var(--line); }
.faq__item { border-bottom: 1px solid var(--line); }
.faq__item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 64px;
  padding: 1.1rem 0;
  color: var(--text-1);
  font-family: var(--font-display);
  font-size: clamp(1.125rem, 1.05rem + 0.35vw, 1.3125rem);
  font-weight: 620;
  letter-spacing: -0.015em;
  line-height: 1.3;
  list-style: none;
  cursor: pointer;
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary:hover { color: var(--accent); }
.faq__sign { position: relative; display: grid; place-items: center; width: 32px; height: 32px; flex: none; border: 1px solid var(--line-strong); border-radius: 50%; color: var(--accent); }
.faq__sign .icon { transition: transform 300ms var(--ease-out); }
.faq__item[open] .faq__sign .icon { transform: rotate(45deg); }
.faq__a { padding: 0 3.5rem 1.4rem 0; }
.faq__a p { color: var(--text-2); }

/* ---------- Closing call to action and form ---------- */

.closing { position: relative; isolation: isolate; overflow: clip; }
.closing::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: -30%; right: -20%;
  width: max(480px, 50vw);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--accent) 50%, transparent), transparent);
  opacity: 0.1;
  pointer-events: none;
}
.closing__grid { display: grid; gap: clamp(2rem, 5vw, 4.5rem); }
@media (min-width: 1024px) { .closing__grid { grid-template-columns: 5fr 7fr; } }
.closing__intro { display: grid; gap: 1.1rem; align-content: start; }
.next-steps { display: grid; gap: 0.9rem; margin-top: 0.75rem; list-style: none; counter-reset: step; }
.next-steps li { position: relative; padding-left: 2.6rem; color: var(--text-2); font-size: var(--fs-small); counter-increment: step; }
.next-steps li::before {
  content: "0" counter(step);
  position: absolute;
  left: 0; top: 0.1rem;
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: var(--fs-lab);
  letter-spacing: 0.1em;
}
.contact-list { display: grid; gap: 0.25rem; margin-top: 0.5rem; list-style: none; }
.contact-list a { display: inline-flex; align-items: center; gap: 0.65rem; min-height: 44px; color: var(--text-1); text-decoration: none; }
.contact-list a:hover { color: var(--accent); }
.contact-list .icon { color: var(--accent); }

.form-card { padding: clamp(1.35rem, 3vw, 2.25rem); }
.form { display: grid; gap: 1.15rem; }
.form__row { display: grid; gap: 1.15rem; }
@media (min-width: 640px) { .form__row { grid-template-columns: 1fr 1fr; } }
.form__hp { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.field { display: grid; gap: 0.45rem; min-width: 0; margin: 0; padding: 0; border: 0; }
.field label, .field legend { padding: 0; color: var(--text-1); font-size: var(--fs-small); font-weight: 500; }
.field__opt { color: var(--text-3); font-weight: 400; }
.input {
  width: 100%;
  min-height: 50px;
  padding: 0.75rem 0.95rem;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  background: var(--bg-2);
  color: var(--text-1);
  font: inherit;
  font-size: 1rem;
  line-height: 1.4;
  transition: border-color 200ms var(--ease-out), box-shadow 200ms var(--ease-out);
}
textarea.input { min-height: 132px; resize: vertical; }
.input::placeholder { color: var(--text-3); opacity: 1; }
.input:hover { border-color: rgba(255, 255, 255, 0.26); }
.input:focus { outline: none; border-color: var(--gold-500); box-shadow: 0 0 0 3px rgba(240, 193, 0, 0.18); }
.input:focus-visible { outline: 2px solid var(--gold-500); outline-offset: 2px; }
.input[aria-invalid="true"] { border-color: var(--danger); }
.field__error { margin: 0; color: var(--danger); font-size: 0.875rem; line-height: 1.4; }
.field__error:empty { display: none; }

.chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.chips legend { margin-bottom: 0.55rem; }
.chip { position: relative; display: inline-flex; }
.chip input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.chip span {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 44px;
  padding: 0.5rem 1rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  color: var(--text-2);
  font-size: var(--fs-small);
  font-weight: 500;
  transition: border-color 200ms var(--ease-out), background-color 200ms var(--ease-out), color 200ms var(--ease-out);
}
.chip span::before {
  content: "";
  width: 8px; height: 8px;
  border: 1px solid currentColor;
  border-radius: 50%;
  transition: background-color 200ms var(--ease-out);
}
.chip input:hover + span { border-color: rgba(255, 255, 255, 0.3); color: var(--text-1); }
.chip input:checked + span { border-color: var(--c, var(--gold-500)); background: color-mix(in srgb, var(--c, var(--gold-500)) 10%, transparent); color: var(--text-1); }
.chip input:checked + span::before { border-color: var(--c, var(--gold-500)); background: var(--c, var(--gold-500)); }
.chip input:focus-visible + span { outline: 2px solid var(--gold-500); outline-offset: 2px; }
.chip--build { --c: var(--cyan); }
.chip--grow { --c: var(--gold-500); }
.chip--automate { --c: var(--lavender); }

.form__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem 1.25rem; margin-top: 0.35rem; }
.form__alt { min-height: 44px; padding: 0 0.25rem; border: 0; background: none; color: var(--text-1); font-size: var(--fs-small); font-weight: 500; text-decoration: underline; text-decoration-color: var(--line-strong); text-underline-offset: 0.25em; cursor: pointer; }
.form__alt:hover { text-decoration-color: currentColor; }
.form__note { color: var(--text-3); font-size: 0.875rem; }
.form__note a { color: var(--text-2); }
.form__status { margin: 0; color: var(--text-1); font-size: var(--fs-small); }
.form__status:empty { display: none; }

.form__submit { min-width: 13.5rem; }
.form__submit .tick { position: absolute; inset: 0; margin: auto; width: 26px; height: 26px; fill: none; stroke: var(--ink); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; opacity: 0; }
.form__submit .tick path { stroke-dasharray: 1; stroke-dashoffset: 1; }
.form__submit.is-done .btn__label { opacity: 0; }
.form__submit.is-done .tick { opacity: 1; }
.form__submit.is-done .tick path { stroke-dashoffset: 0; }

.form-done { display: grid; gap: 0.85rem; }
.form-done[hidden] { display: none; }
.form-done h3 { font-size: 1.375rem; }
.form-done:focus { outline: none; }

.form__submit[aria-disabled="true"] { cursor: progress; opacity: 0.85; }

/* Shown when the backend can't send: what was typed stays in the form. */
.form-error { display: grid; gap: 0.85rem; padding: 1rem 1.1rem; border: 1px solid color-mix(in srgb, var(--danger) 55%, transparent); border-radius: 12px; background: color-mix(in srgb, var(--danger) 7%, transparent); }
.form-error[hidden] { display: none; }
.form-error p { margin: 0; color: var(--text-1); font-size: var(--fs-small); }
.form-error .btn-row { align-items: center; }
/* On a phone the two ways to send a failed message are equal buttons. */
@media (max-width: 767.98px) {
  .form-error .btn-row > .form__alt {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 48px;
    padding: 0 1.25rem;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    font-size: 1rem;
    font-weight: 600;
    text-decoration: none;
  }
}
/* Narrowest phones: the box sits inside the form card, so it and its buttons
   give up a little padding to keep both labels on one line. */
@media (max-width: 379.98px) {
  .form-error { padding-inline: 0.8rem; }
  .form-error .btn-row > .btn, .form-error .btn-row > .form__alt { padding-inline: 0.75rem; font-size: 0.9375rem; }
}

/* Quick check: a sum the backend signs, shown on number tiles. */
.captcha {
  display: grid;
  gap: 0.75rem;
  padding: 1rem 1.1rem 1.15rem;
  border: 1px solid color-mix(in srgb, var(--accent) 22%, var(--line));
  border-radius: 14px;
  background:
    radial-gradient(130% 160% at 0% 0%, color-mix(in srgb, var(--accent) 8%, transparent), transparent 55%),
    var(--bg-1);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
  transition: border-color 260ms var(--ease-out), box-shadow 260ms var(--ease-out);
}
.captcha[hidden] { display: none; }
.captcha__head { display: flex; align-items: center; gap: 0.6rem; min-height: 44px; }
.captcha__icon {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex: none;
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  color: var(--accent);
}
.captcha__label {
  color: var(--text-1);
  font-family: var(--font-mono);
  font-size: var(--fs-lab);
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}
.captcha__refresh {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 44px;
  margin-left: auto;
  padding: 0 0.95rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: transparent;
  color: var(--text-2);
  font: inherit;
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  transition: border-color 200ms var(--ease-out), color 200ms var(--ease-out), background-color 200ms var(--ease-out);
}
.captcha__refresh:hover { border-color: color-mix(in srgb, var(--accent) 55%, transparent); color: var(--text-1); background: color-mix(in srgb, var(--accent) 6%, transparent); }
.captcha__refresh .icon { color: var(--accent); }
.captcha__hint { margin: 0; color: var(--text-3); font-size: 0.875rem; line-height: 1.45; }
.captcha__row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; }
.captcha__sum { display: flex; align-items: center; gap: 0.6rem; }
.captcha__tile {
  display: grid;
  place-items: center;
  min-width: 3.4rem;
  height: 3.5rem;
  padding: 0 0.8rem;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.015)), var(--bg-2);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 10px 22px -14px rgba(0, 0, 0, 0.9);
  color: var(--text-1);
  font-family: var(--font-mono);
  font-size: 1.6rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.captcha__op { color: var(--accent); font-family: var(--font-mono); font-size: 1.35rem; font-weight: 500; line-height: 1; }
.captcha__answer { position: relative; }
.captcha__input {
  width: 5.75rem;
  height: 3.5rem;
  min-height: 0;
  padding: 0 0.5rem;
  border-radius: 12px;
  font-family: var(--font-mono);
  font-size: 1.6rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  text-align: center;
}
.captcha__tick {
  position: absolute;
  top: -9px;
  right: -9px;
  width: 24px;
  height: 24px;
  padding: 4px;
  border-radius: 50%;
  background: var(--metal);
  box-shadow: 0 4px 12px -2px color-mix(in srgb, var(--accent) 60%, transparent);
  fill: none;
  stroke: var(--ink);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0;
  transform: scale(0.4);
}
.captcha__tick path { stroke-dasharray: 1; stroke-dashoffset: 1; }
.captcha .field__error { margin-top: -0.15rem; }

.captcha.is-solved { border-color: color-mix(in srgb, var(--accent) 50%, var(--line)); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), 0 0 0 1px color-mix(in srgb, var(--accent) 12%, transparent), 0 18px 40px -28px color-mix(in srgb, var(--accent) 70%, transparent); }
.captcha.is-solved .captcha__input { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent); }
.captcha.is-solved .captcha__tick { opacity: 1; transform: none; }
.captcha.is-solved .captcha__tick path { stroke-dashoffset: 0; }
.captcha.is-loading .captcha__tile {
  color: transparent;
  background: linear-gradient(100deg, var(--bg-2) 30%, rgba(255, 255, 255, 0.09) 50%, var(--bg-2) 70%) 0 0 / 220% 100%, var(--bg-2);
}
.captcha.is-failed .captcha__tile::after { content: "–"; color: var(--text-3); }

.captcha__label, .captcha__refresh { white-space: nowrap; }
.captcha__input::placeholder { color: var(--text-3); font-weight: 500; }

/* Narrow phones: the refresh button keeps its name for screen readers but
   shows only its arrow, and the tiles tighten so the sum stays on one line. */
@media (max-width: 419px) {
  .captcha__refresh { justify-content: center; width: 44px; padding: 0; }
  .captcha__refresh-text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
@media (max-width: 379px) {
  .captcha { padding-inline: 0.85rem; }
  .captcha__row, .captcha__sum { gap: 0.4rem; }
  .captcha__tile { min-width: 2.6rem; height: 3rem; padding: 0 0.5rem; font-size: 1.3rem; }
  .captcha__op { font-size: 1.1rem; }
  .captcha__input { width: 4.4rem; height: 3rem; font-size: 1.3rem; }
}

@media (forced-colors: active) {
  .captcha, .captcha__tile { border: 1px solid CanvasText; }
  .captcha__tick { background: Highlight; stroke: HighlightText; }
}

.form-fallback { display: none; gap: 1rem; }
.form-fallback .contact-list { margin-top: 0; }
/* Without scripts the form can't send, so direct contact routes replace it. */
@media (scripting: none) {
  .form[data-form] { display: none; }
  .form-fallback { display: grid; }
}
.form-card.is-offline .form-fallback { display: grid; margin-top: 1.5rem; }

/* ---------- Footer ---------- */

.site-footer { position: relative; padding-top: clamp(3.5rem, 7vw, 6rem); background: var(--bg-0); }
.site-footer > .divider { position: absolute; inset: 0 0 auto; }
.footer__top { display: grid; gap: 2.75rem; }
.footer__brand { display: grid; gap: 1.1rem; align-content: start; }
.footer__logo { justify-self: start; border-radius: 4px; }
.footer__logo img { width: 250px; }
.footer__about { max-width: 38ch; color: var(--text-2); font-size: var(--fs-small); }
.footer__coords { color: var(--text-3); white-space: pre-wrap; }
.footer__time { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem 0.75rem; color: var(--text-1); font-size: var(--fs-small); }
.footer__nav { display: grid; grid-template-columns: repeat(2, 1fr); gap: 2rem 1.5rem; }
.footer__h { margin-bottom: 0.75rem; color: var(--text-2); font-family: var(--font-mono); font-size: var(--fs-lab); font-weight: 500; letter-spacing: 0.13em; line-height: 1.4; text-transform: uppercase; }
/* Links that wrap onto two lines on a phone get room above and below, so
   neighbouring items don't read as one. */
.footer__list { display: grid; gap: 0.15rem; list-style: none; }
.footer__list a { display: inline-flex; align-items: center; min-height: 36px; padding-block: 0.4rem; color: var(--text-2); font-size: var(--fs-small); line-height: 1.35; text-decoration: none; }
.footer__list a:hover { color: var(--text-1); text-decoration: underline; }
.footer__contact { margin-top: clamp(2.5rem, 5vw, 3.5rem); padding-top: 1.75rem; border-top: 1px solid var(--line); }
.footer__contact > .footer__h { margin-bottom: 1.25rem; }
.footer__address { display: grid; gap: 1.5rem 2.5rem; color: var(--text-2); font-size: var(--fs-small); }
.footer__item { display: grid; gap: 0.35rem; align-content: start; }
.footer__item p { margin: 0; }
.footer__label { color: var(--text-3); font-family: var(--font-mono); font-size: var(--fs-lab); letter-spacing: 0.13em; text-transform: uppercase; }
.footer__item a { display: inline-block; padding-block: 0.3rem; color: var(--text-1); text-decoration: underline; text-decoration-color: var(--line-strong); }
.footer__item a:hover { text-decoration-color: currentColor; }
@media (min-width: 600px) {
  .footer__address { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .footer__address { grid-template-columns: minmax(0, 2fr) repeat(3, minmax(0, 1fr)); }
}
.footer__base {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 2rem;
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-block: 1.5rem;
  border-top: 1px solid var(--line);
  color: var(--text-3);
  font-size: 0.875rem;
}
.footer__base p { margin: 0; }
@media (min-width: 760px) {
  .footer__nav { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .footer__top { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 3rem; }
}

/* Motion switch */
.switch { position: relative; display: inline-flex; align-items: center; gap: 0.75rem; min-height: 44px; color: var(--text-2); font-size: 0.875rem; cursor: pointer; }
.switch input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.switch__track { position: relative; width: 40px; height: 24px; flex: none; border: 1px solid var(--line-strong); border-radius: 999px; background: var(--bg-2); transition: background-color 200ms var(--ease-out), border-color 200ms var(--ease-out); }
.switch__track::after { content: ""; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: var(--text-3); transition: transform 200ms var(--ease-out), background-color 200ms var(--ease-out); }
.switch input:checked + .switch__track { border-color: var(--gold-500); background: rgba(240, 193, 0, 0.18); }
.switch input:checked + .switch__track::after { background: var(--gold-500); transform: translateX(16px); }
.switch input:focus-visible + .switch__track { outline: 2px solid var(--gold-500); outline-offset: 2px; }
.switch input:disabled { cursor: not-allowed; }
/* Without scripts nothing loops, and the switch couldn't remember a choice. */
@media (scripting: none) { .switch { display: none; } }

/* ---------- Phone dock and floating WhatsApp ---------- */

.dock {
  position: fixed;
  inset: auto 0 0;
  z-index: 55;
  display: grid;
  grid-template-columns: auto auto 1fr;
  gap: 0.5rem;
  padding: 0.5rem var(--pad) calc(0.5rem + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--line);
  background: var(--bg-1);
  transition: transform 250ms var(--ease-out);
}
.dock__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-height: 48px;
  padding-inline: 0.85rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  color: var(--text-1);
  font-size: 0.875rem;
  font-weight: 600;
  white-space: nowrap;
  text-decoration: none;
}
.dock__item.btn--primary { border-color: transparent; color: var(--ink); }
@media (max-width: 359.98px) {
  .dock__item .icon { display: none; }
}
@media (max-width: 767.98px) and (max-height: 440px) and (orientation: landscape) {
  .dock { padding-block: 0.375rem calc(0.375rem + env(safe-area-inset-bottom, 0px)); }
  .dock__item { min-height: 44px; }
}
:root:has(:is(input:not([type="checkbox"]):not([type="radio"]), textarea, select):focus) .dock { transform: translateY(110%); }
@media (min-width: 768px) { .dock { display: none; } }

.wa-float { display: none; }
@media (min-width: 768px) {
  .wa-float {
    position: fixed;
    right: clamp(1rem, 2.5vw, 2rem);
    bottom: clamp(1rem, 2.5vw, 2rem);
    z-index: 55;
    display: grid;
    place-items: center;
    width: 56px; height: 56px;
    border: 1px solid var(--line-strong);
    border-radius: 50%;
    background: var(--bg-2);
    color: var(--text-1);
    box-shadow: 0 12px 30px -10px rgba(0, 0, 0, 0.8);
    transition: border-color 200ms var(--ease-out), color 200ms var(--ease-out);
  }
  .wa-float:hover { border-color: rgba(255, 255, 255, 0.34); color: var(--gold-400); }
  .wa-float::after { content: ""; position: absolute; inset: -1px; border: 1px solid var(--gold-500); border-radius: 50%; opacity: 0; pointer-events: none; }
}

/* ---------- Back to top ----------
   A plain link to the top of the page, so it works without scripts. With
   them, it appears once the page has been scrolled and glides up, unless
   motion is reduced. Its ring fills with the spectrum as the page is read,
   like the reading bar along the top. Phones: above the bottom bar.
   Wider screens: above the WhatsApp button, centred on it. */

@property --read { syntax: "<percentage>"; inherits: false; initial-value: 0%; }

.to-top {
  position: fixed;
  right: max(1rem, env(safe-area-inset-right, 0px));
  bottom: calc(var(--dock-h) + 0.875rem);
  z-index: 55;
  display: grid;
  place-items: center;
  width: 48px; height: 48px;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: radial-gradient(circle at 50% 28%, rgba(255, 255, 255, 0.08), transparent 62%), var(--bg-2);
  color: var(--text-1);
  box-shadow: 0 14px 32px -12px rgba(0, 0, 0, 0.9), inset 0 1px 0 rgba(255, 255, 255, 0.06);
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
.to-top::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: 50%;
  background: conic-gradient(#F0C100, #7FF8FB 50%, #E7B4FC);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 1.5px)), conic-gradient(#000 var(--read), transparent 0);
  -webkit-mask-composite: source-in;
  mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 1.5px)), conic-gradient(#000 var(--read), transparent 0);
  mask-composite: intersect;
  pointer-events: none;
}
.to-top::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(240, 193, 0, 0.35), 0 0 26px -4px rgba(240, 193, 0, 0.6);
  opacity: 0;
  pointer-events: none;
}
.to-top__icon { position: relative; display: grid; place-items: center; width: 22px; height: 22px; overflow: hidden; }
.to-top__icon .icon { transform: rotate(-90deg); }
.to-top__tip {
  position: absolute;
  top: 50%; right: calc(100% + 0.75rem);
  padding: 0.45rem 0.8rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--bg-1);
  color: var(--text-1);
  font-family: var(--font-mono);
  font-size: var(--fs-lab);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
  opacity: 0;
  transform: translate(6px, -50%);
  pointer-events: none;
}
.to-top:focus-visible { outline: 2px solid var(--gold-500); outline-offset: 3px; }
.to-top:focus-visible .to-top__tip { opacity: 1; transform: translate(0, -50%); }
@media (hover: hover) and (pointer: fine) {
  .to-top:hover { border-color: rgba(255, 255, 255, 0.34); }
  .to-top:hover::after { opacity: 1; }
  .to-top:hover .to-top__tip { opacity: 1; transform: translate(0, -50%); }
}
@media (min-width: 768px) {
  .to-top { right: calc(clamp(1rem, 2.5vw, 2rem) + 4px); bottom: calc(clamp(1rem, 2.5vw, 2rem) + 56px + 0.75rem); }
}
@media (scripting: enabled) {
  .to-top:not(.is-shown) { opacity: 0; visibility: hidden; transform: translateY(10px) scale(0.92); pointer-events: none; }
}
/* Out of the way while a phone's keyboard is up, like the bottom bar. */
@media (max-width: 767.98px) {
  :root:has(:is(input:not([type="checkbox"]):not([type="radio"]), textarea, select):focus) .to-top { opacity: 0; visibility: hidden; }
}

/* ---------- Plain page hero (404 and inner pages) ---------- */

.page-hero { position: relative; isolation: isolate; overflow: clip; padding-top: calc(var(--header-h) + clamp(2.5rem, 7vw, 6rem)); padding-bottom: clamp(3rem, 7vw, 5.5rem); }
.page-hero h1 { max-width: 18ch; font-size: clamp(2.5rem, 1.6rem + 4vw, 4.75rem); line-height: 1; }
.page-hero .lede { margin-top: 1.25rem; }
.page-hero .btn-row { margin-top: 2rem; }
/* Contact: a short hero, so the form is in the first view. */
.page-hero--compact { padding-top: calc(var(--header-h) + clamp(1.5rem, 4vw, 3rem)); padding-bottom: clamp(1.5rem, 3vw, 2.25rem); }
.page-hero--compact .hero__bg { -webkit-mask-image: linear-gradient(#000 55%, transparent); mask-image: linear-gradient(#000 55%, transparent); }
.page-hero--compact h1 { max-width: none; font-size: clamp(2.25rem, 1.6rem + 2.6vw, 3.5rem); }
.page-hero--compact .lede { margin-top: 0.85rem; }
.page-hero--compact .btn-row { margin-top: 1.5rem; }
.section--after-hero { padding-top: 0.75rem; }

.breadcrumb { margin-bottom: 1.5rem; }
.breadcrumb ol { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.5rem; list-style: none; }
.breadcrumb li { display: inline-flex; align-items: center; gap: 0.5rem; color: var(--text-3); font-family: var(--font-mono); font-size: var(--fs-lab); letter-spacing: 0.1em; text-transform: uppercase; }
.breadcrumb li + li::before { content: "/"; color: var(--text-3); }
.breadcrumb a { display: inline-flex; align-items: center; min-height: 32px; color: var(--text-2); text-decoration: none; }
.breadcrumb a:hover { color: var(--text-1); text-decoration: underline; }
.breadcrumb [aria-current] { color: var(--text-1); }

.link-grid { display: grid; gap: 1rem; list-style: none; }
.lab + .link-grid { margin-top: 1rem; }
@media (min-width: 700px) { .link-grid { grid-template-columns: repeat(2, 1fr); } }
/* Two columns on a tablet: an odd last card takes the whole row rather than
   leaving an empty cell beside it. */
@media (min-width: 700px) and (max-width: 1023.98px) {
  .link-grid > :last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@media (min-width: 1024px) { .link-grid { grid-template-columns: repeat(3, 1fr); } }
.link-card { display: grid; gap: 0.5rem; align-content: start; }
.link-card h2, .link-card h3 { font-size: 1.25rem; }
.link-card h2 a, .link-card h3 a { text-decoration: none; }
.link-card h2 a:hover, .link-card h3 a:hover { text-decoration: underline; text-decoration-color: var(--accent); }
.link-card p:not(.lab) { color: var(--text-2); font-size: var(--fs-small); }

.updated { padding-block: 0 2.5rem; }

/* ---------- Service pages ---------- */

.svc-hero { position: relative; isolation: isolate; overflow: clip; padding-top: calc(var(--header-h) + clamp(1.75rem, 4.5vw, 4rem)); padding-bottom: clamp(2.5rem, 5vw, 4rem); }
.svc-hero__inner { display: grid; grid-template-columns: minmax(0, 1fr); gap: 2.5rem; align-items: center; }
.svc-hero__lab { margin-bottom: clamp(1rem, 2vw, 1.4rem); }
.svc-hero__title { font-size: clamp(2.375rem, 1.4rem + 4vw, 4.5rem); font-weight: 700; line-height: 1; letter-spacing: -0.035em; }
.svc-hero__line { display: block; max-width: 16ch; text-wrap: balance; }
.svc-hero__title .hero__desc { max-width: 40ch; }
.svc-hero__art { display: none; }
@media (min-width: 1024px) {
  .svc-hero__inner { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: clamp(2rem, 4vw, 4rem); }
  .svc-hero__art { display: block; }
}

/* The line art beside a service hero, framed like an instrument panel. */
.instrument { display: grid; gap: 1.5rem; padding: clamp(1.25rem, 2vw, 1.75rem); }
.instrument__bar { display: flex; justify-content: space-between; gap: 1rem; }
.instrument__bar .lab:first-child { color: var(--accent); }
.instrument .art { width: 100%; height: auto; color: var(--accent); --sw: 1.1; --sw-faint: 0.8; }

/* The short answer */
.answer { display: grid; gap: clamp(1.25rem, 3vw, 3rem); }
@media (min-width: 1024px) { .answer { grid-template-columns: 5fr 7fr; align-items: start; } }
.answer__head { display: grid; gap: 1.1rem; align-content: start; }
.answer__text { max-width: 60ch; padding-left: clamp(1rem, 2vw, 1.5rem); border-left: 2px solid var(--accent); color: var(--text-1); font-size: var(--fs-lede); line-height: 1.6; }
.glance { display: grid; margin: clamp(1.5rem, 3vw, 2.25rem) 0 0; border-top: 1px solid var(--line); }
.glance > div { display: grid; gap: 0.2rem; padding: 0.85rem 0; border-bottom: 1px solid var(--line); }
.glance dt { color: var(--text-3); font-family: var(--font-mono); font-size: var(--fs-lab); letter-spacing: 0.13em; text-transform: uppercase; }
.glance dd { margin: 0; color: var(--text-1); font-size: var(--fs-small); }
@media (min-width: 760px) { .glance > div { grid-template-columns: 10rem 1fr; gap: 1rem; align-items: baseline; } }

/* Problems and cost factors share one grid: two columns, then three. An
   odd last item spans its row, and a row of two splits the width evenly,
   so five items read 3 + 2 rather than leaving an empty cell. */
.problems, .factors { display: grid; gap: clamp(1.75rem, 3vw, 2.5rem) 2.5rem; list-style: none; }
@media (min-width: 760px) and (max-width: 1099.98px) {
  .problems, .factors { grid-template-columns: repeat(2, 1fr); }
  :is(.problem, .factor):last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@media (min-width: 1100px) {
  .problems, .factors { grid-template-columns: repeat(6, 1fr); }
  .problem, .factor { grid-column: span 2; }
  :is(.problem, .factor):nth-child(3n + 1):nth-last-child(2),
  :is(.problem, .factor):nth-child(3n + 2):last-child { grid-column: span 3; }
  :is(.problem, .factor):nth-child(3n + 1):last-child { grid-column: 1 / -1; }
}
.problem { position: relative; display: grid; align-content: start; gap: 0.7rem; padding-top: 1.25rem; border-top: 1px solid var(--line-strong); }
.problem::before { content: ""; position: absolute; top: -1px; left: 0; width: 2.5rem; height: 1px; background: var(--accent); }
.problem h3 { font-size: 1.25rem; }
.problem p { max-width: 68ch; color: var(--text-2); font-size: var(--fs-small); line-height: 1.62; }

/* Included in every project */
.checklist-title { margin-top: clamp(2.25rem, 4vw, 3rem); }
.checklist { display: grid; gap: 0.65rem 2rem; margin-top: 1rem; list-style: none; }
@media (min-width: 700px) { .checklist { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .checklist { grid-template-columns: repeat(3, 1fr); } }
.checklist li { display: flex; align-items: flex-start; gap: 0.65rem; color: var(--text-1); font-size: var(--fs-small); line-height: 1.55; }
.checklist .icon { margin-top: 0.1rem; color: var(--accent); }

/* Measures */
.metrics { display: grid; list-style: none; border-top: 1px solid var(--line); }
.metric { display: grid; gap: 0.5rem; padding: 1.4rem 0; border-bottom: 1px solid var(--line); }
.metric__name { display: grid; gap: 0.35rem; align-content: start; }
.metric h3 { font-size: 1.25rem; }
.metric p:not(.lab) { max-width: 68ch; color: var(--text-2); font-size: var(--fs-small); line-height: 1.62; }
@media (min-width: 900px) { .metric { grid-template-columns: 16rem minmax(0, 1fr); gap: 2.5rem; } }

/* Tools */
.stack { display: grid; gap: 2rem 2.5rem; }
@media (min-width: 900px) { .stack { grid-template-columns: repeat(3, 1fr); } }
.stack__group { display: grid; gap: 0.9rem; align-content: start; }
.stack__group h3 { font-size: 1.25rem; }
.stack__list { display: grid; margin: 0; border-top: 1px solid var(--line); }
.stack__list > div { display: grid; gap: 0.2rem; padding: 0.8rem 0; border-bottom: 1px solid var(--line); }
.stack__list dt { color: var(--text-1); font-size: var(--fs-small); font-weight: 600; }
.stack__list dd { margin: 0; color: var(--text-2); font-size: var(--fs-small); line-height: 1.55; }

/* What moves the cost (grid shared with .problems above) */
.factors { counter-reset: factor; }
.factor { display: grid; align-content: start; gap: 0.5rem; padding-top: 1rem; border-top: 1px solid var(--line-strong); counter-increment: factor; }
.factor::before { content: "0" counter(factor); color: var(--accent); font-family: var(--font-mono); font-size: var(--fs-lab); letter-spacing: 0.13em; }
.factor h3 { font-size: 1.1875rem; }
.factor p { max-width: 68ch; color: var(--text-2); font-size: var(--fs-small); line-height: 1.62; }

/* Comparison table. From 760 px it's an ordinary table. On phones each row
   becomes a block: the row's heading on top, then every value labelled with
   its column (from data-label), so nothing sits off to the side. */
.table-wrap { border-top: 1px solid var(--line-strong); }
.compare { width: 100%; border-collapse: collapse; font-size: var(--fs-small); line-height: 1.5; }
.compare th, .compare td { padding: 0.95rem 1rem; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; text-wrap: pretty; }
.compare thead th { color: var(--text-1); font-family: var(--font-display); font-size: 1.125rem; font-weight: 650; letter-spacing: -0.015em; line-height: 1.2; }
.compare thead th:first-child { color: var(--text-3); font-family: var(--font-mono); font-size: var(--fs-lab); font-weight: 500; letter-spacing: 0.13em; text-transform: uppercase; }
.compare th:first-child { width: 22%; padding-left: 0; }
.compare tbody th { color: var(--text-1); font-weight: 600; }
.compare td { color: var(--text-2); }
@media (max-width: 759.98px) {
  .table-wrap { border-top: 0; }
  .compare, .compare tbody, .compare tr, .compare th, .compare td { display: block; }
  .compare thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .compare tr { padding: 1.1rem 0 0.9rem; border-top: 1px solid var(--line-strong); }
  .compare tr:last-child { border-bottom: 1px solid var(--line-strong); }
  .compare th, .compare td { padding: 0; border: 0; }
  .compare th:first-child { width: auto; }
  .compare tbody th { margin-bottom: 0.55rem; }
  .compare td { display: grid; grid-template-columns: minmax(6.5rem, 38%) 1fr; gap: 1rem; padding-block: 0.3rem; }
  .compare td::before { content: attr(data-label); color: var(--text-3); }
}
.table-note { margin-top: 1.25rem; color: var(--text-3); font-size: 0.875rem; }

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

/* ---------- How we work: stages ---------- */

.phases { display: grid; list-style: none; border-top: 1px solid var(--line); }
.phase { display: grid; gap: 0.75rem 2.5rem; padding: clamp(1.5rem, 3vw, 2.25rem) 0; border-bottom: 1px solid var(--line); }
@media (min-width: 900px) { .phase { grid-template-columns: 16rem minmax(0, 1fr); } }
.phase__meta { display: grid; gap: 0.4rem; align-content: start; }
.phase__meta h3 { font-size: 1.375rem; }
.phase__body { display: grid; gap: 1rem; max-width: 68ch; }
.phase__body > p { margin: 0; color: var(--text-2); }
.phase__io { display: grid; gap: 0.75rem 2rem; margin: 0; }
@media (min-width: 640px) { .phase__io { grid-template-columns: 1fr 1fr; } }
.phase__io > div { display: grid; align-content: start; gap: 0.25rem; padding-top: 0.75rem; border-top: 1px solid var(--line); }
.phase__io dt { color: var(--accent); font-family: var(--font-mono); font-size: var(--fs-lab); letter-spacing: 0.13em; text-transform: uppercase; }
.phase__io dd { margin: 0; color: var(--text-1); font-size: var(--fs-small); }

/* Four cards read better as two rows of two than as three and one. */
@media (min-width: 1100px) { .features--two { grid-template-columns: repeat(2, 1fr); } }
.stack__list--single { max-width: 48rem; }

/* ---------- Contact ---------- */

.contact__grid { display: grid; gap: clamp(2rem, 4vw, 3.5rem); }
@media (min-width: 1024px) { .contact__grid { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); align-items: start; } }
.contact__main, .contact__side { display: grid; gap: 1.1rem; align-content: start; }
:is(.contact__main, .contact__side) > h2:not(.lab) { font-size: var(--fs-h3); }
.contact__side .lab { margin-top: 0.75rem; }
.contact__time { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem 0.75rem; color: var(--text-1); font-size: var(--fs-small); }

/* Contact puts the live map beside the text (its card is in diagrams.css);
   the Guwahati page keeps a drawing that links out to Google Maps. */
.location { display: grid; gap: clamp(2rem, 4vw, 3.5rem); }
@media (min-width: 900px) { .location { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); align-items: center; } }
@media (min-width: 900px) { .location:has(.mapcard) { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); } }
.location__text { display: grid; gap: 1.1rem; align-content: start; }
.location__address { margin: 0; color: var(--text-1); font-size: var(--fs-lede); line-height: 1.5; }
.location__coords { color: var(--text-3); white-space: pre-wrap; }

/* ---------- Legal pages ---------- */

.page-hero--compact .toc { margin-top: clamp(1.75rem, 3vw, 2.5rem); }
.legal { max-width: 72ch; color: var(--text-2); }
.legal h2 { margin: clamp(2.5rem, 5vw, 3.5rem) 0 1rem; font-size: var(--fs-h3); line-height: 1.2; }
.legal h2:first-child { margin-top: 0; }
.legal h3 { margin: 1.75rem 0 0.6rem; font-family: var(--font-body); font-size: 1.0625rem; font-weight: 650; line-height: 1.35; }
.legal p, .legal li { line-height: 1.7; }
.legal strong { color: var(--text-1); font-weight: 600; }
.legal ul { margin: 0 0 1em; padding-left: 1.25rem; list-style: disc; }
.legal li { margin-bottom: 0.5em; }
.legal li::marker { color: var(--accent); }
.legal a:not(.btn) { color: var(--accent); text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--accent) 45%, transparent); overflow-wrap: anywhere; }
.legal a:not(.btn):hover { color: var(--text-1); text-decoration-color: currentColor; }
.legal .table-wrap { margin: 1.5rem 0; }
.legal a[href^="tel:"] { white-space: nowrap; overflow-wrap: normal; }

/* ---------- Reveal ---------- */

[data-stagger] > * { --i: 0; }
[data-stagger] > :nth-child(2) { --i: 1; }
[data-stagger] > :nth-child(3) { --i: 2; }
[data-stagger] > :nth-child(4) { --i: 3; }
[data-stagger] > :nth-child(5) { --i: 4; }
[data-stagger] > :nth-child(6) { --i: 5; }
[data-stagger] > :nth-child(n + 7) { --i: 6; }

/* ---------- Motion (all of it) ----------
   Runs only when the visitor has not asked for reduced motion, either in
   their system settings or with the footer switch. Loops also wait for
   .is-live, which site.js adds to each [data-loop] container once the page
   has loaded and gone idle, so they never compete with the first paint. */

@keyframes settle { from { transform: translateY(0.22em); opacity: 0.4; } to { transform: none; opacity: 1; } }
@keyframes rise { from { transform: translateY(14px); opacity: 0.4; } to { transform: none; opacity: 1; } }
@keyframes sheen { from { background-position: 100% 0; } to { background-position: 0 0; } }
@keyframes drift-a { 0%, 100% { transform: translate3d(0, 0, 0); } 50% { transform: translate3d(9vw, 5vw, 0); } }
@keyframes drift-b { 0%, 100% { transform: translate3d(0, 0, 0); } 50% { transform: translate3d(-8vw, 7vw, 0); } }
@keyframes drift-c { 0%, 100% { transform: translate3d(0, 0, 0); } 50% { transform: translate3d(6vw, -6vw, 0); } }
@keyframes marquee { to { transform: translateX(-50%); } }
@keyframes progress { to { transform: scaleX(1); } }
@keyframes line-draw-x { from { transform: scaleX(0); } to { transform: none; } }
@keyframes line-draw-y { from { transform: scaleY(0); } to { transform: none; } }
@keyframes reveal { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes marker-on { from { opacity: 0.25; } to { opacity: 1; } }
@keyframes pulse { 0% { opacity: 0.75; transform: scale(1); } 100% { opacity: 0; transform: scale(1.55); } }
@keyframes fade-rise { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
@keyframes digit-in { from { opacity: 0; transform: translateY(45%); filter: blur(4px); } to { opacity: 1; transform: none; filter: none; } }
@keyframes shimmer { from { background-position: 100% 0, 0 0; } to { background-position: -120% 0, 0 0; } }
@keyframes spin-once { to { transform: rotate(360deg); } }
@keyframes read-ring { to { --read: 100%; } }
@keyframes lift-off { 0% { transform: rotate(-90deg); opacity: 1; } 45% { transform: rotate(-90deg) translateX(150%); opacity: 0; } 46% { transform: rotate(-90deg) translateX(-150%); opacity: 0; } 100% { transform: rotate(-90deg); opacity: 1; } }

/* Tile loops. Each cycle starts from the finished drawing (the static
   state), fades it out, redraws it and holds, so a loop can begin at any
   moment without a jump. */
@keyframes draw-loop {
  0%, 8% { stroke-dashoffset: 0; opacity: 1; }
  14% { stroke-dashoffset: 0; opacity: 0; }
  15% { stroke-dashoffset: 1; opacity: 0; }
  16% { stroke-dashoffset: 1; opacity: 1; }
  44%, 100% { stroke-dashoffset: 0; opacity: 1; }
}
@keyframes fade-loop {
  0%, 8% { opacity: 1; }
  14%, 44% { opacity: 0; }
  54%, 100% { opacity: 1; }
}
@keyframes travel {
  0%, 50% { transform: translate(28px, 70px); opacity: 0; }
  53% { transform: translate(28px, 70px); opacity: 1; }
  62% { transform: translate(92px, 70px); }
  71% { transform: translate(152px, 36px); }
  80% { transform: translate(212px, 70px); opacity: 1; }
  88%, 100% { transform: translate(212px, 70px); opacity: 0; }
}
@keyframes node-on {
  0% { fill-opacity: 0; }
  3%, 14% { fill-opacity: 0.9; }
  18%, 100% { fill-opacity: 0; }
}

@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }

  :root:not([data-motion="reduce"]) {
    /* Page change: short cross-fade, header held in place. */
    &::view-transition-old(root), &::view-transition-new(root) { animation-duration: 260ms; animation-timing-function: var(--ease-out); }

    /* Hero entrance: visible in the first frame, done within 600 ms. */
    & .hero__eyebrow, & .hero__coords { animation: rise 460ms var(--ease-out) both; }
    & .hero__word { animation: settle 440ms var(--ease-out) both; }
    & .hero__line:first-child .hero__word:nth-child(2) { animation-delay: 50ms; }
    & .hero__line:nth-child(2) .hero__word { animation-delay: 100ms; }
    & .hero__desc { animation: rise 460ms var(--ease-out) 120ms both; }
    & .hero__lede { animation: rise 460ms var(--ease-out) 140ms both; }
    & .hero__actions { animation: rise 440ms var(--ease-out) 160ms both; }
    & .hero__sheen { animation: sheen 700ms var(--ease-out) 650ms both; }

    /* Hero light fields: slow CSS loops. */
    & .is-live .hero__light--gold { animation: drift-a 26s ease-in-out infinite; }
    & .is-live .hero__light--cyan { animation: drift-b 23s ease-in-out infinite; }
    & .is-live .hero__light--lavender { animation: drift-c 29s ease-in-out infinite; }
    & .is-live .hero__light--one { animation: drift-b 24s ease-in-out infinite; }
    & .is-live .hero__light--two { animation: drift-c 28s ease-in-out infinite; }

    /* Service hero entrance: same rules as the home hero. */
    & .svc-hero .breadcrumb, & .svc-hero__lab { animation: rise 460ms var(--ease-out) both; }
    & .svc-hero__line { animation: settle 440ms var(--ease-out) 40ms both; }
    & .svc-hero__art { animation: rise 600ms var(--ease-out) 120ms both; }

    /* Tile loops */
    & .art.is-live .draw { stroke-dasharray: 1; animation: draw-loop var(--loop, 7s) var(--ease-out) infinite both; animation-delay: calc(var(--d, 0) * 1ms); }
    & .art.is-live .appear { animation: fade-loop var(--loop, 7s) var(--ease-out) infinite both; }
    & .art.is-live .traveller { animation: travel var(--loop, 7s) ease-in-out infinite both; }
    & .art.is-live .lit { animation: node-on var(--loop, 7s) ease-out infinite both; animation-delay: calc(var(--d, 0) * 1ms); }

    /* Capability marquee: its one-line layout is set below from the first
       frame; starting the loop only adds movement, so nothing shifts. */
    & .is-live .marquee__track { animation: marquee 80s linear infinite; }
    & .marquee:is(:hover, :focus-within) .marquee__track { animation-play-state: paused; }

    /* Client voices: one row gliding left at a reading pace, about 12.5 s a
       card (site.js sets --voices-time from the number of cards). Pointing
       at or focusing the row stops it, and the card under the pointer lifts. */
    & .voices__viewport.is-live .voices__track { animation: marquee var(--voices-time, 200s) linear infinite; }
    & .voices__viewport:is(:hover, :focus-within) .voices__track { animation-play-state: paused; }
    & .voice__figure { transition: transform 320ms var(--ease-out), border-color 320ms var(--ease-out), box-shadow 320ms var(--ease-out); }
    @media (hover: hover) and (pointer: fine) {
      & .voice__figure:hover {
        transform: translateY(-5px);
        box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 34px 70px -38px color-mix(in srgb, var(--c) 45%, rgba(0, 0, 0, 0.9));
      }
    }

    /* Buttons */
    & .btn { transition: transform 180ms var(--ease-out), background-color 200ms, border-color 200ms, color 200ms; }
    & .btn:active { transform: scale(0.98); }
    & .btn--primary:is(:hover, :focus-visible)::after { transform: translateX(130%); transition: transform 700ms var(--ease-out); }

    /* Popover panel */
    & .nav-panel { transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out), overlay 220ms allow-discrete, display 220ms allow-discrete; }
    & .nav-panel:not(:popover-open) { opacity: 0; transform: translateY(-6px); }
    & .nav-panel:popover-open {
      @starting-style { opacity: 0; transform: translateY(-6px); }
    }
    & .menu:popover-open .menu__body > * { animation: rise 420ms var(--ease-out) both; }
    & .menu:popover-open .menu__body > :nth-child(2) { animation-delay: 60ms; }
    & .menu:popover-open .menu__body > :nth-child(3) { animation-delay: 120ms; }

    /* FAQ: the answer fades and rises; height is not animated. */
    & .faq__item[open] .faq__a { animation: fade-rise 320ms var(--ease-out); }

    /* Back to top: rises in and fades out, the halo and label ease in,
       and on hover the arrow lifts off and comes back from below. */
    & .to-top { transition: opacity 260ms var(--ease-out), transform 380ms var(--ease-out), visibility 0s linear 380ms, border-color 200ms; }
    & .to-top.is-shown { transition: opacity 260ms var(--ease-out), transform 380ms var(--ease-out), visibility 0s, border-color 200ms; }
    & .to-top.is-shown:active { transform: scale(0.94); }
    & .to-top::after, & .to-top__tip { transition: opacity 220ms var(--ease-out), transform 260ms var(--ease-out); }
    @media (hover: hover) and (pointer: fine) {
      & .to-top:hover .to-top__icon .icon { animation: lift-off 560ms var(--ease-out); }
    }

    /* WhatsApp: one pulse after half the page */
    & .wa-float.is-pulsing::after { animation: pulse 1100ms var(--ease-out) 1; }

    /* Form success tick */
    & .form__submit .btn__label { transition: opacity 200ms var(--ease-out); }
    & .form__submit .tick path { transition: stroke-dashoffset 600ms var(--ease-out) 150ms; }

    /* Quick check: shimmer while a sum loads, digits rise in, the refresh
       arrow turns once, and the tick badge springs in and draws itself. */
    & .captcha.is-loading .captcha__tile { animation: shimmer 1.3s linear infinite; }
    & .captcha.is-new .captcha__tile, & .captcha.is-new .captcha__op { animation: digit-in 520ms var(--ease-out) both; }
    & .captcha.is-new .captcha__sum > :nth-child(2) { animation-delay: 70ms; }
    & .captcha.is-new .captcha__sum > :nth-child(3) { animation-delay: 140ms; }
    & .captcha.is-new .captcha__sum > :nth-child(4) { animation-delay: 210ms; }
    & .captcha__refresh.is-spinning .icon { animation: spin-once 620ms var(--ease-out); }
    & .captcha__tick { transition: opacity 220ms var(--ease-out), transform 420ms cubic-bezier(0.34, 1.56, 0.64, 1); }
    & .captcha__tick path { transition: stroke-dashoffset 420ms var(--ease-out) 120ms; }

    /* Scroll reveals. site.js marks only elements that start below the
       fold as pending, so nothing on screen is ever hidden. */
    & [data-reveal].is-pending, & [data-stagger].is-pending > * { opacity: 0; }
    & [data-reveal].is-in, & [data-stagger].is-in > * { animation: reveal 640ms var(--ease-out) both; animation-delay: calc(var(--i, 0) * 60ms); }

    /* Scroll-linked effects, where supported. The drawing front sits at
       60% of the viewport height. */
    @supports (animation-timeline: view()) {
      & .progress { animation: progress linear both; animation-timeline: scroll(root block); }
      & .to-top::before { animation: read-ring linear both; animation-timeline: scroll(root block); }
      & .step:not(:last-child)::after { animation: line-draw-y linear both; animation-timeline: view(); animation-range: cover 40vh cover calc(100% - 60vh); }
      & .step__marker::after { animation: marker-on linear both; animation-timeline: view(); animation-range: cover 40vh cover 46vh; }
      @media (min-width: 1024px) {
        & .steps { view-timeline: --steps block; }
        & .steps::after { animation: line-draw-x linear both; animation-timeline: --steps; animation-range: cover 25% cover 50%; }
        & .step__marker::after { animation-timeline: --steps; animation-range: cover calc(24% + var(--i, 0) * 6.25%) cover calc(26% + var(--i, 0) * 6.25%); }
      }
    }
  }
}

/* The marquee is one moving line only where motion is welcome and scripts
   run; otherwise it stays the wrapped list above, with every item visible. */
@media (prefers-reduced-motion: no-preference) and (scripting: enabled) {
  :root:not([data-motion="reduce"]) {
    & .marquee__viewport { -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent); mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent); }
    & .marquee__track { justify-content: flex-start; width: max-content; }
    & .marquee__list { flex-wrap: nowrap; padding-inline: 0; }
    & .marquee__list--copy { display: flex; }

    /* Client voices: the row becomes a masked, endless strip. The trailing
       padding equals the gap between cards, so the copy follows seamlessly. */
    & .voices__viewport {
      overflow: hidden;
      scroll-snap-type: none;
      -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
      mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
    }
    & .voices__list { padding-inline: 0 1.25rem; }
    & .voices__list--copy { display: flex; }
  }
}

/* Paused loops: off screen, tab hidden, or hovered marquee. Pseudo-elements
   are listed too, since play state isn't inherited. */
.is-paused, .is-paused *, .is-paused::before, .is-paused::after, .is-paused *::before, .is-paused *::after,
.is-hidden [data-loop], .is-hidden [data-loop] *, .is-hidden [data-loop]::before, .is-hidden [data-loop]::after,
.is-hidden [data-loop] *::before, .is-hidden [data-loop] *::after { animation-play-state: paused !important; }

/* ---------- Forced colours ---------- */

@media (forced-colors: active) {
  .btn--primary, .dock__item.btn--primary { border: 1px solid ButtonText; }
  .hero__sheen { color: CanvasText; background: none; }
  .card::before, .card::after, .divider, .progress { display: none; }
  .voice__avatar { border: 1px solid CanvasText; }
  .voice__figure::before { display: none; }
  .to-top { border-color: ButtonText; }
  .to-top::before, .to-top::after { display: none; }
}

/* ---------- Print ---------- */

@media print {
  .site-header, .dock, .wa-float, .hero__bg, .marquee, .voices, .menu, .nav-panel, .switch, .to-top { display: none !important; }
  body { padding: 0; background: #fff; color: #000; }
  h1, h2, h3, a, strong, .lede { color: #000 !important; }
}
