/* =========================================================
   AYVA — Design System
   Editorial / Boutique-Advisory aesthetic
   ========================================================= */

@font-face {
  font-family: "Recline";
  src: url("../fonts/Recline1.woff2") format("woff2"),
       url("../fonts/Recline1.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Figtree";
  src: url("../fonts/Figtree-VariableFont_wght.woff2") format("woff2-variations"),
       url("../fonts/Figtree-VariableFont_wght.woff2") format("woff2"),
       url("../fonts/Figtree-VariableFont_wght.ttf") format("truetype-variations");
  font-weight: 300 800;
  font-display: swap;
}

:root{
  /* Brand palette — AYVA Website 2.0 (Off White, Stone, Sage, Aubergine, Black) */
  --cream: #E8E3D7;      /* Stone */
  --off-white: #F7F6F2;  /* Off White */
  --sage: #A8B69A;       /* Sage */
  --ink: #0D0D0D;        /* Black */
  --sky: #E4D5E0;        /* soft Aubergine tint (badges/tags) */
  --aubergine: #4B2046;  /* Aubergine — primary accent */

  --sage-deep: #4B2046;  /* = Aubergine, kept for backward-compat with existing usages */
  --ink-70: rgba(13,13,13,.7);
  --ink-50: rgba(13,13,13,.64);
  --ink-30: rgba(13,13,13,.3);
  --ink-12: rgba(13,13,13,.12);
  --ink-08: rgba(13,13,13,.08);
  --cream-line: rgba(13,13,13,.14);

  --display: "Recline", "Times New Roman", serif;
  --body: "Figtree", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --container: 1240px;
  --gutter: clamp(24px, 5vw, 72px);

  --ease: cubic-bezier(.16,.8,.24,1);
  --dur: .9s;

  /* =========================================================
     SPRINT 1 — Semantic Design Tokens
     Additive layer on top of the palette above. Existing
     variables (--ink, --cream, --sage-deep, …) are kept
     untouched for backward-compatibility with all existing
     rules/inline styles; these semantic tokens are the
     documented, forward-looking names used from here on.
     ========================================================= */

  /* Color — semantic */
  --color-off-white: #F7F6F2;
  --color-stone: #E8E3D7;
  --color-sage: #A8B69A;
  --color-aubergine: #4B2046;
  --color-black: #0D0D0D;

  --background-primary: var(--color-off-white);
  --background-secondary: var(--color-stone);
  --background-dark: var(--color-black);
  --surface-elevated: #FFFFFF;

  --text-primary: var(--color-black);
  --text-secondary: var(--ink-70);
  --text-muted: var(--ink-50);
  --text-inverse: var(--color-off-white);

  --accent-primary: var(--color-aubergine);
  --accent-secondary: var(--color-sage);

  --border-subtle: var(--cream-line);
  --border-strong: var(--ink-30);
  --focus-ring: var(--color-aubergine);

  /* Sprint 12 — readable "sage" for text/icons/small UI (raw --sage, #A8B69A,
     fails WCAG AA as text on our light backgrounds — ~2:1). Reuses the same
     dark-green value as --success (already proven at 5.6:1 on off-white)
     under its own accent-facing name, so brand-accent usage reads as
     intentional design rather than borrowing a form-validation token. */
  --sage-ink: #4B6B3F;

  /* functional colors — form validation only, never brand-decorative */
  --success: #4B6B3F;
  --success-bg: rgba(75,107,63,.1);
  --error: #8A2E2E;
  --error-bg: rgba(138,46,46,.08);

  /* Spacing — modular scale (4px base) */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;
  --space-10: 128px;

  /* Containers */
  --container-narrow: 680px;   /* text-heavy blocks */
  --container-regular: 1240px; /* = --container, standard page content */
  --container-wide: 1440px;    /* visual / image-forward sections */

  /* Radii */
  --radius-sm: 4px;
  --radius-md: 12px;
  --radius-lg: 20px;
  --radius-xl: 26px; /* Sprint 18: formalized from the Expert Card's existing
    26px one-off (Sprint 15 finding #27) — same value, now a named token
    instead of a hardcoded number, zero visual change. */
  --radius-pill: 999px;

  /* Shadows — soft, low-contrast, never pure black */
  --shadow-sm: 0 2px 10px rgba(13,13,13,.06);
  --shadow-md: 0 16px 40px rgba(13,13,13,.10);
  --shadow-lg: 0 30px 60px rgba(13,13,13,.12);
  --shadow-xl: 0 40px 90px rgba(13,13,13,.16);

  /* Motion */
  --duration-fast: .2s;
  --duration-standard: .4s;
  --duration-slow: .9s;
  --ease-standard: cubic-bezier(.16,.8,.24,1);
  --ease-enter: cubic-bezier(.16,.8,.24,1);
  --ease-exit: cubic-bezier(.4,0,.2,1);

  /* Header */
  --header-height: 94px;
  --header-height-scrolled: 78px;
}

*,*::before,*::after{ box-sizing:border-box; }
html{ scroll-behavior:smooth; }
html,body{ margin:0; padding:0; }
body{
  background: var(--off-white);
  color: var(--ink);
  font-family: var(--body);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}
body.no-scroll{ overflow:hidden; }

img{ max-width:100%; display:block; }
a{ color:inherit; text-decoration:none; }
button{ font-family:inherit; cursor:pointer; background:none; border:none; color:inherit; }
ul{ list-style:none; margin:0; padding:0; }
h1,h2,h3,h4,p,figure{ margin:0; }

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

/* ---------- Typography ---------- */
h1,h2,h3,h4,
.font-display{
  font-family: var(--display);
  font-weight: 400;
  letter-spacing: -0.01em;
  line-height: 1.05;
}
.eyebrow{
  font-family: var(--body);
  font-size: 12.5px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--sage-ink);
  font-weight: 700;
  display:flex;
  align-items:center;
  gap:10px;
}
.eyebrow::before{
  content:"";
  width:22px; height:2px;
  background: var(--sage);
  opacity:1;
}
.eyebrow.on-dark, .bleed-dark .eyebrow{ color: var(--sage); }
.eyebrow.on-dark::before, .bleed-dark .eyebrow::before{ background: var(--sage); }
/* Sprint 18: text-wrap:balance on every headline size — the browser
   distributes words evenly across lines instead of the default
   greedy-fill algorithm, so a headline never leaves a single orphaned
   word (or a much-shorter last line) when the full phrase would sit
   more calmly across two balanced lines. Unsupported browsers (older
   Safari/Firefox) simply fall back to normal wrapping — no risk, pure
   enhancement. */
.h-xl{ font-size: clamp(32px, 4.4vw, 62px); line-height:1.12; text-wrap: balance; }
.h-l{ font-size: clamp(25px, 3vw, 42px); text-wrap: balance; }
.h-m{ font-size: clamp(21px, 2.3vw, 32px); text-wrap: balance; }
.h-s{ font-size: clamp(19px, 1.9vw, 24px); text-wrap: balance; }

.lede{
  font-size: clamp(17px, 1.6vw, 21px);
  line-height: 1.6;
  color: var(--ink-70);
  font-weight: 350;
  text-wrap: pretty;
}
.tiny{ font-size:12.5px; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-50); }
.serif-num{ font-family: var(--display); font-size: 15px; color: var(--ink-50); }

/* ---------- Buttons / Links ---------- */
.btn{
  display:inline-flex;
  align-items:center;
  gap:10px;
  padding: 15px 30px;
  border-radius: var(--radius-pill);
  font-size: 14px;
  letter-spacing:.02em;
  font-weight:600;
  transition: transform var(--duration-standard) var(--ease), background var(--duration-standard) ease, color var(--duration-standard) ease, border-color var(--duration-standard) ease;
  white-space:nowrap;
}
.btn-primary{
  background: var(--ink);
  color: var(--off-white);
}
.btn-primary:hover{ background: var(--sage); color:var(--ink); transform: translateY(-2px); }
/* Ghost = secondary: quieter at rest (thin, low-opacity border, no fill)
   than primary's solid fill, so the two read as genuinely different
   weights side by side rather than "two buttons, one outlined." */
.btn-ghost{
  border:1px solid var(--ink-12);
  color: var(--ink);
}
.btn-ghost:hover{ border-color: var(--ink); background: var(--ink); color: var(--off-white); transform: translateY(-2px); }
.btn-light{
  background: var(--off-white);
  color: var(--ink);
}
.btn-light:hover{ background: var(--sage); transform: translateY(-2px); }
.btn svg{ width:14px; height:14px; transition: transform var(--duration-standard) var(--ease); }
.btn:hover svg{ transform: translateX(4px); }

/* Text link = tertiary: a full step down from either button in visual
   weight, so it never competes with a primary/ghost CTA on the same
   screen. Was the same 600 weight as .btn — indistinguishable in
   emphasis from a real button at a glance. */
.text-link{
  position:relative;
  display:inline-flex;
  align-items:center;
  gap:8px;
  font-weight:500;
  font-size:14.5px;
  padding-bottom:3px;
  border-bottom:1px solid var(--ink-30);
  transition: border-color var(--duration-standard) ease, gap var(--duration-standard) ease;
}
.text-link:hover{ border-color: var(--ink); gap:12px; }
.text-link svg{ width:12px; height:12px; }

/* ---------- Nav ---------- */
body{ padding-top:3px; }
.accent-bar{
  position: fixed; top:0; left:0; right:0; height:3px;
  background: linear-gradient(90deg, var(--sage) 0%, var(--sky) 100%);
  z-index: 501;
}
.site-header{
  position: fixed;
  top:3px; left:0; right:0;
  z-index: 500;
  padding: 24px 0;
  transition: padding .4s var(--ease), background .4s var(--ease), border-color .4s ease;
  border-bottom: 1px solid transparent;
}
.site-header.is-scrolled{
  padding: 16px 0;
  background: rgba(247,246,242,.86);
  backdrop-filter: blur(14px);
  border-color: var(--cream-line);
}
.site-header .container{
  display:flex;
  align-items:center;
  justify-content:space-between;
}
/* flex-shrink:0 — verified live (Sprint 17) that without it, the header's
   flex row shrinks the logo below its true aspect ratio on narrower
   desktop windows (measured 160px instead of the correct ~178px at a
   904px window) once every nav item + the CTA button stops fitting at
   full width. The logo should never be the item that gives up space. */
.nav-logo{ flex-shrink:0; }
.nav-logo img{ height: 46px; width:auto; transition: height .4s var(--ease); display:block; }
.site-header.is-scrolled .nav-logo img{ height:38px; }

.nav-desktop{ display:flex; align-items:center; gap: 48px; }
.nav-links{ display:flex; gap:34px; }
.nav-links a{
  font-size:13.5px;
  font-weight:600;
  letter-spacing:.03em;
  position:relative;
  padding: 4px 0;
}
.nav-links a::after{
  content:"";
  position:absolute; left:0; right:100%; bottom:0;
  height:1px; background: var(--ink);
  transition: right .35s var(--ease);
}
.nav-links a:hover::after, .nav-links a.active::after{ right:0; }
.nav-links a.active{ color: var(--ink); }

.nav-links li{ position:relative; }
.nav-links li.has-dropdown > a{ display:inline-flex; align-items:center; gap:6px; }
.nav-links li.has-dropdown > a::before{
  content:""; width:5px; height:5px; border-right:1px solid currentColor; border-bottom:1px solid currentColor;
  transform: rotate(45deg); margin-top:-3px; opacity:.6; transition: transform .3s ease;
}
.nav-links li.has-dropdown:hover > a::before{ transform: rotate(225deg); margin-top:3px; }
.dropdown{
  position:absolute; top: calc(100% + 22px); left:50%; transform: translateX(-50%) translateY(6px);
  width: 320px;
  background: rgba(247,246,242,.92);
  backdrop-filter: blur(16px) saturate(1.1);
  -webkit-backdrop-filter: blur(16px) saturate(1.1);
  border:1px solid var(--cream-line);
  border-radius: 16px;
  padding: 10px;
  box-shadow: 0 30px 60px rgba(13,13,13,.12);
  opacity:0; visibility:hidden;
  transition: opacity .35s var(--ease), transform .35s var(--ease), visibility .35s;
}
.nav-links li.has-dropdown:hover .dropdown{ opacity:1; visibility:visible; transform: translateX(-50%) translateY(0); }
.nav-links li.has-dropdown.dropdown-open .dropdown{ opacity:1; visibility:visible; transform: translateX(-50%) translateY(0); }
.dropdown a{
  display:flex; align-items:flex-start; gap:14px;
  padding: 14px 12px;
  border-radius: 10px;
  transition: background .25s ease;
}
.dropdown a:hover{ background: var(--cream); }
.dropdown a .d-num{ font-family:var(--display); font-size:14px; color:var(--sage-ink); padding-top:2px; }
.dropdown a b{ display:block; font-weight:600; font-size:14px; line-height:1.35; }
.dropdown a small{ display:block; font-size:11.5px; color:var(--ink-50); margin-top:3px; letter-spacing:.03em; text-transform:uppercase; }

.nav-right{ display:flex; align-items:center; gap: 22px; }
.lang-toggle{
  display:flex; align-items:center; gap:6px;
  font-size:12.5px; font-weight:700; letter-spacing:.04em;
}
.lang-toggle button{
  padding:9px 11px;
  min-width:38px;
  border-radius: var(--radius-pill);
  color: var(--ink-50);
  transition: color .3s ease, background .3s ease;
}
.lang-toggle button.active{ color: var(--sage-ink); background: rgba(168,182,154,.22); }

.nav-burger{ display:none; }

/* Mobile nav */
@media (max-width: 860px){
  /* Sprint 13 fix: only .nav-links and .btn were hidden here — .nav-right
     itself (which wraps the lang-toggle AND the button) was never targeted,
     so the desktop language-toggle pill was left floating next to the
     burger on every phone, duplicating the one already inside the mobile
     panel's .mobile-foot. Hiding the whole wrapper removes the duplicate
     and the stray leftover empty gap it left in the header. */
  .nav-desktop .nav-links, .nav-desktop .nav-right{ display:none; }
  /* Sprint 13: hit area raised to a full 44×44 touch target (was ~26×24)
     without changing the visible glyph — padding carries the extra area,
     the icon itself keeps its original size and position. */
  .nav-burger{
    display:flex; flex-direction:column; align-items:center; justify-content:center; gap:5px;
    width:44px; height:44px; margin-right:-9px;
    -webkit-tap-highlight-color: transparent;
  }
  .nav-burger span{ height:1px; background:var(--ink); width:22px; transition: transform .35s var(--ease), opacity .3s ease; }
  .nav-burger:active{ opacity:.6; }
  body.menu-open .nav-burger span:nth-child(1){ transform: translateY(6px) rotate(45deg); }
  body.menu-open .nav-burger span:nth-child(2){ opacity:0; }
  body.menu-open .nav-burger span:nth-child(3){ transform: translateY(-6px) rotate(-45deg); }

  /* Sprint 13: safe-area padding (notch/home-indicator devices) on every
     edge — this is a fixed, inset:0 full-screen panel, so it needs its
     own insets rather than relying on the document flow. */
  .mobile-menu{
    position:fixed; inset:0;
    background: var(--cream);
    z-index:400;
    display:flex; flex-direction:column;
    justify-content:center;
    padding: calc(32px + env(safe-area-inset-top)) calc(var(--gutter) + env(safe-area-inset-right)) calc(32px + env(safe-area-inset-bottom)) calc(var(--gutter) + env(safe-area-inset-left));
    overflow-y:auto;
    -webkit-overflow-scrolling: touch;
    opacity:0; visibility:hidden; transform: translateY(-14px);
    transition: opacity .5s var(--ease), transform .5s var(--ease), visibility .5s;
  }
  body.menu-open .mobile-menu{ opacity:1; visibility:visible; transform:none; }
  .mobile-menu a{
    font-family: var(--display);
    font-size: 40px;
    padding: 15px 0;
    border-bottom: 1px solid var(--cream-line);
    min-height:44px;
    display:flex; align-items:center;
    -webkit-tap-highlight-color: transparent;
  }
  .mobile-menu a:active{ color: var(--sage-ink); }
  /* Sprint 13: each top-level item/group fades and lifts in with a short
     stagger while the panel is open — reads as one deliberate sequence
     rather than the whole list appearing at once. Panel itself still
     opens instantly if reduced-motion is on (see override below). */
  .mobile-menu > a, .mobile-menu > .mobile-menu-label, .mobile-menu .mobile-foot{
    opacity:0; transform: translateY(10px);
    transition: opacity .45s var(--ease), transform .45s var(--ease);
  }
  body.menu-open .mobile-menu > a, body.menu-open .mobile-menu > .mobile-menu-label, body.menu-open .mobile-menu .mobile-foot{
    opacity:1; transform:none;
  }
  .mobile-menu > a:nth-of-type(1){ transition-delay:.08s; }
  .mobile-menu > .mobile-menu-label{ transition-delay:.14s; }
  .mobile-menu > a:nth-of-type(2){ transition-delay:.2s; }
  .mobile-menu > a:nth-of-type(3){ transition-delay:.26s; }
  .mobile-menu .mobile-foot{ transition-delay:.32s; }
  .mobile-menu .mobile-foot{
    margin-top: 34px;
    display:flex; flex-direction:column; gap:18px;
  }
  .mobile-menu .mobile-submenu{
    display:flex; flex-direction:column;
    padding-left: 20px;
    margin-top:-4px;
    border-bottom: 1px solid var(--cream-line);
  }
  .mobile-menu .mobile-sub{
    font-family: var(--body);
    font-size: 16px;
    padding: 13px 0;
    min-height:44px;
    border-bottom: 1px solid var(--cream-line);
    display:flex; flex-direction:column; justify-content:center; gap:3px;
    -webkit-tap-highlight-color: transparent;
  }
  .mobile-menu .mobile-sub:active{ color: var(--sage-ink); }
  .mobile-menu .mobile-submenu .mobile-sub:last-child{ border-bottom:none; }
  .mobile-menu .mobile-sub span{ font-weight:600; line-height:1.3; }
  .mobile-menu .mobile-sub small{
    font-size:11px; font-weight:400; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-50);
  }
  /* Non-interactive group heading above a .mobile-submenu (e.g. "Solutions") —
     same rhythm as .mobile-menu a but visually subordinate (smaller, muted,
     no bottom border of its own since the submenu below supplies one) */
  .mobile-menu-label{
    font-family: var(--display);
    font-size: 28px;
    padding: 15px 0 4px;
    color: var(--ink-50);
  }
  /* The lang-toggle inside .mobile-foot is the only one a phone visitor
     ever sees (the desktop nav-right copy is hidden above) — give it a
     full 44px target here rather than the tighter desktop pill sizing. */
  .mobile-foot .lang-toggle button{ padding:12px 16px; min-width:44px; min-height:44px; }
}
@media (min-width:861px){ .mobile-menu{ display:none; } }
@media (max-width:860px) and (prefers-reduced-motion: reduce){
  .mobile-menu > a, .mobile-menu > .mobile-menu-label, .mobile-menu .mobile-foot{
    transition-delay:0s !important; transform:none !important;
  }
}

/* ---------- Sections / layout ---------- */
section{ position: relative; }
.section{ padding: clamp(56px,8vw,108px) 0; }
.section-tight{ padding: clamp(40px,5vw,72px) 0; }
/* ---------- Accessibility ---------- */
.skip-link{
  position:absolute; top:-60px; left:16px; z-index:3000;
  background: var(--ink); color: var(--off-white);
  padding:12px 20px; border-radius:8px;
  font-size:14px; font-weight:600;
  transition: top .25s ease;
}
.skip-link:focus{ top:16px; }

a:focus-visible, button:focus-visible, [tabindex]:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible{
  outline: 2px solid var(--sage-deep);
  outline-offset: 3px;
  border-radius: 4px;
}
.dropdown a:focus-visible{ outline-offset: -2px; }

@media (prefers-reduced-motion: reduce){
  *, *::before, *::after{
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

.bleed-dark{ background: var(--ink); color: var(--off-white); }
.ink-70{ color: var(--ink-70); }
.ink-50{ color: var(--ink-50); }
.bleed-dark .ink-70{ color: rgba(247,246,242,.62); }
.bleed-dark .ink-50{ color: rgba(247,246,242,.5); }
.bleed-dark .text-link{ color: var(--off-white); border-color: rgba(247,246,242,.35); }
.bleed-dark .text-link:hover{ border-color: var(--off-white); }
.bleed-cream{ background: var(--cream); }
.bleed-sage{ background: var(--sage); color: var(--ink); }
.bleed-sage-tint{ background: linear-gradient(180deg, rgba(168,182,154,.16), rgba(168,182,154,.08)); }
.bleed-sky-tint{ background: linear-gradient(180deg, rgba(75,32,70,.22), rgba(75,32,70,.1)); }
.border-top{ border-top:1px solid var(--cream-line); }

/* subtle full-bleed background photography, senior-designer treatment:
   photo sits low-opacity behind a brand-tinted gradient so it reads as
   texture/atmosphere rather than a literal photo card */
.bg-photo{ position:relative; overflow:hidden; }
.bg-photo::before{
  content:""; position:absolute; inset:0;
  background-size:cover; background-position:center;
  opacity:.16;
  z-index:0;
}
.bg-photo::after{
  content:""; position:absolute; inset:0; z-index:0;
}
.bg-photo > .container{ position:relative; z-index:1; }
.bg-photo-handshake::before{ background-image:url("../img/bg-handshake.jpg"); }
.bg-photo-handshake::after{ background: linear-gradient(180deg, var(--cream) 0%, rgba(232,227,215,.85) 55%, var(--cream) 100%); }
.bg-photo-bokeh::before{ background-image:url("../img/bg-light-bokeh.jpg"); opacity:.22; }
.bg-photo-bokeh::after{ background: linear-gradient(180deg, rgba(13,13,13,.88), rgba(13,13,13,.94)); }
.bg-photo-bokeh-light::before{ background-image:url("../img/bg-light-bokeh.jpg"); opacity:.28; }
.bg-photo-bokeh-light::after{ background: linear-gradient(180deg, var(--cream) 0%, rgba(232,227,215,.82) 100%); }
.bg-photo-desk::before{ background-image:url("../img/bg-desk-laptop.jpg"); background-position:top center; }
.bg-photo-desk::after{ background: linear-gradient(90deg, var(--off-white) 0%, rgba(247,246,242,.9) 45%, rgba(247,246,242,.75) 100%); }

.grid{ display:grid; gap: var(--gutter); }
.grid-2{ grid-template-columns: 1fr 1fr; }
.grid-12{ grid-template-columns: repeat(12,1fr); }
@media (max-width: 860px){
  .grid-2, .grid-12{ grid-template-columns: 1fr; }
  /* safety net: collapse any grid to one column on mobile, even where an
     inline style sets a fixed column count (form rows, stat/feature grids) */
  .grid{ grid-template-columns: 1fr !important; }
}

.rule{ height:1px; background: var(--cream-line); border:none; margin:0; }

/* ---------- Reveal animation ---------- */
[data-reveal]{
  opacity:0;
  transform: translateY(28px);
  transition: opacity 1s var(--ease), transform 1s var(--ease);
}
[data-reveal].in{ opacity:1; transform:none; }
[data-reveal="fade"]{ transform:none; }
[data-reveal-delay="1"]{ transition-delay:.08s; }
[data-reveal-delay="2"]{ transition-delay:.18s; }
[data-reveal-delay="3"]{ transition-delay:.28s; }
[data-reveal-delay="4"]{ transition-delay:.38s; }

/* portrait card — plain, no background box; whole photo stays visible */
.portrait-card{
  position:relative;
  display:flex; align-items:center; justify-content:center;
  background: none;
}
.portrait-card img{
  width:100%; height:auto; max-height:100%; object-fit:contain; display:block;
  opacity:1;
}

/* abstract number panel — used where a photo isn't appropriate */
.panel-number{
  position:relative;
  border-radius:20px;
  overflow:hidden;
  display:flex; align-items:center; justify-content:center;
  background: linear-gradient(150deg, var(--cream) 0%, rgba(168,182,154,.4) 100%);
}
.panel-number .big-num{
  font-family:var(--display);
  font-size: clamp(90px,14vw,180px);
  color: rgba(13,13,13,.14);
  line-height:1;
}
.panel-number.sky{ background: linear-gradient(150deg, var(--cream) 0%, rgba(75,32,70,.55) 100%); }
.panel-number.ink{ background: linear-gradient(150deg, #0D0D0D 0%, var(--sage-deep) 130%); }
.panel-number.ink .big-num{ color: rgba(247,246,242,.16); }
.panel-number.has-photo img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  opacity:0; transform: scale(1.08);
  transition: opacity 1s var(--ease), transform 1.4s var(--ease);
}
.panel-number.has-photo img.is-loaded{ opacity:1; }
[data-reveal].in .panel-number.has-photo img.is-loaded{ transform: scale(1); }

/* image reveal wipe */
.img-wrap{ overflow:hidden; position:relative; background:var(--cream); }
.img-wrap img{
  width:100%; height:100%; object-fit:cover;
  transform: scale(1.12);
  transition: transform 1.4s var(--ease);
}
[data-reveal].in .img-wrap img{ transform: scale(1); }

/* ---------- Hero ---------- */
.hero{
  min-height: 100svh;
  display:flex;
  flex-direction:column;
  justify-content:flex-end;
  padding-top: 150px;
  padding-bottom: 56px;
  background: var(--off-white);
}
.hero-top{ display:flex; justify-content:space-between; align-items:flex-start; gap:40px; flex-wrap:wrap; }
.hero-title{ max-width: 780px; flex:1 1 480px; }
.hero-side{ max-width:400px; flex:0 1 400px; text-align:left; padding-top:.4em; }
@media (max-width:860px){
  .hero-top{ flex-direction:column; align-items:flex-start; }
  .hero-side{ text-align:left; max-width:100%; }
}
/* ---------- Sprint 13: hero — mobile is a distinct composition, not a
   shrunk desktop one. Desktop heroes rely on a large forced svh height +
   justify-content:flex-end to balance a wide two-column (or centred)
   layout — on a phone that same rule leaves a dead, empty band above the
   content before anything readable appears, since the content itself is
   far shorter than the viewport. Every hero on the site now content-sizes
   and top-anchors on mobile instead, so the headline is visible the
   instant the page loads (true above-the-fold), regardless of what
   per-page inline min-height (34svh–100svh) was set for desktop. The one
   exception is the two centred "end state" heroes (danke/404), which are
   deliberately short, single-message screens where vertical centring is
   still the right read on a phone — they keep a capped, shorter svh. */
@media (max-width:860px){
  .hero{
    min-height:auto !important;
    padding-top: calc(112px + env(safe-area-inset-top));
    padding-bottom: 36px;
    justify-content:flex-start;
  }
  .hero.center{
    min-height:64svh !important;
    justify-content:center;
  }
}
/* ---------- Sprint 12: homepage hero rebalance ----------
   The two-column hero (headline left, lede+CTAs right) exists only on
   index.html — every other page's hero is single-column — so this is
   scoped to #hero rather than changing .h-xl/.hero-title/.hero-side
   globally and shrinking every page's H1. Goal: smaller headline,
   tighter line-height, narrower headline column, wider/closer lede
   column, less empty space between the two. */
#hero .h-xl{ font-size: clamp(27px, 3.6vw, 50px); line-height:1.22; }
#hero .hero-top{ gap: 28px; }
#hero .hero-title{ max-width: 660px; flex-basis: 440px; }
#hero .hero-side{ max-width: 460px; flex-basis: 440px; padding-top:.6em; }

.hero-meta{
  margin-top: 56px;
  display:flex; justify-content:space-between; align-items:flex-end; gap:30px;
  padding-top: 26px;
  border-top: 1px solid var(--cream-line);
}
@media (max-width:700px){ .hero-meta{ flex-direction:column; align-items:flex-start; gap:22px; } }

/* ---------- Sprint 29: hero cycling word (product pages) ----------
   A small "living system" glimpse in the hero: cycles through the same
   framework/journey steps the page explains further down, so the hero
   itself hints at depth instead of sitting static for five seconds. */
.hero-cycle{ display:flex; align-items:baseline; gap:9px; flex-wrap:wrap; }
.hero-cycle-eyebrow{ font-size:11.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--ink-50); }
.hero-cycle-word{
  font-family:var(--display); font-size:16px; font-weight:600; color:var(--sage-ink);
  min-width:150px; display:inline-block;
  transition:opacity .22s var(--ease-standard);
}

.scroll-cue{
  writing-mode: vertical-rl;
  font-size:11.5px; letter-spacing:.18em; text-transform:uppercase; color:var(--ink-50);
  display:flex; align-items:center; gap:10px;
}
.scroll-cue .dot{
  width:6px; height:6px; border-radius:50%; background: var(--sage);
  animation: pulse 2.2s infinite;
}
@keyframes pulse{ 0%,100%{ opacity:.4 } 50%{ opacity:1 } }

/* ---------- Cards ---------- */
.pillar-card{
  border-top:1px solid var(--cream-line);
  padding: 40px 0;
  display:grid;
  grid-template-columns: 90px 1fr 200px;
  gap: 30px;
  align-items:start;
  transition: padding .5s var(--ease);
}
.pillar-card:last-child{ border-bottom:1px solid var(--cream-line); }
.pillar-card:hover{ padding-left:14px; }
@media (max-width:860px){
  .pillar-card{ grid-template-columns: 1fr; gap:14px; }
}
.pillar-num{ font-family:var(--display); font-size:16px; color: var(--sage-ink); }
.pillar-tags{ display:flex; flex-wrap:wrap; gap:8px; align-content:flex-start; }
.tag{
  font-size:11.5px; letter-spacing:.05em; text-transform:uppercase;
  padding:6px 12px; border-radius:20px; border:1px solid transparent;
  background: rgba(168,182,154,.22); color: var(--sage-ink); font-weight:700;
}
.tag.sky{ background: rgba(75,32,70,.3); color:#3A1836; }

.feature-card{
  background: var(--off-white);
  border-top: 2px solid var(--sage);
  border-radius: 2px;
  padding: 38px 34px;
  transition: transform .5s var(--ease), box-shadow .5s var(--ease);
}
.feature-card:hover{ transform: translateY(-6px); box-shadow: 0 30px 60px rgba(13,13,13,.08); }

.stat{
  display:flex; flex-direction:column; gap:10px;
  padding: 26px 0;
}
.stat b{ font-family: var(--display); font-size: clamp(30px,3.4vw,46px); font-weight:400; color: var(--sage-ink); }
.stat > span{ font-size:13px; color:var(--ink-50); max-width:210px; text-wrap: pretty; }
.stat b span{ font-size:inherit; color:inherit; max-width:none; }
.bleed-dark .stat b{ color: var(--sage); }

/* ---------- Marquee ---------- */
.marquee-wrap{ overflow:hidden; border-top:1px solid var(--cream-line); border-bottom:1px solid var(--cream-line); }
.marquee{ display:flex; width:max-content; animation: marquee 32s linear infinite; }
.marquee span{
  font-family: var(--display);
  font-size: clamp(22px,3vw,40px);
  padding: 22px 40px;
  white-space:nowrap;
  color: var(--ink-30);
}
.marquee span.on{ color: var(--ink); }
@keyframes marquee{ from{ transform:translateX(0);} to{ transform: translateX(-50%);} }

/* ---------- Footer ---------- */
.site-footer{ background: var(--ink); color: var(--off-white); padding: 90px 0 30px; }
.footer-top{ display:grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 40px; padding-bottom:70px; }
@media (max-width:860px){ .footer-top{ grid-template-columns: 1fr 1fr; row-gap:44px; } }
@media (max-width:520px){ .footer-top{ grid-template-columns: 1fr; } }
.footer-top h4{ font-size:12px; letter-spacing:.1em; text-transform:uppercase; color:rgba(247,246,242,.45); margin-bottom:20px; font-family:var(--body); font-weight:700; }
.footer-links li{ margin-bottom:12px; }
.footer-links a{ font-size:14.5px; color: rgba(247,246,242,.85); transition: opacity .3s; }
.footer-links a:hover{ opacity:.6; }
@media (max-width:860px){
  /* Footer link rows on a phone: the tappable area was just the text's own
     line-height (~14.5px text, well under the 44px target) with only
     margin between rows to reduce mis-taps. Padding the anchor itself
     turns each row into a real 44px-tall tap target. */
  .footer-links li{ margin-bottom:0; border-bottom:1px solid rgba(247,246,242,.1); }
  .footer-links li:last-child{ border-bottom:none; }
  .footer-links a{ display:block; padding:13px 0; min-height:44px; }
  .footer-links a:active{ opacity:.6; }
}
/* Sprint 21: quiet trust bar between the footer link columns and the legal
   line. Deliberately minimal — a label plus a checkmark list, no badges,
   no logos, no shield icons. Only claims already established elsewhere on
   the site (science.html's AI/human boundaries, data-permission rules) are
   listed here; compliance-specific claims (GDPR, hosting region, encryption,
   auth, vendor stack) are intentionally not included pending confirmation. */
.footer-trust{ border-top:1px solid rgba(247,246,242,.14); padding:36px 0; }
.footer-trust-label{ font-size:12px; letter-spacing:.1em; text-transform:uppercase; color:rgba(247,246,242,.45); margin-bottom:18px; font-family:var(--body); font-weight:700; }
.footer-trust-list{ display:flex; flex-wrap:wrap; gap:12px 32px; list-style:none; padding:0; margin:0; }
.footer-trust-list li{ display:flex; align-items:center; gap:8px; font-size:13.5px; color:rgba(247,246,242,.75); }
.footer-trust-list li::before{ content:"✓"; color: var(--sage); font-weight:700; }

.footer-bottom{ border-top:1px solid rgba(247,246,242,.14); padding-top:26px; display:flex; justify-content:space-between; flex-wrap:wrap; gap:14px; font-size:12.5px; color:rgba(247,246,242,.5); }
.footer-bottom a{ color:rgba(247,246,242,.5); }
.footer-bottom a:hover{ color:#fff; }
/* Both dimensions pinned deliberately, not just height: inside the
   .footer-top CSS Grid, a replaced element (img) with only height
   constrained lets the grid's auto track-sizing pick up the image's
   raw, unconstrained natural width (955px) when computing the column
   size — even though the image itself paints at the intended small
   height. Verified live (real browser, Sprint 17): with only
   height:34px set, the column and image box measured 218px wide;
   pinning width:131px (34 × 955/247, the logo's true aspect ratio)
   fixes it to the intended compact size, matching the header logo's
   proportions at footer scale. */
.footer-logo img{ height:34px; width:131px; margin-bottom:22px; }
.footer-claim{ font-family:var(--display); font-size:22px; max-width:320px; color:rgba(247,246,242,.92); }

/* ---------- Forms ---------- */
.field{ margin-bottom: 26px; }
.field label{ display:block; font-size:12.5px; letter-spacing:.06em; text-transform:uppercase; color:var(--ink-50); margin-bottom:10px; }
.field input, .field select, .field textarea{
  width:100%;
  background:transparent;
  border:none;
  border-bottom: 1px solid var(--ink-30);
  padding: 12px 2px;
  font-family: var(--body);
  font-size:16px;
  color: var(--ink);
  transition: border-color .3s ease;
}
.field textarea{ resize: vertical; min-height:110px; }
.field input:focus, .field select:focus, .field textarea:focus{ outline:none; border-color: var(--ink); }
.field input::placeholder, .field textarea::placeholder{ color: var(--ink-30); }
.checkbox-field{ display:flex; gap:12px; align-items:flex-start; flex-wrap:wrap; }
.checkbox-field input{ width:16px; height:16px; margin-top:3px; accent-color: var(--ink); }
.checkbox-field label{ text-transform:none; font-size:13px; letter-spacing:0; line-height:1.5; }
.checkbox-field .field-error{ flex-basis:100%; }

/* Invalid-submit feedback on the whole form (class toggled by main.js);
   respects the global prefers-reduced-motion rule above automatically
   since that rule zeroes all animation-duration values. */
@keyframes formShake{
  10%,90%{ transform: translateX(-1px); }
  20%,80%{ transform: translateX(2px); }
  30%,50%,70%{ transform: translateX(-4px); }
  40%,60%{ transform: translateX(4px); }
}
.shake{ animation: formShake .5s ease; }

/* ---------- Utilities ---------- */
.center{ text-align:center; margin-left:auto; margin-right:auto; }
.max-w-sm{ max-width:480px; }
.max-w-md{ max-width:640px; }
.max-w-lg{ max-width:820px; }
.max-w-xl{ max-width:1040px; } /* Sprint 22: wide enough for a large (h-xl)
  centered statement headline to balance across 2 clean lines instead of
  wrapping into 3 fragmented ones inside the narrower max-w-lg. */

/* Positioning + typography sprint: a few section-intro wrapper divs were
   tuned narrow (680-720px) in an earlier pass and now cause headings with
   an intentional sentence-boundary <br> to wrap a second time inside each
   sentence at wide desktop, e.g. "Komplexität wächst / nicht mit der
   Kopfzahl." instead of "Komplexität wächst nicht mit der Kopfzahl." on
   one line. This is an opt-in utility, not a global change: it only
   widens the specific wrapper divs it's added to, only at desktop widths,
   using !important because those divs already carry a narrower inline
   max-width for tablet/mobile that must keep winning below 1200px. */
@media (min-width:1200px){
  .measure-heading-wide{ max-width:940px !important; }
}
@media (min-width:1500px){
  .measure-heading-wide{ max-width:1080px !important; }
}
.mt-0{margin-top:0} .mt-1{margin-top:12px} .mt-2{margin-top:24px} .mt-3{margin-top:40px} .mt-4{margin-top:64px} .mt-5{margin-top:96px}
.mb-1{margin-bottom:12px} .mb-2{margin-bottom:24px}
.flex{ display:flex; }
.flex-wrap{ flex-wrap:wrap; }
.items-center{ align-items:center; }
.justify-between{ justify-content:space-between; }
.gap-1{gap:10px} .gap-2{gap:20px} .gap-3{gap:32px}

.hidden{ display:none !important; }
/* Visually hidden but still announced by screen readers — unlike .hidden
   (display:none), this keeps the element in the accessibility tree.
   Use for things like a <table> <caption> that a sighted user doesn't
   need (the heading above already states it) but that gives assistive
   tech useful table context. */
.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;
}
[data-lang-hide]{ display:none !important; }

/* ---------- Language toggle (DE / EN content swap) ---------- */
html[data-lang="de"] .lang-en{ display:none !important; }
html[data-lang="en"] .lang-de{ display:none !important; }
.lang-de, .lang-en{ display:contents; }
span.lang-de, span.lang-en{ display:inline; }
html[data-lang="de"] span.lang-en{ display:none !important; }
html[data-lang="en"] span.lang-de{ display:none !important; }

.numbered-list{ counter-reset: item; min-width:0; }
.numbered-list li{
  counter-increment: item;
  display:grid; grid-template-columns: 40px minmax(0,1fr); gap:18px;
  padding: 20px 0; border-top:1px solid var(--cream-line);
  min-width:0;
}
.numbered-list li:last-child{ border-bottom:1px solid var(--cream-line); }
.numbered-list li::before{
  content: counter(item, decimal-leading-zero);
  font-family: var(--display); color: var(--sage-deep); font-size:16px;
}
.numbered-list li > div{ min-width:0; width:100%; }

/* steps-row: horizontal 3-up step layout (Analyse / Intervention / Integration) */
.steps-row{
  counter-reset: item;
  display:grid; grid-template-columns: repeat(3,1fr); gap:44px;
  list-style:none; margin:0; padding:0;
}
.steps-row li{
  counter-increment: item;
  padding-top:24px;
  border-top:2px solid var(--sage);
}
.steps-row li::before{
  content: counter(item, decimal-leading-zero);
  display:block;
  font-family: var(--display); color: var(--sage-deep); font-size:15px;
  margin-bottom:16px;
}
@media (max-width:860px){
  .steps-row{ grid-template-columns: 1fr; gap:0; }
  .steps-row li{ padding:24px 0; }
  .steps-row li:last-child{ border-bottom:2px solid var(--sage); }
}

.accordion-item{ border-top:1px solid var(--cream-line); }
.accordion-item:last-child{ border-bottom:1px solid var(--cream-line); }
.accordion-head{
  width:100%;
  display:flex; justify-content:space-between; align-items:center;
  padding: 26px 0;
  text-align:left;
  font-family:var(--display);
  font-size: clamp(18px,2vw,24px);
}
.accordion-head .plus{ position:relative; width:16px; height:16px; flex:none; }
.accordion-head .plus::before, .accordion-head .plus::after{
  content:""; position:absolute; background:var(--sage-ink); transition: transform .4s var(--ease);
}
.accordion-head .plus::before{ top:7px; left:0; width:16px; height:1px; }
.accordion-head .plus::after{ top:0; left:7px; width:1px; height:16px; }
.accordion-item.open .accordion-head .plus::after{ transform: rotate(90deg); opacity:0; }
.accordion-panel{
  max-height:0; overflow:hidden;
  transition: max-height .5s var(--ease);
}
.accordion-panel-inner{ padding-bottom: 28px; max-width:760px; color:var(--ink-70); }

.badge-soon{
  display:inline-flex; align-items:center; gap:8px;
  font-size:11px; letter-spacing:.1em; text-transform:uppercase;
  padding:6px 14px; border-radius:20px; background: var(--sky); color: var(--ink);
  font-weight:700;
}

/* cursor dot (desktop only, subtle) */
.cursor-dot{
  position:fixed; top:0; left:0; width:8px; height:8px; border-radius:50%;
  background: var(--sage-ink); pointer-events:none; z-index:9999;
  transform: translate(-50%,-50%);
  transition: opacity .3s ease, width .3s ease, height .3s ease, background .3s ease;
  opacity:0;
}
@media (hover:hover) and (pointer:fine){ .cursor-dot.active{ opacity:.9; } }

/* Preloader-less: simple fade-in on load */
body{ animation: bodyIn .8s ease both; }
@keyframes bodyIn{ from{ opacity:0 } to{ opacity:1 } }

::selection{ background: var(--sage); color: var(--ink); }

/* Split image / text section */
.split{ display:grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: var(--gutter); align-items:center; }
@media (max-width:860px){ .split{ grid-template-columns:1fr; } }
.split.reverse .split-img{ order:2; }
@media (max-width:860px){ .split.reverse .split-img{ order:0; } }

.ratio-4-5{ aspect-ratio: 4/5; }
.ratio-3-2{ aspect-ratio: 3/2; }
.ratio-1-1{ aspect-ratio: 1/1; }
.ratio-16-9{ aspect-ratio: 16/9; }

/* testimonials */
.testimonial-card{
  border-top: 2px solid var(--sage);
  padding: 30px 0 6px;
  display:flex; flex-direction:column; height:100%;
  transition: transform var(--duration-standard) var(--ease-standard);
}
.testimonial-card:hover{ transform: translateY(-3px); }
.testimonial-card p{
  font-family: var(--display); font-size: clamp(17px,1.7vw,21px); line-height:1.5;
  color: var(--ink); flex:1;
}
.testimonial-card cite{
  display:block; font-style:normal; margin-top:22px; font-size:13px; color: var(--ink-50);
}
.testimonial-card cite a{ color: var(--sage-ink); border-bottom: 1px solid rgba(75,107,63,.4); }

/* quote */
.pull-quote{
  font-family: var(--display);
  font-size: clamp(24px,3vw,38px);
  line-height:1.3;
  max-width: 820px;
}
.pull-quote cite{ display:block; font-style:normal; font-family:var(--body); font-size:13px; color:var(--ink-50); margin-top:22px; letter-spacing:.03em; }

/* matrix / comparison list */
.matrix-row{
  display:grid; grid-template-columns: 1.4fr 1fr 1fr;
  gap: 20px;
  padding: 22px 0;
  border-top:1px solid var(--cream-line);
  align-items:center;
}
.matrix-row.head{ font-size:12px; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-50); }
@media (max-width:700px){
  .matrix-row{ grid-template-columns:1fr; gap:6px; padding:20px 0; }
  .matrix-row.head{ display:none; }
  .matrix-row div::before{ content: attr(data-label) ": "; color:var(--ink-50); font-size:11px; text-transform:uppercase; letter-spacing:.06em; }
  .matrix-row div:first-child::before{ content:none; }
}

/* =========================================================
   SPRINT 1 — Design System Foundation
   Typography scale · Containers · Radii/Shadows · Buttons ·
   Cards · Forms · Shell motif · Motion utilities
   Reusable building blocks for later content sprints.
   Nothing in this section changes existing page content.
   ========================================================= */

/* ---------- Typography — full scale ---------- */
.type-display{
  font-family: var(--display);
  font-weight: 400;
  letter-spacing: -0.01em;
  line-height: 1.02;
  font-size: clamp(40px, 6vw, 84px);
}
.type-body-lg{ font-family: var(--body); font-size: clamp(17px,1.6vw,21px); line-height:1.6; font-weight:350; text-wrap: pretty; }
.type-body{ font-family: var(--body); font-size:16px; line-height:1.6; font-weight:400; text-wrap: pretty; }
.type-body-sm{ font-family: var(--body); font-size:14px; line-height:1.55; font-weight:400; text-wrap: pretty; }
.type-label{ font-family: var(--body); font-size:12.5px; letter-spacing:.08em; text-transform:uppercase; font-weight:700; }
.type-caption{ font-family: var(--body); font-size:12px; line-height:1.5; color:var(--text-muted); text-wrap: pretty; }
.type-button{ font-family: var(--body); font-size:14px; letter-spacing:.02em; font-weight:600; }

/* Recline is reserved for headings, display statements and a few
   emphasised words — never for full paragraphs of body copy or
   dense UI text. See DESIGN_SYSTEM.md, "Typography". */
strong.font-display, em.font-display{ font-style:normal; }

/* ---------- Containers ---------- */
.container-narrow{ max-width: var(--container-narrow); margin:0 auto; padding:0 var(--gutter); }
.container-regular{ max-width: var(--container-regular); margin:0 auto; padding:0 var(--gutter); }
.container-wide{ max-width: var(--container-wide); margin:0 auto; padding:0 var(--gutter); }
.container-full{ width:100%; padding:0 var(--gutter); }

/* ---------- Radius / Shadow utilities ---------- */
.radius-sm{ border-radius: var(--radius-sm); }
.radius-md{ border-radius: var(--radius-md); }
.radius-lg{ border-radius: var(--radius-lg); }
.radius-pill{ border-radius: var(--radius-pill); }
.shadow-sm{ box-shadow: var(--shadow-sm); }
.shadow-md{ box-shadow: var(--shadow-md); }
.shadow-lg{ box-shadow: var(--shadow-lg); }
.shadow-xl{ box-shadow: var(--shadow-xl); }

/* ---------- Buttons — completed state set ---------- */
/* Default/hover already defined above (.btn, .btn-primary, .btn-ghost, .btn-light).
   This block only adds the missing interaction states. */
.btn:focus-visible{ outline: 2px solid var(--focus-ring); outline-offset: 3px; }
.btn:active{ transform: translateY(0) scale(.98); }
.btn:disabled, .btn.is-disabled{
  opacity:.4; cursor:not-allowed; pointer-events:none;
}
.btn.is-loading{ position:relative; color:transparent !important; pointer-events:none; }
.btn.is-loading::after{
  content:""; position:absolute; left:50%; top:50%; width:16px; height:16px;
  margin:-8px 0 0 -8px;
  border-radius:50%;
  border:2px solid currentColor; border-top-color:transparent;
  color: var(--off-white);
  animation: btnSpin .7s linear infinite;
}
.btn-ghost.is-loading::after{ color: var(--ink); }
@keyframes btnSpin{ to{ transform: rotate(360deg); } }

/* Icon Button — compact, square, for nav/close/carousel controls */
.btn-icon{
  display:inline-flex; align-items:center; justify-content:center;
  width:44px; height:44px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-strong);
  color: var(--ink);
  transition: background var(--duration-standard) var(--ease-standard), border-color var(--duration-standard) var(--ease-standard), transform var(--duration-standard) var(--ease-standard);
}
.btn-icon svg{ width:18px; height:18px; }
.btn-icon:hover{ background: var(--ink); border-color: var(--ink); color: var(--off-white); }
.btn-icon:focus-visible{ outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.btn-icon:active{ transform: scale(.94); }

/* ---------- Cards — reusable base types ---------- */
/* Shared base */
.card{
  background: var(--surface-elevated);
  border-radius: var(--radius-md);
  padding: var(--space-6) var(--space-5);
  transition: transform var(--duration-standard) var(--ease-standard), box-shadow var(--duration-standard) var(--ease-standard), border-color var(--duration-standard) var(--ease-standard);
}
.card h3, .card h4{ margin-bottom: var(--space-2); }
.card p{ color: var(--text-secondary); }

/* Product Card — one of the two core offerings (People Strategy / Mental Performance) */
.card-product{
  border-top: 2px solid var(--accent-primary);
  border-radius: var(--radius-sm);
  padding: var(--space-7) var(--space-6);
  transition: transform var(--duration-standard) var(--ease-standard), box-shadow var(--duration-standard) var(--ease-standard);
}
.card-product:hover{ transform: translateY(-6px); box-shadow: var(--shadow-md); }

/* Process Card — for step/loop style content */
.card-process{
  border-top: 1px solid var(--border-subtle);
  padding: var(--space-5) 0;
}

/* Insight Card — data point / recommendation style content */
.card-insight{
  background: var(--background-secondary);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  transition: transform var(--duration-standard) var(--ease-standard), box-shadow var(--duration-standard) var(--ease-standard);
}
/* Non-clickable hover lift only — no cursor:pointer, no focus-visible ring:
   these cards carry no click destination, so they stay out of tab order
   and never imply an affordance they don't have (see .card-interactive
   for the clickable variant). */
.card-insight:hover{ transform: translateY(-4px); box-shadow: var(--shadow-sm); }

/* Stat Card — number + context (extends existing .stat) */
.card-stat{ padding: var(--space-5) 0; }
.card-stat b{ font-family: var(--display); font-size: clamp(30px,3.4vw,46px); font-weight:400; color: var(--accent-primary); display:block; }
.card-stat span{ font-size:13px; color: var(--text-muted); }

/* Quote / Trust Card (extends existing .testimonial-card) */
.card-quote{
  border-top: 2px solid var(--accent-primary);
  padding: var(--space-5) 0 var(--space-1);
}

/* Interactive Card — clickable, whole-card hover target */
.card-interactive{
  cursor:pointer;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  padding: var(--space-6);
  transition: border-color var(--duration-standard) var(--ease-standard), box-shadow var(--duration-standard) var(--ease-standard), transform var(--duration-standard) var(--ease-standard);
}
.card-interactive:hover{ border-color: var(--border-strong); box-shadow: var(--shadow-sm); transform: translateY(-3px); }
.card-interactive:focus-visible{ outline: 2px solid var(--focus-ring); outline-offset: 3px; }

/* Floating Card — for Expert CTA / overlay-style panels (built in a later sprint) */
.card-floating{
  background: var(--surface-elevated);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-lg);
  border: 1px solid var(--border-subtle);
}

@media (max-width:700px){
  .card, .card-product, .card-insight, .card-interactive{ padding: var(--space-5); }
}

/* Platform Band — Sprint 16: the two Solutions cards above converge into
   one combined-offering panel. Reuses .shell-mark and the existing pill/
   token language rather than introducing new visual primitives; the tag
   row is purely illustrative (both labels already exist as real card
   headings above it), so it's hidden from assistive tech the same way
   the hero-visual module is. */
.platform-band{
  background: var(--background-secondary);
  border-radius: var(--radius-lg);
  padding: var(--space-7) var(--space-6);
  margin-top: var(--space-6);
  text-align: center;
}
.platform-band-inputs{
  display:flex; align-items:center; justify-content:center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
}
.platform-band-tag{
  font-size:12px; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  padding:7px 16px;
  border-radius: var(--radius-pill);
  background: var(--sky);
  color: var(--accent-primary);
}
.platform-band-connector{ width:28px; height:1px; background: var(--border-strong); flex:none; }
.platform-band-mark{ width:22px; height:22px; color: var(--accent-primary); flex:none; }
.platform-band h3{ margin-bottom: var(--space-2); }
.platform-band .lede{ max-width:560px; margin-left:auto; margin-right:auto; }
.platform-band .btn{ margin-top: var(--space-5); }
@media (max-width:700px){
  .platform-band{ padding: var(--space-6) var(--space-4); }
  .platform-band-connector{ width:14px; }
}

/* Sprint 22: the platform equation — People Strategy + Mental Performance +
   Continuous AI = One Operating System, as an actual equation rather than
   a sentence. Reuses .platform-band-tag for the three inputs; the result
   gets a filled, higher-contrast chip so it visually reads as the answer,
   not a fourth input. */
.platform-equation{
  display:flex; align-items:center; justify-content:center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
}
.platform-eq-op{
  font-family: var(--display);
  font-size: 20px;
  color: var(--ink-30);
  flex: none;
}
.platform-eq-op.platform-eq-equals{ color: var(--accent-primary); font-size:22px; }
.platform-eq-result{
  font-size:12px; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  padding:8px 18px;
  border-radius: var(--radius-pill);
  background: var(--accent-primary);
  color: var(--off-white);
}
@media (max-width:700px){
  .platform-equation{ gap:8px; }
  .platform-eq-op{ font-size:16px; }
}

/* ---------- Forms — validation & loading states ---------- */
/* Base .field / input styles already defined above. This block
   adds success/error/disabled/loading, not yet wired into
   contact.html logic (Sprint 2+), styles only. */
.field.has-error input, .field.has-error select, .field.has-error textarea{
  border-color: var(--error);
}
.field .field-error{
  display:none;
  color: var(--error);
  font-size:12.5px; margin-top:8px;
}
.field.has-error .field-error{ display:block; }

.field.has-success input, .field.has-success select, .field.has-success textarea{
  border-color: var(--success);
}
.field .field-helper{ color: var(--text-muted); font-size:12.5px; margin-top:8px; }

.field.is-disabled{ opacity:.5; }
.field input:disabled, .field select:disabled, .field textarea:disabled{ cursor:not-allowed; }

.form-success-banner{
  background: var(--success-bg); color: var(--success);
  border-radius: var(--radius-sm); padding: var(--space-4) var(--space-5);
  font-size:14px;
}
.form-error-banner{
  background: var(--error-bg); color: var(--error);
  border-radius: var(--radius-sm); padding: var(--space-4) var(--space-5);
  font-size:14px;
}
.form-success-banner{
  background: var(--success-bg); color: var(--success);
  border-radius: var(--radius-sm); padding: var(--space-4) var(--space-5);
  font-size:14px;
}

/* ---------- Shell motif — sparse, structural use only ---------- */
/* Small inline mark, e.g. beside a quote or label */
/* Sprint 14: was two 398×406 raster PNGs (144KB black + 48KB light variant,
   ~192KB combined, loaded sitewide to render an 18–44px icon) swapped via a
   .bleed-dark/.on-dark override. Replaced with the existing 4.5KB brand SVG
   used as a CSS mask, filled with currentColor — one ~4.5KB asset instead of
   two oversized ones, infinitely crisp at any size/DPI instead of a fixed
   398px raster stretched down, and the dark/light swap now happens for free
   through normal color inheritance (.bleed-dark already sets color:var(--off-white)
   at the section level) instead of needing a second image file. Shape is
   pixel-identical to the black PNG this replaces — same source artwork. */
.shell-mark{
  display:inline-block;
  width:18px; height:18px;
  vertical-align:middle;
  background-color: currentColor;
  -webkit-mask: url("../brand/ayva-shell.svg") center/contain no-repeat;
  mask: url("../brand/ayva-shell.svg") center/contain no-repeat;
}

/* Sprint 12: the large decorative shell watermark in the footer background
   was removed sitewide — at real footer size, the raster PNG mark
   (upscaled via background-size:contain) read as blurry/distorted rather
   than premium. Class kept only as documented history; no longer applied
   to any live page (see DESIGN_SYSTEM.md). If a background shell mark is
   reintroduced later, use the true ayva-shell.svg asset at very low
   opacity (3-5%), not a scaled-up PNG. */

/* Section divider — thin rule with a centred shell mark */
.shell-divider{
  display:flex; align-items:center; gap:16px;
  color: var(--border-strong);
}
.shell-divider::before, .shell-divider::after{
  content:""; flex:1; height:1px; background: var(--border-subtle);
}
/* .shell-divider sets color:var(--border-strong) for its rule lines, but the
   mark itself was always solid black under the old PNG (background-image
   ignores `color` entirely) — pin it explicitly now that the mark is a
   currentColor mask, so this one spot keeps its original appearance instead
   of picking up the much lighter border tone. */
.shell-divider .shell-mark{ background-color: var(--ink); opacity:.5; }

/* Loader — brief, first-visit only (wired up in a later sprint).
   Same PNG→SVG-mask swap as .shell-mark above, same reasoning. */
.shell-loader{
  width:32px; height:32px;
  background-color: currentColor;
  -webkit-mask: url("../brand/ayva-shell.svg") center/contain no-repeat;
  mask: url("../brand/ayva-shell.svg") center/contain no-repeat;
  animation: shellPulse 1.4s var(--ease-standard) infinite;
}
@keyframes shellPulse{ 0%,100%{ opacity:.35; transform:scale(.94); } 50%{ opacity:1; transform:scale(1); } }

@media (prefers-reduced-motion: reduce){
  .shell-loader{ animation: none; opacity:.8; }
}

/* ---------- Motion utilities ---------- */
.motion-fast{ transition-duration: var(--duration-fast) !important; }
.motion-standard{ transition-duration: var(--duration-standard) !important; }
.motion-slow{ transition-duration: var(--duration-slow) !important; }

/* =========================================================
   SPRINT 3 — Hero System, First Impression & Core Positioning
   ========================================================= */

/* Status tags — global (previously page-local to how-it-works.html,
   now reused in the homepage hero visual; single source of truth) */
.status-tag{ font-size:11px; letter-spacing:.05em; text-transform:uppercase; padding:5px 11px; border-radius:20px; font-weight:700; display:inline-block; }
.status-available{ background:rgba(168,182,154,.28); color:#3F5A3F; }
.status-development{ background:rgba(168,182,154,.16); color:var(--sage-ink); }
.status-planned{ background:transparent; border:1px solid var(--ink-30); color:var(--ink-50); }

/* Hero CTA row */
.hero-ctas{ display:flex; align-items:center; gap:28px; flex-wrap:wrap; margin-top:34px; }
/* Secondary CTA sits as a standalone row item here (not inline in a
   sentence), so give it a larger tap target than the running-text
   .text-link default — WCAG 2.5.8 target-size headroom. */
.hero-ctas .text-link{ padding: 12px 0; }
/* Sprint 13: on phones the primary action reads as one full-width bar
   (the pattern every native app uses for its main CTA) instead of a
   pill sized to its own text — the secondary link stays compact and
   centred underneath rather than also stretching, so the hierarchy
   between "the one thing to do" and "learn more" stays visible. */
@media (max-width:520px){
  .hero-ctas{ flex-direction:column; align-items:stretch; gap:16px; margin-top:30px; }
  .hero-ctas .btn{ justify-content:center; width:100%; }
  .hero-ctas .text-link{ justify-content:center; }
}

/* Hero trust line — short, factual principles, not a buzzword list */
.hero-trust{ display:flex; flex-wrap:wrap; gap:8px 18px; font-size:12.5px; letter-spacing:.03em; color:var(--ink-50); }
.hero-trust span{ display:inline-flex; align-items:center; gap:8px; }
.hero-trust span::before{ content:""; width:4px; height:4px; border-radius:50%; background:var(--sage); }

/* ---------- Hero visual system: two areas + one connecting core ---------- */
.hero-visual{
  display:flex;
  align-items:center;
  justify-content:center;
  gap: clamp(8px, 2.6vw, 26px);
  margin: clamp(56px, 7vw, 88px) 0 8px;
  will-change: transform, opacity;
  --hv-x: 0px; --hv-y: 0px;
  transform: translate(var(--hv-x), var(--hv-y));
  transition: opacity var(--duration-slow) var(--ease-standard), transform var(--duration-standard) var(--ease-standard);
}
.hero-visual-panel{
  flex: 0 1 200px;
  display:flex; flex-direction:column; align-items:center; text-align:center; gap:10px;
  padding: 32px 24px;
  border: 1px solid var(--cream-line);
  border-radius: var(--radius-lg);
  background: var(--surface-elevated);
  box-shadow: var(--shadow-sm); /* floats gently above the page even at rest */
  transition: transform var(--duration-slow) var(--ease-standard), box-shadow var(--duration-standard) var(--ease-standard), border-color var(--duration-standard) var(--ease-standard);
}
.hero-visual-panel-name{ font-family:var(--display); font-size:17px; line-height:1.25; }
.hero-visual:hover .hero-visual-panel{ box-shadow: var(--shadow-md); border-color: var(--border-strong); }

.hero-visual-core{
  flex: 0 0 auto;
  width: 88px;
  display:flex; flex-direction:column; align-items:center; gap:10px;
}
.hero-visual-shell{
  width: 44px; height:auto;
  color: var(--accent-primary);
  filter: drop-shadow(0 10px 22px rgba(75,32,70,.20));
  animation: heroShellDrift 7s ease-in-out infinite;
}
.hero-visual-core-label{ font-family:var(--display); font-size:15px; color:var(--ink-70); }
@keyframes heroShellDrift{
  0%,100%{ transform: translateY(0) scale(1); }
  50%{ transform: translateY(-5px) scale(1.02); }
}

.hero-visual-line{
  flex: 1 1 56px;
  max-width: 96px;
  height: 1px;
  position: relative;
  background: var(--cream-line);
  align-self: center; /* .hero-visual already sets align-items:center, so this
    thin line naturally centres on the row's cross-axis against the taller
    panel/core siblings — no manual offset needed */
}
.hero-visual-line::before{
  content:"";
  position:absolute; top:0; left:0;
  width:0%; height:1px;
  background: var(--sage);
  transition: width 1.2s var(--ease-standard) .4s;
}
[data-reveal].in .hero-visual-line::before{ width:100%; }

/* ---------- Sprint 12: hero-visual "assembly" — the site's one signature
   wow-moment. Previously the whole two-panel + shell + lines group faded
   in together as a single block; now each piece arrives in sequence
   (left panel → connecting line draws → AYVA core → second line draws →
   right panel), so the visitor watches the system assemble itself rather
   than seeing it appear pre-built. Pure CSS (staggered transition-delay
   per child, all gated by the existing parent [data-reveal].in trigger)
   — no new JS, no change to the reveal/IntersectionObserver mechanism. */
#heroVisual > .hero-visual-panel-left,
#heroVisual > .hero-visual-line,
#heroVisual > .hero-visual-core,
#heroVisual > .hero-visual-panel-right{
  opacity:0;
  transition: opacity .7s var(--ease-standard);
}
[data-reveal].in #heroVisual > .hero-visual-panel-left{ opacity:1; transition-delay:.05s; }
[data-reveal].in #heroVisual > .hero-visual-line:nth-of-type(2){ opacity:1; transition-delay:.3s; }
[data-reveal].in #heroVisual > .hero-visual-core{ opacity:1; transition-delay:.55s; }
[data-reveal].in #heroVisual > .hero-visual-line:nth-of-type(4){ opacity:1; transition-delay:.8s; }
[data-reveal].in #heroVisual > .hero-visual-panel-right{ opacity:1; transition-delay:1.05s; }
/* coordinate each connecting line's own fill-draw with its container's
   arrival above, instead of both lines drawing on one shared fixed delay */
#heroVisual > .hero-visual-line:nth-of-type(2)::before{ transition-delay:.45s; }
#heroVisual > .hero-visual-line:nth-of-type(4)::before{ transition-delay:.95s; }

/* Desktop/tablet visual is hidden below 861px — mobile gets its own
   compact composition instead of a stacked-desktop version (see
   .hero-visual-mobile below). Avoids 3 full-height panels stacking
   and blowing out the mobile hero height. */
@media (max-width:860px){
  .hero-visual{ display:none; }
}

@media (prefers-reduced-motion: reduce){
  .hero-visual-shell{ animation: none; }
  .hero-visual, .hero-visual-panel{ transition: opacity var(--duration-fast) linear !important; }
}

/* ---------- Hero visual — mobile: one compact strip, not a stack ---------- */
.hero-visual-mobile{
  display:none;
}
@media (max-width:860px){
  .hero-visual-mobile{
    display:flex;
    align-items:center;
    gap:14px;
    margin: 28px 0 4px;
    padding: 16px 18px;
    border: 1px solid var(--cream-line);
    border-radius: var(--radius-md);
    background: var(--surface-elevated);
  }
  .hero-visual-mobile-shell{
    flex: 0 0 auto;
    width: 30px; height:auto;
    color: var(--sage-ink);
  }
  .hero-visual-mobile-text{ flex:1 1 auto; min-width:0; }
  .hero-visual-mobile-areas{ font-family:var(--display); font-size:15px; line-height:1.3; display:block; }
  .hero-visual-mobile-status{ font-size:11.5px; color:var(--ink-50); letter-spacing:.02em; display:block; margin-top:4px; }
}

/* Scroll-linked hero → next-section handoff (class toggled by main.js,
   IntersectionObserver-driven, no-op if reduced motion / JS disabled) */
.hero-visual.is-condensing{
  opacity:.5;
  transform: translate(var(--hv-x), calc(var(--hv-y) - 6px)) scale(.94);
}
@media (prefers-reduced-motion: reduce){
  .hero-visual.is-condensing{ opacity:1; transform:none; }
}

/* =========================================================
   SPRINT 4 — Reusable product-page components
   (first used on people-strategy.html; written generically so
   later product pages / sprints can reuse them unchanged)
   ========================================================= */

/* ---------- Process flow: connected steps with draw-in lines ----------
   Generalises the Sprint 3 hero-visual connecting-line pattern to an
   arbitrary number of steps. Desktop: horizontal row. Mobile: vertical
   stack, lines replaced by a simple left border (no diagonal geometry
   needed, avoids reduced-motion-unfriendly redraws). */
.process-flow{
  display:flex;
  align-items:center; /* thin connecting lines centre naturally against the
    tallest step's content height — same robust approach as the Sprint 3
    hero-visual connector, no manual pixel offsets */
  gap: clamp(6px, 2vw, 20px);
}
.process-step{
  flex: 1 1 0;
  min-width:0;
  align-self: flex-start;
  display:flex; flex-direction:column; gap:10px;
}
.process-step-num{ font-family:var(--display); font-size:15px; color:var(--sage-ink); }
.process-step h4{ font-size:17px; }
.process-line{
  flex: 0 0 auto;
  width: clamp(20px, 4vw, 56px);
  height:1px;
  align-self: center;
  background: var(--cream-line);
  position:relative;
}
.process-line::before{
  content:""; position:absolute; top:0; left:0; width:0%; height:1px;
  background: var(--sage);
  transition: width 1s var(--ease-standard) .2s;
}
[data-reveal].in .process-line::before{ width:100%; }

@media (max-width:860px){
  .process-flow{ flex-direction:column; gap:0; }
  .process-line{ display:none; }
  .process-step{ padding: 20px 0 20px 18px; border-left:2px solid var(--cream-line); position:relative; }
  .process-step:first-child{ padding-top:0; }
  .process-step::before{
    content:""; position:absolute; left:-5px; top:22px;
    width:8px; height:8px; border-radius:50%; background:var(--sage);
  }
  .process-step:first-child::before{ top:2px; }
}

/* ---------- Compare table: AYVA vs. classic HR consulting vs. HR software ---------- */
.compare-scroll{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
/* Sprint 13: on mobile the table is wider than the viewport and scrolls
   horizontally (already the case pre-Sprint-13) — but nothing signalled
   that there was more to see off-screen. A soft inset shadow on the
   trailing edge reads as "more content this way" regardless of whatever
   background sits behind it (unlike a solid-colour fade, which would
   need to match cream/off-white/sage-tint per section), no JS required. */
@media (max-width:860px){
  .compare-scroll{ box-shadow: inset -24px 0 16px -16px rgba(13,13,13,.14); }
}
.compare-table{
  width:100%;
  min-width: 640px;
  border-collapse: collapse;
}
.compare-table th, .compare-table td{
  text-align:left;
  padding: 18px 20px;
  border-bottom: 1px solid var(--cream-line);
  vertical-align:top;
  font-size:14.5px;
  line-height:1.5;
}
.compare-table thead th{
  font-family: var(--body);
  font-size:12.5px;
  letter-spacing:.05em;
  text-transform:uppercase;
  color: var(--ink-50);
  font-weight:700;
  border-bottom: 2px solid var(--ink-30);
}
.compare-table th[scope="row"]{
  font-family: var(--body);
  font-weight:700;
  color: var(--ink);
  white-space:nowrap;
}
.compare-table thead th.compare-col-ayva,
.compare-table td.compare-col-ayva{
  background: rgba(168,182,154,.14);
}
.compare-table thead th.compare-col-ayva{ color: var(--sage-ink); }

/* ---------- Sprint 22: framework-chain (People Strategy value chain,
   Mental Performance journey) — a numbered, responsively-wrapping row of
   real insight-cards standing in for a "visual framework" instead of a
   paragraph. Deliberately no literal arrow connectors between cards: those
   break visually the moment the row wraps onto a second line at narrower
   widths, whereas numbering + a consistent accent top-border reads as a
   sequence regardless of how many cards land per row. ---------- */
.framework-chain{
  display:grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap:16px;
}
.framework-chain-step{
  background: var(--off-white);
  border:1px solid var(--cream-line);
  border-top:3px solid var(--sage);
  border-radius: var(--radius-md);
  padding: 20px 18px;
  transition: transform var(--duration-standard) var(--ease-standard), box-shadow var(--duration-standard) var(--ease-standard);
}
.framework-chain-step:hover{ transform: translateY(-3px); box-shadow: var(--shadow-sm); }
.framework-chain-step .serif-num{ display:block; margin-bottom:8px; }
.framework-chain-step h4{ font-size:16px; margin-bottom:6px; }
.framework-chain-step p{ font-size:13.5px; line-height:1.45; color: var(--ink-70); }
.framework-chain-step:last-child{ border-top-color: var(--aubergine); }
.framework-chain-step:last-child h4{ color: var(--aubergine); }

/* ---------- Sprint 25: interactive framework-chain example toggle ----------
   Extends the Sprint 22 framework/journey chains: each step can now expand
   to reveal a concrete usage example, not just a label + one sentence. */
.framework-chain{ align-items: start; }
.framework-chain-toggle{
  display:inline-flex; align-items:center; gap:6px; margin-top:12px; padding:0; border:none;
  background:none; font-size:11.5px; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  color:var(--sage-ink); cursor:pointer;
}
.framework-chain-plus{ position:relative; width:10px; height:10px; flex:none; }
.framework-chain-plus::before,.framework-chain-plus::after{
  content:""; position:absolute; background:var(--sage-ink); transition:opacity .2s var(--ease-standard);
}
.framework-chain-plus::before{ left:0; top:4.25px; width:10px; height:1.5px; }
.framework-chain-plus::after{ left:4.25px; top:0; width:1.5px; height:10px; }
.framework-chain-step[aria-expanded="true"] .framework-chain-plus::after,
.framework-chain-toggle[aria-expanded="true"] .framework-chain-plus::after{ opacity:0; }
.framework-chain-detail{ max-height:0; overflow:hidden; transition:max-height .3s var(--ease-standard); }
.framework-chain-detail p{ font-size:12.5px; line-height:1.55; color:var(--ink-70); padding-top:10px; border-top:1px solid var(--cream-line); margin-top:10px; }

/* =========================================================
   LEVELS CIRCLE — reusable interactive radial component.
   Currently used once (people-strategy.html, the 7 AYVA levels:
   Organisation -> Business Performance). Markup/JS are generic
   (keyed by [data-levels-stage]/[data-levels-node]), so a second
   instance elsewhere would only need its own set of nodes/panels,
   no new CSS or JS. The 7 nodes sit on an open arc rather than a
   closed circle: the gap at the bottom signals "this is a
   progression, not a loop", ending at Business Performance
   (accented in aubergine). Node labels are identical in DE/EN on
   this site (Organisation, Leadership, Analytics, etc.), so only
   the description/example text below needs the lang-de/lang-en
   pairs already used sitewide. ========================================================= */
.levels-circle{
  display:grid;
  grid-template-columns: minmax(260px,460px) 1fr;
  gap: var(--space-8);
  align-items:center;
}
.levels-circle-stage{
  position:relative;
  width:100%;
  max-width:460px;
  aspect-ratio:1;
  margin:0 auto;
}
.levels-circle-svg{
  position:absolute; inset:0;
  width:100%; height:100%;
}
.levels-circle-path{
  fill:none;
  stroke:var(--ink-12);
  stroke-width:1.25;
}
.levels-circle-core{
  position:absolute; left:50%; top:50%;
  transform:translate(-50%,-50%);
  text-align:center;
  max-width:130px;
  pointer-events:none;
}
.levels-circle-core-num{
  font-family:var(--display);
  font-size:13px;
  color:var(--ink-50);
  margin:0 0 4px;
}
.levels-circle-core-name{
  font-family:var(--display);
  font-size:18px;
  line-height:1.25;
  color:var(--ink);
  margin:0;
}
.levels-circle-node{
  position:absolute;
  transform:translate(-50%,-50%);
  display:flex; align-items:center; gap:7px;
  min-height:40px;
  padding:8px 14px;
  border-radius:var(--radius-pill);
  border:1px solid var(--cream-line);
  background:var(--off-white);
  box-shadow:var(--shadow-sm);
  cursor:pointer;
  font-family:var(--body);
  white-space:nowrap;
  transition: transform var(--duration-standard) var(--ease-standard),
              box-shadow var(--duration-standard) var(--ease-standard),
              border-color var(--duration-standard) var(--ease-standard),
              opacity var(--duration-standard) var(--ease-standard),
              background var(--duration-standard) var(--ease-standard);
}
.levels-circle-node-num{
  font-family:var(--display);
  font-size:12px;
  color:var(--ink-50);
}
.levels-circle-node-name{
  font-size:13px;
  font-weight:500;
  color:var(--ink);
}
.levels-circle-node:hover,
.levels-circle-node:focus-visible{
  border-color:var(--aubergine);
  box-shadow:var(--shadow-md);
  transform:translate(-50%,-50%) scale(1.06);
  z-index:2;
}
.levels-circle-node.is-active{
  background:#FFFFFF;
  border-color:var(--aubergine);
  box-shadow:var(--shadow-md);
  transform:translate(-50%,-50%) scale(1.08);
  z-index:3;
}
.levels-circle-node.is-active .levels-circle-node-num{ color:var(--aubergine); }
.levels-circle-node-final{
  border-color:var(--aubergine);
  background:var(--sky);
}
.levels-circle-node-final .levels-circle-node-num{ color:var(--aubergine); }
.levels-circle-stage.has-active .levels-circle-node:not(.is-active){ opacity:.55; }
.levels-circle-detail-panel{ display:none; }
.levels-circle-detail-panel.is-active{
  display:block;
  animation: levelsFadeIn var(--duration-standard) var(--ease-standard);
}
.levels-circle-detail-panel .serif-num{ display:block; margin-bottom:8px; color:var(--aubergine); }
.levels-circle-detail-panel h4{ font-size:22px; margin-bottom:10px; }
.levels-circle-detail-panel p{ font-size:15px; line-height:1.6; color:var(--ink-70); }
.levels-circle-detail-example{
  margin-top:16px; padding-top:16px;
  border-top:1px solid var(--cream-line);
  font-size:14px !important;
}
@keyframes levelsFadeIn{
  from{ opacity:0; transform:translateY(4px); }
  to{ opacity:1; transform:translateY(0); }
}
@media (prefers-reduced-motion: reduce){
  .levels-circle-node{ transition:none !important; }
  .levels-circle-detail-panel.is-active{ animation:none !important; }
}
@media (max-width:860px){
  .levels-circle{ grid-template-columns:1fr; gap:32px; }
  .levels-circle-stage{ max-width:340px; }
  .levels-circle-node{ padding:7px 11px; min-height:36px; }
  .levels-circle-node-name{ font-size:11.5px; }
  .levels-circle-core{ max-width:100px; }
  .levels-circle-core-name{ font-size:15px; }
}

/* ---------- Sprint 22: exponential-complexity network diagrams ----------
   Two mathematically exact complete graphs (n·(n-1)/2 edges), not stock
   icons — 190 real chords for 20 nodes, 780 for 40. Low edge opacity keeps
   the denser graph legible as "much denser" rather than a solid block. */
.complexity-diagrams{
  display:grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--gutter);
  align-items:start;
  max-width: 760px;
}
.complexity-diagram{ text-align:center; }
.complexity-graph{ width:100%; height:auto; max-width:260px; }
.complexity-graph-edges-a line{ stroke: var(--sage-ink); stroke-width:.5; opacity:.16; }
.complexity-graph-edges-b line{ stroke: var(--aubergine); stroke-width:.4; opacity:.045; }
.complexity-graph-nodes circle{ fill: var(--ink); }
.complexity-diagram-label{ margin-top:18px; }
.complexity-diagram-num{ font-family:var(--display); font-size:clamp(30px,3.4vw,42px); line-height:1; }
.complexity-diagram-caption{ font-size:13px; color:var(--ink-50); margin-top:2px; }
.complexity-diagram-rel{ font-size:15px; font-weight:600; color:var(--sage-ink); margin-top:8px; }
@media (max-width:560px){
  .complexity-diagrams{ grid-template-columns:1fr; max-width:280px; margin-left:auto; margin-right:auto; }
}

/* ---------- Sprint 24: interactive complexity calculator ----------
   Personalizes the two static diagrams above: visitor drags a slider
   for their own headcount and sees live relationship count via the
   same n*(n-1)/2 formula, wired up in main.js. */
.complexity-calc{
  max-width: 620px;
  background: var(--off-white);
  border: 1px solid var(--cream-line);
  border-radius: var(--radius-lg);
  padding: 28px 28px 24px;
}
.complexity-calc-head{ display:flex; align-items:baseline; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.complexity-calc-label{ font-size:13px; font-weight:600; letter-spacing:.02em; text-transform:uppercase; color:var(--ink-50); }
.complexity-calc-readout{ display:flex; align-items:baseline; gap:6px; }
.complexity-calc-readout #complexityCalcCount{ font-family:var(--display); font-size:28px; color:var(--ink); }
.complexity-calc-unit{ font-size:13px; color:var(--ink-50); }
.complexity-calc-slider{
  width:100%; margin-top:18px; -webkit-appearance:none; appearance:none;
  height:4px; border-radius:2px; background:var(--cream-line); outline:none;
}
.complexity-calc-slider::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none; width:18px; height:18px; border-radius:50%;
  background:var(--accent-primary); cursor:pointer; border:3px solid var(--off-white); box-shadow:var(--shadow-sm);
}
.complexity-calc-slider::-moz-range-thumb{
  width:18px; height:18px; border-radius:50%; background:var(--accent-primary); cursor:pointer;
  border:3px solid var(--off-white); box-shadow:var(--shadow-sm);
}
.complexity-calc-result{ margin-top:20px; display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; }
.complexity-calc-result-num{ font-family:var(--display); font-size:clamp(30px,4vw,40px); color:var(--accent-primary); line-height:1; }
.complexity-calc-result-label{ font-size:14px; color:var(--ink-70); max-width:320px; }
.complexity-calc-bar{ margin-top:12px; height:8px; border-radius:4px; background:var(--cream-line); overflow:hidden; }
.complexity-calc-bar-fill{
  height:100%; border-radius:4px; background:linear-gradient(90deg, var(--sage-ink), var(--accent-primary));
  width:2%; transition:width .25s var(--ease-standard);
}

/* ---------- Sprint 27: privacy funnel (science.html) ----------
   Visualizes the access-control model described in the Privacy &
   Organisational Knowledge section: bar width narrows as information
   moves up the organisation, becoming more abstract, never more
   specific about any one person. */
.privacy-funnel{ display:flex; flex-direction:column; gap:16px; max-width:640px; }
.privacy-funnel-tier{ display:flex; align-items:center; gap:22px; }
.privacy-funnel-bar{ height:40px; border-radius:6px; background:linear-gradient(90deg, var(--sage-ink), var(--accent-primary)); flex:none; }
.privacy-funnel-tier-1 .privacy-funnel-bar{ width:280px; opacity:.55; }
.privacy-funnel-tier-2 .privacy-funnel-bar{ width:190px; opacity:.75; }
.privacy-funnel-tier-3 .privacy-funnel-bar{ width:110px; opacity:1; }
.privacy-funnel-label h4{ font-size:15px; margin-bottom:4px; }
.privacy-funnel-label p{ font-size:13px; color:var(--ink-70); max-width:360px; }
@media (max-width:640px){
  .privacy-funnel-tier{ flex-direction:column; align-items:flex-start; gap:8px; }
  .privacy-funnel-tier-1 .privacy-funnel-bar{ width:200px; }
  .privacy-funnel-tier-2 .privacy-funnel-bar{ width:140px; }
  .privacy-funnel-tier-3 .privacy-funnel-bar{ width:90px; }
}

/* ---------- Sprint 20: "Today vs. With AYVA" signature moment ----------
   One deliberate, larger-than-usual storytelling section: two lists in
   quiet contrast rather than a bordered table, so it reads as a single
   big idea instead of another data grid. Built entirely from existing
   tokens (colour, radius, duration) — no new palette or type scale. */
.today-vs-ayva{
  display:grid;
  grid-template-columns: 1fr auto 1fr;
  gap: var(--gutter);
  align-items:start;
}
.today-vs-ayva-col{ padding-top:4px; }
.today-vs-ayva-label{
  font-family: var(--display);
  font-size: clamp(22px, 2.6vw, 32px);
  color: var(--ink-50);
  margin-bottom:28px;
}
.today-vs-ayva-col-ayva .today-vs-ayva-label{ color: var(--sage-ink); }
.today-vs-ayva-list{
  display:flex;
  flex-direction:column;
  gap:22px;
  list-style:none;
  padding:0;
  margin:0;
}
.today-vs-ayva-list li{
  position:relative;
  padding:2px 10px 2px 30px;
  margin:0 -10px;
  border-radius:8px;
  font-size:clamp(15px,1.6vw,17px);
  line-height:1.5;
  color: var(--ink-50);
  opacity:0;
  transform: translateY(10px);
  transition: opacity .5s var(--ease-standard), transform .5s var(--ease-standard),
              background-color .2s var(--ease-standard);
}
.today-vs-ayva.in .today-vs-ayva-list li{ opacity:1; transform:none; }
.today-vs-ayva-list li:nth-child(1){ transition-delay:.05s; }
.today-vs-ayva-list li:nth-child(2){ transition-delay:.15s; }
.today-vs-ayva-list li:nth-child(3){ transition-delay:.25s; }
.today-vs-ayva-list li:nth-child(4){ transition-delay:.35s; }
.today-vs-ayva-list li:nth-child(5){ transition-delay:.45s; }
.today-vs-ayva-list li::before{
  content:"–";
  position:absolute;
  left:10px;
  top:2px;
  font-weight:700;
  color: var(--ink-30);
}
.today-vs-ayva-col-ayva .today-vs-ayva-list li{ color: var(--ink); font-weight:500; }
.today-vs-ayva-col-ayva .today-vs-ayva-list li::before{ content:"✓"; color: var(--sage-ink); }
/* Row pairing: hovering either side highlights both halves of that
   specific "today" -> "with AYVA" transformation, not just the row
   under the cursor — makes the 1:1 correspondence something you feel,
   not just something you read. */
.today-vs-ayva-list li.is-paired{ background: rgba(75,32,70,.05); }
.today-vs-ayva-col-ayva .today-vs-ayva-list li.is-paired{ background: rgba(75,107,63,.10); }
.today-vs-ayva-divider{
  width:1px;
  align-self:stretch;
  background: var(--cream-line);
}
@media (max-width:760px){
  .today-vs-ayva{ grid-template-columns:1fr; gap:40px; }
  .today-vs-ayva-divider{ width:100%; height:1px; }
}

/* ---------- Sticky-scroll: label pinned, content scrolls alongside ---------- */
.sticky-scroll{
  display:grid;
  grid-template-columns: minmax(220px, 0.85fr) 1.7fr;
  gap: var(--gutter);
  align-items:start;
}
.sticky-scroll-label{
  position: sticky;
  top: calc(var(--header-height) + 48px);
}
.sticky-scroll-content{ display:flex; flex-direction:column; gap: var(--space-6); }
@media (max-width:860px){
  .sticky-scroll{ grid-template-columns: 1fr; }
  .sticky-scroll-label{ position:static; }
}

/* ---------- Audience panel: used inside sticky-scroll for Manager/Employee ---------- */
.audience-panel{
  border: 1px solid var(--cream-line);
  border-radius: var(--radius-md);
  padding: var(--space-6);
  transition: border-color var(--duration-standard) var(--ease-standard), box-shadow var(--duration-standard) var(--ease-standard);
}
.audience-panel:hover{ border-color: var(--border-strong); box-shadow: var(--shadow-sm); }
.audience-panel-list{ margin-top: var(--space-4); display:flex; flex-direction:column; gap: var(--space-3); }
.audience-panel-list li{ display:flex; gap:10px; font-size:14.5px; color:var(--ink-70); line-height:1.5; text-wrap: pretty; }
.audience-panel-list li::before{ content:"—"; color:var(--sage-ink); flex:none; }

/* ---------- Outcomes list: qualitative shifts, no fabricated numbers ---------- */
.outcomes-grid{ display:grid; grid-template-columns:repeat(2,1fr); gap: var(--space-5) var(--gutter); }
.outcome-item{ display:flex; gap:16px; align-items:flex-start; }
.outcome-item .shell-mark{ margin-top:4px; flex:none; }
@media (max-width:700px){ .outcomes-grid{ grid-template-columns:1fr; } }

/* =========================================================
   AYVA EXPERT INTRO CARD
   One quiet, sitewide personal-invitation card. Replaces a
   classic "About the Founder" area — never a chat/support
   widget, never a modal, never intrusive. Shown by main.js
   after a real engagement signal (scroll depth, dwell time,
   or repeat product-page visits), dismissible once per
   session via sessionStorage.
   ========================================================= */
.expert-card{
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 850; /* below the fixed header (500) is irrelevant here since it
    sits at the bottom, but keep well above page content, below any future
    modal/overlay layer */
  width: 372px;
  max-width: calc(100vw - 32px);
  background: rgba(255,255,255,.82);
  backdrop-filter: blur(28px) saturate(1.3);
  -webkit-backdrop-filter: blur(28px) saturate(1.3);
  border: 1px solid rgba(255,255,255,.6);
  border-radius: var(--radius-xl);
  padding: 44px 36px 36px;
  box-shadow: 0 24px 70px rgba(13,13,13,.10), 0 4px 16px rgba(13,13,13,.05);
  opacity: 0;
  transform: translateY(14px) scale(.98);
  transition: opacity var(--duration-slow) var(--ease-standard),
              transform var(--duration-slow) var(--ease-standard),
              box-shadow var(--duration-standard) var(--ease-standard);
  pointer-events: none;
}
.expert-card.is-visible{
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}
.expert-card:hover{ box-shadow: 0 30px 80px rgba(13,13,13,.13), 0 6px 20px rgba(13,13,13,.06); }
.expert-card[hidden]{ display:none; }

.expert-card-close{
  position: absolute;
  top: 16px; right: 16px;
  width: 30px; height: 30px;
  display:flex; align-items:center; justify-content:center;
  border-radius: 50%;
  color: var(--ink-50);
  transition: background var(--duration-fast) ease, color var(--duration-fast) ease, transform var(--duration-fast) ease;
}
.expert-card-close:hover{ background: rgba(13,13,13,.06); color: var(--ink); transform: scale(1.06); }
.expert-card-close svg{ width:13px; height:13px; }

/* Sprint 12: redesigned from a horizontal "chat header" row (avatar left,
   name/title right) to a centred column — reads as a digital business
   card, not a message bubble. Close button stays absolutely positioned
   top-right, independent of this centred flow.
   Sprint 18: avatar sized up slightly, ring thinned to a single hairline
   (was a 3px solid ring + a 1px shadow ring stacked, which read heavier
   than intended), shadow softened and pulled apart into two layers for a
   more diffused, less "cut out" edge — same treatment direction as the
   card's own shadow below. */
.expert-card-top{ display:flex; flex-direction:column; align-items:center; text-align:center; gap:16px; }
.expert-card-avatar{
  width:104px; height:104px;
  border-radius:50%;
  object-fit:cover;
  object-position:center center;
  flex:none;
  background: var(--cream);
  border: 1px solid rgba(255,255,255,.9);
  box-shadow: 0 0 0 1px var(--cream-line), 0 10px 24px rgba(13,13,13,.08);
}
.expert-card-name{ font-family:var(--display); font-size:22px; line-height:1.2; }
.expert-card-title{ font-size:12px; color:var(--ink-50); line-height:1.5; margin-top:6px; letter-spacing:.01em; }

.expert-card-copy{ font-size:14.5px; line-height:1.6; color:var(--ink-70); margin-top:26px; text-align:center; }

.expert-card .btn{ width:100%; justify-content:center; margin-top:22px; }

@media (max-width:520px){
  .expert-card{
    right:16px; left:16px; bottom:16px;
    width:auto; max-width:none;
    padding: 30px 26px 26px;
  }
}

@media (prefers-reduced-motion: reduce){
  .expert-card{ transition: opacity var(--duration-fast) linear !important; transform:none; }
}

/* =========================================================
   SPRINT 6 — Journey scroll-story (how-it-works.html)
   A sticky, numbered rail tracks which of the six journey
   stages is currently in view (scroll-spy via IntersectionObserver
   in main.js) and fills a connecting progress line accordingly.
   No scroll-jacking: navigation is native <a href="#id"> anchor
   jumping (smooth via the global html{scroll-behavior:smooth},
   already reduced-motion-safe). Written generically enough to be
   reused by any future multi-stage narrative page.
   ========================================================= */
.journey-scroll-grid{
  display:grid;
  grid-template-columns: minmax(180px, 0.55fr) 1.9fr;
  gap: var(--gutter);
  align-items:start;
}
.journey-rail{
  position: sticky;
  top: calc(var(--header-height) + 56px);
}
.journey-rail-list{
  position: relative;
  list-style: none;
  padding-left: 28px;
  display:flex; flex-direction:column; gap:30px;
}
.journey-rail-track{
  position:absolute; left:8px; top:6px; bottom:6px; width:1px;
  background: var(--cream-line);
}
.journey-rail-fill{
  position:absolute; left:0; top:0; width:100%; height:0%;
  background: var(--sage);
  transition: height .6s var(--ease-standard);
}
.journey-rail-item{ position:relative; }
.journey-rail-link{
  display:flex; flex-direction:column; gap:2px;
  font-size:13.5px; color: var(--ink-50);
  transition: color var(--duration-standard) var(--ease-standard);
}
.journey-rail-link:hover{ color: var(--ink); }
.journey-rail-num{ font-family:var(--display); font-size:12px; color:inherit; }
.journey-rail-dot{
  position:absolute; left:-24px; top:4px; width:9px; height:9px; border-radius:50%;
  background: var(--off-white); border:2px solid var(--cream-line);
  transition: background var(--duration-standard) var(--ease-standard), border-color var(--duration-standard) var(--ease-standard), transform var(--duration-standard) var(--ease-standard);
}
.journey-rail-item.is-active .journey-rail-link{ color: var(--ink); }
.journey-rail-item.is-active .journey-rail-dot{
  background: var(--sage); border-color: var(--sage); transform:scale(1.3);
}

.journey-stages{ display:flex; flex-direction:column; gap: var(--space-9); }
.journey-stage{ scroll-margin-top: calc(var(--header-height) + 32px); max-width: 620px; }
.journey-stage-num{ font-family:var(--display); font-size:15px; color:var(--sage-ink); }
.journey-stage h3{ margin-top:10px; }
.journey-stage p{ margin-top:14px; }
.journey-stage .status-tag{ margin-top:18px; }

.journey-examples{
  margin-top: var(--space-6);
  display:grid; grid-template-columns:repeat(3,1fr); gap: var(--space-4);
  max-width: none;
}
.journey-example{
  border:1px solid var(--cream-line); border-radius: var(--radius-md);
  padding: var(--space-5); transition: border-color var(--duration-standard) var(--ease-standard), box-shadow var(--duration-standard) var(--ease-standard);
}
.journey-example:hover{ border-color: var(--border-strong); box-shadow: var(--shadow-sm); }
.journey-example h5{ font-family:var(--display); font-size:16px; }
.journey-example p{ font-size:13.5px; color:var(--ink-70); line-height:1.5; margin-top:8px; }

@media (max-width:860px){
  .journey-scroll-grid{ grid-template-columns:1fr; }
  .journey-rail{ position:static; margin-bottom: var(--space-6); }
  .journey-rail-list{
    flex-direction:row; padding-left:0; gap: var(--space-6);
    overflow-x:auto; -webkit-overflow-scrolling:touch;
    padding-bottom: 4px;
  }
  .journey-rail-track, .journey-rail-dot{ display:none; }
  /* Sprint 13: the link itself carried no padding — its tap target was
     just the text's own line height. Vertical padding brings it to a
     real touch target without changing the row's visual density (the
     36px scroll-list gap already provided most of the mis-tap safety
     margin between adjacent items). */
  .journey-rail-link{ flex-direction:row; gap:6px; white-space:nowrap; padding:12px 2px; }
  .journey-examples{ grid-template-columns:1fr; }
}
@media (prefers-reduced-motion: reduce){
  .journey-rail-fill, .journey-rail-dot, .journey-rail-link{ transition: none !important; }
}

/* =========================================================
   SPRINT 8 — The AYVA Experience (experience.html)
   A cinematic, low-copy scroll-story: a sequence of "moments"
   (.moment), each pairing a short headline with a small,
   illustrative "concept snippet" (.snippet-frame + variant).
   Snippets are deliberately abstracted, brand-coloured concept
   visualisations — not literal product screenshots — consistent
   with the sitewide rule of never presenting unbuilt
   functionality as a finished screen.
   ========================================================= */

/* ---------- Scroll progress fill (page-scoped: only present when
   experience.html injects #experienceProgressFill into its own
   .accent-bar; every other page's .accent-bar is untouched) ---------- */
.accent-bar-fill{
  height:100%; width:0%;
  background: var(--sage);
}

/* ---------- Actor tag: which side of Human+AI is acting ---------- */
.moment-actor{
  display:inline-flex; align-items:center; gap:7px;
  font-size:11.5px; letter-spacing:.04em; text-transform:uppercase;
  color: var(--ink-50);
}
.moment-actor::before{ content:""; width:7px; height:7px; border-radius:50%; flex:none; }
.moment-actor-ai::before{ background: var(--sage); }
.moment-actor-human::before{ background: var(--accent-primary); }

/* ---------- Moment: one beat of the story ---------- */
.moment{
  padding: var(--space-9) 0;
  display:grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--gutter);
  align-items:center;
}
.moment-text{ max-width: 460px; }
.moment-index{ font-family:var(--display); font-size:14px; color: var(--sage-ink); }
.moment-title{ font-family:var(--display); font-size:clamp(28px,3.6vw,46px); line-height:1.1; margin-top:12px; }
.moment-copy{ font-size:16px; line-height:1.55; color:var(--ink-70); margin-top:16px; max-width:400px; text-wrap: pretty; }
.moment-visual{ display:flex; justify-content:center; }
.moment:nth-child(even) .moment-visual{ order:-1; }

@media (max-width:860px){
  .moment{ grid-template-columns:1fr; padding: var(--space-7) 0; text-align:left; }
  .moment:nth-child(even) .moment-visual{ order:0; }
  .moment-text{ max-width:none; }
  .moment-visual{ margin-top: var(--space-5); }
}

/* ---------- Snippet frame: shared base for every concept visualisation ---------- */
.snippet-frame{
  background:#FFFFFF;
  border:1px solid var(--cream-line);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-md);
  width: 100%;
  max-width: 360px;
  transition: transform var(--duration-standard) var(--ease-standard), box-shadow var(--duration-standard) var(--ease-standard);
}
.snippet-frame:hover{ transform: translateY(-4px); box-shadow: var(--shadow-lg); }

/* Welcome */
.snippet-welcome{ text-align:center; padding: var(--space-6) var(--space-5); }
.snippet-welcome .shell-mark{ width:32px; height:32px; margin:0 auto; }
.snippet-welcome-text{ font-family:var(--display); font-size:20px; margin-top:16px; }
.snippet-welcome-sub{ font-size:13.5px; color:var(--ink-50); margin-top:6px; }

/* Chat / check-in */
.snippet-chat{ display:flex; flex-direction:column; gap:10px; }
.snippet-bubble{ font-size:13.5px; line-height:1.5; padding:12px 14px; border-radius: var(--radius-md); max-width:88%; }
.snippet-bubble-user{ align-self:flex-end; background: var(--cream); color:var(--ink); border-bottom-right-radius:4px; }
.snippet-bubble-ai{ align-self:flex-start; background: var(--off-white); border:1px solid var(--cream-line); color:var(--ink-70); border-bottom-left-radius:4px; }

/* Calendar */
.snippet-calendar{ padding: var(--space-5); }
.snippet-calendar-row{ display:flex; justify-content:space-between; font-size:11px; color:var(--ink-30); text-transform:uppercase; letter-spacing:.05em; }
.snippet-calendar-slots{ margin-top:14px; display:flex; flex-direction:column; gap:8px; }
.snippet-calendar-slot{ font-size:13px; color:var(--ink-50); padding:10px 12px; border-radius: var(--radius-sm); border:1px solid var(--cream-line); }
.snippet-calendar-slot.is-active{ background: rgba(168,182,154,.18); border-color: var(--sage); color:var(--sage-ink); font-weight:600; }

/* Insight (abstract proportions only — never a claimed statistic) */
.snippet-insight{ padding: var(--space-5); }
.snippet-insight-label{ font-size:12.5px; color:var(--ink-50); text-transform:uppercase; letter-spacing:.05em; }
.snippet-insight-bars{ margin-top:16px; display:flex; align-items:flex-end; gap:10px; height:64px; }
/* Sprint 12: bars now grow in on reveal instead of appearing at full
   height instantly — "diagrams build themselves in" (staggered per bar
   via nth-child delays so they don't all land in lockstep). */
.snippet-insight-bars span{
  display:block; width:100%; height:0; background: var(--sage); border-radius: 3px 3px 0 0;
  transition: height 1s var(--ease-standard) .1s;
}
[data-reveal].in .snippet-insight-bars span{ height:var(--w,40%); }
.snippet-insight-bars span:nth-child(2){ background: var(--accent-primary); opacity:.75; transition-delay:.22s; }
.snippet-insight-bars span:nth-child(3){ transition-delay:.34s; }
@media (prefers-reduced-motion: reduce){
  .snippet-insight-bars span{ transition:none !important; height:var(--w,40%) !important; }
}

/* Session (nested compact process-flow reuse) */
.snippet-session .process-flow{ flex-direction:column; align-items:flex-start; gap:0; }
.snippet-session .process-step{ padding:12px 0 12px 18px; border-left:2px solid var(--cream-line); position:relative; align-self:stretch; }
.snippet-session .process-step:first-child{ padding-top:0; }
.snippet-session .process-step:last-child{ padding-bottom:0; }
.snippet-session .process-step::before{
  content:""; position:absolute; left:-5px; top:14px; width:8px; height:8px; border-radius:50%; background:var(--sage);
}
.snippet-session .process-step:first-child::before{ top:2px; }
.snippet-session .process-step h4{ font-size:14.5px; }
.snippet-session .process-line{ display:none; }

/* Cycle motif (kept deliberately simple: one large shell mark) */
.snippet-cycle{ text-align:center; }
.snippet-cycle .shell-mark{ width:44px; height:44px; margin:0 auto; }
.snippet-cycle-label{ font-size:13px; color:var(--ink-50); margin-top:14px; }

@media (prefers-reduced-motion: reduce){
  .snippet-frame{ transition:none !important; }
}

/* =========================================================
   SPRINT 10 — Premium Motion Design & Microinteractions
   No new content. Formalises the motion language already in use
   across Sprints 1–9 and adds a small number of purposeful,
   previously-missing pieces: a guarded page-exit transition and a
   real success state on the contact form button. See
   DESIGN_SYSTEM.md "Motion Language" for the naming system these
   map to.
   ========================================================= */

/* ---------- Page transition: exit ----------
   Entrance already existed (body{ animation: bodyIn … }). This is
   the missing exit half: a very brief, guarded fade+lift applied
   to <body> right before an internal navigation (see main.js —
   heavily whitelisted, skips entirely under reduced motion). */
body.is-leaving{
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity .16s var(--ease-standard), transform .16s var(--ease-standard);
}

/* ---------- Button success state (contact form) ---------- */
.btn.is-success{
  background: var(--success);
  border-color: var(--success);
  color: #fff;
  pointer-events:none;
  transition: background var(--duration-standard) var(--ease-standard), border-color var(--duration-standard) var(--ease-standard), color var(--duration-standard) var(--ease-standard);
}

@media (prefers-reduced-motion: reduce){
  body.is-leaving{ transition: opacity .05s linear !important; transform:none !important; }
}

/* =========================================================
   SPRINT 13 — Mobile Excellence & Responsive Experience
   No new content. A touch/mobile-specific pass on top of every
   earlier sprint's existing responsive work: touch feedback for
   cards that only had :hover states, safe-area awareness for
   fixed/full-bleed elements, and a lighter motion profile on
   touch devices generally. See DESIGN_SYSTEM.md "Mobile" for the
   reasoning and SPRINT_13_REPORT.md for the full change list.
   ========================================================= */

/* ---------- Touch feedback for hover-only cards ----------
   `:hover` on a touch device either never fires or fires-and-sticks
   after a tap, so it's not real feedback. `@media (hover:none)` only
   matches actual touch/stylus input — mouse users keep the original
   :hover lift untouched, this never overrides it. */
@media (hover:none) and (pointer:coarse){
  .feature-card:active,
  .card-product:active,
  .card-interactive:active,
  .testimonial-card:active,
  .journey-example:active,
  .snippet-frame:active,
  .card-insight:active{
    transform: scale(.98);
    transition-duration: .12s;
  }
  .pillar-card:active{ padding-left:10px; }
  /* Hover-driven reveals that have no touch equivalent (nav dropdown,
     cursor-dot) are already gated elsewhere by (hover:hover) and
     (pointer:fine) respectively, so nothing further to guard here. */
}

/* ---------- Safe-area padding for fixed full-bleed chrome ----------
   Header and skip-link are fixed/absolute and can sit under a notch or
   Dynamic Island in landscape; the mobile menu already got its own
   4-edge inset above. Bottom-fixed elements, if any future sprint adds
   one (e.g. a sticky mobile CTA bar), should follow the same pattern. */
.site-header{ padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); }
.skip-link{ left: calc(16px + env(safe-area-inset-left)); }

/* ---------- Lighter motion profile on touch devices ----------
   Not the same as prefers-reduced-motion (a user preference we already
   respect everywhere) — this is a perf/feel choice: the large reveal
   travel distance and long hero-visual assembly delays read as
   "premium" on a desktop trackpad-scroll but can feel sluggish on a
   phone where sections arrive faster under a thumb-flick. Shortens
   distances/durations only; never disables the motion outright. */
@media (max-width:860px){
  [data-reveal]{ transform: translateY(16px); transition-duration: .7s; }
  .hero-visual-mobile, .mobile-menu > a, .mobile-menu > .mobile-menu-label, .mobile-menu .mobile-foot{ will-change:auto; }
}
