/* ==========================================================================
   Typefaces - self-hosted (assets/fonts). Switzer and Sentient by Indian Type
   Foundry, via Fontshare (ITF Free Font License). Served from our own origin
   so no visitor IP reaches a font CDN before consent.
   ========================================================================== */

@font-face { font-family: 'Switzer'; src: url('../assets/fonts/switzer-300.woff2') format('woff2'); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: 'Switzer'; src: url('../assets/fonts/switzer-400.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Switzer'; src: url('../assets/fonts/switzer-500.woff2') format('woff2'); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'Sentient'; src: url('../assets/fonts/sentient-300.woff2') format('woff2'); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: 'Sentient'; src: url('../assets/fonts/sentient-300-italic.woff2') format('woff2'); font-weight: 300; font-style: italic; font-display: swap; }

/* ==========================================================================
   Navigant Holding - design tokens (design.md, Appendix A, verbatim values)
   ========================================================================== */

:root {
  /* ink */
  --ink:        #16181A;
  --ink-80:     #3B4045;
  --ink-55:     #6E7377;
  --ink-35:     #9AA0A4;

  /* surfaces */
  --porcelain:  #F4F5F6;
  --mist:       #E6E9EC;
  --white:      #FFFFFF;
  --line:       #D5DBE1;

  /* accent */
  --sky:        #C5D4E0;
  --sky-deep:   #9FB6C8;

  /* inversion */
  --ink-bg:     #16181A;
  --on-ink:     #F4F5F6;

  /* pearl LUT (shader + gradients only, never UI) */
  --pearl-1:    #C5D4E0;
  --pearl-2:    #D9D2E6;
  --pearl-3:    #CFE3DC;
  --pearl-4:    #EBD9DC;
  --pearl-5:    #F2ECE3;

  /* type families */
  --font-sans:  'Switzer', ui-sans-serif, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-serif: 'Sentient', Georgia, 'Times New Roman', serif;

  /* type scale - desktop (redefined <=768px below) */
  --t-display-1: 10rem;  --t-display-2: 6.25rem; --t-display-3: 5rem;
  --t-h1: 4rem;          --t-h2: 3rem;           --t-h3: 2rem;
  --t-lead: 1.5rem;      --t-body-l: 1.2rem;     --t-body: 1rem;
  --t-caption: 0.8rem;   --t-micro: 0.7rem;

  --lh-display: 0.9;  --lh-heading: 1.1;  --lh-body: 1.5;
  --ls-display: -0.035em; --ls-heading: -0.02em; --ls-body: 0; --ls-micro: 0.09em;

  /* grid */
  --grid-cols: 12;
  --gutter: 2rem;
  --edge: 1.25rem;
  --max-w: 2400px;

  /* spacing */
  --sp-05: 0.5rem;  --sp-1: 1rem;   --sp-2: 2rem;   --sp-3: 3rem;
  --sp-4:  4rem;    --sp-5: 5rem;   --sp-6: 6rem;   --sp-8: 8rem;
  --sp-10: 10rem;   --sp-13: 13rem; --sp-15: 15rem; --sp-20: 20rem;

  /* form */
  --r-pill: 12.5rem;  --r-btn: 1.5rem;  --r-circle: 50%;
  --r-media: 0;       --r-field: 0;
  --bw: 1px;          --bw-cursor: 1.5px;
  --glass: rgba(255,255,255,.62);
  --shadow-float: 0 1px 2px rgba(22,24,26,.04), 0 8px 24px rgba(22,24,26,.06);

  /* motion */
  --ease-out:      cubic-bezier(.19, 1, .22, 1);
  --ease-out-soft: cubic-bezier(.16, 1, .30, 1);
  --ease-inout:    cubic-bezier(.87, 0, .13, 1);
  --ease-micro:    cubic-bezier(.33, 1, .68, 1);
  --d-micro: .2s;  --d-fast: .3s;   --d-hover: .5s;
  --d-base:  .8s;  --d-reveal: 1s;  --d-scene: 2s;
  --stagger-char: .014s;  --stagger-item: .03s;  --stagger-block: .05s;

  /* shader */
  --fx-dispersion: 0.12;
  --fx-grain:      0.030;
  --fx-vignette:   0.050;
  --field-intensity-hero:    0.55;
  --field-intensity-cta:     0.45;
  --field-intensity-contact: 0.40;
  --field-intensity-bg:      0.20;
  --iso-density: 16;
  --iso-alpha:   0.14;
}

@media (min-width: 768px)  { :root { --edge: 2rem;   } }
@media (min-width: 1366px) { :root { --edge: 2.5rem; } }

/* design.md's type scale only defines Desktop / <=768px steps; the frozen
   14px root between 768-1400px (§II.5) makes desktop-scale display tokens
   wrap badly on tablet widths, so the smaller step is applied through
   1024px (the grid's own tablet upper bound, §II.6) rather than inventing
   a third scale the brief never specified. */
@media (max-width: 1024px) {
  :root {
    --t-display-1: 4rem;   --t-display-2: 3.25rem; --t-display-3: 3rem;
    --t-h1: 2.5rem;        --t-h2: 2.25rem;        --t-h3: 1.6rem;
    --t-lead: 1.3rem;      --t-body-l: 1.1rem;
  }
}

/* ==========================================================================
   Reset + fluid-rem foundation
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }
html {
  font-size: clamp(14px, 1vw, 24px);
  scroll-behavior: auto;
  /* any future overflow stays un-pannable on iOS; hidden is the fallback for
     browsers without clip */
  overflow-x: hidden;
  overflow-x: clip;
}
body {
  margin: 0;
  background: var(--porcelain);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  overflow-x: clip;
}
body.is-gated { overflow: hidden; height: 100vh; }
html.no-scroll, html.no-scroll body { overflow: hidden; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: none; padding: 0; cursor: pointer; }
ul, ol { list-style: none; margin: 0; padding: 0; }
h1, h2, h3, p { margin: 0; }
input, textarea { font: inherit; color: inherit; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

.icon-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.icon { width: 1em; height: 1em; display: inline-block; vertical-align: -0.15em; }
.icon--down { transform: rotate(90deg); }

.skip-link {
  position: fixed; top: -3rem; left: var(--edge); z-index: 12000;
  background: var(--ink); color: var(--on-ink);
  padding: 0.75rem 1.25rem; border-radius: var(--r-btn);
  font-size: var(--t-caption); transition: top var(--d-micro) var(--ease-micro);
}
.skip-link:focus { top: var(--edge); }

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

/* ==========================================================================
   Type
   ========================================================================== */

.display-1, .display-2, .display-3 { font-family: var(--font-sans); font-weight: 300; line-height: var(--lh-display); letter-spacing: var(--ls-display); }
.display-1 { font-size: var(--t-display-1); }
.display-2 { font-size: var(--t-display-2); }
.display-3 { font-size: var(--t-display-3); }

h1, h2, h3 { font-family: var(--font-sans); font-weight: 400; line-height: var(--lh-heading); letter-spacing: var(--ls-heading); }
h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); }
.h3 { font-size: var(--t-h3); line-height: var(--lh-heading); letter-spacing: var(--ls-heading); }
.lead { font-size: var(--t-lead); line-height: 1.35; letter-spacing: -0.01em; }
.body-l { font-size: var(--t-body-l); line-height: 1.45; letter-spacing: -0.005em; }
.caption { font-size: var(--t-caption); line-height: 1.4; color: var(--ink-55); }
.micro, .section-label__n, .section-label__text {
  font-size: var(--t-micro); line-height: 1.2; letter-spacing: var(--ls-micro);
  text-transform: uppercase; font-weight: 500;
}
.section-label__n { font-weight: 300; }

em { font-family: var(--font-serif); font-style: italic; font-weight: 300; letter-spacing: 0; }

/* ==========================================================================
   Persistent visual layers
   ========================================================================== */

#gl {
  position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: 0; pointer-events: none;
}
/* A8: a rendered frame of the real field (assets/field/), not a lookalike
   gradient. Shown wherever the shader can't or shouldn't run. */
.field-poster { position: fixed; inset: 0; z-index: 0; pointer-events: none; display: none; }
.field-poster img { width: 100%; height: 100%; object-fit: cover; }
.no-webgl .field-poster, .reduced-motion .field-poster { display: block; }
.no-webgl #gl, .reduced-motion #gl { display: none; }

/* M15: three tiles cycled at 8 steps/sec. Film grain shouldn't be smooth,
   so this is steps(), not a transition; the raster tiles also cost less on
   weak GPUs than re-running feTurbulence every frame. */
.grain-overlay {
  position: fixed; inset: 0; z-index: 9000; pointer-events: none;
  opacity: var(--fx-grain);
  mix-blend-mode: multiply;
  background-image: url("../assets/texture/grain-01.png");
  background-repeat: repeat;
  background-size: 256px 256px;
  animation: grain-phase 0.375s steps(1, end) infinite;
}
@keyframes grain-phase {
  0%   { background-image: url("../assets/texture/grain-01.png"); background-position: 0 0; }
  33%  { background-image: url("../assets/texture/grain-02.png"); background-position: -37px 91px; }
  66%  { background-image: url("../assets/texture/grain-03.png"); background-position: 113px -53px; }
}
/* not legible on a phone, and it costs battery there */
@media (pointer: coarse) { .grain-overlay { animation: none; } }

.scroll-progress {
  position: fixed; top: 0; right: 0; width: 2px; height: 100vh; height: 100svh;
  z-index: 9500; background: var(--line); pointer-events: none;
}
.scroll-progress__bar {
  display: block; width: 100%; height: 100%; background: var(--ink);
  transform: scaleY(0); transform-origin: top;
  transition: transform 0.05s linear;
}

/* custom cursor */
.cursor {
  position: fixed; top: 0; left: 0; z-index: 11000;
  width: 2.2rem; height: 2.2rem; margin: -1.1rem 0 0 -1.1rem;
  pointer-events: none; display: none;
}
.has-cursor .cursor { display: block; }
.has-cursor, .has-cursor * { cursor: none; }
/* elements where cursor.js hides the custom cursor need the native one back */
.has-cursor input, .has-cursor textarea { cursor: text; }
.has-cursor .logo-lockup, .has-cursor [data-cursor="hide"] { cursor: pointer; }
.cursor__circle {
  position: absolute; inset: 0; border-radius: 50%;
  border: var(--bw-cursor) solid var(--ink);
  transition: transform var(--d-fast) var(--ease-micro), border-color var(--d-hover) var(--ease-out), background-color var(--d-fast) var(--ease-micro);
}
.cursor__label {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: var(--t-micro); text-transform: uppercase; letter-spacing: var(--ls-micro);
  opacity: 0; transition: opacity var(--d-fast) var(--ease-micro);
  white-space: nowrap;
}
.cursor.is-link .cursor__circle { transform: scale(0.55); background: var(--ink); }
.cursor.is-media { width: 5rem; height: 5rem; margin: -2.5rem 0 0 -2.5rem; }
.cursor.is-media .cursor__circle { background: var(--glass); backdrop-filter: blur(20px) saturate(1.4); border-color: rgba(255,255,255,.7); }
.cursor.is-media .cursor__label { opacity: 1; color: var(--ink); }
.cursor.is-hide { opacity: 0; }

@media (pointer: coarse) { .has-cursor .cursor { display: none !important; } }

/* ==========================================================================
   Layout primitives
   ========================================================================== */

.screen {
  position: relative;
  padding-inline: var(--edge);
  display: flex; flex-direction: column;
  z-index: 1;
}

.section-label { display: flex; align-items: center; gap: var(--sp-1); margin-bottom: var(--sp-2); }
.section-label__n { font-family: var(--font-serif); font-style: italic; color: var(--ink-55); text-transform: none; letter-spacing: 0; }
.section-label__rule { flex: 1 1 auto; height: 1px; background: var(--line); transform-origin: left; transform: scaleX(0); transition: transform var(--d-base) var(--ease-out); max-width: 12rem; }
.reveal-in .section-label__rule { transform: scaleX(1); }
.section-label__text { color: var(--ink-55); }

/* ==========================================================================
   Intro gate
   ========================================================================== */

.gate {
  position: fixed; inset: 0; z-index: 10000;
  background: var(--porcelain);
  display: flex; align-items: center; justify-content: center;
  flex-direction: column;
  transition: opacity 1.2s var(--ease-inout);
}
.gate__inner { display: flex; flex-direction: column; align-items: center; gap: var(--sp-3); text-align: center; padding: var(--sp-2); }
.gate__drum { height: 2rem; overflow: hidden; transition: height var(--d-hover) var(--ease-inout), opacity var(--d-fast) var(--ease-micro); }
.gate__drum.is-done { height: 0; opacity: 0; }
.gate__drum-track { display: flex; gap: 0.15em; font-family: var(--font-sans); color: var(--ink); }
.gate__reel { display: inline-block; height: 2rem; overflow: hidden; }
.gate__reel-col { display: flex; flex-direction: column; transition: transform 0.9s var(--ease-out); }
.gate__reel-char { height: 2rem; line-height: 2rem; font-size: 1.6rem; width: 1.15rem; text-align: center; }
/* M1: the gate's lockup draws itself, then fills. Two stacked copies -
   stroked letters on top for the draw, the merged solid underneath. */
.lockup--gate { position: relative; width: 15rem; }
.lockup--gate .lockup__draw,
.lockup--gate .lockup__solid { display: block; width: 100%; height: auto; }
.lockup--gate .lockup__solid { position: absolute; inset: 0; opacity: 0; transition: opacity var(--d-fast) var(--ease-micro); }
.lockup--gate .lockup__draw path {
  fill: none; stroke: currentColor; stroke-width: 0.5;
  stroke-dasharray: 100; stroke-dashoffset: 100;
  transition: stroke-dashoffset 0.9s var(--ease-out), opacity var(--d-fast) linear;
  transition-delay: calc(var(--i) * 0.045s);
}
.lockup--gate.is-drawing .lockup__draw path { stroke-dashoffset: 0; }
.lockup--gate.is-filled .lockup__solid { opacity: 1; }
.lockup--gate.is-filled .lockup__draw path { opacity: 0; transition-delay: 0s; }
.gate__lockup { opacity: 0; transition: opacity var(--d-fast) var(--ease-micro); }
.gate__lockup.is-visible { opacity: 1; }
.gate__teaser { max-width: 32rem; font-size: var(--t-caption); color: var(--ink-80); line-height: 1.6; }
.gate__enter { margin-top: var(--sp-1); }
.gate__progress {
  position: absolute; bottom: var(--sp-3); left: 0; right: 0; text-align: center;
  font-size: var(--t-micro); text-transform: uppercase; letter-spacing: var(--ls-micro); color: var(--ink-55);
  display: flex; justify-content: center; gap: 0.5em;
}

.gate.is-leaving { opacity: 0; pointer-events: none; }
.gate[hidden] { display: none; }

/* ==========================================================================
   Header + logo + nav
   ========================================================================== */

.site-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 5000;
  height: 5rem; padding-inline: var(--edge);
  display: flex; align-items: center; justify-content: space-between;
  color: var(--ink);
  transition: color var(--d-hover) var(--ease-out);
}

/* A3: the lockup is outlined (assets/brand/lockup-*.svg, inlined in the
   markup). Live <text> on a webfont used to flash a fallback face here. */
.lockup { display: block; fill: currentColor; }
.lockup--header { height: 1.3rem; width: auto; }
.logo-lockup { display: block; }

.header__right { display: flex; align-items: center; gap: var(--sp-2); }

.site-nav { display: flex; gap: 0.5rem; }
.nav-item {
  position: relative; overflow: hidden; display: inline-flex;
  padding: 0.15rem 0.75rem; font-size: var(--t-body);
}
.nav-item::after {
  content: ''; position: absolute; left: 0.75rem; right: 0.75rem; bottom: 0.05rem; height: 1px;
  background: currentColor; transform: scaleX(0); transform-origin: left;
  transition: transform var(--d-fast) var(--ease-out);
}
.nav-item[aria-current="true"]::after { transform: scaleX(1); }
.nav-item .swap__alt { font-size: 1.08em; }

/* generic sans <-> serif-italic character swap (nav + menu items) */
.swap { display: inline-flex; }
.swap__char { position: relative; display: inline-block; overflow: hidden; }
.swap__base, .swap__alt {
  display: inline-block; transition: transform var(--d-hover) var(--ease-out);
  transition-delay: calc(var(--i, 0) * var(--stagger-char));
}
.swap__alt {
  position: absolute; left: 0; top: 0; transform: translateY(105%);
  font-family: var(--font-serif); font-style: italic; font-weight: 300;
}
.nav-item:hover .swap__base, .nav-item:focus-visible .swap__base,
.menu-item:hover .swap__base, .menu-item:focus-visible .swap__base { transform: translateY(-105%); }
.nav-item:hover .swap__alt, .nav-item:focus-visible .swap__alt,
.menu-item:hover .swap__alt, .menu-item:focus-visible .swap__alt { transform: translateY(0); }

.menu-btn { position: relative; width: 3.7rem; height: 3.7rem; display: grid; place-items: center; }
.menu-btn__zone {
  width: 2.7rem; height: 2.7rem; border-radius: 50%;
  border: var(--bw) solid currentColor;
  display: grid; place-items: center;
  transition: background var(--d-hover) var(--ease-inout);
}
.menu-btn__dots { display: flex; gap: 0.25rem; transition: transform var(--d-hover) var(--ease-inout); }
.menu-btn__dots i { width: 0.3rem; height: 0.3rem; border-radius: 50%; background: currentColor; }
.menu-btn[aria-expanded="true"] .menu-btn__dots { transform: rotate(45deg) scale(1.4); }
.menu-btn[aria-expanded="true"] .menu-btn__dots i:first-child { transform: translate(0.18rem, 0); }
.menu-btn[aria-expanded="true"] .menu-btn__dots i:last-child { transform: translate(-0.18rem, 0); }

@media (max-width: 768px) { .site-nav { display: none; } }

/* ==========================================================================
   Menu overlay
   ========================================================================== */

.menu-overlay { position: fixed; inset: 0; z-index: 9800; }
.menu-overlay[hidden] { display: none; }
.menu-overlay__scrim {
  position: absolute; inset: 0; background: rgba(22,24,26,.35); backdrop-filter: blur(2px);
  opacity: 0; transition: opacity var(--d-base) var(--ease-inout);
}
.menu-overlay.is-open .menu-overlay__scrim { opacity: 1; }

.menu-overlay__panel {
  position: absolute; top: 0; right: 0; bottom: 0; width: 100%; max-width: 41rem;
  overflow: hidden; background: var(--mist);
  transform: translateX(100%); transition: transform var(--d-base) var(--ease-inout);
}
.menu-overlay.is-open .menu-overlay__panel { transform: translateX(0); }

.menu-overlay__inner {
  height: 100%; padding: 6rem var(--edge) 4rem 3rem;
  display: flex; flex-direction: column; justify-content: space-between;
  transform: translateX(-100%); transition: transform var(--d-base) var(--ease-inout);
}
.menu-overlay.is-open .menu-overlay__inner { transform: translateX(0); }

.menu-overlay__nav { display: flex; flex-direction: column; gap: 0.5rem; }
.menu-item {
  position: relative; display: flex; align-items: baseline; gap: 1rem;
  padding: 0.5rem 0; overflow: hidden;
}
.menu-item__n { font-family: var(--font-sans); font-weight: 500; font-size: var(--t-micro); letter-spacing: var(--ls-micro); color: var(--ink-55); }
.menu-item .swap {
  font-family: var(--font-serif); font-weight: 300; font-size: 3.25rem; line-height: 0.95; letter-spacing: -0.02em;
}
.menu-item .swap__alt { font-size: 1em; }

.menu-overlay__footer { display: flex; flex-direction: column; gap: 0.75rem; }
.menu-overlay__meta { margin: 0; }

.menu-overlay__close {
  position: absolute; top: 1.5rem; right: 1.5rem; z-index: 2;
  width: 2.7rem; height: 2.7rem; border-radius: 50%; background: var(--white);
  display: grid; place-items: center; font-size: 1.2rem;
  box-shadow: var(--shadow-float);
}

@media (min-width: 768px) {
  .menu-item .swap { font-size: 6.25rem; }
  .menu-overlay__inner { padding: 8.3rem 0 8.3rem 6.25rem; }
}

/* ==========================================================================
   Buttons
   ========================================================================== */

.btn {
  --text: var(--ink); --hover-text: var(--porcelain); --border: var(--ink); --fill: var(--ink); --bg: transparent;
  position: relative; display: inline-flex; align-items: center; gap: 0.6rem;
  height: 2.9rem; padding: 0.8rem 1.5rem; border-radius: var(--r-btn);
  border: var(--bw) solid var(--border); background: var(--bg); color: var(--text);
  font-size: 1.05rem; line-height: 0.9; overflow: hidden;
}
.btn::before {
  content: ''; position: absolute; inset: 0; background: var(--fill);
  clip-path: inset(100% 0 0 0); transition: clip-path var(--d-hover) var(--ease-out);
  z-index: 0;
}
.btn:hover::before, .btn:focus-visible::before { clip-path: inset(0 0 0 0); }
.btn__label-wrap { position: relative; z-index: 1; overflow: hidden; display: inline-grid; }
.btn__label { grid-area: 1 / 1; transition: transform var(--d-hover) var(--ease-out), color var(--d-hover) var(--ease-out); }
.btn__label--clone { transform: translateY(-120%); }
.btn:hover .btn__label:not(.btn__label--clone), .btn:focus-visible .btn__label:not(.btn__label--clone) { transform: translateY(120%); }
.btn:hover .btn__label--clone, .btn:focus-visible .btn__label--clone { transform: translateY(0); }
.btn:hover, .btn:focus-visible { color: var(--hover-text); }
.btn__icon { position: relative; z-index: 1; transition: transform var(--d-hover) var(--ease-out), color var(--d-hover) var(--ease-out); }
.btn:hover .btn__icon, .btn:focus-visible .btn__icon { color: var(--hover-text); transform: translate(0.15rem, -0.1rem); }

.btn--light  { --text: var(--ink);       --hover-text: var(--porcelain); --border: var(--ink);       --fill: var(--ink); }
.btn--dark   { --text: var(--porcelain); --hover-text: var(--ink);       --border: var(--porcelain); --fill: var(--porcelain); }
.btn--solid  { --text: var(--porcelain); --hover-text: var(--ink); --border: var(--ink); --bg: var(--ink); --fill: var(--sky); }

.arrow-link { position: relative; display: inline-flex; align-items: center; gap: 0.2rem; }
.arrow-link__arrow { display: inline-block; transform: translate(-0.4rem, 0.1rem); opacity: 0; transition: transform var(--d-fast) var(--ease-micro), opacity var(--d-fast) var(--ease-micro); }
.arrow-link::after {
  content: ''; position: absolute; left: 0; right: 1.3em; bottom: -0.1em; height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: left; transition: transform var(--d-fast) var(--ease-micro);
}
.arrow-link:hover, .arrow-link:focus-visible { transform: translateX(0.2rem); }
.arrow-link:hover .arrow-link__arrow, .arrow-link:focus-visible .arrow-link__arrow { transform: translate(0,0); opacity: 1; }
.arrow-link:hover::after, .arrow-link:focus-visible::after { transform: scaleX(1); }

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
  /* the scrim below reaches 15% past both edges; unclipped, that made the
     document ~60px wider than a phone, and iOS let the page be dragged
     sideways to reach it. Its outer third is transparent, so the clip is
     invisible. */
  overflow-x: clip;
  min-height: 100vh; min-height: 100svh;
  align-items: center; justify-content: center; text-align: center;
  padding-top: 5rem;
}
/* DESIGN.md §15.3: text on the shader always sits on a scrim, checked at
   the field's most saturated point, not its average color. z-index:-1
   keeps it under the (non-positioned, normal-flow) headline while staying
   inside .hero's own stacking context, above the fixed canvas behind it. */
.hero::before {
  content: ''; position: absolute; z-index: -1;
  inset: 10% -15%;
  background: radial-gradient(60% 65% at 50% 50%, color-mix(in srgb, var(--porcelain) 65%, transparent) 0%, transparent 70%);
  pointer-events: none;
}
.hero__headline { position: relative; font-family: var(--font-sans); font-weight: 300; font-size: var(--t-display-1); line-height: var(--lh-display); letter-spacing: -0.04em; }
.hero__cta { margin-top: var(--sp-3); }

/* char/word reveal */
.char-word { display: inline-block; white-space: nowrap; }
/* The reveal splits headlines into inline-block words, and every inline-block
   boundary is a legal line break - so a period after </em> could wrap onto a
   line of its own (it did, on a 393px iPhone 16). .nobr keeps it with the word. */
.nobr { white-space: nowrap; }
/* The cells clip their word/char while it sits below the line (that's what
   makes the reveal read as a rise). The clip box is one line-height tall, and
   at line-height < 1 that cuts the tails off g/y/p - so extend the box below
   the baseline and pull the extra height back off with a negative margin, so
   nothing moves in the layout. */
.char-cell, .word-cell {
  display: inline-block; overflow: hidden; vertical-align: top;
  padding-bottom: 0.14em; margin-bottom: -0.14em;
}
.reveal-chars .char, .reveal-words .word {
  display: inline-block; will-change: transform, opacity;
  transform: translateY(1.2rem); opacity: 0;
  transition: transform var(--d-reveal) var(--ease-out), opacity var(--d-reveal) var(--ease-out);
}
.reveal-in .char, .reveal-in .word { transform: translateY(0); opacity: 1; }

/* ==========================================================================
   Statement
   ========================================================================== */

.statement { min-height: 60svh; justify-content: center; padding-block: var(--sp-6); max-width: 62rem; }
.statement__text { font-family: var(--font-sans); font-weight: 300; font-size: var(--t-display-3); line-height: 0.95; letter-spacing: -0.03em; }
/* the italic word answers a hover over the sentence, same rule-draw idiom */
.statement__text em { position: relative; transition: color var(--d-fast) var(--ease-micro); }
.statement__text em::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0.08em; height: 1px;
  background: currentColor; transform: scaleX(0); transform-origin: left;
  transition: transform var(--d-base) var(--ease-out);
}
.statement__text:hover em::after { transform: scaleX(1); }

/* ==========================================================================
   Work / case cards
   ========================================================================== */

.work { min-height: 80svh; padding-block: var(--sp-8); gap: var(--sp-5); }
.work__head { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--sp-2); }
.work__count { margin-left: auto; }

.work__list { display: grid; grid-template-columns: repeat(12, 1fr); gap: var(--gutter) var(--gutter); }
.case-card { position: relative; transition: opacity var(--d-hover) var(--ease-out); }
.case-card--wide { grid-column: span 8; }
.case-card--narrow { grid-column: span 6; }
/* asymmetric zigzag, one explicit row per card (DESIGN.md §10.6) */
.case-card--1 { grid-row: 1; grid-column: 1 / span 8; }
.case-card--2 { grid-row: 2; grid-column: 7 / span 6; }
.case-card--3 { grid-row: 3; grid-column: 1 / span 6; }
.case-card--4 { grid-row: 4; grid-column: 5 / span 8; }
.case-card--5 { grid-row: 5; grid-column: 1 / span 8; }

.case-card__link, .case-card { display: block; }
.case-card__frame { position: relative; }
.case-card__media {
  display: block; aspect-ratio: 16 / 10; border-radius: var(--r-media);
  overflow: hidden; position: relative;
}
/* A1 + M4: real covers. The picture scales inside the media box; the box
   itself is what M4d clips open and M4a tilts. */
.case-card__pic, .case-card__pic img { display: block; width: 100%; height: 100%; }
.case-card__pic img { object-fit: cover; }
.case-card__pic {
  position: absolute; inset: 0;
  /* single transform, composed from variables - reveal (--pic-scale), hover
     and tilt (--px/--py) would otherwise overwrite each other */
  transform: scale(var(--pic-scale, 1.001)) translate3d(var(--px, 0px), var(--py, 0px), 0);
  transition: transform var(--d-base) var(--ease-out);
  will-change: transform;
}
.case-card:not(.case-card--static):hover .case-card__pic,
.case-card:not(.case-card--static):focus-within .case-card__pic { --pic-scale: 1.04; }

/* A12: hairline chassis + corner crop marks, drawn over any cover (the
   generated placeholders bake it in too, so real photos match them) */
.case-card__chassis { position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity var(--d-hover) var(--ease-out); }
.case-card__chassis::before {
  content: ''; position: absolute; inset: 2.8%;
  border: var(--bw) solid color-mix(in srgb, var(--ink) 22%, transparent);
}
/* ink, not white: the covers are shots mounted on a porcelain board, and the
   frame lands in that board's margin where a white hairline would vanish */
.case-card__chassis::after {
  content: ''; position: absolute; inset: 1.2%;
  --mark: color-mix(in srgb, var(--ink) 38%, transparent);
  background:
    linear-gradient(to right, var(--mark) 0 1.6%, transparent 1.6%) top left / 100% 1px no-repeat,
    linear-gradient(to bottom, var(--mark) 0 3%, transparent 3%) top left / 1px 100% no-repeat,
    linear-gradient(to left, var(--mark) 0 1.6%, transparent 1.6%) top right / 100% 1px no-repeat,
    linear-gradient(to bottom, var(--mark) 0 3%, transparent 3%) top right / 1px 100% no-repeat,
    linear-gradient(to right, var(--mark) 0 1.6%, transparent 1.6%) bottom left / 100% 1px no-repeat,
    linear-gradient(to top, var(--mark) 0 3%, transparent 3%) bottom left / 1px 100% no-repeat,
    linear-gradient(to left, var(--mark) 0 1.6%, transparent 1.6%) bottom right / 100% 1px no-repeat,
    linear-gradient(to top, var(--mark) 0 3%, transparent 3%) bottom right / 1px 100% no-repeat;
  opacity: 0.8;
}
.case-card:hover .case-card__chassis, .case-card:focus-within .case-card__chassis { opacity: 1; }

/* M4b: hover video, faded in over its own first frame */
.case-card__video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: 0; pointer-events: none;
  transition: opacity var(--d-hover) var(--ease-out);
}
.case-card.is-playing .case-card__video { opacity: 1; }

/* hovering one case recedes the rest of the grid */
.work__list:has(.case-card:hover) .case-card:not(:hover),
.work__list:has(.case-card:focus-within) .case-card:not(:focus-within) { opacity: 0.45; }

/* light sweeping across the cover, once per hover */
.case-card__media::after {
  content: ''; position: absolute; inset: -1px; pointer-events: none;
  background: linear-gradient(105deg, transparent 38%, color-mix(in srgb, var(--white) 60%, transparent) 50%, transparent 62%);
  transform: translateX(-115%);
  transition: transform 1.15s var(--ease-out);
}
.case-card:not(.case-card--static):hover .case-card__media::after,
.case-card:not(.case-card--static):focus-within .case-card__media::after { transform: translateX(115%); }

.case-card__badge {
  position: absolute; top: 1rem; left: 1rem; z-index: 1;
  padding: 0.325rem 0.875rem; border-radius: var(--r-pill); border: var(--bw) solid var(--line);
  background: var(--glass); backdrop-filter: blur(20px);
  pointer-events: none;
  transition: transform var(--d-fast) var(--ease-micro);
}
.case-card:hover .case-card__badge, .case-card:focus-within .case-card__badge { transform: translateY(-0.25rem); }
.case-card__meta-row { position: relative; display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-top: 1rem; transition: transform var(--d-fast) var(--ease-micro); }
.case-card__title { font-weight: 400; transition: font-style var(--d-hover) var(--ease-out); }
.case-card:not(.case-card--static):hover .case-card__title,
.case-card:not(.case-card--static):focus-within .case-card__title { font-family: var(--font-serif); font-style: italic; font-weight: 300; }
.case-card:not(.case-card--static):hover .case-card__meta-row,
.case-card:not(.case-card--static):focus-within .case-card__meta-row { transform: translateX(0.3rem); }
.case-card__meta { margin: 0; }

/* hairline under the caption, drawn left-to-right like the section rules */
.case-card__meta-row::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -0.55rem; height: 1px;
  background: var(--line); transform: scaleX(0); transform-origin: left;
  transition: transform var(--d-base) var(--ease-out);
}
.case-card:not(.case-card--static):hover .case-card__meta-row::after,
.case-card:not(.case-card--static):focus-within .case-card__meta-row::after { transform: scaleX(1); }

.case-card__link--overlay { display: block; width: 100%; text-align: left; }

@media (max-width: 1024px) {
  .case-card--1, .case-card--2, .case-card--3, .case-card--4, .case-card--5 {
    grid-row: auto; grid-column: 1 / -1;
  }
}

/* ==========================================================================
   Process
   ========================================================================== */

.process { min-height: 50svh; justify-content: center; padding-block: var(--sp-6); }
/* with the camera move carrying the entrance, the per-item pop is one
   animation too many - the counters and the drawing draw-on still fire */
.process.has-zoom .reveal-item { opacity: 1; transform: none; transition: none; }
.process__list { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gutter); }
.process__step { position: relative; padding-top: 1.1rem; transition: transform var(--d-hover) var(--ease-out), opacity var(--d-hover) var(--ease-out); }
.process__step::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: var(--line); transform: scaleX(0); transform-origin: left;
  transition: transform var(--d-base) var(--ease-out);
}
.process__list:has(.process__step:hover) .process__step:not(:hover) { opacity: 0.5; }
.process__step:hover { transform: translateY(-0.3rem); }
.process__step:hover::before { transform: scaleX(1); }
.process__num { display: block; color: var(--ink-55); margin-bottom: 1rem; transition: color var(--d-fast) var(--ease-micro), font-style var(--d-hover) var(--ease-out); }
.process__step:hover .process__num { font-family: var(--font-serif); font-style: italic; color: var(--ink); }
.process__name { margin-bottom: 0.5rem; }
.process__desc { color: var(--ink-80); max-width: 26ch; }
@media (max-width: 768px) { .process__list { grid-template-columns: 1fr; gap: var(--sp-3); } }


/* ==========================================================================
   CTA + Contact
   ========================================================================== */

.cta {
  min-height: 100vh; min-height: 100svh; justify-content: center; align-items: center;
  padding-block: var(--sp-20) var(--sp-6); gap: var(--sp-5); position: relative;
}
@media (max-width: 768px) { .cta { padding-top: var(--sp-10); } }
.cta__intro { position: relative; max-width: 44rem; text-align: center; }
.cta__intro::before {
  content: ''; position: absolute; z-index: -1;
  inset: -15% -20%;
  background: radial-gradient(65% 70% at 50% 40%, color-mix(in srgb, var(--porcelain) 65%, transparent) 0%, transparent 70%);
  pointer-events: none;
}
.cta__headline { font-family: var(--font-sans); font-weight: 300; font-size: var(--t-display-2); line-height: 0.92; letter-spacing: -0.035em; }
.cta__lead { margin-top: var(--sp-2); max-width: 34rem; margin-inline: auto; }
.cta__email { margin-top: var(--sp-2); }

.contact-form, .cta__success {
  width: 100%; max-width: 40rem; padding: var(--sp-2);
  background: var(--glass);
  border: var(--bw) solid var(--line);
  box-shadow: var(--shadow-float);
  backdrop-filter: blur(14px) saturate(1.08);
  -webkit-backdrop-filter: blur(14px) saturate(1.08);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .contact-form, .cta__success { background: color-mix(in srgb, var(--white) 90%, transparent); }
}
@media (max-width: 768px) { .contact-form, .cta__success { padding: var(--sp-1); } }
.contact-form__fieldset { border: 0; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.field { display: flex; flex-direction: column; gap: 0.4rem; }
.field label, .field__group-label { font-size: var(--t-micro); text-transform: uppercase; letter-spacing: var(--ls-micro); color: var(--ink-55); }
.field__optional { text-transform: none; letter-spacing: 0; }
.field input, .field textarea {
  border: none; border-bottom: var(--bw) solid var(--line); border-radius: var(--r-field);
  background: color-mix(in srgb, var(--white) 55%, transparent); padding: 0.75rem 0.6rem; font-size: var(--t-body-l);
  transition: border-color var(--d-fast) var(--ease-micro);
  resize: vertical;
}
.field input:hover, .field textarea:hover { border-bottom-color: var(--ink-55); }
.field input:focus-visible, .field textarea:focus-visible { border-bottom-color: var(--ink); outline-offset: 4px; }
.field.has-error input, .field.has-error textarea { border-bottom-width: 1.5px; border-bottom-color: var(--ink); }
.field__err { font-size: var(--t-caption); color: var(--ink-80); min-height: 1.2em; }

.pill-group { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.pill-toggle {
  padding: 0.5rem 1.1rem; border-radius: var(--r-pill); border: var(--bw) solid var(--line);
  font-size: var(--t-caption); background: var(--white);
  transition: background var(--d-fast) var(--ease-micro), color var(--d-fast) var(--ease-micro), border-color var(--d-fast) var(--ease-micro), transform var(--d-fast) var(--ease-micro);
}
.pill-toggle:hover { border-color: var(--ink-55); transform: translateY(-1px); }
.pill-toggle[aria-pressed="true"] { background: var(--ink); color: var(--porcelain); border-color: var(--ink); }

.contact-form__submit { align-self: center; margin-top: 0.5rem; }
.contact-form__status { min-height: 1.4em; font-size: var(--t-caption); color: var(--ink-80); text-align: center; }

.cta__success { text-align: center; display: flex; flex-direction: column; align-items: center; }
.cta__thanks { font-family: var(--font-serif); font-weight: 300; font-size: var(--t-display-3); }
.cta__success[hidden] { display: none; }

/* colophon: seal, then company / reg / city on one centred axis */
.cta__legal {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-1);
  margin-top: var(--sp-3); text-align: center;
}
.cta__legal p { margin: 0; }
.cta__legal-lines { display: flex; flex-direction: column; gap: 0.15rem; }

/* ==========================================================================
   Case overlay (archived galleries)
   ========================================================================== */

.case-overlay {
  position: fixed; inset: 0; z-index: 9700; background: var(--porcelain);
  overflow-y: auto; transform: translateY(100%); transition: transform var(--d-base) var(--ease-inout);
  padding: var(--sp-6) var(--edge);
}
.case-overlay.is-open { transform: translateY(0); }
.case-overlay[hidden] { display: none; }
.case-overlay__body { max-width: 44rem; margin-inline: auto; padding-top: var(--sp-6); }
.case-overlay__title { font-family: var(--font-sans); font-weight: 300; font-size: var(--t-display-3); }
.case-overlay__meta { margin-top: 0.75rem; }
.case-overlay__text { margin-top: var(--sp-2); max-width: 60ch; color: var(--ink-80); }
.case-overlay__badge { display: inline-block; margin-top: var(--sp-2); padding: 0.325rem 0.875rem; border: var(--bw) solid var(--line); border-radius: var(--r-pill); }
.case-overlay__close { position: fixed; top: 1.5rem; right: 1.5rem; width: 2.7rem; height: 2.7rem; border-radius: 50%; background: var(--white); box-shadow: var(--shadow-float); display: grid; place-items: center; font-size: 1.2rem; z-index: 2; }

/* ==========================================================================
   Media reveal
   ========================================================================== */

.reveal-media .case-card__media { clip-path: inset(0 0 100% 0); transition: clip-path 1.2s var(--ease-out); }
.reveal-media.reveal-in .case-card__media { clip-path: inset(0 0 0 0); }

.reveal-item { opacity: 0; transform: translateY(1rem); transition: opacity var(--d-reveal) var(--ease-out), transform var(--d-reveal) var(--ease-out); }
.reveal-item.reveal-in { opacity: 1; transform: translateY(0); }


/* ==========================================================================
   v3 - motion layer (ASSETS-BRIEF.md M1-M16)
   ========================================================================== */

/* --- M16: no FOUT. Text that depends on Switzer/Sentient stays hidden until
   the faces are ready (or 800ms have passed, whichever comes first). The
   lockup is outlined, so it is deliberately NOT in this list. ------------- */
.fonts-loading main,
.fonts-loading .site-nav,
.fonts-loading .gate__drum,
.fonts-loading .gate__teaser,
.fonts-loading .gate__enter,
.fonts-loading .gate__progress,
main, .site-nav, .gate__drum, .gate__teaser, .gate__enter,
.gate__progress { transition: opacity var(--d-fast) var(--ease-micro); }

/* --- M1/M2: gate choreography ------------------------------------------- */
.gate__enter { opacity: 0; transform: translateY(0.5rem); transition: opacity var(--d-base) var(--ease-out), transform var(--d-base) var(--ease-out); }
.gate.is-armed .gate__enter { opacity: 1; transform: translateY(0); }
/* in flight the lockup belongs to <body>, above the fading gate */
.lockup--gate.is-flying { pointer-events: none; }
.lockup--gate.is-flying .lockup__draw { display: none; }

/* --- contour layers (A9) -------------------------------------------------
   Presentation lives here, not on the SVG root: the maps are inlined into the
   markup, so their own root attributes are gone. The ink alpha is carried by
   the stroke colour, which leaves element opacity free for the fades. */
.iso { fill: none; stroke: color-mix(in srgb, var(--ink) 15%, transparent); stroke-linecap: round; stroke-linejoin: round; }
.iso path { stroke-width: 1; vector-effect: non-scaling-stroke; }
.gate__iso {
  position: absolute; inset: -10%; width: 120%; height: 120%;
  opacity: 0; transform: scale(1.04);
  transition: opacity var(--d-scene) var(--ease-out), transform var(--d-scene) var(--ease-out);
  pointer-events: none;
}
.gate.is-ready .gate__iso { opacity: 1; transform: scale(1); }

/* M3: dividers drawn by scroll position, not by a timer */
.iso-divider { position: relative; height: clamp(9rem, 18vh, 15rem); overflow: hidden; pointer-events: none; }
.iso-divider--flip { transform: scaleY(-1); }
.iso--divider { position: absolute; inset: 0; width: 100%; height: 100%; }
.iso--divider path {
  stroke-dasharray: 100;
  /* --draw runs 100 -> 0 with scroll; --i fans the paths out slightly */
  stroke-dashoffset: clamp(0, calc(var(--draw, 100) + var(--i) * 1.1), 100);
}

/* --- M17: camera pull-back ------------------------------------------------
   The section is the frame (it clips); a layer inside it scales. The frame
   must not be the thing that scales - a clip region scales with its own box
   and would then clip nothing at all.
   --zoom-origin tracks the viewport centre, so the move pivots around
   whatever the reader is actually looking at; on blocks taller than the
   screen a fixed centre origin would slide the content instead. */
.screen[data-zoom-out] { overflow: clip; }
.zoom-layer {
  display: flex; flex-direction: column; gap: inherit;
  transform: scale(var(--zoom, 1));
  transform-origin: 50% var(--zoom-origin, 50%);
  opacity: var(--zoom-fade, 1);
}
/* promoted only while it is actually moving: Work is ~3700px tall, and a
   permanent compositor layer that size costs real memory for nothing */
.is-zooming > .zoom-layer { will-change: transform; }

/* --- M13: scroll progress, with a section tick --------------------------- */
.scroll-progress__bar { transition: none; }   /* smoothed in js/motion.js instead */
.scroll-progress__tick {
  position: absolute; right: 0; top: 0; width: 100%; height: 1px;
  background: var(--ink); opacity: 0;
  transform: translateY(var(--tick-y, 0px));
  transition: opacity var(--d-fast) var(--ease-micro);
}
.scroll-progress__tick::before {
  content: ''; position: absolute; right: 0; top: 0; width: 0.55rem; height: 1px; background: var(--ink);
}
.scroll-progress__tick-n {
  position: absolute; right: 0.85rem; top: -0.62em; color: var(--ink-55);
  letter-spacing: var(--ls-micro); white-space: nowrap;
}
.scroll-progress__tick.is-visible { opacity: 1; }

/* --- M4c: cursor ring over media ----------------------------------------- */
.cursor__ring {
  position: absolute; left: 50%; top: 50%; width: 5.5rem; height: 5.5rem;
  margin: -2.75rem 0 0 -2.75rem;
  opacity: 0; transform: scale(0.6);
  transition: opacity var(--d-fast) var(--ease-micro), transform var(--d-fast) var(--ease-out);
  animation: ring-spin 18s linear infinite;
  animation-play-state: paused;
}
.cursor__ring-text {
  font-family: var(--font-sans); font-size: 6.4px; letter-spacing: 0.22em;
  fill: var(--ink-55); text-transform: uppercase;
}
.cursor.is-media .cursor__ring { opacity: 1; transform: scale(1); animation-play-state: running; }
.cursor.is-media .cursor__label { opacity: 0; }
@keyframes ring-spin { to { transform: rotate(360deg); } }

/* --- M4a: tilt ----------------------------------------------------------- */
[data-tilt] { perspective: 1200px; }
[data-tilt] .case-card__media {
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transform-style: preserve-3d;
  will-change: transform;
}
/* M4d: the cover eases down from 1.08 while the box clips open */
.reveal-media .case-card__pic { --pic-scale: 1.08; }
.reveal-media.reveal-in .case-card__pic { --pic-scale: 1.001; transition: transform 1.2s var(--ease-out); }

/* --- M5: magnetic buttons ------------------------------------------------ */
[data-magnetic] { will-change: transform; }
[data-magnetic] .btn__label-wrap { transform: translate3d(var(--mlx, 0px), var(--mly, 0px), 0); }

/* --- M6: services ribbon ------------------------------------------------- */
.ribbon {
  position: relative; overflow: hidden; margin-block: var(--sp-4);
  padding-block: var(--sp-1);
  border-top: var(--bw) solid var(--line); border-bottom: var(--bw) solid var(--line);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.ribbon__track { display: flex; width: max-content; will-change: transform; }
.ribbon__set { display: flex; align-items: baseline; flex: none; }
.ribbon__item, .ribbon__sep {
  font-size: var(--t-h3); font-weight: 300; line-height: 1.2;
  padding-inline: 0.5rem; color: var(--ink-80);
  transition: color var(--d-fast) var(--ease-micro), font-style var(--d-hover) var(--ease-out);
}
.ribbon__item--alt { font-family: var(--font-serif); font-style: italic; }
.ribbon__sep { color: var(--ink-35); }
.ribbon:hover .ribbon__item { color: var(--ink-55); }
.ribbon__item:hover { color: var(--ink); font-family: var(--font-serif); font-style: italic; }

/* --- M7: process drawings + counters ------------------------------------- */
.process__step { padding-top: 1.1rem; }
.process__draw {
  width: 3rem; height: 3rem; margin-bottom: 0.9rem; color: var(--ink-35);
  fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round;
  transition: color var(--d-hover) var(--ease-out);
}
.process__draw path {
  stroke-dasharray: 100; stroke-dashoffset: 100;
  transition: stroke-dashoffset 0.7s var(--ease-out);
  transition-delay: calc(var(--i) * 0.06s);
}
.reveal-in .process__draw path { stroke-dashoffset: 0; }
.process__step:hover .process__draw { color: var(--ink-80); }
.process__num { font-variant-numeric: tabular-nums; }

/* --- M9: seal ------------------------------------------------------------ */
.seal {
  width: 5.25rem; height: 5.25rem; color: var(--ink-55);
  fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round;
}
.seal__ring {
  transform-box: fill-box; transform-origin: center;
  animation: seal-spin 44s linear infinite;
  animation-play-state: paused;
}
.seal.is-visible .seal__ring { animation-play-state: running; }
@keyframes seal-spin { to { transform: rotate(360deg); } }
.seal--legal { margin: 0; }
@media (max-width: 768px) { .seal--legal { display: none; } }
.seal--stamp {
  width: 4.5rem; height: 4.5rem; margin-bottom: var(--sp-1);
  opacity: 0; transform: scale(1.3);
  transition: opacity var(--d-fast) var(--ease-inout), transform 0.4s var(--ease-inout);
}
.seal--stamp.is-stamped { opacity: 1; transform: scale(1); }

/* --- M10: menu overlay contour --------------------------------------------*/
.menu-overlay__panel { position: relative; overflow: hidden; }
.menu-overlay__iso {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transform: scale(1.15); pointer-events: none;
  transition: opacity var(--d-base) var(--ease-out), transform 0.9s var(--ease-out);
}
.menu-overlay.is-open .menu-overlay__iso { opacity: 1; transform: scale(1); }
.menu-overlay__inner { position: relative; }
.menu-overlay.is-open .menu-item {
  animation: menu-item-in var(--d-base) var(--ease-out) both;
  animation-delay: calc(0.12s + var(--mi, 0) * 0.06s);
}
.menu-overlay.is-open .menu-item:nth-child(1) { --mi: 0; }
.menu-overlay.is-open .menu-item:nth-child(2) { --mi: 1; }
.menu-overlay.is-open .menu-item:nth-child(3) { --mi: 2; }
.menu-overlay.is-open .menu-item:nth-child(4) { --mi: 3;
}
@keyframes menu-item-in { from { opacity: 0; transform: translateY(0.9rem); } to { opacity: 1; transform: none; } }

/* --- M11: form ----------------------------------------------------------- */
.field { position: relative; }
.field:not(.field--pills) { padding-top: 1.15rem; }
.field:not(.field--pills) label {
  position: absolute; top: 1.15rem; left: 0.6rem; pointer-events: none;
  transform-origin: left top;
  transition: transform var(--d-micro) var(--ease-micro), color var(--d-micro) var(--ease-micro);
  transform: translateY(0.75rem) scale(1.35);
  color: var(--ink-55);
}
.field:not(.field--pills).is-filled label,
.field:not(.field--pills):focus-within label {
  transform: translateY(-0.05rem) scale(1);
  color: var(--ink-80);
}
/* the rule under a field is drawn from wherever the caret landed */
.field__rule {
  position: absolute; left: 0; right: 0; bottom: 0; height: 1.5px; background: var(--ink);
  transform: scaleX(0); transform-origin: var(--ox, 0%) 50%;
  transition: transform var(--d-fast) var(--ease-out);
}
.field:focus-within .field__rule { transform: scaleX(1); }
.field.has-error .field__rule { transform: scaleX(1); background: var(--ink); }
.field.is-shake input, .field.is-shake textarea { animation: field-shake 0.16s var(--ease-micro) 2; }
@keyframes field-shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }

.pill-toggle { position: relative; overflow: hidden; isolation: isolate; }
.pill-toggle > span { position: relative; z-index: 1; }
.pill-toggle::before {
  content: ''; position: absolute; z-index: 0;
  left: var(--rx, 50%); top: var(--ry, 50%); width: 240%; aspect-ratio: 1;
  translate: -50% -50%; border-radius: 50%; background: var(--ink);
  transform: scale(0); transition: transform var(--d-fast) var(--ease-out);
}
.pill-toggle[aria-pressed="true"]::before { transform: scale(1); }
.pill-toggle[aria-pressed="true"] { background: var(--white); }

.contact-form__submit { position: relative; overflow: hidden; }
.btn__progress {
  position: absolute; left: 0; bottom: 0; width: 100%; height: 1.5px; background: var(--sky);
  transform: scaleX(0); transform-origin: left;
}
/* waiting on the network: an indeterminate sweep, since we can't know how
   long the relay will take */
.contact-form__submit.is-sending .btn__progress {
  width: 38%; transform: none;
  animation: progress-sweep 1.1s var(--ease-inout) infinite;
}
/* answered: the bar closes to full width, then the success state takes over */
.contact-form__submit.is-sent .btn__progress {
  width: 100%; animation: none; transform: scaleX(1);
  transition: transform 0.4s var(--ease-out);
}
@keyframes progress-sweep {
  from { translate: -100% 0; }
  to   { translate: 265% 0; }
}
.contact-form__submit:disabled { cursor: progress; }
.contact-form__fallback { text-decoration: underline; text-underline-offset: 0.15em; }
.contact-form__submit.is-sending .btn__label-wrap { transform: translateY(-140%); transition: transform var(--d-fast) var(--ease-out); }

/* --- M12: archived gallery ---------------------------------------------- */
.case-overlay__gallery { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--gutter); margin-top: var(--sp-3); }
.case-overlay__gallery:empty { display: none; }
.case-overlay__gallery img {
  width: 100%; aspect-ratio: 16 / 10; object-fit: cover;
  clip-path: inset(0 0 100% 0); transition: clip-path 1s var(--ease-out);
  transition-delay: calc(var(--i) * 0.12s);
}
.case-overlay.is-open .case-overlay__gallery img { clip-path: inset(0); }
@media (max-width: 768px) { .case-overlay__gallery { grid-template-columns: 1fr; } }


/* ==========================================================================
   Cookie consent (js/consent.js)
   First layer: Accept and Reject carry identical weight - EU regulators treat
   a harder-to-find "reject" as invalid consent. Second layer: per-category
   switches, nothing optional pre-ticked.
   ========================================================================== */

.consent {
  position: fixed; z-index: 9600;
  left: var(--edge); bottom: var(--edge);
  width: min(34rem, calc(100vw - var(--edge) * 2));
  padding: 1.25rem 1.4rem 1.3rem;
  background: var(--glass);
  -webkit-backdrop-filter: blur(18px) saturate(1.08);
          backdrop-filter: blur(18px) saturate(1.08);
  border: var(--bw) solid var(--line);
  box-shadow: var(--shadow-float);
  opacity: 0; transform: translateY(1rem);
  transition: opacity var(--d-base) var(--ease-out), transform var(--d-base) var(--ease-out);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .consent, .consent-prefs__panel { background: color-mix(in srgb, var(--white) 94%, transparent); }
}
.consent.is-in { opacity: 1; transform: none; }
.consent__title, .consent-prefs__eyebrow {
  font-size: var(--t-micro); text-transform: uppercase; letter-spacing: var(--ls-micro);
  color: var(--ink-55); margin-bottom: 0.55rem;
}
.consent__text { font-size: var(--t-caption); line-height: 1.55; color: var(--ink-80); }
.consent a, .consent-prefs a { text-decoration: underline; text-underline-offset: 0.15em; }
.consent__actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem;
  margin-top: 1rem;
}
.consent .btn, .consent-prefs .btn { height: 2.5rem; padding: 0.7rem 1.2rem; font-size: 0.95rem; }
.consent__link {
  margin-left: auto; font-size: var(--t-caption); color: var(--ink-80);
  text-decoration: underline; text-underline-offset: 0.2em;
  /* a text link, but with a finger-sized hit area (WCAG 2.2: 24px minimum) */
  padding: 0.6rem 0.5rem; margin-right: -0.5rem;
}
.consent__link:hover { color: var(--ink); }
@media (max-width: 520px) {
  .consent { left: 0.75rem; right: 0.75rem; bottom: 0.75rem; width: auto; padding: 1.1rem 1.1rem 1.15rem; }
  .consent__actions .btn { flex: 1 1 0; justify-content: center; }
  .consent__link { margin: 0.2rem auto 0; }
}

/* second layer: a proper modal */
.consent-prefs { position: fixed; inset: 0; z-index: 10500; display: grid; place-items: center; padding: var(--edge); }
.consent-prefs[hidden] { display: none; }
.consent-prefs__scrim {
  position: absolute; inset: 0; background: color-mix(in srgb, var(--ink) 28%, transparent);
  opacity: 0; transition: opacity var(--d-fast) var(--ease-micro);
}
.consent-prefs__panel {
  position: relative; width: min(36rem, 100%); max-height: calc(100svh - var(--edge) * 2); overflow-y: auto;
  padding: 1.75rem 1.75rem 1.5rem;
  background: var(--glass);
  -webkit-backdrop-filter: blur(22px) saturate(1.08);
          backdrop-filter: blur(22px) saturate(1.08);
  border: var(--bw) solid var(--line); box-shadow: var(--shadow-float);
  opacity: 0; transform: translateY(0.75rem) scale(0.985);
  transition: opacity var(--d-fast) var(--ease-out), transform var(--d-base) var(--ease-out);
}
.consent-prefs.is-open .consent-prefs__scrim { opacity: 1; }
.consent-prefs.is-open .consent-prefs__panel { opacity: 1; transform: none; }
.consent-prefs__title { font-size: var(--t-h3); font-weight: 300; letter-spacing: var(--ls-heading); line-height: var(--lh-heading); }
.consent-prefs__intro { margin-top: 0.6rem; font-size: var(--t-caption); color: var(--ink-80); line-height: 1.55; }
.consent-prefs__close { position: absolute; top: 1rem; right: 1rem; width: 2.25rem; height: 2.25rem; display: grid; place-items: center; border-radius: 50%; }
.consent-prefs__close:hover { background: color-mix(in srgb, var(--ink) 6%, transparent); }

.consent-cat { padding: 1rem 0; border-top: var(--bw) solid var(--line); }
.consent-cat:first-of-type { margin-top: 1.25rem; }
.consent-cat__head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.consent-cat__name { font-size: var(--t-body); }
.consent-cat__always { font-size: var(--t-micro); text-transform: uppercase; letter-spacing: var(--ls-micro); color: var(--ink-55); }
.consent-cat__desc { margin-top: 0.4rem; font-size: var(--t-caption); color: var(--ink-80); line-height: 1.55; max-width: 44ch; }

/* switch: a real checkbox, restyled - keyboard and screen readers get the native control */
.switch { position: relative; flex: none; width: 2.6rem; height: 1.45rem; }
.switch input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; z-index: 1; }
.switch__track {
  position: absolute; inset: 0; border-radius: var(--r-pill);
  border: var(--bw) solid var(--ink-35); background: var(--white);
  transition: background var(--d-fast) var(--ease-micro), border-color var(--d-fast) var(--ease-micro);
}
.switch__track::after {
  content: ''; position: absolute; top: 50%; left: 0.2rem; width: 1rem; height: 1rem; border-radius: 50%;
  background: var(--ink-55); transform: translateY(-50%);
  transition: transform var(--d-fast) var(--ease-out), background var(--d-fast) var(--ease-micro);
}
.switch input:checked + .switch__track { background: var(--ink); border-color: var(--ink); }
.switch input:checked + .switch__track::after { transform: translate(1.1rem, -50%); background: var(--porcelain); }
.switch input:focus-visible + .switch__track { outline: 2px solid var(--ink); outline-offset: 3px; }

.consent-prefs__actions {
  display: flex; flex-wrap: wrap; gap: 0.6rem; justify-content: flex-end;
  padding-top: 1.1rem; border-top: var(--bw) solid var(--line);
}
@media (max-width: 520px) {
  .consent-prefs__panel { padding: 1.4rem 1.2rem 1.2rem; }
  .consent-prefs__actions .btn { flex: 1 1 100%; justify-content: center; }
}

/* withdrawal has to be as reachable as consent: a permanent link in the colophon */
.cta__legal-links { margin-top: 0.6rem; display: flex; gap: 0.5rem; justify-content: center; flex-wrap: wrap; }
.cta__legal-links a, .cta__legal-links button {
  font: inherit; color: inherit; text-decoration: underline; text-underline-offset: 0.2em;
}
.cta__legal-links a:hover, .cta__legal-links button:hover { color: var(--ink); }


/* ==========================================================================
   Privacy & cookie policy page (privacy.html)
   ========================================================================== */

.legal-header {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1.5rem var(--edge); max-width: 60rem; margin: 0 auto;
}
.legal { max-width: 46rem; margin: 0 auto; padding: var(--sp-4) var(--edge) var(--sp-5); }
.legal__eyebrow { font-size: var(--t-micro); text-transform: uppercase; letter-spacing: var(--ls-micro); color: var(--ink-55); }
.legal__title {
  margin-top: 0.75rem; font-size: var(--t-h1); font-weight: 300;
  line-height: var(--lh-heading); letter-spacing: -0.03em;
}
.legal__title em { font-family: var(--font-serif); font-style: italic; font-weight: 300; }
.legal__meta { margin-top: 1rem; font-size: var(--t-caption); color: var(--ink-55); }
.legal__lead { margin-top: var(--sp-3); font-size: var(--t-lead); font-weight: 300; line-height: 1.35; color: var(--ink); max-width: 36ch; }
.legal section { margin-top: var(--sp-4); padding-top: var(--sp-2); border-top: var(--bw) solid var(--line); }
.legal h2 { font-size: var(--t-h3); font-weight: 300; letter-spacing: var(--ls-heading); line-height: var(--lh-heading); }
.legal h3 { margin-top: var(--sp-2); font-size: var(--t-body-l); font-weight: 400; }
.legal p { margin-top: 0.75rem; color: var(--ink-80); line-height: 1.65; max-width: 64ch; }
.legal a, .legal__inline-btn { color: var(--ink); text-decoration: underline; text-underline-offset: 0.18em; }
.legal__inline-btn { font: inherit; }
.legal code, .consent-prefs code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.9em; }
.legal__table-wrap { margin-top: 1.25rem; overflow-x: auto; }
.legal__table-wrap:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }
.legal__table { width: 100%; min-width: 38rem; border-collapse: collapse; font-size: var(--t-caption); }
.legal__table th, .legal__table td { text-align: left; vertical-align: top; padding: 0.75rem 1rem 0.75rem 0; border-bottom: var(--bw) solid var(--line); }
.legal__table th { font-weight: 400; font-size: var(--t-micro); text-transform: uppercase; letter-spacing: var(--ls-micro); color: var(--ink-55); }
.legal__table td { color: var(--ink-80); }
.legal-footer {
  max-width: 46rem; margin: 0 auto; padding: var(--sp-2) var(--edge) var(--sp-5);
  border-top: var(--bw) solid var(--line); color: var(--ink-55);
}
.legal-footer p + p { margin-top: 0.3rem; }

/* ==========================================================================
   Reduced motion + no-JS safety
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
  .reveal-chars .char, .reveal-words .word, .reveal-item, .reveal-media .case-card__media { opacity: 1; transform: none; clip-path: inset(0); }
  .gate { display: none !important; }
  body.is-gated { overflow: visible; height: auto; }

  /* v3 motion layer: hold every added animation at its finished state */
  .iso--divider path, .process__draw path, .lockup--gate .lockup__draw path { stroke-dashoffset: 0 !important; }
  .zoom-layer { transform: none !important; opacity: 1 !important; }
  .screen[data-zoom-out] { overflow: visible; }
  .lockup--gate .lockup__solid { opacity: 1 !important; }
  .lockup--gate .lockup__draw { display: none; }
  .grain-overlay { animation: none !important; }
  .seal__ring { animation: none !important; }
  .cursor__ring { animation: none !important; }
  .ribbon__track { transform: none !important; }
  .seal--stamp { opacity: 1 !important; transform: none !important; }
  .contact-form__submit.is-sending .btn__progress { animation: none; width: 100%; translate: none; transform: scaleX(1); }
  .consent, .consent-prefs__panel { transform: none !important; }
  .field:not(.field--pills) label { position: static; transform: none; }
  .field__rule { display: none; }
  .case-overlay__gallery img { clip-path: inset(0) !important; }
  .menu-overlay.is-open .menu-item { animation: none; }
  .fonts-loading main, .fonts-loading .site-nav, .fonts-loading .gate__drum,
  .fonts-loading .gate__teaser, .fonts-loading .gate__enter,
  .fonts-loading .gate__progress { opacity: 1; }
}
.no-js .reveal-chars .char, .no-js .reveal-words .word, .no-js .reveal-item, .no-js .reveal-media .case-card__media { opacity: 1; transform: none; clip-path: inset(0); }
.no-js .iso--divider path, .no-js .process__draw path { stroke-dashoffset: 0; }
.no-js main { opacity: 1; }
.no-js .gate { display: none; }
.no-js body.is-gated { overflow: visible; height: auto; }
