/* ============================================================
   Handova — Phase 1 marketing site
   ------------------------------------------------------------
   1.  Design tokens
   2.  Reset & base
   3.  Typography helpers
   4.  Icons
   5.  Buttons
   6.  Layout primitives
   7.  Header & navigation
   8.  Hero + dashboard mockup
   9.  Cards (problem / features)
   10. Solution flow
   11. How it works (steps)
   12. Split sections (schools / parents)
   13. School mockup
   14. Phone mockup
   15. Security
   16. Pricing
   17. FAQ
   18. Final CTA
   19. Forms
   20. Contact
   21. Book-a-demo modal
   22. Floating WhatsApp button
   23. Footer
   24. Scroll reveal
   25. Responsive
   26. Reduced motion
   ============================================================ */


/* ------------------------------------------------------------
   1. DESIGN TOKENS
   ------------------------------------------------------------ */
:root {
  /* Marketing-site-only tokens. Everything else comes from
     packages/design-system/tokens.css, linked before this file. */
  --whatsapp:       #1FA855;
  --whatsapp-hover: #17904A;
  --fs-display: clamp(2.5rem, 1.35rem + 4.6vw, 4.25rem);
  --fs-h2:      clamp(1.875rem, 1.25rem + 2.4vw, 2.75rem);
  --fs-h3:      clamp(1.0625rem, 1rem + 0.3vw, 1.1875rem);
  --fs-lede:    clamp(1.0625rem, 1rem + 0.45vw, 1.25rem);
  --lh-tight: 1.08;
  --section-y: clamp(4rem, 8vw, 7.5rem);
  --container-narrow: 800px;
  --header-h: 68px;
  --header-h-compact: 58px;
}


/* ------------------------------------------------------------
   2. RESET & BASE
   ------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 1.5rem);
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--text);
  background-color: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

body.is-locked { overflow: hidden; }

h1, h2, h3, h4, p, figure, dl, dd { margin: 0; }

ul, ol { margin: 0; padding: 0; list-style: none; }

a {
  color: inherit;
  text-decoration: none;
  transition: color var(--t-fast) var(--ease);
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

strong { font-weight: 600; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

/* Landmarks and sections receive focus programmatically after an in-page
   jump. The scroll itself signals arrival — a ring around a whole section
   would only be noise. */
main:focus,
main:focus-visible,
section:focus,
section:focus-visible { outline: none; }

.skip-link {
  position: absolute;
  top: -100%;
  left: var(--gutter);
  z-index: 200;
  padding: 0.75rem 1.125rem;
  background: var(--navy-900);
  color: var(--text-invert);
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  font-weight: 500;
}
.skip-link:focus { top: 0.75rem; }


/* ------------------------------------------------------------
   3. TYPOGRAPHY HELPERS
   ------------------------------------------------------------ */
.eyebrow {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: var(--space-4);
}

.section-title {
  font-size: var(--fs-h2);
  font-weight: 600;
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-tight);
  color: var(--text);
  text-wrap: balance;
}

.section-lede {
  margin-top: var(--space-4);
  font-size: var(--fs-lede);
  color: var(--text-muted);
  max-width: 58ch;
  text-wrap: pretty;
}

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


/* ------------------------------------------------------------
   4. ICONS
   ------------------------------------------------------------ */
.icon-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* fill/stroke are inherited, so one rule styles every icon
   instance consistently — single stroke weight throughout. */
.icon {
  width: 20px;
  height: 20px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: middle;
}

/* Brand marks are filled rather than stroked. */
.icon-filled { fill: currentColor; stroke: none; }

.icon-sm { width: 16px; height: 16px; }
.icon-xs { width: 13px; height: 13px; stroke-width: 1.8; }


/* ------------------------------------------------------------
   5. BUTTONS
   ------------------------------------------------------------ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.625rem 1.125rem;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color var(--t-fast) var(--ease),
    border-color var(--t-fast) var(--ease),
    color var(--t-fast) var(--ease),
    box-shadow var(--t-fast) var(--ease),
    transform var(--t-fast) var(--ease);
}

.btn-lg { padding: 0.8125rem 1.5rem; font-size: var(--fs-body); }
.btn-block { width: 100%; }

.btn-primary {
  background-color: var(--navy-900);
  color: var(--text-invert);
  box-shadow: var(--shadow-sm);
}
.btn-primary:hover { background-color: var(--navy-800); transform: translateY(-1px); box-shadow: var(--shadow-md); }
.btn-primary:active { transform: translateY(0); box-shadow: var(--shadow-xs); }

.btn-secondary {
  background-color: var(--surface);
  border-color: var(--border-strong);
  color: var(--text);
  box-shadow: var(--shadow-xs);
}
.btn-secondary:hover { border-color: var(--navy-700); color: var(--text); transform: translateY(-1px); box-shadow: var(--shadow-sm); }
.btn-secondary:active { transform: translateY(0); }

.btn-ghost { color: var(--text-muted); }
.btn-ghost:hover { color: var(--text); background-color: var(--surface-sunk); }

/* Tertiary: reads as a link, sized like a button so it aligns in a CTA row. */
.btn-quiet {
  padding-inline: 0.5rem;
  color: var(--text-muted);
}
.btn-quiet:hover { color: var(--accent); }

.btn-invert {
  background-color: var(--surface);
  color: var(--text);
}
.btn-invert:hover { background-color: #EEF1F5; transform: translateY(-1px); }

.btn-outline {
  border-color: rgba(255, 255, 255, 0.28);
  color: var(--text-invert);
}
.btn-outline:hover { border-color: rgba(255, 255, 255, 0.6); background-color: rgba(255, 255, 255, 0.06); }

.btn .icon { transition: transform var(--t-base) var(--ease); }
.btn:hover .icon-sm { transform: translateX(2px); }


/* ------------------------------------------------------------
   6. LAYOUT PRIMITIVES
   ------------------------------------------------------------ */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container-narrow { max-width: var(--container-narrow); }

.section { padding-block: var(--section-y); }
.section-alt { background-color: var(--bg-alt); }

.section-head {
  max-width: 46rem;
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
/* A section head that centers itself in the container instead of
   sitting flush against its left edge — for a section like pricing,
   where the cards below it are also centered rather than filling
   the full width. */
.section-head-center { margin-inline: auto; text-align: center; }

.grid { display: grid; gap: var(--space-5); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.1875rem 0.5rem;
  border-radius: var(--r-full);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.pill-sm { font-size: 0.6875rem; padding: 0.125rem 0.4375rem; }
.pill-success { background: var(--success-soft); color: var(--success); }
.pill-accent  { background: var(--accent-soft);  color: var(--accent); }
.pill-warning { background: var(--warning-soft); color: var(--warning); }
.pill-neutral { background: var(--surface-sunk); color: var(--text-muted); }


/* ------------------------------------------------------------
   7. HEADER & NAVIGATION
   ------------------------------------------------------------ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background-color: var(--header-bg);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid transparent;
  transition:
    height var(--t-base) var(--ease),
    background-color var(--t-base) var(--ease),
    border-color var(--t-base) var(--ease);
}

.site-header.is-scrolled {
  background-color: var(--header-bg-scrolled);
  border-bottom-color: var(--border);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  height: var(--header-h);
  transition: height var(--t-base) var(--ease);
}
.site-header.is-scrolled .header-inner { height: var(--header-h-compact); }

/* Logo */
/* Matches the auth screens: the 30px mark takes a 10px gap, where the
   28px mark in the portal sidebars takes 8px. */
.logo {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  font-weight: 600;
  font-size: 1.0625rem;
  letter-spacing: -0.015em;
  color: var(--text);
}
.logo-mark {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background-color: var(--navy-900);
  color: var(--text-invert);
  transition: transform var(--t-base) var(--ease);
}
.logo-mark .icon { width: 17px; height: 17px; }
.logo:hover .logo-mark { transform: rotate(-6deg); }

/* Desktop nav */
.nav-desktop { margin-inline: auto; }
.nav-list { display: flex; align-items: center; gap: var(--space-1); }

.nav-link {
  position: relative;
  display: block;
  padding: 0.4375rem 0.75rem;
  border-radius: var(--r-sm);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--text-muted);
}
.nav-link:hover { color: var(--text); background-color: rgba(22, 32, 46, 0.045); }
.nav-link.is-active { color: var(--text); }

/* One underline that wipes in on hover and stays for the active section. */
.nav-link::after {
  content: "";
  position: absolute;
  left: 0.75rem;
  right: 0.75rem;
  bottom: 0.0625rem;
  height: 1.5px;
  border-radius: 2px;
  background-color: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--t-base) var(--ease), background-color var(--t-fast) var(--ease);
}
.nav-link:hover::after,
.nav-link.is-active::after { transform: scaleX(1); }
.nav-link.is-active:hover::after { background-color: var(--accent-hover); }

.header-actions { display: flex; align-items: center; gap: var(--space-2); }

/* Light/dark toggle. Always visible — next to the action buttons on
   desktop, next to the hamburger on mobile — so it never needs a
   second copy inside the mobile menu panel. */
.theme-toggle {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: var(--r-md);
  color: var(--text);
  transition: background-color var(--t-fast) var(--ease);
}
.theme-toggle:hover { background-color: var(--surface-sunk); }
.theme-toggle .icon { width: 20px; height: 20px; }

/* Hamburger */
.nav-toggle {
  display: none;
  place-items: center;
  width: 40px;
  height: 40px;
  margin-left: auto;
  border-radius: var(--r-md);
  color: var(--text);
  transition: background-color var(--t-fast) var(--ease);
}
.nav-toggle:hover { background-color: var(--surface-sunk); }
.nav-toggle .icon { width: 22px; height: 22px; grid-area: 1 / 1; transition: opacity var(--t-base) var(--ease), transform var(--t-base) var(--ease); }
.nav-toggle-close { opacity: 0; transform: rotate(-45deg) scale(0.8); }
.nav-toggle[aria-expanded="true"] .nav-toggle-open { opacity: 0; transform: rotate(45deg) scale(0.8); }
.nav-toggle[aria-expanded="true"] .nav-toggle-close { opacity: 1; transform: none; }

/* Mobile menu */
.mobile-menu {
  display: none;
  overflow: hidden;
  border-top: 1px solid var(--border);
  background-color: var(--surface);
  padding: var(--space-4) var(--gutter) var(--space-6);
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity var(--t-base) var(--ease), transform var(--t-base) var(--ease);
}
.mobile-menu.is-open { opacity: 1; transform: none; }

/* Author rules beat the UA [hidden] rule, so restate it explicitly. */
.mobile-menu[hidden] { display: none; }

.mobile-nav-list { display: grid; gap: 0.125rem; }
.mobile-nav-link {
  display: block;
  padding: 0.75rem 0.5rem;
  border-radius: var(--r-md);
  font-size: 1.0625rem;
  font-weight: 500;
  color: var(--text);
}
.mobile-nav-link:hover { background-color: var(--surface-sunk); }

.mobile-menu-actions {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border);
}

.nav-scrim {
  position: fixed;
  inset: var(--header-h) 0 0;
  z-index: 90;
  background-color: rgba(12, 20, 36, 0.28);
  opacity: 0;
  transition: opacity var(--t-base) var(--ease);
}
.nav-scrim.is-open { opacity: 1; }


/* Reading-progress hairline pinned above the sticky header. */
.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  z-index: 110;
  pointer-events: none;
}
.scroll-progress span {
  display: block;
  height: 100%;
  background-color: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
}


/* ------------------------------------------------------------
   8. HERO
   ------------------------------------------------------------ */
.hero {
  position: relative;
  padding-block: clamp(3rem, 6vw, 5.5rem) clamp(4rem, 8vw, 7rem);
  overflow: hidden;
}
.hero::before {
  content: "";
  position: absolute;
  top: -30%;
  left: 50%;
  width: min(1100px, 130%);
  height: 700px;
  transform: translateX(-50%);
  background: radial-gradient(60% 55% at 50% 50%, rgba(37, 87, 214, 0.06), transparent 70%);
  pointer-events: none;
}

/* --- Entrance choreography ---
   The hero animates on load rather than on scroll, so the first paint is
   already in motion. Everything below the fold uses .reveal instead. */
@keyframes rise {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
@keyframes rise-visual {
  from { opacity: 0; transform: translateY(26px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}

.js .hero-copy > *  { animation: rise 700ms var(--ease) backwards; }
.js .hero-copy > *:nth-child(1) { animation-delay:  80ms; }
.js .hero-copy > *:nth-child(2) { animation-delay: 160ms; }
.js .hero-copy > *:nth-child(3) { animation-delay: 250ms; }
.js .hero-copy > *:nth-child(4) { animation-delay: 340ms; }
.js .hero-copy > *:nth-child(5) { animation-delay: 430ms; }
.js .hero-visual { animation: rise-visual 900ms var(--ease) 300ms backwards; }

.hero-grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  align-items: center;
  gap: clamp(2.5rem, 5vw, 4.5rem);
}

.hero-title {
  font-size: var(--fs-display);
  font-weight: 700;
  line-height: var(--lh-tight);
  letter-spacing: -0.032em;
  color: var(--text);
  text-wrap: balance;
}

.hero-lede {
  margin-top: var(--space-5);
  font-size: var(--fs-lede);
  color: var(--text-muted);
  max-width: 34rem;
  text-wrap: pretty;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-7);
}

.hero-trust {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: var(--space-6);
  font-size: var(--fs-sm);
  color: var(--text-faint);
}


/* --- Hero dashboard mockup --- */
.hero-visual { position: relative; }

.mock {
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}

.mock-bar {
  display: flex;
  gap: 6px;
  align-items: center;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
  background-color: var(--surface-sunk);
}
.mock-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: var(--border-strong);
}

.mock-body { padding: clamp(1.125rem, 2.2vw, 1.5rem); }

/* The floating toast sits over the bottom-left of the hero mock; this
   keeps it clear of the last pickup row. */
.mock-dashboard .mock-body { padding-bottom: 3.5rem; }

.mock-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

.mock-label {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.01em;
}
.mock-date { font-size: var(--fs-xs); color: var(--text-faint); }

.mock-live {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--text-faint);
}
.mock-live-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: var(--success);
  animation: pulse 2.4s var(--ease) infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

.mock-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.mock-stat {
  padding: 0.875rem 1rem;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background-color: var(--surface-sunk);
}
.mock-stat-value {
  font-size: 1.625rem;
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.03em;
  color: var(--text);
}
.mock-stat-label {
  margin-top: 0.125rem;
  font-size: var(--fs-xs);
  color: var(--text-muted);
  line-height: 1.4;
}

.mock-list { display: grid; gap: var(--space-2); }

.mock-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  transition: border-color var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease);
}
.mock-row:hover { border-color: var(--border-strong); box-shadow: var(--shadow-xs); }

/* Rows deal in one after the other, as if the list were filling up. */
.js .mock-dashboard .mock-row { animation: rise 600ms var(--ease) backwards; }
.js .mock-dashboard .mock-row:nth-child(1) { animation-delay: 760ms; }
.js .mock-dashboard .mock-row:nth-child(2) { animation-delay: 900ms; }

.mock-avatar {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  flex: none;
  border-radius: var(--r-full);
  background-color: var(--accent-soft);
  color: var(--accent);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.mock-row-main { min-width: 0; flex: 1; }
.mock-name {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text);
  line-height: 1.35;
  letter-spacing: -0.01em;
}
.mock-name-sm { font-size: var(--fs-sm); font-weight: 600; color: var(--text); line-height: 1.4; }
.mock-sub {
  font-size: var(--fs-xs);
  color: var(--text-muted);
  line-height: 1.45;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.mock-verify {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  margin-top: 0.1875rem;
  font-size: 0.6875rem;
  font-weight: 500;
  color: var(--success);
}

.mock-row-end {
  display: grid;
  justify-items: end;
  gap: 0.25rem;
  flex: none;
}
.mock-time { font-size: 0.6875rem; color: var(--text-faint); font-variant-numeric: tabular-nums; }

/* Floating notification */
.mock-toast {
  position: absolute;
  left: clamp(-1rem, -2vw, 0rem);
  bottom: clamp(-1.25rem, -2vw, -0.5rem);
  display: flex;
  align-items: flex-start;
  gap: 0.625rem;
  max-width: 17rem;
  padding: 0.75rem 0.875rem;
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  animation: float 6s var(--ease) 2.6s infinite;
}
@keyframes float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}
@keyframes toast-in {
  from { opacity: 0; transform: translateY(14px) scale(0.96); }
  to   { opacity: 1; transform: none; }
}
/* Arrives last, once the dashboard behind it has settled. */
.js .mock-toast {
  animation:
    toast-in 500ms var(--ease) 1250ms backwards,
    float 6s var(--ease) 2.6s infinite;
}
.mock-toast-icon {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex: none;
  border-radius: var(--r-full);
  background-color: var(--success-soft);
  color: var(--success);
}
.mock-toast-title { font-size: var(--fs-xs); font-weight: 600; color: var(--text); }
.mock-toast-text { font-size: var(--fs-xs); color: var(--text-muted); line-height: 1.45; }


/* ------------------------------------------------------------
   9. CARDS
   ------------------------------------------------------------ */
.card-grid { align-items: stretch; }

.card {
  display: flex;
  flex-direction: column;
  padding: var(--space-5);
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  transition:
    border-color var(--t-base) var(--ease),
    box-shadow var(--t-base) var(--ease),
    transform var(--t-base) var(--ease);
}
.card:hover {
  border-color: var(--border-strong);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.card-icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin-bottom: var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background-color: var(--surface-sunk);
  color: var(--text);
  transition:
    color var(--t-base) var(--ease),
    border-color var(--t-base) var(--ease),
    background-color var(--t-base) var(--ease),
    transform var(--t-base) var(--ease);
}
.card:hover .card-icon {
  color: var(--accent);
  border-color: var(--accent-border);
  background-color: var(--accent-soft);
  transform: scale(1.08);
}

.card-title {
  font-size: var(--fs-h3);
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.015em;
  color: var(--text);
}
.card-text {
  margin-top: var(--space-2);
  font-size: var(--fs-sm);
  color: var(--text-muted);
  line-height: 1.6;
}
.card-text a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.card-text a:hover { color: var(--accent-hover); }


/* ------------------------------------------------------------
   10. SOLUTION FLOW
   ------------------------------------------------------------ */
.flow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: clamp(1.5rem, 3vw, 2.5rem);
  background-color: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
}

.flow-step {
  display: grid;
  justify-items: center;
  gap: 0.625rem;
  flex: 1 1 0;
  min-width: 0;
}

.flow-icon {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  background-color: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-xs);
  transition: color var(--t-base) var(--ease), border-color var(--t-base) var(--ease), transform var(--t-base) var(--ease);
}
.flow-step:hover .flow-icon {
  color: var(--accent);
  border-color: var(--accent-border);
  transform: translateY(-2px);
}

.flow-label {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
  text-align: center;
}

.flow-arrow {
  display: grid;
  place-items: center;
  flex: none;
  color: var(--border-strong);
  padding-bottom: 1.5rem;
}


/* A signal travelling the workflow once the diagram comes into view:
   each stage lights up in turn, Parent through Record. */
@keyframes flow-ping {
  0%, 100% {
    transform: none;
    border-color: var(--border);
    color: var(--text);
    box-shadow: var(--shadow-xs);
  }
  35% {
    transform: translateY(-5px);
    border-color: var(--accent-border);
    color: var(--accent);
    box-shadow: 0 0 0 5px var(--accent-soft);
  }
}
@keyframes arrow-ping {
  0%, 100% { color: var(--border-strong); }
  40%      { color: var(--accent); }
}

.js .flow.is-visible .flow-icon        { animation: flow-ping 900ms var(--ease) backwards; }
.js .flow.is-visible .flow-arrow .icon { animation: arrow-ping 900ms var(--ease) backwards; }

.js .flow.is-visible > li:nth-child(1)  .flow-icon,
.js .flow.is-visible > li:nth-child(1)  .icon { animation-delay: 320ms; }
.js .flow.is-visible > li:nth-child(2)  .icon { animation-delay: 390ms; }
.js .flow.is-visible > li:nth-child(3)  .flow-icon { animation-delay: 460ms; }
.js .flow.is-visible > li:nth-child(4)  .icon { animation-delay: 530ms; }
.js .flow.is-visible > li:nth-child(5)  .flow-icon { animation-delay: 600ms; }
.js .flow.is-visible > li:nth-child(6)  .icon { animation-delay: 670ms; }
.js .flow.is-visible > li:nth-child(7)  .flow-icon { animation-delay: 740ms; }
.js .flow.is-visible > li:nth-child(8)  .icon { animation-delay: 810ms; }
.js .flow.is-visible > li:nth-child(9)  .flow-icon { animation-delay: 880ms; }
.js .flow.is-visible > li:nth-child(10) .icon { animation-delay: 950ms; }
.js .flow.is-visible > li:nth-child(11) .flow-icon { animation-delay: 1020ms; }


/* ------------------------------------------------------------
   11. HOW IT WORKS
   ------------------------------------------------------------ */
.steps {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-5);
}

.step {
  position: relative;
  padding-top: var(--space-5);
  border-top: 1px solid var(--border);
}
.step::after {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 2.5rem;
  height: 1px;
  background-color: var(--navy-900);
  transition: width var(--t-slow) var(--ease);
}
.step:hover::after { width: 100%; }

/* The marker rule draws in as the step arrives. */
@keyframes draw-rule {
  from { width: 0; }
  to   { width: 2.5rem; }
}
.js .step.is-visible::after { animation: draw-rule 650ms var(--ease) 200ms backwards; }

.step-number {
  display: block;
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.step-icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin: var(--space-4) 0 var(--space-4);
  border-radius: var(--r-md);
  background-color: var(--navy-900);
  color: var(--text-invert);
}

.step-title {
  font-size: var(--fs-h3);
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.015em;
  color: var(--text);
}
.step-text {
  margin-top: var(--space-2);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}


/* ------------------------------------------------------------
   12. SPLIT SECTIONS
   ------------------------------------------------------------ */
.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  align-items: center;
  gap: clamp(2.5rem, 6vw, 5rem);
}
.split-reverse .split-copy  { order: 2; }
.split-reverse .split-visual { order: 1; }

.split-copy .section-lede { margin-bottom: var(--space-6); }

.benefits {
  display: grid;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}
.benefits li {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--text);
}
.benefits .icon { color: var(--success); }


/* ------------------------------------------------------------
   13. SCHOOL MOCKUP
   ------------------------------------------------------------ */
.mock-school { max-width: 30rem; margin-inline: auto; }

.mock-switcher {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.3125rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background-color: var(--surface-sunk);
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--text-muted);
  white-space: nowrap;
}
.mock-switcher .icon:last-child { color: var(--text-faint); }

.mock-search {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.625rem 0.75rem;
  margin-bottom: var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background-color: var(--surface-sunk);
  color: var(--text-faint);
  font-size: var(--fs-sm);
}

.mock-panel {
  padding: var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background-color: var(--surface);
  box-shadow: var(--shadow-xs);
}

.mock-panel-head {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--border);
}

.mock-meta { padding-block: var(--space-4); }
.mock-meta dd > span { display: block; }
.mock-meta dt {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 0.375rem;
}

.mock-panel-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border);
}

.mock-btn {
  padding: 0.5rem 0.875rem;
  border-radius: var(--r-md);
  background-color: var(--navy-900);
  color: var(--text-invert);
  font-size: var(--fs-xs);
  font-weight: 500;
}


/* ------------------------------------------------------------
   14. PHONE MOCKUP
   ------------------------------------------------------------ */
.phone {
  position: relative;
  width: min(300px, 100%);
  margin-inline: auto;
  padding: 10px;
  border-radius: 40px;
  background-color: var(--navy-900);
  box-shadow: var(--shadow-lg);
}
.phone-notch {
  position: absolute;
  top: 17px;
  left: 50%;
  transform: translateX(-50%);
  width: 72px;
  height: 16px;
  border-radius: var(--r-full);
  background-color: var(--navy-900);
  z-index: 2;
}

.phone-screen {
  padding: 2.25rem 1rem 1.25rem;
  border-radius: 31px;
  background-color: var(--bg-alt);
  min-height: 30rem;
}

.phone-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-4);
}
.phone-avatar {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: var(--r-full);
  border: 1px solid var(--border);
  background-color: var(--surface-sunk);
  color: var(--text-muted);
}

.phone-child {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  padding: 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background-color: var(--surface-sunk);
}

.phone-section-label {
  margin: var(--space-5) 0 var(--space-3);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-faint);
}

.phone-list { display: grid; gap: 0.5rem; }
.phone-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.6875rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background-color: var(--surface);
}

/* Pickup people deal in when the phone scrolls into view. */
.js .split-visual.is-visible .phone-item { animation: rise 550ms var(--ease) backwards; }
.js .split-visual.is-visible .phone-item:nth-child(1) { animation-delay: 260ms; }
.js .split-visual.is-visible .phone-item:nth-child(2) { animation-delay: 360ms; }
.js .split-visual.is-visible .phone-item:nth-child(3) { animation-delay: 460ms; }

.phone-add {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4375rem;
  margin-top: var(--space-4);
  padding: 0.6875rem;
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-md);
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-weight: 500;
}


/* ------------------------------------------------------------
   15. SECURITY
   ------------------------------------------------------------ */
.security { background-color: var(--bg); }

.security-grid { gap: 0; }
.security-item {
  padding: var(--space-5);
  border-top: 1px solid var(--border);
  border-left: 1px solid var(--border);
}
.security-grid > .security-item:last-child { border-right: 1px solid var(--border); }
.security-grid { border-bottom: 1px solid var(--border); }

.security-icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin-bottom: var(--space-4);
  color: var(--accent);
}


/* ------------------------------------------------------------
   16. PRICING
   ------------------------------------------------------------ */
.pricing-grid {
  display: grid;
  /* Four plans: Starter, Growth, Enterprise and the quoted Custom. */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-4);
  align-items: stretch;
  max-width: 80rem;
  margin-inline: auto;
}

.plan {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: var(--space-5);
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  transition: border-color var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease), transform var(--t-base) var(--ease);
}
.plan:hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); transform: translateY(-2px); }

.plan-featured {
  border-color: var(--navy-900);
  box-shadow: var(--shadow-md);
}
.plan-featured:hover { border-color: var(--navy-900); box-shadow: var(--shadow-lg); }

.plan-amount { transition: transform var(--t-base) var(--ease); transform-origin: left center; }
.plan:hover .plan-amount { transform: scale(1.03); }

.plan-badge {
  position: absolute;
  top: calc(var(--space-6) + 0.125rem);
  right: var(--space-6);
  padding: 0.1875rem 0.5rem;
  border-radius: var(--r-full);
  background-color: var(--navy-900);
  color: var(--text-invert);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.01em;
}

.plan-name {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-faint);
}

.plan-price {
  display: flex;
  align-items: baseline;
  gap: 0.375rem;
  margin-top: var(--space-4);
}
.plan-amount {
  font-size: 2.25rem;
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.035em;
  color: var(--text);
}
.plan-period { font-size: var(--fs-sm); color: var(--text-faint); }

.plan-for {
  margin-top: var(--space-2);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

/* flex: 1 keeps every card's button on one line across the row;
   align-content: start keeps a shorter list at the same spacing as
   a longer one, instead of stretching its rows to fill the card. */
.plan-features {
  display: grid;
  align-content: start;
  gap: 0.6875rem;
  margin: var(--space-5) 0 var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border);
  flex: 1;
}
.plan-features li {
  display: flex;
  align-items: flex-start;
  gap: 0.5625rem;
  font-size: var(--fs-sm);
  color: var(--text);
}
.plan-features .icon { color: var(--success); margin-top: 0.2rem; }
/* "Everything in Starter, plus:" -- a line ending in ':' in the
   catalog. A small heading between the plan's limits and what it
   adds, not a feature, so no tick. */
.plan-features .plan-features-label {
  margin-top: 0.375rem;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-faint);
}


.pricing-note,
.about-note {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: var(--space-6);
  text-align: center;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.pricing-note .icon,
.about-note .icon { color: var(--text-faint); }
.pricing-note strong,
.about-note strong { color: var(--text); }
.pricing-note a,
.about-note a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.pricing-note a:hover,
.about-note a:hover { color: var(--accent-hover); }

/* Both notes are full sentences -- a flex row would split them into
   gapped runs -- so they flow as ordinary text with the icon sitting
   on the baseline. */
.pricing-note,
.about-note {
  display: block;
  max-width: 46rem;
  margin-inline: auto;
  line-height: 1.6;
}
.pricing-note .icon,
.about-note .icon {
  vertical-align: -0.15em;
  margin-right: 0.375rem;
}

/* The grid is rendered by pricing() in js/script.js from
   GET /api/public/plans. What follows is what shows while that
   is in flight, and what shows if it never resolves. */
.pricing-loading {
  margin-top: var(--space-6);
  text-align: center;
  font-size: var(--fs-sm);
  color: var(--text-faint);
}
#pricingGrid[data-state="ready"] + .pricing-loading,
#pricingGrid[data-state="error"] + .pricing-loading { display: none; }

@keyframes pricing-shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}
.skeleton {
  display: block;
  border-radius: var(--r-md);
  background: linear-gradient(90deg,
    var(--bg-alt) 25%, var(--border) 37%, var(--bg-alt) 63%);
  background-size: 200% 100%;
  animation: pricing-shimmer 1.6s ease-in-out infinite;
}
.plan-skeleton { gap: var(--space-3); }
.skeleton-name  { width: 40%; height: 0.75rem; }
.skeleton-price { width: 65%; height: 2rem; margin-top: var(--space-2); }
.skeleton-line  { width: 100%; height: 0.875rem; }
.skeleton-line + .skeleton-line { width: 80%; }

.pricing-error {
  display: flex;
  gap: var(--space-3);
  max-width: 40rem;
  margin: var(--space-6) auto 0;
  padding: var(--space-5);
  background-color: var(--danger-soft);
  border-radius: var(--r-lg);
  text-align: left;
}
.pricing-error[hidden] { display: none; }
.pricing-error:focus { outline: none; }
.pricing-error .icon { flex: none; color: var(--danger); margin-top: 0.15em; }
.pricing-error-title {
  font-weight: 600;
  color: var(--text);
}
.pricing-error-text {
  margin-top: var(--space-1);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.pricing-error-text a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.pricing-error-text a:hover { color: var(--accent-hover); }

.link-button {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.link-button:hover { color: var(--accent-hover); }

/* Hero trust counters, filled in by trustCounters() from
   GET /api/public/stats. Absent (not empty) until the request
   resolves, and left out entirely on failure — see the JS. */
.hero-counters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5);
  margin-top: var(--space-5);
}
.hero-counters[hidden] { display: none; }
.hero-counter dt {
  font-size: 1.375rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text);
}
.hero-counter dd {
  font-size: var(--fs-xs);
  color: var(--text-faint);
}


/* ------------------------------------------------------------
   17. FAQ
   ------------------------------------------------------------ */
.faq { border-top: 1px solid var(--border); }

.faq-item { border-bottom: 1px solid var(--border); }
.faq-item h3 { margin: 0; font-size: inherit; font-weight: inherit; }

.faq-question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
  padding: var(--space-5) 0;
  text-align: left;
  font-size: var(--fs-h3);
  font-weight: 500;
  line-height: 1.45;
  letter-spacing: -0.012em;
  color: var(--text);
  transition: color var(--t-fast) var(--ease);
}
.faq-question:hover { color: var(--accent); }

.faq-chevron {
  flex: none;
  color: var(--text-faint);
  transition: transform var(--t-slow) var(--ease), color var(--t-fast) var(--ease);
}
.faq-question[aria-expanded="true"] .faq-chevron { transform: rotate(180deg); color: var(--accent); }

/* The paragraph carries the spacing; .faq-answer-inner is the clip box.
   Padding on a grid item floors its track size, so it must live INSIDE the
   element that gets overflow:hidden — otherwise a collapsed answer keeps
   its padding height. */
.faq-answer p {
  padding-bottom: var(--space-5);
  font-size: var(--fs-sm);
  color: var(--text-muted);
  max-width: 62ch;
}

/* Collapsed state is CSS-driven once JS has initialised.
   Without JS the answers simply render open below their question. */
.faq.is-enhanced .faq-answer {
  display: grid;
  grid-template-rows: 0fr;
  visibility: hidden;
  transition: grid-template-rows var(--t-slow) var(--ease), visibility var(--t-slow) var(--ease);
}
.faq.is-enhanced .faq-answer-inner {
  overflow: hidden;
  min-height: 0;
}
.faq.is-enhanced .faq-answer.is-open {
  grid-template-rows: 1fr;
  visibility: visible;
}


/* ------------------------------------------------------------
   18. FINAL CTA
   ------------------------------------------------------------ */
.cta {
  position: relative;
  padding-block: clamp(4rem, 8vw, 7rem);
  background-color: var(--navy-900);
  color: var(--text-invert);
  overflow: hidden;
}

/* Subtle geometric line field */
.cta-lines {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, 0.05) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
  background-size: 72px 72px;
  -webkit-mask-image: radial-gradient(70% 70% at 50% 45%, #000 5%, transparent 78%);
  mask-image: radial-gradient(70% 70% at 50% 45%, #000 5%, transparent 78%);
  pointer-events: none;
}

.cta-inner {
  position: relative;
  display: grid;
  justify-items: center;
  text-align: center;
}

.cta-title {
  font-size: var(--fs-h2);
  font-weight: 600;
  line-height: var(--lh-snug);
  letter-spacing: var(--tracking-tight);
  max-width: 20ch;
  text-wrap: balance;
}
.cta-text {
  margin-top: var(--space-4);
  font-size: var(--fs-lede);
  color: rgba(255, 255, 255, 0.68);
  max-width: 48ch;
}
.cta-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-7);
}



/* ------------------------------------------------------------
   19. FORMS
   Shared by the contact form and the demo modal.
   ------------------------------------------------------------ */
.form { display: grid; gap: var(--space-4); }

.form-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-4);
}

.field { display: grid; gap: 0.375rem; min-width: 0; align-content: start; }

.field label {
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text);
}
.field-optional { font-weight: 400; color: var(--text-faint); }

.control {
  width: 100%;
  padding: 0.625rem 0.75rem;
  font: inherit;
  font-size: var(--fs-sm);
  color: var(--text);
  background-color: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-md);
  transition:
    border-color var(--t-fast) var(--ease),
    box-shadow var(--t-fast) var(--ease),
    background-color var(--t-fast) var(--ease);
}
.control::placeholder { color: var(--text-faint); }

.control:hover { border-color: var(--navy-700); }

.control:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
/* The ring above already marks focus, so skip the global outline. */
.control:focus-visible { outline: none; }

textarea.control { resize: vertical; min-height: 6rem; }
input.control:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
select.control { height: 2.75rem; }

/* Native select arrow is inconsistent across platforms; draw our own. */
select.control {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.25rem;
  background-image:
    url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235C6779' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6.5 9.75 5.5 5.5 5.5-5.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.625rem center;
  background-size: 18px 18px;
  cursor: pointer;
}

.control[aria-invalid="true"] { border-color: var(--danger); }
.control[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px var(--danger-soft); }

.field-error {
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--danger);
}
/* A field with something to fix flashes once when it is brought into view. */
.field-flash { animation: field-flash 1.2s ease 1; border-radius: var(--r-md); }
@keyframes field-flash {
  0%, 100% { box-shadow: 0 0 0 0 transparent; background-color: transparent; }
  20%, 60% { box-shadow: 0 0 0 6px var(--danger-soft); background-color: var(--danger-soft); }
}
@media (prefers-reduced-motion: reduce) { .field-flash { animation: none; } }

.form-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-2);
}
.form-note {
  font-size: var(--fs-xs);
  color: var(--text-faint);
  flex: 1 1 12rem;
}

/* Success panel replaces the form in place. */
.form-success {
  display: grid;
  justify-items: start;
  gap: var(--space-3);
}
.form-success[hidden] { display: none; }
.form-success:focus { outline: none; }

.form-success-icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: var(--r-full);
  background-color: var(--success-soft);
  color: var(--success);
}
.form-success-title {
  font-size: var(--fs-h3);
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--text);
}
.form-success-text {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  max-width: 42ch;
}
.form-success-text a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.form-success-text a:hover { color: var(--accent-hover); }

/* Off-screen rather than display:none — a screen reader still
   skips it because of aria-hidden on the wrapper, but a display
   that stays "visible" to automated form-fillers is exactly the
   point of a honeypot. See the note beside the markup. */
.hp {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Shown above the submit button in place of the success panel
   when the request to the API failed. The form stays visible
   with everything the visitor typed still in it. */
.form-error {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  background-color: var(--danger-soft);
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  color: var(--danger);
}
.form-error[hidden] { display: none; }
.form-error:focus { outline: none; }


/* ------------------------------------------------------------
   20. CONTACT
   ------------------------------------------------------------ */
.contact { background-color: var(--bg-alt); }

.contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: start;
}

.contact-details {
  display: grid;
  gap: var(--space-4);
  margin-top: var(--space-7);
  padding-top: var(--space-6);
  border-top: 1px solid var(--border);
}
.contact-details li {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: 0.75rem;
}
.contact-icon {
  grid-row: span 2;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background-color: var(--surface-sunk);
  color: var(--text);
}
.contact-label {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-faint);
}
.contact-details a,
.contact-details li > span:last-child {
  font-size: var(--fs-sm);
  color: var(--text);
}
.contact-details a:hover { color: var(--accent); }

.contact-nudge {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-6);
  padding-top: var(--space-6);
  border-top: 1px solid var(--border);
}
.contact-nudge-text { font-size: var(--fs-sm); color: var(--text-muted); }

.contact-panel {
  padding: clamp(1.5rem, 3vw, 2rem);
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
}
.contact-panel .control { background-color: var(--surface); }


/* ------------------------------------------------------------
   21. BOOK-A-DEMO MODAL
   Native <dialog> — the platform supplies focus trapping,
   Escape handling and focus restoration.
   ------------------------------------------------------------ */
.modal {
  /* The UA sheet sets dialog { max-width: calc(100% - 38px) }, which would
     otherwise clamp these widths. Override it and size explicitly. */
  width: min(46rem, calc(100% - 2rem));
  max-width: none;
  max-height: calc(100dvh - 2rem);
  padding: 0;
  margin: auto;
  color: var(--text);
  background-color: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-lg);
  overflow: auto;
  overscroll-behavior: contain;
}
.modal::backdrop {
  background-color: rgba(12, 20, 36, 0.45);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

@keyframes modal-in {
  from { opacity: 0; transform: translateY(12px) scale(0.985); }
  to   { opacity: 1; transform: none; }
}
@keyframes backdrop-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.modal[open] { animation: modal-in 260ms var(--ease); }
.modal[open]::backdrop { animation: backdrop-in 260ms var(--ease); }

.modal-card { padding: clamp(1.5rem, 3.5vw, 2.25rem); }

.modal-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}
.modal-eyebrow { margin-bottom: var(--space-2); }
.modal-title {
  font-size: clamp(1.375rem, 1.1rem + 1vw, 1.75rem);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: var(--tracking-tight);
  color: var(--text);
}
.modal-sub {
  margin-top: var(--space-3);
  font-size: var(--fs-sm);
  color: var(--text-muted);
  max-width: 48ch;
}

.modal-close {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  flex: none;
  border-radius: var(--r-md);
  color: var(--text-muted);
  transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.modal-close:hover { background-color: var(--surface-sunk); color: var(--text); }

.modal-actions { margin-top: var(--space-3); }

.modal .form-success { padding-block: var(--space-4) var(--space-2); }


/* ------------------------------------------------------------
   22. FLOATING WHATSAPP BUTTON
   Sits below the nav scrim (z-index 90) so an open mobile menu
   dims it, and hides outright while the body is scroll-locked.
   ------------------------------------------------------------ */
.wa-float {
  position: fixed;
  right: clamp(1rem, 3vw, 1.75rem);
  bottom: clamp(1rem, 3vw, 1.75rem);
  z-index: 85;

  display: inline-flex;
  align-items: center;
  gap: 0;
  height: 54px;
  padding: 0 15px;
  border-radius: var(--r-full);

  background-color: var(--whatsapp);
  color: #FFFFFF;
  box-shadow:
    0 10px 24px -6px rgba(31, 168, 85, 0.45),
    0 4px 10px -4px rgba(12, 20, 36, 0.18);

  /* Revealed on scroll by script.js. */
  opacity: 0;
  transform: translateY(12px) scale(0.9);
  pointer-events: none;

  transition:
    opacity var(--t-slow) var(--ease),
    transform var(--t-slow) var(--ease),
    background-color var(--t-fast) var(--ease),
    box-shadow var(--t-fast) var(--ease),
    gap var(--t-base) var(--ease);
}

.wa-float.is-visible {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

.wa-float:hover,
.wa-float:focus-visible {
  background-color: var(--whatsapp-hover);
  box-shadow:
    0 14px 30px -6px rgba(31, 168, 85, 0.5),
    0 6px 14px -4px rgba(12, 20, 36, 0.2);
}
.wa-float.is-visible:hover { transform: translateY(-2px); }

.wa-glyph {
  display: grid;
  place-items: center;
  flex: none;
}
.wa-glyph .icon { width: 24px; height: 24px; }

/* The label unfurls on hover or keyboard focus, so at rest the
   button is a quiet circle rather than a permanent banner. */
.wa-label {
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  opacity: 0;
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: -0.005em;
  transition:
    max-width var(--t-slow) var(--ease),
    opacity var(--t-base) var(--ease);
}
.wa-float:hover .wa-label,
.wa-float:focus-visible .wa-label {
  max-width: 10rem;
  opacity: 1;
}
.wa-float:hover,
.wa-float:focus-visible { gap: 0.5rem; }

/* An open mobile menu or modal owns the screen. */
body.is-locked .wa-float {
  opacity: 0;
  transform: translateY(12px) scale(0.9);
  pointer-events: none;
}

.contact-icon-wa { color: var(--whatsapp); }

/* ------------------------------------------------------------
   23. FOOTER
   ------------------------------------------------------------ */
.site-footer {
  background-color: var(--bg-alt);
  border-top: 1px solid var(--border);
  padding-top: clamp(3rem, 6vw, 4.5rem);
}

.footer-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  gap: clamp(2.5rem, 5vw, 4rem);
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
}

.footer-tagline {
  margin-top: var(--space-3);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.footer-social {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-5);
}
.footer-social a {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  color: var(--text-muted);
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.footer-social a:hover {
  color: var(--text);
  border-color: var(--border-strong);
  transform: translateY(-2px);
}

.footer-nav {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-5);
}

.footer-heading {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text);
  margin-bottom: var(--space-4);
}
.footer-col ul { display: grid; gap: 0.6875rem; }
.footer-col a { font-size: var(--fs-sm); color: var(--text-muted); }
.footer-col a:hover { color: var(--text); }

.footer-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-5);
  padding-block: var(--space-5);
  border-top: 1px solid var(--border);
  font-size: var(--fs-xs);
  color: var(--text-faint);
}

.footer-credit a {
  color: var(--text-muted);
  font-weight: 500;
  text-decoration: underline;
  text-decoration-color: var(--border-strong);
  text-underline-offset: 3px;
  transition: color var(--t-fast) var(--ease), text-decoration-color var(--t-fast) var(--ease);
}
.footer-credit a:hover {
  color: var(--accent);
  text-decoration-color: var(--accent);
}


/* ------------------------------------------------------------
   24. SCROLL REVEAL
   ------------------------------------------------------------ */
.js .reveal {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 500ms var(--ease), transform 500ms var(--ease);
}
.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* Gentle stagger inside grids */
.js .card-grid > .reveal:nth-child(2),
.js .steps > .reveal:nth-child(2),
.js .security-grid > .reveal:nth-child(2),
.js .pricing-grid > .reveal:nth-child(2) { transition-delay: 60ms; }

.js .card-grid > .reveal:nth-child(3),
.js .steps > .reveal:nth-child(3),
.js .security-grid > .reveal:nth-child(3),
.js .pricing-grid > .reveal:nth-child(3) { transition-delay: 120ms; }

.js .card-grid > .reveal:nth-child(4),
.js .steps > .reveal:nth-child(4),
.js .security-grid > .reveal:nth-child(4),
.js .pricing-grid > .reveal:nth-child(4) { transition-delay: 180ms; }

.js .card-grid > .reveal:nth-child(n + 5) { transition-delay: 60ms; }


/* ------------------------------------------------------------
   25. RESPONSIVE
   ------------------------------------------------------------ */

/* --- Laptop / small desktop --- */
@media (max-width: 1080px) {
  .grid-3,
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .steps  { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .security-grid > .security-item:nth-child(2n) { border-right: 1px solid var(--border); }

  /* Four cards are too narrow side by side here; two by two keeps
     every card readable until the 900px breakpoint stacks them. */
  .pricing-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 54rem; gap: var(--space-4); }
}

/* --- The header runs out of room before the layout does ---
   Six nav items plus three actions plus the theme toggle stop
   fitting beside the logo at about 1110px, so the header folds into
   the menu at the 1150px breakpoint. Nothing is lost: the mobile
   menu carries every link and all three actions, and the toggle
   stays put next to the hamburger. --- */
@media (max-width: 1150px) {
  .nav-desktop,
  .header-actions { display: none; }

  .nav-toggle { display: grid; }
  .mobile-menu { display: block; }
}

/* --- Tablet --- */
@media (max-width: 900px) {
  :root { --header-h: 62px; --header-h-compact: 56px; }

  /* No hover on touch, so the button stays a plain circle. */
  .wa-float { height: 52px; padding: 0 14px; }
  .wa-label { display: none; }

  .hero-grid { grid-template-columns: minmax(0, 1fr); gap: clamp(3rem, 8vw, 4rem); }
  .hero-copy { max-width: 40rem; }
  .hero-visual { max-width: 34rem; margin-inline: auto; width: 100%; }
  .mock-toast { left: 0; }

  .split { grid-template-columns: minmax(0, 1fr); gap: clamp(2.5rem, 7vw, 3.5rem); }
  .split-reverse .split-copy,
  .split-reverse .split-visual { order: initial; }

  .pricing-grid { grid-template-columns: minmax(0, 1fr); max-width: 32rem; margin-inline: auto; }

  .footer-grid { grid-template-columns: minmax(0, 1fr); }

  .contact-grid { grid-template-columns: minmax(0, 1fr); }
}

/* --- Flow stacks --- */
@media (max-width: 860px) {
  .flow {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }
  .flow-step {
    flex: none;
    grid-template-columns: 52px minmax(0, 1fr);
    justify-items: start;
    align-items: center;
    gap: var(--space-4);
  }
  .flow-label { text-align: left; }
  .flow-arrow {
    /* Fixed width so it does not stretch, and stays centred under the
       52px step circle. Rotate the glyph, not the box. */
    width: 52px;
    height: 1.75rem;
    padding: 0;
  }
  .flow-arrow .icon { transform: rotate(90deg); }
}

/* --- Mobile --- */
@media (max-width: 620px) {
  :root { --header-h: 58px; --header-h-compact: 54px; }

  .grid-3,
  .grid-4 { grid-template-columns: minmax(0, 1fr); }
  .steps  { grid-template-columns: minmax(0, 1fr); }

  .security-item { border-right: 1px solid var(--border); }

  .hero-actions .btn,
  .cta-actions .btn { flex: 1 1 auto; min-width: 12rem; }

  .mock-stats { grid-template-columns: 1fr; }

  .mock-row { flex-wrap: wrap; }
  .mock-row-end { flex: 1 1 100%; justify-items: start; grid-auto-flow: column; justify-content: start; gap: 0.5rem; align-items: center; }

  .mock-toast { position: static; margin-top: var(--space-4); max-width: none; animation: none; }
  .mock-dashboard .mock-body { padding-bottom: 1rem; }

  .footer-nav { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6) var(--space-5); }
  .footer-bottom { justify-content: flex-start; }

  .plan-badge { position: static; align-self: flex-start; margin-bottom: var(--space-3); }

  .form-row { grid-template-columns: minmax(0, 1fr); }
  .form-actions .btn { width: 100%; }
  .form-note { flex: 1 1 100%; }

  /* Full-bleed sheet on phones: override the UA max-width and margin too. */
  .modal {
    width: 100%;
    max-width: none;
    max-height: 100dvh;
    margin: 0;
    border-radius: 0;
    border: 0;
  }
  .modal-head { margin-bottom: var(--space-5); }
}

@media (max-width: 400px) {
  .mock-body { padding: 1rem; }
  .plan { padding: var(--space-5); }
}


/* ------------------------------------------------------------
   26. REDUCED MOTION
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

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

  .js .reveal { opacity: 1; transform: none; }
}


/* ------------------------------------------------------------
   27. SPARING THE CPU
   ------------------------------------------------------------
   Looping decoration costs a frame every frame. script.js marks
   sections scrolled out of view .is-offscreen, which pauses what
   loops inside them, and marks the page .calm on low-end devices
   (2 cores or fewer, or data saver on), where every loop plays
   once and settles and the header drops its live blur. */
.is-offscreen, .is-offscreen *, .is-offscreen *::before, .is-offscreen *::after {
  animation-play-state: paused !important;
}

.calm *, .calm *::before, .calm *::after {
  animation-iteration-count: 1 !important;
}
.calm .site-header {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  background-color: var(--surface);
}

/* ------------------------------------------------------------
   28. LANGUAGE PICKER (packages/design-system/i18n.js)
   ------------------------------------------------------------ */
.footer-language { margin-top: var(--space-4, 1rem); }
.language-picker { display: inline-flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; }
.language-picker-select {
  font: inherit; padding: 0.375rem 0.625rem; border-radius: 8px;
  border: 1px solid var(--border); background-color: var(--surface); color: var(--text);
}

/* ------------------------------------------------------------
   PHOTOS (Unsplash) — an addition, not a replacement.
   Everything below is inert unless <html data-photos="on">. Take that
   attribute away and the site is exactly as it was: the hero
   illustration returns and every photo block disappears.
   ------------------------------------------------------------ */
.photo-hero, .photo-band, .photo-inline, .photo-credits { display: none; }

[data-photos="on"] .hero-visual .hero-illus { display: none; }
[data-photos="on"] .photo-hero {
  display: block; position: relative; width: 100%; aspect-ratio: 4 / 3;
  /* Painted at once, before the photo arrives: a ~200-byte blurred
     copy of it over its own darkest tone, so the white headline reads
     from the first frame and nothing pops. */
  background: var(--hero-lqip) var(--hero-focus) / cover no-repeat, var(--hero-tone);
  border-radius: var(--r-xl); box-shadow: var(--shadow-lg);
}
/* The real photo, on a layer of its own so it can fade in over the
   preview once js/hero-photo.js has it (html.hero-photo-ready).
   Without the script it is simply there. */
[data-photos="on"] .photo-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--hero-photo) var(--hero-focus) / cover no-repeat;
  transition: opacity 600ms var(--ease);
}
.js[data-photos="on"]:not(.hero-photo-ready) .photo-hero::after { opacity: 0; }
/* Phones get a copy 1000px wide, under half the bytes. The script
   asks for the same file at the same breakpoint. */
@media (max-width: 900px) {
  [data-photos="on"] .photo-hero::after { background-image: var(--hero-photo-m); }
}
/* The photo no longer rises with the hero: mid-animation its transform
   made the right column the photo's frame, so it drew in that column
   and then snapped to full width. It fades instead (above); the
   "Amara's day" card keeps its own entrance. */
.js[data-photos="on"] .hero-visual { animation: none; }
/* The hero photos, one per visit (js/hero-photo.js sets data-hero),
   each with where its people are, kept clear of the headline. Only
   the one in use is downloaded. Photo 1 without the script.
   The headline sits straight on the photo, so only photos whose left
   side is plain (no faces, no bright sky) belong here. */
   Each photo also has a phone-sized copy (-m), the average tone of its
   left half and a 32px blurred preview (both for the moment before it
   loads). File names are repeated in js/hero-photo.js. */
:root {
  --hero-photo: url(/assets/site/photos/hero-walking-home.webp);
  --hero-photo-m: url(/assets/site/photos/hero-walking-home-m.webp);
  --hero-focus: 70% 55%;
  --hero-tone: #3A2D0F;
  --hero-lqip: url("data:image/webp;base64,UklGRrYAAABXRUJQVlA4IKoAAACQBQCdASogABUAPtFcpE0oJSOiMBgIAQAaCUAWHYYqNwYPYYLidJ+FYTvsCUXjC97Bp7D1AAD+9pPZBqURL7UQvB9ZjP//dxUF+IHYAFAcnXbJrN2GzAc/4QPAOYA48OTuszhQVggOdVzJ1RzGwwKO7xjJ0A26Ae1r2AKW+uuYy2zPRcNXMzB2UBvYBHCtp1bvXMSxL1j13atyUZEyRRBpZBDA06VvqqwAAA==");
}
html[data-hero="2"] {
  --hero-photo: url(/assets/site/photos/hero-field.webp);
  --hero-photo-m: url(/assets/site/photos/hero-field-m.webp);
  --hero-focus: 72% 40%;
  --hero-tone: #6E4626;
  --hero-lqip: url("data:image/webp;base64,UklGRpgAAABXRUJQVlA4IIwAAADwBACdASogABUAPtFYo0uoJSMhsAgBABoJQBOmW0hqWyQ2GU6DKX5NpV9QOb6BxQAA/uyrFNjFWLFtJfzCjc8Ocypg6af6V4TxwFPndKmotQARayRQ8hkanVsTNIEc7LsVuicH7oZFRqKN9gEQIiBZfxtIdCoLBaSLLXZYYnhdFH547Ayj36jq5p+AAA==");
}
[data-photos="on"] .photo-band {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4);
  margin: 0 0 var(--space-6);
}
[data-photos="on"] .photo-band-one { grid-template-columns: minmax(0, 1fr); }
[data-photos="on"] .photo-band .photo {
  width: 100%; height: clamp(12rem, 28vw, 20rem); object-fit: cover; border-radius: var(--r-lg);
}
[data-photos="on"] .photo-inline { display: block; margin: var(--space-5) 0; }
[data-photos="on"] .photo-inline .photo {
  width: 100%; max-height: 16rem; object-fit: cover; border-radius: var(--r-lg);
}
[data-photos="on"] .photo-credits { display: block; font-size: var(--fs-xs, 0.75rem); opacity: 0.75; }
[data-photos="on"] .photo-credits a { color: inherit; text-decoration: underline; }
.photo-band figure, figure.photo-band, figure.photo-inline { margin-left: 0; margin-right: 0; }

@media (max-width: 620px) {
  [data-photos="on"] .photo-band { grid-template-columns: minmax(0, 1fr); }
  [data-photos="on"] .photo-band .photo { height: 13rem; }
}
/* Portrait photos keep the faces in frame when cropped to a band. */
[data-photos="on"] .photo[src*="parent-and-child"] { object-position: center 22%; }
[data-photos="on"] .photo[src*="school-walk"] { object-position: center 60%; }

/* Photos only: the drawn illustrations (and the hero's abstract shapes)
   step aside. Still just this attribute: remove it and they return. */
[data-photos="on"] .hero-backdrop,
[data-photos="on"] .section-illus,
[data-photos="on"] .cta-illus { display: none; }

/* The hero photo blends in rather than sitting on the page as a card:
   on a wide screen it fills the hero's right side, edge to edge, and
   fades into the hero's own background towards the headline and at the
   foot, with the "Pickup completed" card resting on it. */
@media (min-width: 901px) {
  [data-photos="on"] .hero-grid { position: static; }
  [data-photos="on"] .hero-copy { position: relative; z-index: 1; }
  [data-photos="on"] .hero-visual { position: static; min-height: clamp(26rem, 38vw, 34rem); }
  [data-photos="on"] .photo-hero {
    position: absolute;
    inset: 0 0 0 auto;
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
    border-radius: 0;
    box-shadow: none;
    /* Only the foot fades, into the section below. */
    -webkit-mask-image: linear-gradient(to top, transparent 0%, #000 14%);
    mask-image: linear-gradient(to top, transparent 0%, #000 14%);
  }
  /* The photo covers the whole hero and the headline sits on it. This
     light shade, neutral so the photo keeps its own colours, is just
     enough for white type and clears by the middle so the people stay
     untouched. */
  [data-photos="on"] .hero::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    /* Measured from the centre, like the content column the headline
       sits in (it ends about 60px left of centre at every width). */
    background: linear-gradient(to right,
      rgba(10, 8, 20, 0.55) 0%,
      rgba(10, 8, 20, 0.42) calc(50% - 60px),
      rgba(10, 8, 20, 0.12) calc(50% + 80px),
      transparent calc(50% + 240px));
    /* The same soft foot as the photo, into the section below. */
    -webkit-mask-image: linear-gradient(to top, transparent 0%, #000 14%);
    mask-image: linear-gradient(to top, transparent 0%, #000 14%);
  }
  /* A soft shadow under the type, for the brighter patches of a photo. */
  [data-photos="on"] .hero-copy { text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 2px 18px rgba(0, 0, 0, 0.35); }
  [data-photos="on"] .hero-actions .btn { text-shadow: none; }
  /* On the photo: white type, lavender accent, inverted buttons. */
  [data-photos="on"] .hero-copy .eyebrow { color: #D9C8FF; }
  [data-photos="on"] .hero-title { color: #fff; }
  [data-photos="on"] .hero-title .text-accent { color: #C9A8FF; }
  [data-photos="on"] .hero-lede { color: rgba(255, 255, 255, 0.85); }
  [data-photos="on"] .hero-trust { color: rgba(255, 255, 255, 0.72); }
  [data-photos="on"] .hero-counter dt { color: #fff; }
  [data-photos="on"] .hero-counter dd { color: rgba(255, 255, 255, 0.7); }
  [data-photos="on"] .hero-actions .btn-primary { background-color: #fff; color: #4A2296; border-color: #fff; }
  [data-photos="on"] .hero-actions .btn-primary:hover { background-color: #F3ECFD; }
  [data-photos="on"] .hero-actions .btn-secondary {
    background-color: transparent; color: #fff; border-color: rgba(255, 255, 255, 0.5);
  }
  [data-photos="on"] .hero-actions .btn-secondary:hover { color: #fff; border-color: #fff; background-color: rgba(255, 255, 255, 0.08); }
  [data-photos="on"] .hero-actions .btn-quiet { color: rgba(255, 255, 255, 0.85); }
  [data-photos="on"] .hero-actions .btn-quiet:hover { color: #fff; }
  [data-photos="on"] .hero-visual .mock-toast {
    z-index: 2;
    /* Top right, over the trees, never over the mother and child. */
    top: clamp(2rem, 6vw, 4rem);
    left: auto;
    right: max(1.5rem, calc(50% - 590px));
    bottom: auto;
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    background-color: color-mix(in srgb, var(--surface) 88%, transparent);
  }
}
/* Narrower: the photo sits under the headline, softened at its foot so
   it eases into the page instead of ending on a hard edge. */
@media (max-width: 900px) {
  [data-photos="on"] .photo-hero {
    box-shadow: none;
    -webkit-mask-image: linear-gradient(to bottom, #000 72%, transparent 100%);
    mask-image: linear-gradient(to bottom, #000 72%, transparent 100%);
  }
}

/* Handova: a two-word name and menu labels stay on one line. */
.logo-text, .nav-link { white-space: nowrap; }
