/* ============================================================
   ADERERA — Design System
   Derived from the Aderera BrandBook (palette, type, nautilus grid)
   ============================================================ */

/* ---------- 1. Fonts ---------- */
@font-face {
  font-family: 'Celine Sans';
  src: url('../fonts/CelineSans.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* ---------- 2. Tokens ---------- */
:root {
  /* Brand palette — brandbook slide 10 */
  --forest:      #416F3B;
  --forest-deep: #33582E;
  --forest-soft: #5A8551;
  --pistachio:   #85B04E;
  --cream:       #FFF1E8;
  --buttercream: #F2E9CC;
  --ink:         #392717;
  --off-white:   #F9F9F9;
  --near-black:  #1B1B1B;

  /* Semantic */
  --bg:          var(--cream);
  --surface:     var(--off-white);
  --text:        var(--ink);
  --text-muted:  #6B5A48;
  --accent:      var(--forest);      /* graphic accent  */
  --accent-text: var(--forest);      /* accent used as small text (AA) */
  --accent-2:    #709442;            /* pistachio, darkened for large text on light */
  --line:        rgba(57, 39, 23, 0.14);
  --line-strong: rgba(57, 39, 23, 0.26);

  /* Brand gradient — brandbook slide 10 */
  --grad-brand:    linear-gradient(180deg, var(--forest) 0%, var(--forest-soft) 38%, #A7B884 68%, var(--buttercream) 100%);
  --grad-brand-up: linear-gradient(0deg,   var(--forest) 0%, var(--forest-soft) 38%, #A7B884 68%, var(--buttercream) 100%);

  /* Typefaces */
  --font-display: 'Celine Sans', 'Optima', 'Didot', 'Georgia', serif;
  --font-sub:     'Montserrat', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-body:    'Montserrat', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* Type scale — anchored to brandbook 128 / 36 / 16 px */
  --fs-hero:  clamp(3rem, 8.6vw, 8.25rem);
  --fs-d1:    clamp(2.5rem, 7.2vw, 7rem);
  --fs-d2:    clamp(2.125rem, 4.8vw, 4.25rem);
  --fs-d3:    clamp(1.75rem, 3.4vw, 3rem);
  --fs-sub:   clamp(1.25rem, 2.3vw, 2.25rem); /* 36px */
  --fs-lead:  clamp(1.0625rem, 1.35vw, 1.25rem);
  --fs-body:  1rem;                           /* 16px */
  --fs-sm:    0.875rem;
  --fs-label: 0.6875rem;

  /* Fibonacci spacing — the nautilus grows by the same rule */
  --s-1:  0.3125rem;  /*  5px */
  --s-2:  0.5rem;     /*  8px */
  --s-3:  0.8125rem;  /* 13px */
  --s-4:  1.3125rem;  /* 21px */
  --s-5:  2.125rem;   /* 34px */
  --s-6:  3.4375rem;  /* 55px */
  --s-7:  5.5625rem;  /* 89px */
  --s-8:  9rem;       /* 144px */
  --s-9:  14.5625rem; /* 233px */

  /* Grid — 13 columns (Fibonacci), golden split at 5 / 8 */
  --wrap:  84rem;   /* 1344px */
  --gutter: var(--s-4);
  --pad-x: clamp(var(--s-4), 5vw, var(--s-6));
  --section-y: clamp(var(--s-6), 9vw, var(--s-8));

  /* Motion */
  --ease:      cubic-bezier(0.22, 1, 0.36, 1);
  --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
  --dur-fast: 180ms;
  --dur:      320ms;
  --dur-slow: 720ms;

  --radius: 2px;
  --z-nav: 50;
  --z-float: 40;
  --z-overlay: 60;
}

/* Dark-on-green sections invert the semantic layer */
.is-forest {
  --bg: var(--forest);
  --text: var(--cream);
  --text-muted: rgba(255, 241, 232, 0.92);
  --line: rgba(255, 241, 232, 0.22);
  --line-strong: rgba(255, 241, 232, 0.42);
  --accent: #B9D299;                 /* pistachio lifted for 3:1 on forest */
  --accent-text: #DDE9CE;            /* AA for small text on forest */
  --accent-2: #B9D299;
  --surface: rgba(27, 27, 27, 0.10);
}
.is-ink {
  --bg: var(--near-black);
  --text: var(--cream);
  --text-muted: rgba(255, 241, 232, 0.8);
  --line: rgba(255, 241, 232, 0.18);
  --line-strong: rgba(255, 241, 232, 0.36);
  --accent: var(--pistachio);        /* 6.82:1 on #1B1B1B — brand green, unmodified */
  --accent-text: var(--pistachio);
  --accent-2: var(--pistachio);
  --surface: rgba(255, 241, 232, 0.05);
}
.is-cream { --bg: var(--cream); }
.is-white { --bg: var(--off-white); }
.is-butter {
  --bg: var(--buttercream);
  --surface: rgba(255, 255, 255, 0.55);
  --line: rgba(57, 39, 23, 0.16);
  --line-strong: rgba(57, 39, 23, 0.3);
  --accent-2: #5F7F38;               /* darkened: #709442 is only 2.9:1 here */
}

/* ---------- 3. Reset & base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.65;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}
img, svg, video { max-width: 100%; display: block; }
img { height: auto; }
h1, h2, h3, h4, h5 { margin: 0; font-weight: 400; line-height: 1.02; }
figure, blockquote { margin: 0; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; }
/* The ring follows the ground like everything else. Fixed pistachio was 2.3:1
   on cream — fine on the old dark hero, illegal on this light one — whereas
   --accent is forest on light (6.4:1), lifted pistachio on forest (3:1) and
   brand pistachio on near-black (6.8:1). */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}
::selection { background: var(--pistachio); color: var(--ink); }

.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;
}
.skip-link {
  position: absolute; top: var(--s-3); left: var(--s-3); z-index: 999;
  transform: translateY(-200%);
  background: var(--forest); color: var(--cream);
  padding: var(--s-3) var(--s-4);
  font: 600 var(--fs-sm)/1 var(--font-body); letter-spacing: 0.04em;
  transition: transform var(--dur) var(--ease);
}
.skip-link:focus { transform: translateY(0); }

/* ---------- 4. Layout ---------- */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--pad-x);
}
.wrap--wide { max-width: 96rem; }

.section {
  position: relative;
  background: var(--bg);
  color: var(--text);
  padding-block: var(--section-y);
  overflow: clip;
}
.section--flush { padding-block: 0; }
.section--tight { padding-block: clamp(var(--s-6), 6vw, var(--s-7)); }

/* 13-column Fibonacci grid */
.g13 {
  display: grid;
  grid-template-columns: repeat(13, minmax(0, 1fr));
  gap: var(--gutter);
}
.c-1  { grid-column: span 1; }  .c-2  { grid-column: span 2; }
.c-3  { grid-column: span 3; }  .c-4  { grid-column: span 4; }
.c-5  { grid-column: span 5; }  .c-6  { grid-column: span 6; }
.c-7  { grid-column: span 7; }  .c-8  { grid-column: span 8; }
.c-9  { grid-column: span 9; }  .c-13 { grid-column: span 13; }
.start-6 { grid-column-start: 6; }
.start-7 { grid-column-start: 7; }
.start-9 { grid-column-start: 9; }

/* The golden pair: 5 | 8 */
.phi {
  display: grid;
  grid-template-columns: 5fr 8fr;
  gap: clamp(var(--s-5), 5vw, var(--s-7));
  align-items: start;
}
.phi--flip { grid-template-columns: 8fr 5fr; }

.sticky-media { position: sticky; top: calc(var(--s-7) + var(--s-4)); align-self: start; }
@media (max-width: 960px) { .sticky-media { position: static; } }

.stack   { display: grid; gap: var(--s-4); }
.stack-5 { display: grid; gap: var(--s-5); }
.stack-6 { display: grid; gap: var(--s-6); }
.row     { display: flex; flex-wrap: wrap; gap: var(--s-4); align-items: center; }

/* ---------- 5. Typography ---------- */
.display {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: 0.005em;
  line-height: 0.92;
  text-transform: uppercase;
}
.display--hero { font-size: var(--fs-hero); letter-spacing: -0.005em; }
.d1 { font-size: var(--fs-d1); }
.d2 { font-size: var(--fs-d2); }
.d3 { font-size: var(--fs-d3); }

.sub {
  font-family: var(--font-sub);
  font-size: var(--fs-sub);
  line-height: 1.22;
  font-weight: 600;
}
.lead {
  font-size: var(--fs-lead);
  line-height: 1.62;
  color: var(--text-muted);
  max-width: 46ch;
}
.body-text { max-width: 62ch; color: var(--text-muted); }
.body-text + .body-text { margin-top: var(--s-4); }
.small { font-size: var(--fs-sm); color: var(--text-muted); }

/* Eyebrow with the brandbook bracket marker */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text);
  line-height: 1;
}
.eyebrow::before {
  content: '';
  width: 10px;
  height: 1.6em;
  border: 1px solid currentColor;
  border-right: 0;
  opacity: 0.85;
  flex: none;
}
.eyebrow--muted { color: var(--text-muted); }

/* Emphasis colour inside display headings */
.tint     { color: var(--accent); }
.tint-2   { color: var(--accent-2); }
.outline-text {
  color: transparent;
  -webkit-text-stroke: 1px currentColor;
  paint-order: stroke fill;
}
.is-forest .outline-text, .is-ink .outline-text { -webkit-text-stroke-color: rgba(255, 241, 232, 0.55); }

/* Signature footer line used on brand collateral */
.signature {
  font-family: var(--font-sub);
  font-weight: 600;
  font-size: var(--fs-sm);
  letter-spacing: 0.02em;
  color: var(--text-muted);
}

/* ---------- 6. Rules & ornaments ---------- */
.rule { height: 1px; background: var(--line); border: 0; margin: 0; }
.rule--strong { background: var(--line-strong); }

/* Colourable SVG shapes — masked so they inherit currentColor */
.mask {
  background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center;  mask-position: center;
  -webkit-mask-size: contain;     mask-size: contain;
}
.mask--mark   { -webkit-mask-image: url('../img/mark.svg');        mask-image: url('../img/mark.svg');        aspect-ratio: 425 / 328; }
.mask--word   { -webkit-mask-image: url('../img/wordmark.svg');    mask-image: url('../img/wordmark.svg');    aspect-ratio: 1563 / 298; }
.mask--lockup { -webkit-mask-image: url('../img/logo-lockup.svg'); mask-image: url('../img/logo-lockup.svg'); aspect-ratio: 2042 / 453; }

/* Oversized ghosted petal watermark (brandbook applications) */
.watermark {
  position: absolute;
  pointer-events: none;
  opacity: 0.04;
  width: min(46rem, 64vw);
  z-index: 0;
}
.is-forest .watermark, .is-ink .watermark { opacity: 0.1; }
.watermark--tr { top: -8%; right: -14%; }
.watermark--bl { bottom: -16%; left: -22%; }
.watermark--br { bottom: -18%; right: -12%; }

.section > .wrap { position: relative; z-index: 1; }

/* ---------- 7. Buttons ---------- */
.btn {
  --btn-bg: var(--forest);
  --btn-fg: var(--cream);
  --btn-bd: var(--forest);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  gap: var(--s-3);
  padding: 1.0625rem var(--s-5);
  min-height: 3.25rem;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid var(--btn-bd);
  border-radius: var(--radius);
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
/* Wipe fill on hover — no transform, so no layout shift */
.btn::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--pistachio);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-slow) var(--ease);
  z-index: -1;
}
.btn:hover::after, .btn:focus-visible::after { transform: scaleX(1); }
.btn:hover { color: var(--ink); border-color: var(--pistachio); }

.btn--ghost { --btn-bg: transparent; --btn-fg: var(--text); --btn-bd: var(--line-strong); }
.btn--ghost:hover { color: var(--ink); }
.btn--light { --btn-bg: var(--cream); --btn-fg: var(--forest); --btn-bd: var(--cream); }
.btn--pistachio { --btn-bg: var(--pistachio); --btn-fg: var(--ink); --btn-bd: var(--pistachio); }
.btn--pistachio::after { background: var(--cream); }
.btn--sm { padding: 0.75rem var(--s-4); min-height: 2.75rem; }
.btn--block { width: 100%; }

/* Text link with animated underline */
.link {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  padding-block: 0.25em;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 0% 1px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  transition: background-size var(--dur) var(--ease), color var(--dur) var(--ease);
}
.link:hover { background-size: 100% 1px; color: var(--accent-text); }
.link svg { width: 1.05em; height: 1.05em; flex: none; transition: transform var(--dur) var(--ease); }
.link:hover svg { transform: translateX(4px); }

/* ---------- 8. Header / navigation ---------- */
/* Always pinned. The header never translates away on scroll — only its
   backdrop firms up once the page has moved (.is-solid). */
.header {
  position: fixed;
  inset: var(--s-3) var(--s-3) auto;
  z-index: var(--z-nav);
}
.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding: 0.75rem 0.75rem 0.75rem var(--s-4);
  background: rgba(255, 241, 232, 0.82);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  backdrop-filter: blur(14px) saturate(1.4);
  border-radius: var(--radius);
  box-shadow: 0 10px 30px -26px rgba(57, 39, 23, 0.4);
  transition: background-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.header.is-solid .header__inner {
  background: rgba(255, 241, 232, 0.95);
  box-shadow: 0 14px 44px -26px rgba(57, 39, 23, 0.6);
}

.brand { display: inline-flex; align-items: center; gap: var(--s-3); color: var(--forest); }
.brand__mark { width: 2.5rem; flex: none; }
.brand__word { width: 6.75rem; flex: none; }

.header__end { display: flex; align-items: center; gap: var(--s-3); }

/* Language switcher */
.lang { display: inline-flex; align-items: center; gap: var(--s-2); }
.lang__opt {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.25rem;
  min-height: 2.25rem;
  padding: 0 0.35rem;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  line-height: 1;
  color: var(--text-muted);
  border-radius: var(--radius);
  transition: color var(--dur) var(--ease);
}
a.lang__opt { cursor: pointer; }
a.lang__opt:hover { color: var(--forest); }
.lang__opt.is-active { color: var(--forest); }
.lang__opt.is-soon { opacity: 0.42; cursor: not-allowed; }
.lang__sep { width: 1px; height: 0.875rem; background: var(--line-strong); flex: none; }

.nav { display: flex; align-items: center; gap: var(--s-2); }
.nav__link {
  position: relative;
  padding: 0.7rem var(--s-3);
  font-size: 0.9375rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.11em;
  color: var(--ink);
  border-radius: var(--radius);
  transition: color var(--dur) var(--ease);
}
.nav__link::after {
  content: '';
  position: absolute;
  left: var(--s-3);
  right: var(--s-3);
  bottom: 0.45rem;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}
.nav__link:hover { color: var(--forest); }
.nav__link:hover::after { transform: scaleX(1); }
.nav__link[aria-current='page'] { color: var(--forest); }
.nav__link[aria-current='page']::after { transform: scaleX(1); background: var(--pistachio); }

.nav__has-sub { position: relative; display: flex; align-items: center; }
.nav__sub {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 50%;
  /* closed state: flattened against its top edge, so opening unrolls it
     downward out of the trigger */
  transform: translateX(-50%) scaleY(0.6);
  transform-origin: top center;
  /* Two columns: five platforms sit as a block the eye takes in at once
     rather than a column it has to read down. Centred on the trigger,
     because at this width anchoring left pushed it off toward Cases. */
  display: grid;
  grid-template-columns: repeat(2, minmax(11.5rem, 1fr));
  gap: 2px;
  width: max-content;
  padding: var(--s-3);
  background: var(--cream);
  border-radius: var(--radius);
  box-shadow: 0 18px 48px -24px rgba(57, 39, 23, 0.55);
  opacity: 0;
  visibility: hidden;
  /* visibility flips instantly on open, and only waits for the fade on close */
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease),
              visibility 0s linear var(--dur);
}
/* Bridge the visual gap between the trigger and the panel. Without this the
   pointer leaves .nav__has-sub on its way down and the menu closes. */
.nav__sub::before {
  content: '';
  position: absolute;
  left: 0; right: 0;
  bottom: 100%;
  height: 0.75rem;
}
/* Opened by click (see header() in aderera.js). It unrolls downward from
   its own top edge rather than sliding in from a side — the panel belongs
   to the trigger above it, so that is the direction it should grow. */
/* A click target needs to look like one: the chevron says the item opens
   rather than navigates, and turns to say it is open. */
.nav__has-sub > .nav__link { cursor: pointer; padding-right: calc(var(--s-3) + 0.7rem); }
.nav__has-sub > .nav__link::before {
  content: '';
  position: absolute;
  right: var(--s-3);
  top: 50%;
  width: 5px; height: 5px;
  margin-top: -3px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  transform-origin: center;
  opacity: 0.6;
  transition: transform var(--dur-fast) var(--ease), opacity var(--dur-fast) var(--ease);
}
.nav__has-sub.is-open > .nav__link::before {
  transform: rotate(-135deg);
  margin-top: -1px;
  opacity: 1;
}

.nav__has-sub.is-open .nav__sub {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) scaleY(1);
  transition: opacity 160ms var(--ease), transform var(--dur) var(--ease), visibility 0s;
}
.nav__sub a {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: 0.6rem var(--s-3);
  font-size: 0.8125rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  white-space: nowrap;
  border-radius: var(--radius);
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.nav__sub a:hover { background: rgba(65, 111, 59, 0.1); color: var(--forest); }

.nav__ico {
  width: 1.35rem; height: 1.35rem;
  flex: none;
  color: var(--forest);
  stroke-width: 1.2;
  opacity: 0.75;
  transition: opacity var(--dur-fast) var(--ease);
}
.nav__sub a:hover .nav__ico { opacity: 1; }

/* the catch-all runs the full width under the five platforms */
.nav__sub-all {
  grid-column: 1 / -1;
  margin-top: var(--s-2);
  padding-top: var(--s-2);
  border-top: 1px solid var(--line);
}
.nav__sub-all a { justify-content: space-between; color: var(--forest); }
.nav__ico--arrow { width: 1rem; height: 1rem; opacity: 0.55; }

[data-cta-desktop] { display: none; }
@media (min-width: 1260px) { [data-cta-desktop] { display: inline-flex !important; } }

.burger {
  display: none;
  position: relative;
  width: 2.75rem; height: 2.75rem;
  cursor: pointer;
  border-radius: var(--radius);
}
/* Bars are absolutely centred so the open state is an exact cross, whatever
   the surrounding layout does. */
.burger span {
  position: absolute;
  top: 50%; left: 50%;
  width: 18px; height: 1.5px;
  background: var(--ink);
  transform: translate(-50%, -50%) translateY(var(--y, 0));
  transition: transform var(--dur) var(--ease), opacity var(--dur-fast) var(--ease);
}
.burger span:nth-child(1) { --y: -6px; }
.burger span:nth-child(3) { --y: 6px; }
.burger[aria-expanded='true'] span:nth-child(1) { transform: translate(-50%, -50%) rotate(45deg); }
.burger[aria-expanded='true'] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded='true'] span:nth-child(3) { transform: translate(-50%, -50%) rotate(-45deg); }

/* ---------- 9. Hero ---------- */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding-block: calc(var(--s-7) + var(--s-5)) var(--s-6);
  background: var(--cream);
  overflow: clip;
}
.hero__grid { display: grid; grid-template-columns: 8fr 5fr; gap: clamp(var(--s-5), 4vw, var(--s-7)); align-items: end; width: 100%; }
.hero__title { color: var(--forest); }
.hero__title .l { display: block; }

/* =========================================================================
   Editorial hero — the room and the page are one surface.

   The photograph is high-key: the wall measures 223-241 in every channel and
   the left third of the frame is empty. So there is no scrim here. A *light*
   wash carries the page's own cream into the picture from the left, is gone
   by 62% — exactly where she begins — and the type sits on the wall in brand
   forest at 6.4:1. The previous hero darkened the whole photograph to rescue
   white type; this one keeps the daylight and changes the ink instead.

   One column, not three anchors. Everything the visitor reads lives in the
   left 8/13 — the site's own golden split — and the right 5/13 is the room.
   ========================================================================= */
.hero-ed {
  position: relative;
  min-height: 100svh;
  max-height: 1040px;
  display: flex;
  isolation: isolate;
  background: var(--cream);
  overflow: clip;
}
.hero-ed__media { position: absolute; inset: 0; z-index: 0; }
.hero-ed__media picture,
.hero-ed__img {
  display: block;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 58% 40%;
}
/* the wash — cream, not shadow */
.hero-ed__media::after {
  content: '';
  position: absolute; inset: 0;
  background:
    linear-gradient(97deg,
      var(--cream) 0%,
      rgba(255, 241, 232, 0.97) 13%,
      rgba(255, 241, 232, 0.82) 27%,
      rgba(255, 241, 232, 0.48) 42%,
      rgba(255, 241, 232, 0.16) 54%,
      rgba(255, 241, 232, 0) 62%),
    /* the floor and the chair edge at the bottom-left run a stop darker than
       the wall; this lifts them so the footer strip keeps its 6.5:1 */
    radial-gradient(116% 62% at 2% 104%,
      rgba(255, 241, 232, 0.94) 0%,
      rgba(255, 241, 232, 0.38) 44%,
      rgba(255, 241, 232, 0) 72%);
}

.hero-ed__inner {
  position: relative;
  z-index: 1;
  width: min(100% - var(--pad-x) * 2, var(--wrap));
  margin-inline: auto;
  padding-block: calc(var(--header-h, 5.25rem) + var(--s-5)) var(--s-5);
  display: grid;
  grid-template-columns: 8fr 5fr;          /* the same 5/8 the rest of the site uses */
  grid-template-rows: 1fr auto;
  gap: var(--s-5) var(--gutter);
}
.hero-ed__col {
  grid-column: 1;
  grid-row: 1;
  align-self: center;
  display: grid;
  justify-items: start;
  gap: var(--s-5);
}

/* ---- the mark, behind the column and on top of the room ----
   The mark is positioned by its *eye*, not by its box. In mark.svg the spiral
   eye sits at 50% / 43.6% of the viewBox, the petals grow outward from it, and
   the largest of them fan to the right — the same direction the headline runs
   and the same direction the headline grows (line two is 1.618x line one). So
   the eye is set at the start of the type and the petals enlarge across the
   line exactly as the type enlarges down it. Half the mark bleeds off the left
   edge, which is the point: this is the detail, not the badge.

   `translate` rather than `transform` for the eye offset, so the scroll exit
   keeps sole ownership of `transform`. */
.hero-ed__mark {
  --mark-o: 0.075;
  --mark-w: clamp(20rem, 56vw, 60rem);
  --mark-x: 1rem;                       /* eye, from the column's left edge */
  --mark-y: 52%;                        /* eye, down the inner box */
  position: absolute;
  left: var(--mark-x);
  top: var(--mark-y);
  width: var(--mark-w);
  translate: -50% -43.6%;
  pointer-events: none;
  transform-origin: 50% 43.6%;          /* it closes toward the eye it opened from */
}
.hero-ed__mark svg { display: block; width: 100%; height: auto; }

/* ---- the display type ----
   The nautilus grows by a fixed ratio and so does the headline: the second
   line is set 1.618x the first, so the sentence enlarges as it is read. The
   small line is tracked open and the large one tracked tight, which is what
   makes the jump read as authored rather than as two sizes that happened. */
.hero-ed__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 0.84;
  color: var(--forest);
  text-transform: uppercase;
}
.hero-ed__line { display: block; overflow: hidden; }
.hero-ed__line > span {
  display: block;
  transform: translateY(112%);
  animation: heroRise 1200ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.hero-ed__line--lg > span { animation-delay: 130ms; }
.hero-ed__line--sm { font-size: clamp(1.95rem, 7.9vw, 6.35rem);  letter-spacing: 0.055em; }
.hero-ed__line--lg { font-size: clamp(3.15rem, 12.78vw, 10.27rem); letter-spacing: -0.022em; }
/* the tracked-open small line carries a trailing space the large one does not,
   so its optical left edge needs no correction — the large one does */
.hero-ed__line--lg > span { margin-left: -0.014em; }
@keyframes heroRise { to { transform: translateY(0); } }

.hero-ed__eyebrow { color: var(--ink); }
.hero-ed__lead {
  max-width: 34rem;
  margin: 0;
  font-family: var(--font-sub);
  font-weight: 600;
  font-size: var(--fs-lead);
  line-height: 1.5;
  color: var(--text-muted);
}
.hero-ed__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4); }

/* ---- footer strip ----
   The rule is the base of the column and it dissolves to the right on the
   same ramp as the wash, so the page's last line hands over to the room
   rather than stopping at an edge. It carries one label: the hero's proof
   numbers live 800px below as counting metrics and do not need saying twice. */
.hero-ed__foot {
  position: relative;
  grid-column: 1;
  grid-row: 2;
  align-self: end;
  padding-top: var(--s-3);
  color: var(--text-muted);
}
.hero-ed__scroll {
  display: inline-flex; align-items: center; gap: var(--s-3);
  font-size: var(--fs-label); font-weight: 700;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--ink);
}
.hero-ed__scroll i {
  width: 1px; height: 2rem;
  background: currentColor;
  transform-origin: top;
  animation: heroScroll 2.1s var(--ease) infinite;
}
@keyframes heroScroll {
  0%   { transform: scaleY(0); opacity: 0; }
  38%  { transform: scaleY(1); opacity: 1; }
  100% { transform: scaleY(1) translateY(100%); opacity: 0; }
}

/* =========================================================================
   Hero motion.

   Load and exit are two different gestures on purpose: the type *rises* into
   place once, and everything *leaves sideways* on scroll. --hero-in is the
   load (a registered custom property so it can be keyframed and still share
   the transform with the exit); --hero-out is the scroll position, written by
   JS, so the exit scrubs with the wheel and runs backwards on the way up.

   --ho-k is a per-element speed. Higher elements leave faster, so the column
   peels off from the top in reading order and the fan is hinged at the base —
   which is also the direction the scroll itself is already carrying them.

   The slowest element still has to clear: the fade is 1 − (--hero-out x k x
   1.2), so any k below 1/1.2 = 0.833 leaves a ghost behind at --hero-out: 1.
   0.90 is the floor for that reason, not for taste.
   ========================================================================= */
@property --hero-in { syntax: '<number>'; inherits: false; initial-value: 1; }
@keyframes heroIn { from { --hero-in: 0; } to { --hero-in: 1; } }

.hero-ed__eyebrow  { --ho-k: 1.76; --in-d:  80; }
.hero-ed__line--sm { --ho-k: 1.56; }
.hero-ed__line--lg { --ho-k: 1.38; }
.hero-ed__lead     { --ho-k: 1.22; --in-d: 460; }
.hero-ed__actions  { --ho-k: 1.06; --in-d: 560; }
.hero-ed__foot     { --ho-k: 0.90; --in-d: 680; }

.hero-ed__eyebrow,
.hero-ed__line,
.hero-ed__lead,
.hero-ed__actions,
.hero-ed__foot {
  --ho: calc(var(--hero-out, 0) * var(--ho-k, 1));
  transform: translate3d(
    calc(var(--ho) * -15vw + (1 - var(--hero-in, 1)) * -2.5rem), 0, 0);
  /* 1.2, not 1.5: the fade has to outlast the slide or the block dissolves
     before the sideways travel has read as travel */
  opacity: clamp(0, calc(var(--hero-in, 1) - var(--ho) * 1.2), 1);
  will-change: transform, opacity;
}
.js .hero-ed__eyebrow,
.js .hero-ed__lead,
.js .hero-ed__actions,
.js .hero-ed__foot {
  animation: heroIn 900ms var(--ease) calc(var(--in-d, 0) * 1ms) both;
}
/* the room drifts the other way, and slower — the separation is what reads
   as depth */
.hero-ed__media {
  transform: translate3d(calc(var(--hero-out, 0) * 3vw), 0, 0)
             scale(calc(1 + var(--hero-out, 0) * 0.045));
}

/* The mark is the middle plane: it goes the way of the page, not the room, but
   at 0.62 speed it lags the copy — three layers, three rates. It also closes
   the way it opened, contracting toward the same spiral eye the petals grew
   from, and it clears ahead of the copy so nothing is left ghosting over the
   photograph once the column has gone. */
.hero-ed__mark {
  transform: translate3d(calc(var(--hero-out, 0) * -9.3vw), 0, 0)
             scale(calc(1 - var(--hero-out, 0) * 0.22));
  opacity: calc(var(--mark-o) * clamp(0, calc(1 - var(--hero-out, 0) * 1.7), 1));
  will-change: transform, opacity;
}

/* ---- mobile ----
   The phone crop is a separate photograph, not the wide one squeezed: the wall
   above her head is extended (row y=6% of the original is clean wall across the
   whole frame, so the seam is invisible) until her head sits at exactly half
   the frame. That buys the column a full half-screen of daylight, so the wash
   here can stop at 46% and leave her face alone. The type scale also changes
   ratio, not just size — the column is the full measure here, not 8/13. ---- */
@media (max-width: 900px) {
  .hero-ed { max-height: none; }
  .hero-ed__inner {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr auto;
    gap: var(--s-4);
    padding-block: calc(var(--header-h, 5.25rem) + var(--s-4)) var(--s-4);
  }
  .hero-ed__col  { grid-column: 1; grid-row: 1; align-self: start; gap: var(--s-3); }
  .hero-ed__foot { grid-column: 1; grid-row: 3; }
  .hero-ed__line--sm { font-size: clamp(2.2rem, 11.43vw, 6.4rem); }
  .hero-ed__line--lg { font-size: clamp(3.56rem, 18.5vw, 10.35rem); }
  .hero-ed__lead { font-size: var(--fs-sm); line-height: 1.55; max-width: 30rem; }
  .hero-ed__actions { gap: var(--s-3); }
  .hero-ed__media picture,
  .hero-ed__img { object-position: 50% 50%; }
  .hero-ed__media::after {
    background:
      linear-gradient(to bottom,
        var(--cream) 0%,
        rgba(255, 241, 232, 0.96) 25%,
        rgba(255, 241, 232, 0.64) 37%,
        rgba(255, 241, 232, 0.16) 46%,
        rgba(255, 241, 232, 0) 54%),
      linear-gradient(to top,
        rgba(255, 241, 232, 0.72) 0%,
        rgba(255, 241, 232, 0.30) 10%,
        rgba(255, 241, 232, 0) 22%);
  }
  /* the column leaves on a shorter throw here — 14vw of a phone is nothing */
  .hero-ed__eyebrow,
  .hero-ed__line,
  .hero-ed__lead,
  .hero-ed__actions,
  .hero-ed__foot { transform: translate3d(calc(var(--ho) * -36vw + (1 - var(--hero-in, 1)) * -1.5rem), 0, 0); }

  /* the copy sits at the top here, so the mark follows it up. Left where it
     was it landed on her face and shoulders — the one part of this crop the
     whole layout is built to keep clear. */
  .hero-ed__mark {
    --mark-w: 96vw;
    --mark-x: 0.5rem;
    --mark-y: 30%;
    transform: translate3d(calc(var(--hero-out, 0) * -22vw), 0, 0)
               scale(calc(1 - var(--hero-out, 0) * 0.22));
  }
}

/* ---- Scroll-scrubbed exits are desktop-only ------------------------------
   On a phone the viewport is short and a thumb-flick covers a lot of it, so
   content that fades on scroll position is often gone before it has been
   read — you cannot scroll to it fast enough to catch it. Both scrubbed
   sections therefore hold at full strength here: the hero column and its
   mark stay put, and the studio copy stops travelling. The entrance
   animations are untouched; only the exits go. */
@media (max-width: 900px) {
  /* --ho is the exit multiplier the formulas below feed on; zeroing it
     leaves the load-in animation (--hero-in) working exactly as before,
     which a blanket opacity:1 would have flattened. */
  .hero-ed__eyebrow,
  .hero-ed__line,
  .hero-ed__lead,
  .hero-ed__actions,
  .hero-ed__foot { --ho: 0; }
  .hero-ed__media,
  .hero-ed__mark { --hero-out: 0; }
  /* the studio copy is scrub-only, so it can simply hold at rest */
  .js .sec-scrub .stack-5 > * {
    transform: none;
    opacity: 1;
    will-change: auto;
  }
}

@media (max-width: 560px) {
  /* at 0.22em the eyebrow is 6px too wide for a 390px screen and breaks to two
     lines under a bracket sized for one */
  .hero-ed__eyebrow { letter-spacing: 0.14em; }
  .hero-ed__actions .btn { width: 100%; }
}

/* DISABLED by client request — the hero animates for everyone, including
   visitors whose OS asks for reduced motion. Change `false` back to
   `(prefers-reduced-motion: reduce)` to restore the accessible behaviour. */
@media false {
  .hero-ed__line > span { transform: none; animation: none; }
  .hero-ed__scroll i { animation: none; }
  .js .hero-ed__eyebrow,
  .js .hero-ed__lead,
  .js .hero-ed__actions,
  .js .hero-ed__foot { animation: none; }
  .hero-ed__eyebrow,
  .hero-ed__line,
  .hero-ed__lead,
  .hero-ed__actions,
  .hero-ed__foot,
  .hero-ed__media { transform: none; opacity: 1; will-change: auto; }
  /* the mark stays, at its resting weight — it is a watermark, not motion */
  .hero-ed__mark { transform: none; opacity: var(--mark-o); will-change: auto; }
}

/* Scroll-linked hero exit. --hero-out is written by JS as 0 -> 1 across the
   first screen, so the motion scrubs with the wheel instead of firing once.
   The copy leaves faster than the photo, which reads as depth. */
.hero__copy,
.hero__media { will-change: transform, opacity; }
.hero__copy {
  transform: translate3d(0, calc(var(--hero-out, 0) * -9vh), 0);
  opacity: clamp(0, calc(1 - var(--hero-out, 0) * 1.45), 1);
}
.hero__media {
  transform: translate3d(0, calc(var(--hero-out, 0) * -3.4vh), 0)
             scale(calc(1 - var(--hero-out, 0) * 0.05));
  opacity: clamp(0, calc(1 - var(--hero-out, 0) * 0.95), 1);
}
.hero__meta { opacity: clamp(0, calc(1 - var(--hero-out, 0) * 2.6), 1); }
.hero__media { position: relative; z-index: 0; }
/* brand gradient panel behind the portrait — brandbook slide 2 */
.hero__media::before {
  content: '';
  position: absolute;
  top: -1.5rem; right: -1.5rem; bottom: 1.5rem; left: 1.5rem;
  background: var(--grad-brand);
  z-index: -1;
}
.hero__photo {
  width: 100%;
  height: min(66svh, 36rem);
  object-fit: cover;
  object-position: 50% 16%;
  filter: saturate(0.97);
}
.hero__stamp {
  position: absolute;
  left: clamp(-3rem, -2.4vw, -1.25rem);
  bottom: clamp(-2.25rem, -1.8vw, -1rem);
  width: clamp(7rem, 10vw, 11rem);
  color: var(--forest);
  background: var(--cream);
  padding: var(--s-4);
}
.hero__stamp svg { width: 100%; height: auto; display: block; }
.hero > .wrap { position: relative; z-index: 2; }
.hero__meta { display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-5); align-items: center; }
.hero__scroll {
  display: inline-flex; align-items: center; gap: var(--s-3);
  font-size: var(--fs-label); font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--text-muted);
}
.hero__scroll i {
  display: block; width: 1px; height: 2.75rem; background: var(--line-strong);
  position: relative; overflow: hidden;
}
.hero__scroll i::after {
  content: ''; position: absolute; inset: 0; background: var(--forest);
  animation: scrollTick 2.2s var(--ease-soft) infinite;
}
@keyframes scrollTick {
  0%   { transform: translateY(-100%); }
  60%  { transform: translateY(100%); }
  100% { transform: translateY(100%); }
}

/* Hero petal bloom */
.bloom { color: var(--forest); }
.bloom .petal {
  transform-box: view-box;
  transform-origin: 395px 788px;
}
.js .bloom.is-armed .petal {
  opacity: 0;
  transform: scale(0.18) rotate(-32deg);
}
.js .bloom.is-open .petal {
  opacity: 1;
  transform: none;
  transition:
    opacity 620ms var(--ease) calc(var(--p) * 34ms),
    transform 900ms var(--ease) calc(var(--p) * 34ms);
}

/* Slow ambient rotation of the mark in the header/footer */
.mark-spin { animation: spin 44s linear infinite; transform-origin: 50% 50%; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- 10. Marquee (clients) ---------- */
.marquee {
  position: relative;
  display: flex;
  overflow: hidden;
  padding-block: var(--s-4);
  border-block: 1px solid var(--line);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.marquee__track {
  display: flex;
  flex: none;
  gap: var(--s-6);
  padding-right: var(--s-6);
  align-items: center;
  animation: marquee 42s linear infinite;
}
.marquee:hover .marquee__track { animation-play-state: paused; }
.marquee__item {
  font-family: var(--font-sub);
  font-weight: 600;
  font-size: clamp(1rem, 1.5vw, 1.375rem);
  letter-spacing: 0.06em;
  white-space: nowrap;
  color: var(--text-muted);
  transition: color var(--dur) var(--ease);
}
.marquee__item:hover { color: var(--accent-text); }
.marquee__item i { font-style: normal; opacity: 0.5; font-size: 0.7em; margin-left: 0.6em; letter-spacing: 0.1em; }
@keyframes marquee { to { transform: translateX(-50%); } }

/* ---------- 11. Pinned services ---------- */
.pin { position: relative; }
/* sticky needs a non-clipping ancestor */
.section.pin { overflow: visible; padding-block: 0; }
.js .section.pin:not(.pin--static) {
  min-height: calc(100svh + (var(--slides, 6) - 1) * 78svh);
}
.pin--static { padding-block: var(--section-y) !important; }
.pin__stage {
  position: sticky;
  top: 0;
  height: 100svh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.pin__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  padding-top: clamp(var(--s-6), 9vh, var(--s-7));
  flex: none;
}
.pin__counter {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 2.6vw, 2.5rem);
  letter-spacing: 0.06em;
  color: var(--text-muted);
}
.pin__counter b { color: var(--text); font-weight: 400; }
.pin__body { flex: 1; position: relative; min-height: 0; }

/* Three columns, per the design's 268 / 1fr / 428 at 1440: the rail of
   section-marks on the left, the service itself in the middle, and the
   schematic block holding the right edge at full height. */
.slide {
  position: absolute;
  inset: 0;
  /* the columns pin their last line to the base, so the clearance above
     the rail belongs to the slide itself — inset:0 ignores the parent's
     padding */
  padding-bottom: var(--s-5);
  display: grid;
  /* 268 / 1fr / 428 at the design's 1440, as ratios so the middle keeps
     the slack: the copy column is the one that must not be squeezed. */
  grid-template-columns: 268fr 616fr 428fr;
  gap: clamp(var(--s-4), 3.2vw, var(--s-6));
  align-items: stretch;
  opacity: 0;
  pointer-events: none;
  transition: opacity 420ms var(--ease);
}
/* Strategy, audit and tracking have no schematic block — the copy takes
   the right column rather than leaving a hole where one would be. */
.slide--novis { grid-template-columns: 268fr 1044fr 0; }
.slide.is-active { opacity: 1; pointer-events: auto; }
.slide__index {
  font-family: var(--font-display);
  font-size: clamp(4rem, 11vw, 11rem);
  line-height: 0.8;
  color: transparent;
  -webkit-text-stroke: 1px var(--line-strong);
  transition: opacity 520ms var(--ease) 60ms, transform 720ms var(--ease) 60ms;
}
/* At twice the size the stroke has to come down with it, or the glyph
   reads heavier than the outlined number above it. */
.slide__icon { width: 6.5rem; height: 6.5rem; color: var(--accent); stroke-width: 0.7; }
/* Platform names are proper nouns — .display would upper-case them. */
.slide__title { font-size: clamp(2rem, 6.1vw, 5.5rem); line-height: 0.95; text-transform: none; }
.slide__text {
  max-width: 30rem;
  color: rgba(255, 241, 232, 0.86);
  font-size: clamp(1rem, 1.46vw, 1.3125rem);
  line-height: 1.62;
  text-wrap: pretty;
  margin-top: var(--s-4);
}
/* Ruled rows, numbered — the design counts the three points off against
   hairlines rather than bulleting them. The number is a column of its
   own so the text edges line up down the list. */
.slide__list {
  display: grid;
  margin-top: var(--s-6);
  counter-reset: pt;
}
.slide__list li {
  counter-increment: pt;
  display: flex; gap: var(--s-4); align-items: baseline;
  padding-block: var(--s-4);
  border-top: 1px solid rgba(255, 241, 232, 0.22);
  font-size: clamp(0.9375rem, 1.25vw, 1.125rem);
  line-height: 1.45;
}
.slide__list li:last-child { border-bottom: 1px solid rgba(255, 241, 232, 0.22); }
.slide__list li::before {
  content: '0' counter(pt);
  width: 1.6rem; flex: none;
  font-size: var(--fs-sm);
  letter-spacing: 0.14em;
  color: rgba(255, 241, 232, 0.5);
  background: none; border-radius: 0; transform: none;
}
.slide__left, .slide__right {
  transition: opacity 520ms var(--ease) 80ms, transform 720ms var(--ease) 80ms;
}
/* The service sits in the middle of its column rather than hanging from
   the top — the lead-out stays pinned to the base by its own margin. */
.slide__right.stack {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0;
  min-height: 0;
}
/* The left column is the section's own marks: the word SERVICES, a rule,
   the outlined number, the platform glyph, and the pointer to whatever
   comes next — pinned to the base so the column reads top and bottom. */
.slide__left {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-height: 0;
}
.slide__word {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 3.75vw, 3.375rem);
  line-height: 1;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.slide__hr {
  width: 4.5rem; height: 1px; border: 0;
  background: rgba(255, 241, 232, 0.4);
  margin: var(--s-5) 0 var(--s-5);
}
/* line-height 0.8 lets the glyph sit above its own box, so the number
   needs the difference back as space or it touches the rule above */
.slide__left .slide__index { margin: 0; padding-top: 0.18em; }
.slide__left .slide__icon { margin-top: var(--s-4); }

.slide__next { margin-top: auto; display: flex; flex-direction: column; gap: var(--s-2); }
.slide__next .eyebrow { color: rgba(255, 241, 232, 0.5); }
.slide__next .eyebrow::before { display: none; }
.slide__nextname {
  display: flex; align-items: baseline; gap: var(--s-3);
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 2.08vw, 1.875rem);
  line-height: 1;
}
.slide__nextname svg { width: 1.1rem; height: 1.1rem; opacity: 0.6; flex: none; }

/* the design closes the middle column with a lead-out rule; it trails
   the list rather than sinking to the base, so the block stays centred */
.slide__cta {
  margin-top: var(--s-6);
  display: flex; align-items: center; gap: var(--s-3);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: inherit;
}
.slide__cta::after {
  content: '';
  width: 2.75rem; height: 1px; flex: none;
  background: rgba(255, 241, 232, 0.7);
  transition: width var(--dur) var(--ease);
}
a.slide__cta:hover::after { width: 4rem; }
.js .pin .slide:not(.is-active) .slide__left,
.js .pin .slide:not(.is-active) .slide__right,
.js .pin .slide:not(.is-active) .slide__index { opacity: 0; transform: translateY(22px); }

.pin__rail {
  display: flex;
  gap: 4px;
  padding-bottom: clamp(var(--s-5), 6vh, var(--s-6));
  flex: none;
}
.pin__rail button {
  flex: 1;
  height: 2px;
  background: var(--line-strong);
  cursor: pointer;
  position: relative;
  padding: 0;
  transition: background-color var(--dur) var(--ease);
}
.pin__rail button::before { content: ''; position: absolute; inset: -10px 0; }
.pin__rail button[aria-selected='true'] { background: var(--accent); }
.pin__rail button:hover { background: var(--accent); }

/* Non-pinned fallback: readable stacked list */
/* relative, not static: the stage must stay the containing block for the
   absolutely-positioned watermark, or its overflow escapes the clip */
.pin--static .pin__stage { position: relative; height: auto; display: block; }
.pin--static .pin__body { position: static; display: grid; gap: var(--s-5); margin-block: var(--s-5); }
.pin--static .slide {
  position: static;
  opacity: 1;
  pointer-events: auto;
  grid-template-columns: 1fr;
  gap: var(--s-4);
  padding-bottom: var(--s-5);
  border-bottom: 1px solid var(--line);
}
.pin--static .slide__index { font-size: 3rem; }
.pin--static .pin__rail { display: none; }
/* The stacked list is already in order and already labelled by its own
   heading, so the section marks and the pointer to the next slide are
   repetition there. */
.pin--static .slide__word,
.pin--static .slide__hr,
.pin--static .slide__next { display: none; }
.pin--static .slide__left { flex-direction: row; align-items: center; gap: var(--s-4); }
.pin--static .slide__cta { margin-top: var(--s-4); }

/* ---------- 11b. Scroll-scrubbed sections ----------
   The hero is tied to scroll position rather than played once; a
   mid-page section needs the same treatment on both ends. JS writes
   --out on the section: -1 while it is still arriving from below, 0
   while it owns the viewport, up to 1 as it leaves out the top. CSS
   reads it here and nowhere else.

   Without JS --out never appears, every value falls back to 0, and the
   section renders exactly as it did before. */
/* The photograph is not animated: it is simply there when the section
   is. Only the copy travels — the same sideways-and-out gesture the
   hero column leaves on, scrubbed by scroll rather than played once. */
.js .sec-scrub .stack-5 > * {
  --in:   clamp(0, calc(0 - var(--out, 0)), 1);   /* 1 → 0 arriving */
  --exit: clamp(0, var(--out, 0), 1);             /* 0 → 1 leaving  */
  /* Each line carries its own speed, and the higher it sits the faster
     it goes, so the column peels off from the top in reading order
     rather than sliding as one slab. --sk is set per child below. */
  --k: calc(1 + var(--sk, 0) * 0.16);
  /* In from the right, and out to the right as well: the column returns
     the way it came rather than sliding on past the reader. */
  transform: translate3d(
    calc((var(--in) * 3.5rem + var(--exit) * 4rem) * var(--k)), 0, 0);
  /* The exit fades gentler than the entrance: at 1.35 the copy was
     transparent while it had barely started travelling, so the movement
     never read as movement. */
  opacity: clamp(0, calc(1 - (var(--in) * 1.35 + var(--exit) * 0.85) * var(--k)), 1);
  will-change: transform, opacity;
}
/* top of the column moves most, base least — the fan is hinged low */
.js .sec-scrub .stack-5 > *:nth-child(1) { --sk: 5; }
.js .sec-scrub .stack-5 > *:nth-child(2) { --sk: 4; }
.js .sec-scrub .stack-5 > *:nth-child(3) { --sk: 3; }
.js .sec-scrub .stack-5 > *:nth-child(4) { --sk: 2; }
.js .sec-scrub .stack-5 > *:nth-child(5) { --sk: 1; }
.js .sec-scrub .stack-5 > *:nth-child(6) { --sk: 0; }
/* drop the compositor hint once the column has settled at either end */
.js .sec-scrub[style*='--moving: 0'] .stack-5 > * { will-change: auto; }

/* ---------- 11c. Testimonial rail ----------
   Full-bleed, and still by default: the quotes only travel while the
   pointer is over them, so the section is readable at a glance and
   becomes a rail when you engage with it. Hovering a single card holds
   the whole rail, which is what lets you actually finish reading one.

   The track is duplicated by JS, so the loop closes on itself; the
   keyframe therefore only ever needs to travel half its width. */
.rail {
  position: relative;
  display: flex;
  margin-top: var(--s-6);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
}
/* The rail is a real scroller, not an animation: the pointer drives it
   directly, so a wheel over the quotes moves them sideways and a finger
   drags them. JS translates vertical wheel to horizontal scroll (see
   §13 in aderera.js) — the wheel is how you read this on a desktop, and
   an animation you cannot control would fight it. */
.rail {
  position: relative;
  display: flex;
  margin-top: var(--s-6);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;                 /* the mask is the affordance */
  -webkit-overflow-scrolling: touch;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent);
}
.rail::-webkit-scrollbar { height: 0; }
.rail__track {
  display: flex;
  flex: none;
  gap: var(--gutter);
  padding-inline: var(--gutter);
  align-items: stretch;
}
.rail .quote {
  width: clamp(19rem, 26vw, 26rem);
  flex: none;
  scroll-snap-align: center;
}
@media (max-width: 720px) {
  /* a finger swipes it; snap gives each quote a resting place */
  .rail { scroll-snap-type: x mandatory; }
  .rail .quote { width: min(80vw, 22rem); }
}

/* ---------- 11e. Service page hero ----------
   Every other page opens on cream with a headline in the 5/8 column. A
   service page is the one place with something better to lead on: the
   account itself. So it opens on forest, with the copy left and a live
   schematic of that platform's dashboard right — the page states what the
   channel is by showing it working.

   The block runs the design's four-beat loop (see .pblock--live). */
.svc-hero {
  position: relative;
  overflow: hidden;
  /* .is-forest only sets the tokens; painting them is the section's job,
     and this is not a .section */
  background: var(--bg);
  color: var(--text);
  /* The header is fixed, so its height has to be cleared before the
     breadcrumb — otherwise the crumbs sit tight under the menu. Same
     allowance the other page heroes make. */
  padding-block: calc(var(--header-h, 5.25rem) + clamp(var(--s-5), 5vh, var(--s-7)))
                 clamp(var(--s-6), 8vh, var(--s-7));
}
.svc-hero__grid {
  display: grid;
  /* the scene needs the wider half: it is a 4:3 composition of five
     cards, and the copy reads fine in the narrower column */
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(var(--s-4), 3vw, var(--s-6));
  align-items: center;
}
.svc-hero .crumbs { margin-bottom: var(--s-5); }
.svc-hero__title {
  font-size: clamp(2.5rem, 6.4vw, 5.75rem);
  line-height: 0.95;
  text-transform: none;
}
.svc-hero__lead {
  max-width: 34rem;
  margin-top: var(--s-4);
  font-size: clamp(1rem, 1.45vw, 1.3125rem);
  line-height: 1.6;
  color: rgba(255, 241, 232, 0.86);
  text-wrap: pretty;
}
.svc-hero__actions { margin-top: var(--s-5); }
/* The block reuses the slide markup, so the slide's own sizing (half
   width, 80% height, centred in a flex row) has to be undone here — in
   the hero it is a column of its own and fills it. */
/* the scene sets its own 4:3 and scales everything inside from its width */
.svc-hero__vis { min-height: 0; }

@media (max-width: 900px) {
  .svc-hero__grid { grid-template-columns: 1fr; }
  /* the schematic is wordless, so on a phone it costs a screen and says
     nothing the copy above has not already said */
  .svc-hero__vis { display: none; }
}

/* ---------- 11f. Hero scene ----------
   The *Ads Visual designs, rebuilt in CSS. The composition is the point:
   four or five separate cards floating at different depths, not one panel
   with everything inside it. Boxes and z-values are the source's own, on
   its 1440x1080 stage, scaled to whatever width the column gives it.

   The camera is the source's too: perspective 1900px, rotateX 8.5deg,
   rotateY -13deg, drifting slowly. Cards lift into place once and hold —
   only the live dot keeps a loop. */
.hb {
  --hb: 255, 241, 232;
  position: relative;
  width: 100%;
  aspect-ratio: 1440 / 1080;
  perspective: 1900px;
  perspective-origin: 50% 45%;
  container-type: inline-size;
  color: var(--cream);
}
.hb__stage {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transform: scale(0.97) rotateX(8.5deg) rotateY(-13deg) rotateZ(0.6deg);
}
.js .svc-hero__vis.is-in .hb__stage { animation: hbCam 9s var(--ease) 200ms forwards; }
@keyframes hbCam {
  to { transform: scale(1.03) rotateX(7.7deg) rotateY(-11.4deg) rotateZ(0.6deg); }
}

/* Each card sits at its authored coordinates. cqw keeps the whole
   composition proportional at any column width. */
.hbc {
  position: absolute;
  left: calc(var(--x) / 1440 * 100cqw);
  top: calc(var(--y) / 1440 * 100cqw);
  width: calc(var(--w) / 1440 * 100cqw);
  height: calc(var(--h) / 1440 * 100cqw);
  border-radius: calc(24 / 1440 * 100cqw);
  background: linear-gradient(152deg, rgba(var(--hb), 0.17), rgba(var(--hb), 0.07));
  border: 1px solid rgba(var(--hb), 0.24);
  box-shadow: 0 50px 90px -34px rgba(12, 26, 10, 0.55),
              0 10px 26px -14px rgba(12, 26, 10, 0.30),
              inset 0 1px 0 rgba(var(--hb), 0.28);
  backdrop-filter: blur(10px);
  transform: translateZ(calc(var(--z) * 1px));
  overflow: hidden;
}
.hbc__in {
  position: absolute;
  inset: 0;
  padding: calc(26 / 1440 * 100cqw);
  display: flex;
  flex-direction: column;
  gap: calc(16 / 1440 * 100cqw);
  font-size: calc(15 / 1440 * 100cqw);
}
/* the deeper a card sits, the further it starts and the later it lands */
.js .hbc { opacity: 0; }
.js .svc-hero__vis.is-in .hbc {
  animation: hbLift 900ms var(--ease) forwards;
  animation-delay: calc(120ms + var(--z) * 2.2ms);
}
@keyframes hbLift {
  from { opacity: 0; transform: translateZ(calc(var(--z) * 1px)) translateY(28px); }
  to   { opacity: 1; transform: translateZ(calc(var(--z) * 1px)); }
}

/* ---- shared parts ---- */
.hb__head { display: flex; align-items: center; justify-content: space-between; }
.hb__title { display: flex; align-items: center; gap: 0.6em; font-family: var(--font-display); font-size: 1.45em; text-transform: none; }
.hb__seed { width: 0.6em; height: 0.6em; border-radius: 50%; background: var(--cream); flex: none; }
.hb__live {
  display: inline-flex; align-items: center; gap: 0.5em;
  padding: 0.4em 0.9em; border-radius: 999px;
  background: rgba(var(--hb), 0.10);
  font-size: 0.72em; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase;
  color: rgba(var(--hb), 0.72);
}
.hb__live i { width: 0.42em; height: 0.42em; border-radius: 50%; background: var(--cream); animation: hbPulse 1.9s var(--ease) infinite; }
@keyframes hbPulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }

.hb__k { font-size: 0.72em; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(var(--hb), 0.58); display: block; }
.hb__strong { font-family: var(--font-display); font-size: 1.3em; }
.hb__spread { display: flex; justify-content: space-between; align-items: baseline; }
.hb__lead { display: flex; align-items: baseline; gap: 0.8em; flex-wrap: wrap; }
.hb__lead .hb__k { flex-basis: 100%; }
.hb__big { font-family: var(--font-display); font-size: 3.6em; line-height: 1; font-variant-numeric: tabular-nums; white-space: nowrap; }
.hb__stats { display: flex; gap: 2.4em; }
.hb__stat { display: flex; flex-direction: column; gap: 0.3em; }
.hb__v { font-family: var(--font-display); font-size: 2em; line-height: 1.1; font-variant-numeric: tabular-nums; }
.hb__foot2 { margin-top: auto; display: flex; align-items: baseline; gap: 0.6em; }
.hb__foot2 .hb__k { order: 2; }
.hb__foot2 .hb__v { font-size: 2.2em; }

/* chart */
.hb__chart { position: relative; flex: 1; min-height: 0; }
.hb__chart svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.hb__grid { stroke: rgba(var(--hb), 0.13); stroke-width: 1; }
.hb__area { fill: rgba(var(--hb), 0.10); opacity: 0; }
.hb__line { fill: none; stroke: var(--cream); stroke-width: 3.5; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 900; stroke-dashoffset: 900; }
.js .svc-hero__vis.is-in .hb__line { animation: hbDraw 1800ms var(--ease) 700ms forwards; }
@keyframes hbDraw { to { stroke-dashoffset: 0; } }
.js .svc-hero__vis.is-in .hb__area { animation: hbFadeIn 900ms var(--ease) 1400ms forwards; }
@keyframes hbFadeIn { to { opacity: 1; } }
.hb__dot { position: absolute; right: 0; top: 2%; width: 0.8em; height: 0.8em; border-radius: 50%; background: var(--cream); box-shadow: 0 0 0 0.35em rgba(var(--hb), 0.18); opacity: 0; }
.js .svc-hero__vis.is-in .hb__dot { animation: hbFadeIn 500ms var(--ease) 2200ms forwards; }
.hb__spark { flex: 1; display: grid; align-items: center; }
.hb__spark svg { width: 100%; height: auto; overflow: visible; }
.hb__chip { padding: 0.3em 0.8em; border-radius: 999px; background: var(--cream); color: var(--forest-deep); font-size: 0.78em; font-weight: 700; }

/* ring */
.hb__ring { position: relative; display: grid; place-items: center; margin: auto; width: 62%; }
.hb__ring svg { width: 100%; height: auto; transform: rotate(-90deg); overflow: visible; grid-area: 1/1; }
.hb__ringbg { fill: none; stroke: rgba(var(--hb), 0.18); stroke-width: 10; }
.hb__ringfg { fill: none; stroke: var(--cream); stroke-width: 10; stroke-linecap: round; stroke-dasharray: 327; stroke-dashoffset: 327; }
.js .svc-hero__vis.is-in .hb__ringfg { animation: hbRing 1400ms var(--ease) 900ms forwards; }
@keyframes hbRing { to { stroke-dashoffset: var(--to, 100); } }
.hb__ringv { grid-area: 1/1; font-family: var(--font-display); font-size: 1.7em; font-variant-numeric: tabular-nums; }

/* rows */
.hb__rows { display: grid; gap: 0.9em; }
.hb__row { display: grid; grid-template-columns: 1fr auto; gap: 0.3em 0.6em; align-items: baseline; }
.hb__rowname { font-size: 0.95em; }
.hb__pct { font-size: 0.85em; font-variant-numeric: tabular-nums; color: rgba(var(--hb), 0.58); }
.hb__track { grid-column: 1 / -1; height: 0.32em; border-radius: 999px; background: rgba(var(--hb), 0.18); overflow: hidden; }
.hb__track i { display: block; height: 100%; width: calc(var(--v) * 1%); border-radius: 999px; background: var(--cream); transform-origin: left; transform: scaleX(0); }
.hb__row:not(:first-child) .hb__track i { background: rgba(var(--hb), 0.55); }
.js .svc-hero__vis.is-in .hb__track i { animation: hbWipe 900ms var(--ease) backwards; animation-delay: calc(1000ms + var(--i) * 160ms); transform: scaleX(1); }
@keyframes hbWipe { from { transform: scaleX(0); } }

/* bars */
.hb__bars { display: flex; align-items: flex-end; gap: 0.45em; height: 45%; margin-top: auto; }
.hb__bars > i { flex: 1; border-radius: 0.2em; min-height: 3px; height: calc(var(--h) * 1%); background: rgba(var(--hb), 0.28); transform-origin: bottom; transform: scaleY(0); }
.hb__bars > i.hot { background: var(--cream); }
.js .svc-hero__vis.is-in .hb__bars > i { animation: hbBar 700ms var(--ease) backwards; animation-delay: calc(1100ms + var(--i) * 70ms); transform: scaleY(1); }
@keyframes hbBar { from { transform: scaleY(0); } }

/* Google — bid slider */
.hb__slider { margin-top: auto; display: grid; gap: 1em; }
.hb__stracks { position: relative; height: 0.36em; border-radius: 999px; background: rgba(var(--hb), 0.20); }
.hb__stracks i { position: absolute; inset: 0 auto 0 0; width: 71%; border-radius: 999px; background: var(--cream); transform-origin: left; transform: scaleX(0.31); }
.hb__stracks b { position: absolute; top: 50%; left: 22%; width: 1.5em; height: 1.5em; margin: -0.75em 0 0 -0.75em; border-radius: 50%; background: var(--forest-deep); border: 0.2em solid var(--cream); }
.js .svc-hero__vis.is-in .hb__stracks i { animation: hbSlide 1400ms var(--ease) 1300ms forwards; }
.js .svc-hero__vis.is-in .hb__stracks b { animation: hbKnob 1400ms var(--ease) 1300ms forwards; }
@keyframes hbSlide { to { transform: scaleX(1); } }
@keyframes hbKnob { to { left: 71%; } }
.hb__sends { display: flex; justify-content: space-between; font-size: 0.7em; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(var(--hb), 0.5); }

/* Meta — audiences and the feed */
.hb__venn { display: grid; place-items: center; flex: 1; min-height: 0; }
.hb__venn svg { width: 92%; height: auto; overflow: visible; }
.hb__venn circle { fill: rgba(var(--hb), 0.08); stroke-width: 1.5; }
.hb__v1 { stroke: var(--cream); }
.hb__v2, .hb__v3 { stroke: rgba(var(--hb), 0.42); }
.hb__core { fill: var(--cream); stroke: none; opacity: 0; }
.js .hb__v1 { transform: translate(9%, 4%); }
.js .hb__v2 { transform: translate(-9%, 5%); }
.js .hb__v3 { transform: translate(1%, -9%); }
.js .svc-hero__vis.is-in .hb__v1,
.js .svc-hero__vis.is-in .hb__v2,
.js .svc-hero__vis.is-in .hb__v3 { animation: hbMerge 1600ms var(--ease) 700ms forwards; }
@keyframes hbMerge { to { transform: none; } }
.js .svc-hero__vis.is-in .hb__core { animation: hbPop 700ms var(--ease) 2000ms forwards; }
@keyframes hbPop { from { opacity: 0; transform: scale(0.3); } to { opacity: 0.9; transform: none; } }

.hb__feed { position: relative; flex: 1; min-height: 0; display: grid; gap: 0.9em; align-content: start; overflow: hidden; }
.hb__post { border-radius: 1em; border: 1px solid rgba(var(--hb), 0.18); background: rgba(var(--hb), 0.05); padding: 0.7em; display: grid; gap: 0.5em; }
.hb__post i { display: block; height: 4.2em; border-radius: 0.7em; background: linear-gradient(160deg, rgba(var(--hb), 0.26), rgba(var(--hb), 0.08)); }
.hb__post b { display: block; height: 0.42em; width: 62%; border-radius: 999px; background: rgba(var(--hb), 0.34); }
.hb__post u { display: block; height: 0.42em; width: 38%; border-radius: 999px; background: rgba(var(--hb), 0.18); text-decoration: none; }
.hb__post.is-hot { border-color: rgba(var(--hb), 0.5); background: rgba(var(--hb), 0.09); position: relative; }
.js .svc-hero__vis.is-in .hb__feed { animation: hbScroll 1600ms var(--ease) 1600ms forwards; }
@keyframes hbScroll { to { transform: translateY(-14%); } }
.hb__buy { position: absolute; right: 0.7em; bottom: 0.7em; padding: 0.35em 0.9em; border-radius: 999px; background: var(--cream); color: var(--forest-deep); font-size: 0.75em; font-weight: 700; opacity: 0; }
.js .svc-hero__vis.is-in .hb__buy { animation: hbFadeIn 600ms var(--ease) 2600ms forwards; }

/* TikTok — the creative frame and the stack */
.hb__viewport { position: relative; flex: 1; min-height: 0; border-radius: 1.2em; background: rgba(var(--hb), 0.06); overflow: hidden; }
.hb__blk { position: absolute; left: calc(var(--l) * 1%); top: calc(var(--t) * 1%); width: calc(var(--bw) * 1%); height: calc(var(--bh) * 1%); border-radius: 0.8em; background: linear-gradient(158deg, rgba(var(--hb), 0.28), rgba(var(--hb), 0.08)); }
.hb__playline { position: absolute; left: 6%; right: 6%; bottom: 6%; height: 0.28em; border-radius: 999px; background: rgba(var(--hb), 0.20); overflow: hidden; }
.hb__playline i { display: block; height: 100%; background: var(--cream); transform-origin: left; transform: scaleX(0); }
.js .svc-hero__vis.is-in .hb__playline i { animation: hbSlide 2600ms linear 900ms forwards; }
.hb__creatives { display: flex; justify-content: center; gap: 0.7em; flex: 1; align-items: center; }
.hb__creatives > i { width: 22%; aspect-ratio: 72/128; border-radius: 0.7em; border: 1px solid rgba(var(--hb), 0.20); background: linear-gradient(165deg, rgba(var(--hb), 0.20), rgba(var(--hb), 0.06)); transform: rotate(calc((var(--i) - 1) * 4deg)); }
.hb__creatives > i.win { border-color: rgba(var(--hb), 0.6); background: linear-gradient(165deg, rgba(var(--hb), 0.34), rgba(var(--hb), 0.10)); }
.js .svc-hero__vis.is-in .hb__creatives > i.win { animation: hbWin 900ms var(--ease) 1500ms forwards; }
@keyframes hbWin { to { transform: translateY(-12%) scale(1.1); } }
.hb__winner { align-self: center; padding: 0.3em 0.9em; border-radius: 999px; background: var(--cream); color: var(--forest-deep); font-size: 0.75em; font-weight: 700; letter-spacing: 0.06em; opacity: 0; }
.js .svc-hero__vis.is-in .hb__winner { animation: hbFadeIn 500ms var(--ease) 2100ms forwards; }

/* LinkedIn — the funnel and the lead form */
.hb__funnel { display: grid; gap: 1.1em; flex: 1; align-content: center; }
.hb__stage { display: grid; grid-template-columns: 1fr auto; gap: 0.35em 0.6em; }
.hb__stageval { font-family: var(--font-display); font-size: 1.4em; font-variant-numeric: tabular-nums; }
.hb__stagebar { grid-column: 1 / -1; height: 1.5em; border-radius: 0.4em; background: rgba(var(--hb), 0.10); overflow: hidden; }
.hb__stagebar i { display: block; height: 100%; width: calc(var(--v) * 1%); border-radius: 0.4em; background: rgba(var(--hb), 0.30); transform-origin: left; transform: scaleX(0); }
.hb__stage:last-child .hb__stagebar i { background: var(--cream); }
.js .svc-hero__vis.is-in .hb__stagebar i { animation: hbSlide 1000ms var(--ease) backwards; animation-delay: calc(700ms + var(--i) * 220ms); transform: scaleX(1); }
.hb__form { display: grid; gap: 0.6em; flex: 1; align-content: center; }
.hb__form > i { height: 2.4em; border-radius: 0.6em; border: 1px solid rgba(var(--hb), 0.22); background: rgba(var(--hb), 0.05); }
.js .svc-hero__vis.is-in .hb__form > i { animation: hbFill 500ms var(--ease) backwards; animation-delay: calc(1200ms + var(--i) * 300ms); background: rgba(var(--hb), 0.22); }
@keyframes hbFill { from { background: rgba(var(--hb), 0.05); } }
.hb__submit { height: 2.6em; border-radius: 0.6em; display: grid; place-items: center; background: rgba(var(--hb), 0.14); color: rgba(var(--hb), 0.6); font-size: 0.8em; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; }
.js .svc-hero__vis.is-in .hb__submit { animation: hbSubmit 600ms var(--ease) 2300ms forwards; }
@keyframes hbSubmit { to { background: var(--cream); color: var(--forest-deep); } }

/* Apple — the query and the results */
.hb__search { display: flex; align-items: center; gap: 0.8em; height: 3em; padding: 0 1em; border-radius: 0.9em; border: 1px solid rgba(var(--hb), 0.22); background: rgba(var(--hb), 0.10); flex: none; }
.hb__search svg { width: 1.1em; height: 1.1em; fill: none; stroke: rgba(var(--hb), 0.58); stroke-width: 2; flex: none; }
.hb__query { white-space: nowrap; overflow: hidden; }
.hb__caret { width: 2px; height: 1.2em; background: var(--cream); animation: hbBlink 1s steps(1) infinite; }
@keyframes hbBlink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0.15; } }
.hb__results { display: grid; gap: 0.7em; }
.hb__res { display: flex; align-items: center; gap: 0.9em; padding: 0.7em 0.9em; border-radius: 1em; border: 1px solid rgba(var(--hb), 0.12); background: rgba(var(--hb), 0.04); }
.hb__res.is-ours { border-color: rgba(var(--hb), 0.44); background: rgba(var(--hb), 0.10); }
.js .hb__res.is-ours { transform: translateY(200%); }
.js .hb__res:not(.is-ours) { transform: translateY(-100%); }
.js .svc-hero__vis.is-in .hb__res { animation: hbClimb 1000ms var(--ease) 2000ms forwards; }
@keyframes hbClimb { to { transform: none; } }
.hb__resicon { width: 2.6em; height: 2.6em; border-radius: 0.7em; background: rgba(var(--hb), 0.18); flex: none; }
.hb__res.is-ours .hb__resicon { background: rgba(var(--hb), 0.42); }
.hb__reslines { flex: 1; display: grid; gap: 0.35em; }
.hb__reslines b, .hb__reslines u { display: block; height: 0.42em; border-radius: 999px; width: calc(var(--w) * 1%); background: rgba(var(--hb), 0.26); text-decoration: none; }
.hb__reslines u { background: rgba(var(--hb), 0.14); }
.hb__ad { padding: 0.25em 0.6em; border-radius: 0.4em; background: var(--cream); color: var(--forest-deep); font-size: 0.62em; font-weight: 700; letter-spacing: 0.1em; }

/* ---------- 11d. Credentials register ----------
   A ledger, not a wall of badges. The expiry column is the point: in paid
   media a certification lapses after a year, so publishing the date is the
   claim — anyone can hang a badge, far fewer keep them current.

   Four columns on the desktop measure, collapsing to two on a phone with
   the dates tucked under the title where they still pair correctly. */
.certs {
  display: grid;
  gap: 0;
  border-top: 1px solid var(--line-strong);
}
.certs__head,
.cert__link {
  display: grid;
  grid-template-columns: 8.5rem minmax(0, 1fr) 7rem 8rem;
  gap: var(--s-4);
  align-items: baseline;
}
.certs__head {
  padding-block: var(--s-3);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--line);
}
.cert { border-bottom: 1px solid var(--line); }
.cert__link {
  padding-block: var(--s-4);
  position: relative;
  transition: background-color var(--dur-fast) var(--ease);
}
.cert__link:hover { background: rgba(65, 111, 59, 0.05); }
/* the row is the target, so the whole line reads as one control */
.cert__link::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}
.cert__link:hover::after,
.cert__link:focus-visible::after { transform: scaleX(1); }

.cert__issuer {
  font-family: var(--font-display);
  font-size: clamp(1.125rem, 1.6vw, 1.5rem);
  line-height: 1;
  color: var(--forest);
}
.cert__title {
  font-size: var(--fs-body);
  line-height: 1.35;
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
  flex-wrap: wrap;
}
.cert__tag {
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--forest);
  border: 1px solid rgba(65, 111, 59, 0.35);
  border-radius: 999px;
  padding: 0.15rem 0.5rem;
}
.cert__dates { display: contents; }
.cert__from,
.cert__until {
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
  white-space: nowrap;
}
.cert__until { color: var(--text); }
.cert__until--none { color: var(--text-muted); font-style: italic; }

/* A lapsed row still belongs in the register — the work behind it happened
   — but it must not read as a live credential. It recedes, and its expiry
   is struck through so the column stays honest at a glance. */
.cert.is-lapsed .cert__issuer,
.cert.is-lapsed .cert__title { opacity: 0.55; }
.cert.is-lapsed .cert__until {
  color: var(--text-muted);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}

@media (max-width: 860px) {
  .certs__head { display: none; }
  .cert__link {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--s-2) var(--s-4);
  }
  .cert__issuer { grid-column: 1 / -1; }
  .cert__title  { grid-column: 1 / -1; }
  .cert__from   { grid-column: 1; }
  .cert__until  { grid-column: 2; text-align: right; }
}

/* ---------- 12. Cards ---------- */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  padding: var(--s-5);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: border-color var(--dur) var(--ease), background-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.is-ink .card { background: rgba(255, 241, 232, 0.05); }
a.card, .card--link { cursor: pointer; }
a.card:hover, .card--link:hover {
  border-color: var(--accent);
  box-shadow: 0 26px 60px -40px rgba(57, 39, 23, 0.55);
}
.card__icon { width: 2.25rem; height: 2.25rem; color: var(--accent); stroke-width: 1.2; }
.card__title { font-family: var(--font-sub); font-weight: 600; font-size: 1.25rem; line-height: 1.25; }
.card__text { font-size: var(--fs-sm); color: var(--text-muted); }
.card__foot { margin-top: auto; padding-top: var(--s-3); }

.grid-auto {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr));
  gap: var(--gutter);
}
.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--gutter); }
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gutter); }
.grid-4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--gutter); }

/* ---------- 13. Process steps ---------- */
.steps { counter-reset: step; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; }
.step {
  counter-increment: step;
  position: relative;
  padding: var(--s-7) var(--s-4) var(--s-5) 0;
  border-top: 1px solid var(--line-strong);
}
.step + .step { padding-left: var(--s-4); }
.step::before {
  content: '0' counter(step);
  position: absolute;
  top: var(--s-4);
  left: var(--s-4);
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  letter-spacing: 0.18em;
  color: var(--accent-text);
}
.step:first-child::before { left: 0; }
.step::after {
  content: '';
  position: absolute;
  top: -1px; left: 0; right: 0;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 900ms var(--ease);
}
.step.is-in::after { transform: scaleX(1); transition-delay: calc(var(--i, 0) * 160ms); }
.step__icon {
  width: 1.75rem; height: 1.75rem;
  margin-bottom: var(--s-3);
  color: var(--accent);
  stroke-width: 1.2;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 520ms var(--ease), transform 520ms var(--ease);
}
.step.is-in .step__icon {
  opacity: 1;
  transform: none;
  transition-delay: calc(var(--i, 0) * 160ms + 120ms);
}
.step__title { font-family: var(--font-sub); font-weight: 600; font-size: clamp(1.25rem, 2vw, 1.75rem); margin-bottom: var(--s-3); }
.step__text { font-size: var(--fs-sm); color: var(--text-muted); }

/* ---------- 14. Cases ---------- */
.case {
  display: grid;
  grid-template-columns: 5fr 8fr;
  gap: clamp(var(--s-4), 4vw, var(--s-6));
  align-items: center;
  padding-block: clamp(var(--s-5), 5vw, var(--s-6));
  border-top: 1px solid var(--line);
}
.case__tag {
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-size: var(--fs-label); font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--accent-text);
}
.case__tag svg { width: 1.15em; height: 1.15em; flex: none; stroke-width: 1.6; }
.case__title { font-family: var(--font-sub); font-weight: 600; font-size: clamp(1.375rem, 2.4vw, 2rem); line-height: 1.2; margin-block: var(--s-3); }
/* Four across, on one line: auto-fit was wrapping them 2x2 in the studio
   column, which read as two unrelated pairs rather than one set. */
.metrics { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-5) var(--s-5); }
@media (max-width: 640px) { .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.metric__value {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 3vw, 3.25rem);
  line-height: 1;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}
.is-forest .metric__value, .is-ink .metric__value { color: var(--accent); }
.metric__label {
  margin-top: var(--s-2);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
}

/* Simple CSS bar chart for case results */
/* ---------- 14b. Cumulative run ----------
   Three months of conversions drawn as one filling bar rather than three
   columns. The columns showed relative height and nothing else; the run
   carries the counts on the segments and makes the real finding legible —
   the last month is worth more than the first two together.

   Segment widths are shares of the total, set inline, so the bar is the
   arithmetic rather than a picture of it. */
.run { margin: 0; display: grid; gap: var(--s-4); }
.run__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-4); }
.run__total { font-size: var(--fs-sm); color: var(--text-muted); }
.run__total b {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.75rem;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  margin-right: 0.35rem;
}

.run__bar {
  display: flex;
  height: 3.25rem;
  border-radius: var(--radius);
  overflow: hidden;
  background: rgba(255, 241, 232, 0.07);
}
.run__seg {
  position: relative;
  width: var(--w);
  display: grid;
  place-items: center;
  background: var(--grad-brand);
  /* each segment grows from its own left edge, in order, so the bar reads
     as accumulating rather than appearing */
  transform-origin: left;
  transform: scaleX(0);
  transition: transform 800ms var(--ease) calc(var(--i, 0) * 220ms);
}
.run__seg + .run__seg { border-left: 1px solid rgba(27, 27, 27, 0.35); }
.run.is-in .run__seg { transform: scaleX(1); }
/* the final month is the point of the chart, so it carries the brand green
   at full strength while the earlier two sit back */
.run__seg.is-last { background: var(--pistachio); }
.run__seg:first-child { background: rgba(255, 241, 232, 0.28); }
.run__seg:nth-child(2) { background: rgba(133, 176, 78, 0.55); }
/* The number sits on the segment, so its colour follows the segment it
   lands on rather than the section: dark ink clears 5.63:1 on full
   pistachio but only 1.99:1 on the muted first band, where cream clears
   6.47:1. Measured against what is actually painted — the first two are
   translucent over the ink ground, not over the page. */
.run__seg i {
  font-style: normal;
  font-size: var(--fs-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--cream);
  opacity: 0;
  transition: opacity 400ms var(--ease) calc(var(--i, 0) * 220ms + 500ms);
}
.run__seg.is-last i { color: var(--ink); }
.run.is-in .run__seg i { opacity: 1; }
/* Narrow screens cannot fit the first band's number inside it, so the
   figure moves to the key instead of disappearing. */
@media (max-width: 720px) {
  .run__seg:first-child i { display: none; }
  .run__key li:nth-child(1)::after { content: ' 99'; font-weight: 600; color: var(--text); }
}

.run__key {
  display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-5);
  font-size: var(--fs-sm); color: var(--text-muted);
}
.run__key li { display: flex; align-items: center; gap: var(--s-2); }
.run__dot { width: 8px; height: 8px; border-radius: 2px; flex: none; }
.run__key li:nth-child(1) .run__dot { background: rgba(255, 241, 232, 0.28); }
.run__key li:nth-child(2) .run__dot { background: rgba(133, 176, 78, 0.55); }
.run__key li:nth-child(3) .run__dot { background: var(--pistachio); }
.run__note { max-width: 46ch; }

/* ---------- 14c. Client roster ----------
   Eleven logos in five formats and eleven palettes. Dropped in as supplied
   they would put eleven foreign colour schemes on a page built from one, so
   they are inked to a single colour the way the platform icons are — the
   silhouette carries the recognition, the palette stays the site's.

   The cell is the unit: the mark sits alone until you approach it, and the
   name, sector and market arrive on hover. That keeps the wall quiet at a
   glance and answers "who is this" on demand. */
.clients {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(13.5rem, 1fr));
  /* Hairlines are drawn per cell rather than by a gap over a coloured
     ground: eleven items never fill the last row evenly, and a background
     grid shows through the empty remainder as grey slabs. */
  gap: 0;
  border-top: 1px solid var(--line);
  border-left: 1px solid var(--line);
}
.client {
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.client__link {
  position: relative;
  display: grid;
  grid-template-rows: 1fr auto;
  gap: var(--s-3);
  min-height: 9.5rem;
  padding: var(--s-5) var(--s-4) var(--s-4);
  transition: background-color var(--dur) var(--ease);
}
.client__link:hover { background: rgba(65, 111, 59, 0.05); }

.client__mark {
  display: grid;
  place-items: center;
  min-height: 0;
}
/* one ink for every mark, so the wall reads as one wall */
.client__mark--ink { color: var(--forest); }
.client__mark--ink svg { width: auto; height: auto; max-width: 78%; max-height: 3.25rem; }
.client__mark--ink img {
  max-width: 78%; max-height: 3.25rem; width: auto; height: auto;
  /* the file is a cream silhouette; this stamps it in the page's own ink */
  filter: brightness(0) saturate(100%) invert(31%) sepia(18%) saturate(1180%) hue-rotate(72deg) brightness(94%) contrast(88%);
  opacity: 0.85;
  transition: opacity var(--dur) var(--ease);
}
.client__link:hover .client__mark--ink img { opacity: 1; }
/* Two marks carry their meaning in colour rather than shape — NATA is a
   light logotype on its own disc, SLY a fox built from orange gradations.
   Silhouetting either gives a solid blob, so they keep their artwork. */
.client__mark--art img,
.client__mark--art svg {
  max-width: 3.75rem; max-height: 3.75rem;
  width: auto; height: auto;
}

.client__meta { display: grid; gap: 2px; }
.client__name {
  font-size: var(--fs-sm);
  font-weight: 600;
  line-height: 1.2;
}
.client__tags {
  display: flex; align-items: center; gap: var(--s-2);
  font-size: var(--fs-label);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.client__tags i { width: 3px; height: 3px; border-radius: 50%; background: currentColor; flex: none; }

/* the arrow only appears on approach — it is a hint, not a permanent mark */
.client__go {
  position: absolute;
  top: var(--s-4); right: var(--s-4);
  width: 1rem; height: 1rem;
  color: var(--forest);
  opacity: 0;
  transform: translate(-4px, 4px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.client__go svg { width: 100%; height: 100%; transform: rotate(-45deg); }
.client__link:hover .client__go,
.client__link:focus-visible .client__go { opacity: 1; transform: none; }

@media (max-width: 560px) {
  .clients { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .client__link { min-height: 8rem; padding: var(--s-4) var(--s-3) var(--s-3); }
  .client__mark--ink svg, .client__mark--ink img { max-height: 2.5rem; }
}

/* ---------- 15. Testimonials ---------- */
.quote {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  padding: var(--s-5);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  height: 100%;
}

.quote__mark { font-family: var(--font-display); font-size: 3rem; line-height: 0.6; color: var(--accent); }
.quote__text { font-family: var(--font-sub); font-weight: 600; font-size: 1.125rem; line-height: 1.5; }
.quote__by { margin-top: auto; padding-top: var(--s-3); border-top: 1px solid var(--line); }
.quote__name { font-size: var(--fs-sm); font-weight: 600; }
.quote__role { font-size: var(--fs-label); letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted); margin-top: 4px; }

/* ---------- 16. Forms ---------- */
.form { display: grid; gap: var(--s-4); }
.field { display: grid; gap: var(--s-2); }
.field label {
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.field input, .field textarea {
  width: 100%;
  padding: 0.9375rem var(--s-3);
  min-height: 3.25rem;
  font: inherit;
  font-size: var(--fs-body);
  color: var(--text);
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  transition: border-color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.field textarea { min-height: 8rem; resize: vertical; line-height: 1.6; }
.field input::placeholder, .field textarea::placeholder { color: var(--text-muted); opacity: 0.6; }
.field input:hover, .field textarea:hover { border-color: var(--accent); }
.field input:focus, .field textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(133, 176, 78, 0.22);
}
.field__error { font-size: var(--fs-sm); color: #B3261E; display: none; }
.is-forest .field__error, .is-ink .field__error { color: #FFB4A8; }
.field.has-error input, .field.has-error textarea { border-color: #B3261E; }
.field.has-error .field__error { display: block; }
.form__note { font-size: var(--fs-sm); color: var(--text-muted); }
.form__status { font-size: var(--fs-sm); min-height: 1.5rem; }
.form__status[data-state='ok'] { color: var(--accent-text); }
.form__status[data-state='err'] { color: #B3261E; }
.is-forest .form__status[data-state='err'] { color: #FFB4A8; }
.hp { position: absolute; left: -9999px; opacity: 0; }

/* ---------- 17. Contact list ---------- */
.contacts { display: grid; gap: 0; }
.contacts a, .contacts div {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding-block: var(--s-4);
  border-bottom: 1px solid var(--line);
  transition: color var(--dur) var(--ease), padding-left var(--dur) var(--ease);
}
.contacts a:hover { color: var(--accent-text); padding-left: var(--s-3); }
.contacts svg { width: 1.25rem; height: 1.25rem; flex: none; stroke-width: 1.4; opacity: 0.8; }
.contacts .k {
  font-size: var(--fs-label); letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--text-muted); width: 6.5rem; flex: none;
}
.contacts .v { font-family: var(--font-sub); font-weight: 600; font-size: 1.0625rem; }

/* ---------- 18. Floating messenger dock ---------- */
.dock {
  position: fixed;
  right: var(--s-4);
  bottom: var(--s-4);
  z-index: var(--z-float);
  display: grid;
  justify-items: end;
  gap: var(--s-3);
}
.dock__items {
  display: grid;
  gap: var(--s-3);
  justify-items: end;
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease), visibility var(--dur);
}
.dock.is-open .dock__items { opacity: 1; visibility: visible; transform: translateY(0); }
.dock__item {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  padding: 0.75rem var(--s-4);
  background: var(--cream);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: var(--fs-sm);
  font-weight: 600;
  box-shadow: 0 18px 44px -28px rgba(57, 39, 23, 0.7);
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.dock__item:hover { background: var(--forest); color: var(--cream); border-color: var(--forest); }
.dock__item svg { width: 1.125rem; height: 1.125rem; flex: none; }
.dock__toggle {
  width: 3.5rem; height: 3.5rem;
  display: grid; place-items: center;
  background: var(--forest);
  color: var(--cream);
  border-radius: 999px;
  cursor: pointer;
  box-shadow: 0 20px 44px -22px rgba(65, 111, 59, 0.85);
  transition: background-color var(--dur) var(--ease);
}
.dock__toggle:hover { background: var(--forest-deep); }
.dock__toggle svg { width: 1.5rem; height: 1.5rem; transition: opacity var(--dur-fast) var(--ease); }
.dock__toggle .i-close { display: none; }
.dock.is-open .dock__toggle .i-chat { display: none; }
.dock.is-open .dock__toggle .i-close { display: block; }

/* ---------- 19. Footer ---------- */
.footer { background: var(--forest); color: var(--cream); padding-block: var(--s-7) var(--s-5); position: relative; overflow: clip; }
.footer a { color: rgba(255, 241, 232, 0.78); transition: color var(--dur) var(--ease); }
.footer a:hover { color: var(--pistachio); }
.footer__top { display: grid; grid-template-columns: 5fr 8fr; gap: clamp(var(--s-5), 5vw, var(--s-7)); }
.footer__nav { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-5); }
.footer__h {
  font-size: var(--fs-label); font-weight: 700; letter-spacing: 0.2em; text-transform: uppercase;
  color: rgba(255, 241, 232, 0.55); margin-bottom: var(--s-4);
}
.footer__nav li + li { margin-top: var(--s-3); }
.footer__nav a { font-size: var(--fs-sm); }
.footer__bottom {
  margin-top: var(--s-6); padding-top: var(--s-4);
  border-top: 1px solid rgba(255, 241, 232, 0.2);
  display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-5); justify-content: space-between; align-items: center;
  font-size: var(--fs-sm); color: rgba(255, 241, 232, 0.62);
}
.footer__lockup { width: min(26rem, 100%); color: var(--cream); }

/* the credit sits on the footer's own ground, so it reads at the same
   weight as the copyright rather than as dark text on dark */
.credit { color: rgba(255, 241, 232, 0.62); }

.social { display: flex; gap: var(--s-3); }
.social a {
  display: grid;
  place-items: center;
  width: 2.5rem; height: 2.5rem;
  border: 1px solid rgba(255, 241, 232, 0.24);
  border-radius: 50%;
  color: rgba(255, 241, 232, 0.78);
  transition: color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              background-color var(--dur-fast) var(--ease);
}
.social a:hover {
  color: var(--forest);
  background: var(--cream);
  border-color: var(--cream);
}
.social svg { width: 1.15rem; height: 1.15rem; }

/* ---------- 20. Platform page bits ---------- */
.page-hero {
  position: relative;
  padding-block: calc(var(--s-8) + var(--s-4)) var(--section-y);
  background: var(--bg);
  color: var(--text);
  overflow: clip;
}
.crumbs { display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center; font-size: var(--fs-sm); color: var(--text-muted); margin-bottom: var(--s-5); }
.crumbs a:hover { color: var(--accent-text); }
.crumbs span { opacity: 0.5; }

.spec { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr)); gap: var(--s-5); }
.spec__k { font-size: var(--fs-label); font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-muted); }
.spec__v { font-family: var(--font-sub); font-weight: 600; font-size: 1.125rem; margin-top: var(--s-2); }

.checks { display: grid; gap: var(--s-3); }
.checks li { display: flex; gap: var(--s-3); align-items: flex-start; font-size: var(--fs-sm); color: var(--text-muted); }
.checks svg { width: 1.125rem; height: 1.125rem; flex: none; color: var(--accent); margin-top: 0.25em; stroke-width: 1.6; }

.faq details {
  border-bottom: 1px solid var(--line);
  padding-block: var(--s-4);
}
.faq summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  gap: var(--s-4);
  align-items: center;
  justify-content: space-between;
  font-family: var(--font-sub);
  font-weight: 600;
  font-size: 1.125rem;
  transition: color var(--dur) var(--ease);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { color: var(--accent-text); }
.faq summary::after {
  content: '';
  width: 12px; height: 12px; flex: none;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: rotate(45deg) translate(-3px, -3px);
  transition: transform var(--dur) var(--ease);
}
.faq details[open] summary::after { transform: rotate(-135deg) translate(-3px, -3px); }
.faq p { margin-top: var(--s-3); max-width: 68ch; font-size: var(--fs-sm); color: var(--text-muted); }

/* ---------- 21. Scroll reveal ----------
   The hero leaves sideways, so the rest of the page arrives sideways: each
   block enters from the edge it is set against, which JS resolves from the
   element's own position in the 5/8 grid (--rx). Blocks that span the full
   measure have no side to come from and keep the vertical lift instead. */
.js [data-reveal] {
  opacity: 0;
  transform: translate3d(var(--rx, 0px), var(--ry, 24px), 0);
}
.js [data-reveal].is-in {
  opacity: 1;
  transform: none;
  transition: opacity 800ms var(--ease) calc(var(--d, 0) * 1ms), transform 980ms var(--ease) calc(var(--d, 0) * 1ms);
}
.js [data-reveal-x='left']  { --rx: -3.25rem; --ry: 0px; }
.js [data-reveal-x='right'] { --rx:  3.25rem; --ry: 0px; }

.js [data-reveal='mask'] { transform: none; clip-path: inset(0 0 100% 0); }
.js [data-reveal='mask'].is-in { clip-path: inset(0 0 0 0); transition: opacity 700ms var(--ease), clip-path 1000ms var(--ease); }

/* Display headings arrive a line at a time. The lines already exist in the
   markup as <br>-separated segments — JS only wraps them, so a heading reads
   identically with JavaScript off. Each line trails the one above it, which
   is the same fan the hero column leaves on. */
.js .rline { display: block; }
.js [data-reveal-lines] { opacity: 1; transform: none; }
.js .rline > span {
  display: block;
  opacity: 0;
  transform: translate3d(var(--rx, -2.5rem), 0, 0);
}
.js [data-reveal-lines].is-in .rline > span {
  opacity: 1;
  transform: none;
  transition: opacity 720ms var(--ease) calc(var(--l, 0) * 105ms + var(--d, 0) * 1ms),
              transform 900ms var(--ease) calc(var(--l, 0) * 105ms + var(--d, 0) * 1ms);
}

/* Ken-burns-free parallax layer */
.parallax { will-change: transform; }

/* ---------- 22. Responsive ---------- */
@media (max-width: 1080px) {
  .hero__photo { width: 22rem; opacity: 0.9; }
  .footer__top { grid-template-columns: 1fr; }
  .footer__nav { grid-template-columns: repeat(3, 1fr); }
}

@media (max-width: 960px) {
  :root { --gutter: var(--s-3); }
  .nav { display: none; }
  .burger { display: block; }
  /* the switcher stays in the bar on mobile — small enough, and reachable
     without opening the menu */
  .lang__opt { min-width: 2rem; padding: 0 0.25rem; }
  .header__inner { padding-right: 0.5rem; }

  .header.is-open .nav {
    display: grid;
    position: absolute;
    top: calc(100% + 0.5rem);
    left: 0; right: 0;
    padding: var(--s-4);
    gap: 0;
    background: var(--cream);
    border-radius: var(--radius);
    box-shadow: 0 22px 56px -26px rgba(57, 39, 23, 0.6);
    max-height: min(76vh, 38rem);
    overflow-y: auto;
  }
  .header.is-open .nav__link { padding: var(--s-3) 0; font-size: 1rem; border-bottom: 1px solid var(--line); }
  .header.is-open .nav__link::after { display: none; }
  .header.is-open .nav__has-sub { position: static; }
  .header.is-open .nav__sub {
    position: static; opacity: 1; visibility: visible; transform: none;
    border: 0; box-shadow: none; background: transparent; padding: 0 0 var(--s-3) var(--s-4);
    min-width: 0;
    /* one column in the drawer: two would leave the labels too narrow
       to read at this size */
    grid-template-columns: 1fr;
    width: auto;
  }
  .header.is-open .nav__sub a { padding: var(--s-2) 0; color: var(--text-muted); }
  .header.is-open .nav__sub-all { margin-top: var(--s-3); }

  .hero { min-height: auto; padding-block: calc(var(--s-8) + var(--s-3)) var(--s-6); }
  .hero__grid { grid-template-columns: 1fr; gap: var(--s-6); align-items: start; }
  .hero__photo { height: min(52svh, 24rem); object-position: 50% 14%; }
  .hero__stamp { left: auto; right: var(--s-4); bottom: -1.75rem; width: 5.5rem; }

  .phi, .phi--flip, .case, .footer__top { grid-template-columns: 1fr; }
  .grid-3, .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .step + .step { padding-left: 0; }
  .step:nth-child(even) { padding-left: var(--s-4); }
  .step:nth-child(even)::before { left: var(--s-4); }
  .step:nth-child(odd)::before { left: 0; }

  .c-3, .c-4, .c-5, .c-6, .c-7, .c-8, .c-9 { grid-column: span 13; }
  .start-6, .start-7, .start-9 { grid-column-start: auto; }
}

@media (max-width: 640px) {
  :root { --fs-body: 1rem; }
  .grid-3, .grid-4, .grid-2 { grid-template-columns: 1fr; }
  .steps { grid-template-columns: 1fr; }
  .step:nth-child(even) { padding-left: 0; }
  .step:nth-child(even)::before { left: 0; }
  .footer__nav { grid-template-columns: 1fr; gap: var(--s-5); }
  .contacts .k { width: 5rem; }
  .card { padding: var(--s-4); }
  .dock { right: var(--s-3); bottom: var(--s-3); }
}

/* ---------- 23. Reduced motion ----------
   DISABLED by client request — motion plays for everyone. Change `false`
   back to `(prefers-reduced-motion: reduce)` to restore the accessible
   behaviour; the rules inside are unchanged and still correct. */
@media false {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .js [data-reveal] { opacity: 1 !important; transform: none !important; clip-path: none !important; }
  .js .rline > span { opacity: 1 !important; transform: none !important; }
  .js .bloom.is-armed .petal { opacity: 1; transform: none; }
  .chart__bar { transform: scaleY(1); }
  .step::after { transform: scaleX(1); }
  .marquee__track { animation: none; }

  /* The pinned section keeps working — stepping through slides is navigation,
     not decoration, so it survives here. Only the motion is removed: slides
     cut instead of crossfading, and their contents do not slide up into
     place. Without this the inactive-slide rule above would still animate. */
  .js .pin .slide { transition: none; }
  .js .pin .slide:not(.is-active) .slide__left,
  .js .pin .slide:not(.is-active) .slide__right,
  .js .pin .slide:not(.is-active) .slide__index { transform: none; }
  .js .pin .slide__left,
  .js .pin .slide__right,
  .js .pin .slide__index { transition: none; }
}

/* ---------- 24. Print ---------- */
@media print {
  .header, .dock, .hero__scroll, .marquee { display: none !important; }
  .section, .hero { padding-block: 1.5rem; }
  body { background: #fff; color: #000; }
}
