/* ============================================================
   Hagawebb — scroll-driven editorial experience
   Static HTML + Lenis + GSAP ScrollTrigger.
   Built as a sequence of full-viewport scenes (not a document).
   Identity: paper / cobalt / orange, Instrument Serif display.
   ============================================================ */

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

:root {
  --paper: #f1ebdc;
  --paper-deep: #e8dfcc;
  --ink: #0f0f0e;
  --ink-soft: #2a2a28;
  --rule: #9a948a;
  --muted: #6b655d;
  --cobalt: #1b2fcc;
  --cobalt-hover: #1526a8;
  --cobalt-lt: #5b6ef5;   /* lighter cobalt for accents on dark */
  --orange: #e2572e;
  --serif: 'Instrument Serif', 'Times New Roman', serif;
  --sans: 'Inter', system-ui, -apple-system, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, monospace;

  /* per-scene theme (overridden by [data-theme]) */
  --bg: var(--paper);
  --fg: var(--ink);
  --fg-soft: var(--ink-soft);
  --line: var(--rule);

  /* fluid type scale — scales up boldly on large/fullscreen displays */
  --fs-display: clamp(4rem, 16vw, 24rem);
  --fs-mega: clamp(2.6rem, 11vw, 15rem);
  --fs-h2: clamp(2.4rem, 7.5vw, 9rem);
  --fs-h3: clamp(1.6rem, 3.2vw, 3.4rem);
  --fs-lead: clamp(1.15rem, 1.8vw, 2.05rem);
  --fs-body: clamp(1rem, 1.15vw, 1.3rem);
  --label: clamp(0.72rem, 0.7vw, 0.92rem);

  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* frozen viewport-height unit: 1% of the load-time viewport height, set by the
     inline head script and only refreshed on orientation change. Fallback to the
     real svh unit if JS is off. Used as calc(N * var(--svh)) everywhere a viewport
     height was needed, so the address-bar collapse can't reflow the layout. */
  --svh: 1svh;
}

[data-theme="dark"] {
  --bg: var(--ink);
  --fg: var(--paper);
  --fg-soft: #cfc8b8;
  --line: #3a3a36;
}

html { -webkit-text-size-adjust: 100%; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }
html:not(.lenis) { scroll-behavior: smooth; }

body {
  font-family: var(--sans);
  background: var(--ink);  /* page backdrop behind scenes */
  color: var(--fg);
  line-height: 1.5;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-size: 16px;
}

a { color: inherit; text-decoration: none; }
a:focus-visible, button:focus-visible { outline: 2px solid var(--cobalt); outline-offset: 4px; }
img { display: block; max-width: 100%; }

.skip-link {
  position: fixed; left: -9999px; top: 1rem;
  background: var(--ink); color: var(--paper); padding: 0.75rem 1rem;
  z-index: 200; font-family: var(--mono); font-size: 0.85rem;
}
.skip-link:focus { left: 1rem; }

/* ─────────────────────────  INTRO / WELCOME OVERLAY  ───────────────── */
/* Covers the first paint, then lifts to reveal the hero (JS-driven).
   Visible by default (no js class needed) so there is no FOUC; <noscript>
   hides it for script-off users. */
.intro {
  position: fixed; inset: 0; z-index: 300; background: var(--paper); color: var(--ink);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; will-change: transform;
}
.intro-inner { display: flex; flex-direction: column; align-items: center; gap: clamp(1.25rem, calc(3 * var(--svh)), 2rem); padding: 2rem; text-align: center; }
.intro-eyebrow { font-family: var(--mono); font-size: var(--label); letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted); opacity: 0; }
.intro-word { font-family: var(--serif); font-weight: 400; font-size: clamp(3.5rem, 13vw, 11rem); line-height: 0.9; letter-spacing: -0.04em; color: var(--ink); overflow: hidden; }
.intro-word .i { font-style: italic; color: var(--cobalt); }
.intro-bar { display: block; width: clamp(120px, 22vw, 240px); height: 2px; background: var(--paper-deep); overflow: hidden; }
.intro-bar-fill { display: block; height: 100%; width: 0; background: var(--cobalt); }

.mono {
  font-family: var(--mono); font-size: var(--label);
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted);
}

/* ─────────────────────────  SCENE SYSTEM  ───────────────────────── */
/* Each scene is opaque and in normal flow. The ONLY hard pin is the
   horizontal work gallery; everything else uses position:sticky or plain
   scroll-scrub, which never ghosts a second fixed layer. */
.scene {
  position: relative;
  background: var(--bg);
  color: var(--fg);
  isolation: isolate; /* contain the seam gradient's negative z-index */
}
/* Smooth gradient seams: each scene melts its bottom into the NEXT scene's
   colour over a tall band (--to = next scene's base colour), so colour
   changes blend instead of hard-cutting. The gradient paints above the
   scene background but below content (content has bottom padding). */
.scene::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0;
  height: calc(20 * var(--svh)); pointer-events: none; z-index: -1;
  background: linear-gradient(to bottom, transparent, var(--to, transparent));
}
.hero::after { display: none; }
.manifesto { --to: var(--ink); }   /* blob bottom darkens into the dark services */
/* services + work are both dark → no visible seam needed between them */
.services::after, .work::after { display: none; }
.process   { --to: var(--ink); }   /* into proof (dark) */
.proof     { --to: var(--ink); }   /* into contact (dark) */
.contact   { --to: var(--ink); }   /* into footer (dark) */
/* work(dark) -> process(light): blend at the TOP of process (the work
   bottom sits in pin-spacer dead-zone, so a gradient there reads as an
   empty white band). */
.process::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: calc(22 * var(--svh));
  z-index: -1; pointer-events: none;
  background: linear-gradient(to bottom, var(--ink), transparent);
}
.scene-pad { padding: 0 clamp(1.25rem, 5vw, 6rem); }
.scene-full {
  min-height: calc(100 * var(--svh));
  display: flex; flex-direction: column; justify-content: center;
  padding-top: clamp(5rem, calc(12 * var(--svh)), 9rem); padding-bottom: clamp(3rem, calc(8 * var(--svh)), 6rem);
}
.eyebrow {
  font-family: var(--mono); font-size: var(--label);
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--muted);
  display: flex; align-items: center; gap: 0.75rem; margin-bottom: clamp(1.5rem, calc(4 * var(--svh)), 3rem);
}
/* the rule line and "§ NN" must never shrink or split across lines — on longer
   (EN/DE) labels the flex line overflowed and broke "§ 03" into two rows.
   Only the label text itself may wrap. */
.eyebrow .idx { color: var(--cobalt); white-space: nowrap; flex-shrink: 0; }
.eyebrow::before { content: ''; width: clamp(2rem,5vw,4rem); height: 1px; background: var(--line); flex-shrink: 0; }

.display { font-family: var(--serif); font-weight: 400; line-height: 0.92; letter-spacing: -0.03em; }
.display em, .accent { font-style: italic; color: var(--cobalt); }
.accent-o { color: var(--orange); }

/* line-mask reveal wrappers (SplitText mask:lines also handles this) */
.reveal-line { display: block; overflow: hidden; }

/* ─────────────────────────  PROGRESS + DOTS + NAV  ───────────────── */
.progress {
  position: fixed; top: 0; left: 0; height: 2px; width: 100%;
  transform: scaleX(0); transform-origin: 0 50%;
  background: var(--cobalt); z-index: 120; pointer-events: none;
}
.dots {
  position: fixed; right: clamp(1rem, 2.5vw, 2rem); top: 50%; transform: translateY(-50%);
  z-index: 110; display: flex; flex-direction: column; gap: 0.85rem; mix-blend-mode: difference;
}
.dots button {
  width: 8px; height: 8px; border-radius: 50%; border: 1px solid #fff;
  background: transparent; cursor: pointer; padding: 0; transition: background 0.3s, transform 0.3s;
}
.dots button.active { background: #fff; transform: scale(1.3); }

.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  display: flex; justify-content: space-between; align-items: center;
  padding: clamp(1rem, calc(2.2 * var(--svh)), 1.6rem) clamp(1.25rem, 5vw, 6rem);
  mix-blend-mode: difference; color: #fff;
}
.nav-logo { font-family: var(--serif); font-style: italic; font-size: 1.6rem; line-height: 1; }
.nav-logo sup { font-family: var(--mono); font-size: 0.55rem; vertical-align: super; margin-left: 0.2rem; letter-spacing: 0.1em; }
.nav-right { display: flex; align-items: center; gap: clamp(1rem, 2vw, 2rem); font-family: var(--mono); font-size: var(--label); letter-spacing: 0.14em; text-transform: uppercase; }
.nav-links { display: flex; gap: clamp(1rem,1.8vw,1.75rem); list-style: none; }
.nav-links a { position: relative; }
.nav-links a::after { content:''; position:absolute; left:0; bottom:-4px; width:0; height:1px; background:#fff; transition:width .3s var(--ease); }
.nav-links a:hover::after { width:100%; }
.lang-switch { display: flex; gap: 0.4rem; padding-left: clamp(0.75rem,1.5vw,1.25rem); border-left: 1px solid currentColor; opacity: 0.85; }
.lang-switch a.active { font-weight: 600; opacity: 1; }
.nav-toggle { display: none; background: none; border: 1px solid #fff; color: #fff; font-family: var(--mono); font-size: var(--label); letter-spacing:0.12em; text-transform:uppercase; padding: 0.5rem 0.8rem; cursor: pointer; }
@media (max-width: 860px) {
  .nav-links, .lang-switch { display: none; }
  .nav-toggle { display: inline-flex; }
  .nav.menu-open { mix-blend-mode: normal; background: var(--ink); color: var(--paper); }
  /* mix-blend:difference forces a fixed-layer recomposite against the whole
     page on every viewport change (address-bar collapse) — a mobile jank source.
     The section dots are a desktop affordance; drop them on touch to remove 7
     blended fixed layers. */
  .dots { display: none; }
}
/* mobile menu overlay */
.menu-overlay {
  position: fixed; inset: 0; z-index: 95; background: var(--ink); color: var(--paper);
  display: flex; flex-direction: column; justify-content: center; gap: 1.5rem;
  padding: 0 clamp(1.25rem,5vw,6rem); transform: translateY(-100%); transition: transform 0.5s var(--ease);
}
.menu-overlay.open { transform: translateY(0); }
.menu-overlay a { font-family: var(--serif); font-size: clamp(2rem, 9vw, 4rem); line-height: 1.1; }
.menu-overlay .menu-lang { display: flex; gap: 1.25rem; font-family: var(--mono); font-size: 0.9rem; margin-top: 2rem; }

/* ─────────────────────────  ACT 1 · HERO + MANIFESTO  ───────────────
   Hero and manifesto share ONE fixed blob background that stays in place
   while you scroll through both (sticky bg inside a tall act1 wrapper). */
.act1 { position: relative; }
.act1-spacer { height: calc(48 * var(--svh)); }
@media (max-width: 860px) { .act1-spacer { display: none; } } /* no scrub on touch */
.act1-bg { position: absolute; inset: 0; z-index: 0; }
.act1[data-hero-mode="cinematic"] .act1-bg {
  position: sticky; top: 0; height: calc(100 * var(--svh)); overflow: hidden;
  background: var(--paper); /* NO poster image — it's a transparent blob still
     that rendered as a static second blob behind the moving canvas */
}
.hero-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; opacity: 0; transition: opacity 0.8s ease; }
.act1[data-hero-mode="cinematic"] .hero-canvas { opacity: 1; }
/* legibility veil over the blob, behind the section text */
.act1[data-hero-mode="cinematic"] .act1-bg::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(241,235,220,0.14), rgba(241,235,220,0.30) 45%, rgba(241,235,220,0.60));
}
/* hero rides above the fixed bg; transparent so the blob shows through */
.act1 .hero { position: relative; z-index: 1; }
/* the sticky blob bg is a calc(100 * var(--svh)) flow element; pull the hero up over it so the
   title shares the FIRST screen with the blob (not pushed to the 2nd viewport) */
/* NOTE: the minus must live INSIDE calc() — `-calc(...)` is invalid CSS and the
   whole declaration gets dropped (the svh conversion once broke this, leaving a
   blob-only first screen with the title a full viewport down). */
.act1[data-hero-mode="cinematic"] .hero { background: transparent; margin-top: calc(-100 * var(--svh)); }
/* manifesto (solid paper) sits ABOVE the blob and rises over it as you scroll
   — a clean cover transition; the blob keeps animating behind until covered */
.act1 .manifesto { position: relative; z-index: 2; }

.hero { position: relative; }
.hero-stage { position: relative; min-height: calc(100 * var(--svh)); display: flex; align-items: flex-end; }
.hero-inner { position: relative; z-index: 2; width: 100%; padding: 0 clamp(1.25rem,5vw,6rem) clamp(3rem,calc(8 * var(--svh)),6rem); }
.hero-meta {
  display: flex; flex-wrap: wrap; gap: clamp(1.5rem,4vw,4rem); margin-bottom: clamp(2rem,calc(6 * var(--svh)),4rem);
  font-family: var(--mono); font-size: var(--label); letter-spacing: 0.06em;
}
.hero-meta .mk { color: var(--muted); text-transform: uppercase; letter-spacing: 0.14em; display:block; margin-bottom:0.3rem; }
.hero-meta .mv { color: var(--ink); }
.hero-meta .issue { color: var(--orange); }
/* margin-bottom in em clears the deep 'g' descender so it doesn't sit on the
   tagline; because the hero is bottom-anchored this pushes the wordmark up. */
.wordmark { font-family: var(--serif); font-weight: 400; font-size: var(--fs-display); line-height: 0.82; letter-spacing: -0.045em; color: var(--ink); margin-bottom: 0.16em; }
.wordmark .i { font-style: italic; color: var(--cobalt); }
.hero-tagline { font-family: var(--serif); font-style: italic; font-size: clamp(1.6rem, 4vw, 3.4rem); line-height: 1.05; color: var(--ink-soft); max-width: 22ch; margin-top: clamp(1rem,calc(2 * var(--svh)),1.75rem); }
.hero-foot { display: flex; flex-wrap: wrap; gap: 1rem 2rem; align-items: center; margin-top: clamp(1.75rem,calc(4 * var(--svh)),2.75rem); }
/* touch: no blob. Anchor the meta right under the nav (kills the big empty band
   that bottom-anchoring left above it) and push the title block to the bottom, so
   the negative space sits between them as an intentional middle band. Shrink the
   meta so it reads compact, not heavy. */
@media (max-width: 860px) {
  .hero-stage { align-items: stretch; }
  .hero-inner { display: flex; flex-direction: column; min-height: calc(100 * var(--svh)); padding-top: clamp(5rem,calc(13 * var(--svh)),7rem); padding-bottom: clamp(2.5rem,calc(6 * var(--svh)),4rem); }
  .hero-meta { gap: 0.5rem 1.5rem; margin-bottom: 0; font-size: 0.66rem; }
  .hero-meta .mk { margin-bottom: 0.2rem; }
  .wordmark { margin-top: auto; } /* push title + tagline + buttons to the bottom */
}
.hero-lede { max-width: 46ch; color: var(--ink-soft); font-size: var(--fs-body); }
.scrollcue { display: flex; align-items: center; gap: 0.75rem; font-family: var(--mono); font-size: var(--label); letter-spacing: 0.18em; text-transform: uppercase; color: var(--muted); }
.scrollcue .ln { width: 46px; height: 1px; background: var(--rule); position: relative; overflow: hidden; }
.scrollcue .ln::after { content:''; position:absolute; inset:0; left:-100%; background: var(--cobalt); animation: cue 1.8s var(--ease) infinite; }
@keyframes cue { 0%{left:-100%} 60%,100%{left:100%} }

/* buttons */
.btn {
  display: inline-flex; align-items: center; gap: 0.6rem; justify-content: center;
  min-height: 52px; padding: 0 1.6rem; font-family: var(--mono); font-size: 0.8rem;
  letter-spacing: 0.12em; text-transform: uppercase; cursor: pointer;
  border: 1px solid currentColor; color: var(--fg); background: transparent;
  transition: background 0.3s var(--ease), color 0.3s var(--ease), transform 0.3s var(--ease);
}
.btn .ar { transition: transform 0.3s var(--ease); }
.btn:hover .ar { transform: translateX(4px); }
.btn-fill { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.btn-fill:hover { background: var(--cobalt); border-color: var(--cobalt); }
.btn-cobalt { background: var(--cobalt); color: var(--paper); border-color: var(--cobalt); }
.btn-cobalt:hover { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.btn-orange { background: var(--orange); color: var(--ink); border-color: var(--orange); }
.btn-orange:hover { background: var(--paper); color: var(--ink); border-color: var(--paper); }

/* ─────────────────────────  SCENE 2 · MANIFESTO (solid paper, sticky hold)  ─── */
/* Robust "hold until the word-fill finishes" via position:sticky inside a
   tall track — no ScrollTrigger hard-pin (those ghosted). */
.manifesto { background: var(--paper); color: var(--ink); text-align: left; }
.manifesto-track { position: relative; height: calc(240 * var(--svh)); }
.manifesto-sticky { position: sticky; top: 0; height: calc(100 * var(--svh)); display: flex; flex-direction: column; justify-content: center; background: var(--paper); overflow: hidden; }
/* the sticky already supplies full height — don't nest another calc(100 * var(--svh)) + big
   padding inside it (that pushed the statement past the clip box) */
.manifesto-sticky .scene-full { min-height: 0; padding-top: clamp(1.5rem,calc(4 * var(--svh)),3rem); padding-bottom: clamp(1.5rem,calc(4 * var(--svh)),3rem); }
/* touch: drop the sticky stage (mobile URL-bar collapse jolts sticky scenes);
   the word-fill still plays as the static section passes. */
@media (max-width: 860px) {
  .manifesto-track { height: auto; }
  /* keep .scene-pad's horizontal padding — only set the vertical (a `padding: … 0`
     shorthand zeroed the left/right and flushed the §01 text to the edge). */
  .manifesto-sticky { position: relative; height: auto; overflow: visible; padding-top: clamp(4rem,calc(10 * var(--svh)),6rem); padding-bottom: clamp(4rem,calc(10 * var(--svh)),6rem); }
}
/* contained so it never overflows the sticky at large fonts / short heights */
.manifesto .statement { font-family: var(--serif); font-size: min(clamp(2.4rem, 8vw, 11rem), calc(16 * var(--svh))); line-height: 1.0; letter-spacing: -0.03em; max-width: 22ch; color: var(--ink); }
.manifesto .statement .w { transition: none; }
.manifesto .statement .hl { color: var(--orange); font-style: italic; }
.manifesto-lede { margin-top: clamp(1.5rem,calc(4 * var(--svh)),2.5rem); max-width: 46ch; font-size: var(--fs-lead); line-height: 1.4; color: var(--ink-soft); }
.manifesto .sig { margin-top: clamp(1.5rem,calc(4 * var(--svh)),2.5rem); font-family: var(--mono); font-size: var(--label); letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }

/* ─────────────────────────  SCENE 3 · SERVICES (premium pricing, dark)  ── */
.services { background: var(--ink); color: var(--paper); }
.services-intro { padding-top: 0; }
.services-intro h2 { font-family: var(--serif); font-size: var(--fs-h2); line-height: 0.95; letter-spacing: -0.02em; color: var(--paper); }
.services-intro h2 em { font-style: italic; color: var(--cobalt-lt); }
.services-intro p { margin-top: 1.25rem; max-width: 52ch; color: #cfc8b8; font-size: var(--fs-lead); }

/* the cards live in a sticky stage (tall track) so the screen holds while
   they reveal one-by-one — sticky, not a hard-pin (those ghosted). */
.services-track { position: relative; height: calc(240 * var(--svh)); }
.services-sticky { position: sticky; top: 0; height: calc(100 * var(--svh)); display: flex; flex-direction: column; justify-content: center; gap: clamp(1rem,calc(2.5 * var(--svh)),2rem); background: var(--ink); overflow: hidden; }
.pricing { width: 100%; display: grid; grid-template-columns: 1fr; gap: 1.25rem; padding-top: clamp(2rem,calc(4 * var(--svh)),3rem); padding-bottom: clamp(2rem,calc(4 * var(--svh)),3rem); }
@media (min-width: 861px) { .pricing { grid-template-columns: repeat(3, 1fr); align-items: start; } }
/* touch / very-short desktop: don't trap the (single-column) cards in a
   clipped calc(100 * var(--svh)) sticky — let the section grow naturally. Above this the
   3-col cards fit, so the sticky pause stays. */
@media (max-width: 860px), (max-height: 640px) and (min-width: 861px) {
  .services-track { height: auto; }
  .services-sticky { position: relative; height: auto; overflow: visible; padding: clamp(4rem,calc(9 * var(--svh)),6rem) 0; }
}
.tier {
  position: relative; display: flex; flex-direction: column; gap: clamp(0.7rem,calc(1.4 * var(--svh)),1.1rem);
  padding: clamp(1.3rem,1.9vw,2.6rem); background: #141413; border: 1px solid #2f2f2b;
  transition: transform 0.4s var(--ease), border-color 0.4s var(--ease), box-shadow 0.4s var(--ease);
}
.tier:hover { transform: translateY(-6px); border-color: var(--cobalt-lt); }
.tier.featured { border-color: var(--cobalt-lt); background: #181820; box-shadow: 0 0 0 1px var(--cobalt-lt), 0 30px 60px -30px rgba(91,110,245,0.5); }
@media (min-width: 920px) { .tier.featured { margin-top: -16px; } .tier.featured:hover { transform: translateY(-10px); } }
.tier-badge { position: absolute; top: -0.75rem; left: clamp(1.75rem,2.6vw,2.75rem); background: var(--cobalt-lt); color: #0a0a14; font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.16em; text-transform: uppercase; padding: 0.3rem 0.7rem; }
.tier-top { display: flex; align-items: baseline; gap: 0.75rem; font-family: var(--mono); font-size: var(--label); letter-spacing: 0.16em; text-transform: uppercase; color: #a8a294; }
.tier-no { font-family: var(--serif); font-style: italic; font-size: 1.6rem; color: var(--cobalt-lt); }
.tier.featured .tier-no { color: var(--cobalt-lt); }
.tier-name { font-family: var(--serif); font-weight: 400; font-size: clamp(1.7rem,2.4vw,3.2rem); line-height: 1; letter-spacing: -0.01em; color: var(--paper); }
.tier-name em { font-style: italic; color: var(--cobalt-lt); }
.tier.featured .tier-name em { color: var(--cobalt-lt); }
.tier-price { font-family: var(--serif); font-size: clamp(1.8rem,3vw,3.6rem); line-height: 1; color: var(--paper); }
.tier-price span { font-family: var(--mono); font-size: 0.8rem; letter-spacing: 0.1em; color: #a8a294; }
.tier-desc { font-size: var(--fs-body); color: #cfc8b8; }
.tier-feat { list-style: none; display: flex; flex-direction: column; gap: clamp(0.4rem,calc(0.9 * var(--svh)),0.6rem); margin-top: auto; padding-top: clamp(0.9rem,calc(1.8 * var(--svh)),1.25rem); border-top: 1px solid #2f2f2b; }
.tier-feat li { font-size: clamp(0.9rem,0.95vw,1.05rem); color: #cfc8b8; padding-left: 1.4rem; position: relative; line-height: 1.4; }
.tier-feat li::before { content: '→'; position: absolute; left: 0; color: var(--cobalt-lt); font-family: var(--mono); }
.tier.featured .tier-feat li::before { color: var(--cobalt-lt); }
.tier-cta { margin-top: clamp(1rem,calc(2 * var(--svh)),1.5rem); color: var(--paper); border-color: #3a3a36; }
.tier-cta:hover { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.services-note { padding-top: clamp(1.5rem,calc(3 * var(--svh)),2.5rem); padding-bottom: clamp(3rem,calc(6 * var(--svh)),5rem); font-family: var(--mono); font-size: 0.8rem; color: #a8a294; }

/* Per-tier identity so the three cards read as distinct, not triplets.
   Grund = restrained / cool · Standard(featured) = elevated blue hero ·
   Premium = warm orange, richest. */
/* GRUND (first) — entry tier: muted, flat, smallest emphasis */
.pricing .tier:first-child { background: #121211; }
.pricing .tier:first-child .tier-name,
.pricing .tier:first-child .tier-price { color: #e7e1d2; }
.pricing .tier:first-child .tier-no,
.pricing .tier:first-child .tier-name em,
.pricing .tier:first-child .tier-feat li::before { color: #8f99e8; }
/* PREMIUM (last) — warm, rich, orange accent + subtle glow */
.pricing .tier:last-child { background: #17120f; border-color: #3a2c22; }
.pricing .tier:last-child:hover { border-color: var(--orange); }
.pricing .tier:last-child .tier-no,
.pricing .tier:last-child .tier-name em,
.pricing .tier:last-child .tier-feat li::before { color: var(--orange); }
.pricing .tier:last-child .tier-feat { border-top-color: #3a2c22; }
.pricing .tier:last-child .tier-tag { color: #d8a07e; }
.pricing .tier:last-child .tier-cta { border-color: #5a4233; }
.pricing .tier:last-child .tier-cta:hover { background: var(--orange); color: var(--ink); border-color: var(--orange); }

/* ─────────────────────────  SCENE 4 · WORK (horizontal)  ────────── */
.work { background: var(--ink); color: var(--paper); }
.work-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 2rem; flex-wrap: wrap; padding: clamp(4rem,calc(8 * var(--svh)),6rem) clamp(1.25rem,5vw,6rem) clamp(1.5rem,calc(3.5 * var(--svh)),2.5rem); }
.work-head h2 { font-family: var(--serif); font-size: var(--fs-h2); line-height: 0.95; letter-spacing: -0.02em; }
.work-head h2 em { font-style: italic; color: var(--orange); }
.work-head p { max-width: 38ch; color: #cfc8b8; font-size: var(--fs-body); }
.hwrap { overflow: hidden; }
.htrack { display: flex; align-items: center; gap: clamp(1.5rem,3vw,3rem); padding: 0 clamp(1.25rem,5vw,6rem) clamp(2.5rem,calc(5 * var(--svh)),4rem); width: max-content; will-change: transform; }
/* sized so the shot + name + meta always fit the viewport during the pin */
.proj { width: clamp(240px, min(34vw, calc(58 * var(--svh))), 640px); flex: 0 0 auto; }
.proj-shot { aspect-ratio: 3/2; overflow: hidden; background: #1a1a18; border: 1px solid #2a2a28; position: relative; }
.proj-shot img { width: 100%; height: 100%; object-fit: cover; object-position: center top; transition: transform 0.8s var(--ease); will-change: transform; }
.proj:hover .proj-shot img { transform: scale(1.05); }
.proj-meta { display: flex; justify-content: space-between; align-items: baseline; margin-top: 1rem; font-family: var(--mono); font-size: var(--label); letter-spacing: 0.12em; text-transform: uppercase; color: #a8a294; }
.proj-meta .cat { color: var(--orange); }
.proj-name { font-family: var(--serif); font-style: italic; font-size: clamp(1.5rem,2.4vw,2.1rem); margin-top: 0.4rem; }
.proj-view { font-family: var(--mono); font-size: var(--label); letter-spacing: 0.12em; text-transform: uppercase; color: var(--orange); margin-top: 0.5rem; display: inline-flex; gap: 0.4rem; }
.work-hint { display: none; }
@media (max-width: 860px) {
  /* touch = JS auto-advancing band that's also swipeable; no scroll-snap (it
     fights the per-frame scrollLeft writes and stutters the auto-advance). */
  .hwrap { overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .hwrap::-webkit-scrollbar { display: none; }
  .htrack { width: max-content; }
}

/* ─────────────────────────  SCENE 5 · PROCESS (sticky, blob + step deck)  ───── */
/* Sticky stage (tall track) — no hard pin, no z-index ladder. The blob
   morphs on the right; the four steps appear as a diagonally-stacked deck
   of cards on the left and accumulate (they never disappear). */
.process { background: var(--paper); color: var(--ink); }
.process::before { display: none; }
.process-track { position: relative; height: calc(360 * var(--svh)); }
.process-sticky { position: sticky; top: 0; height: calc(100 * var(--svh)); background: var(--paper); overflow: hidden; }
.process-head { position: absolute; top: clamp(4.5rem,calc(9 * var(--svh)),6.5rem); left: 0; right: 0; z-index: 4; }
.process-head h2 { font-family: var(--serif); font-size: var(--fs-h2); line-height: 0.95; letter-spacing: -0.02em; }
.process-head h2 em { font-style: italic; color: var(--cobalt); }

/* Deck (left) and blob (right) are anchored to a CENTERED max-width band so
   on big/fullscreen screens they scale up and stay together instead of
   sticking to the screen edges with a huge empty middle. */
.proc-canvas {
  position: absolute; top: 52%; transform: translateY(-50%);
  right: max(-18vw, calc(50% - 1180px));
  width: clamp(600px, 80vw, 1500px); aspect-ratio: 16 / 9; height: auto; pointer-events: none;
  /* frames are keyed transparent now — the blob sits on the page directly,
     so no mask (no edge feather) and no tone mismatch */
}

/* diagonally-stacked deck — uniform card height keeps the offsets even;
   offsets are small relative to the cards so they overlap (not separated). */
.proc-steps {
  list-style: none; position: absolute; top: 56%;
  left: max(clamp(1.25rem,5vw,6rem), calc(50% - 760px));
  width: clamp(260px, 27vw, 520px); height: 0; z-index: 3;
  --ox: clamp(20px, 1.7vw, 36px); --oy: clamp(16px, 1.4vw, 28px);
}
.proc-step {
  position: absolute; left: 0; top: 0; width: 100%; height: clamp(170px, calc(21 * var(--svh)), 300px); overflow: hidden;
  transform: translate(calc(var(--i) * var(--ox) + var(--dx, 0px)), calc(-50% + (var(--i) - 1.5) * var(--oy)));
  background: var(--paper); border: 1px solid var(--rule);
  padding: clamp(1.2rem,1.6vw,2.1rem) clamp(1.3rem,1.7vw,2.3rem);
  box-shadow: 0 34px 70px -30px rgba(15,15,14,0.5); opacity: 0;
}
.proc-step .n { display: block; font-family: var(--serif); font-style: italic; font-size: clamp(1.8rem,2.6vw,3.4rem); line-height: 0.8; color: var(--cobalt); }
.proc-step .t { font-family: var(--serif); font-size: clamp(1.45rem,2vw,2.6rem); line-height: 1; letter-spacing: -0.01em; margin-top: 0.35rem; }
.proc-step .d { font-size: clamp(1rem,1.05vw,1.35rem); color: var(--ink-soft); margin-top: 0.6rem; }
/* short desktop landscape: deck would hit the header — go static stacked */
@media (max-height: 640px) and (min-width: 861px) {
  .process-track { height: auto; }
  .process-sticky { position: relative; height: auto; padding: clamp(4rem,calc(9 * var(--svh)),6rem) clamp(1.25rem,5vw,6rem); }
  .process-head { position: relative; top: auto; left: auto; right: auto; margin-bottom: 2rem; }
  .proc-canvas { display: none; }
  .proc-steps { position: relative; left: auto; top: auto; width: auto; height: auto; display: flex; flex-direction: column; gap: 1.25rem; transform: none; }
  .proc-step { position: relative; transform: none; opacity: 1; }
}

/* touch fallback: static stacked list, no canvas/sticky */
@media (max-width: 860px) {
  .process-track { height: auto; }
  .process-sticky { position: relative; height: auto; padding: clamp(4rem,calc(10 * var(--svh)),6rem) clamp(1.25rem,5vw,6rem); }
  .process-head { position: relative; top: auto; left: auto; right: auto; margin-bottom: 2rem; }
  .proc-canvas { display: none; }
  .proc-steps { position: relative; left: auto; top: auto; width: auto; height: auto; display: flex; flex-direction: column; gap: 1.5rem; }
  .proc-step { position: relative; transform: none; opacity: 1; }
}

/* ─────────────────────────  SCENE 6 · PROOF (dark)  ─────────────── */
.proof { background: var(--ink); color: var(--paper); overflow: hidden; }
.proof-inner { padding: clamp(5rem,calc(12 * var(--svh)),9rem) clamp(1.25rem,5vw,6rem); }
.proof h2 { font-family: var(--serif); font-size: var(--fs-h2); line-height: 0.98; letter-spacing:-0.02em; max-width: 16ch; text-wrap: balance; }
.proof h2 em { font-style: italic; color: var(--orange); }
.stats { display: grid; grid-template-columns: repeat(2,1fr); gap: clamp(2rem,5vw,4rem); margin-top: clamp(3rem,calc(8 * var(--svh)),5rem); }
@media (min-width: 800px) { .stats { grid-template-columns: repeat(4,1fr); } }
.stat .num { font-family: var(--serif); font-size: clamp(2.8rem,7vw,6rem); line-height: 0.9; color: var(--paper); }
.stat .num .u { color: var(--orange); }
.stat .lab { font-family: var(--mono); font-size: var(--label); letter-spacing: 0.12em; text-transform: uppercase; color: #a8a294; margin-top: 0.75rem; }
.marquee { overflow: hidden; padding: clamp(2.5rem,calc(6 * var(--svh)),4rem) 0; border-top: 1px solid #2a2a28; border-bottom: 1px solid #2a2a28; margin-top: clamp(3rem,calc(8 * var(--svh)),5rem); }
.marquee-inner { display: flex; gap: 3rem; width: max-content; font-family: var(--serif); font-style: italic; font-size: clamp(1.6rem,3.5vw,3rem); white-space: nowrap; will-change: transform; }
.marquee-inner .dot { color: var(--orange); font-style: normal; }

/* ─────────────────────────  SCENE 7 · CONTACT (dark, wipe)  ─────── */
.contact { background: var(--ink); color: var(--paper); }
.contact-inner { min-height: calc(100 * var(--svh)); display: flex; flex-direction: column; justify-content: center; padding: clamp(5rem,calc(12 * var(--svh)),9rem) clamp(1.25rem,5vw,6rem); }
.contact .eyebrow .idx { color: var(--orange); }
.contact h2 { font-family: var(--serif); font-size: var(--fs-mega); line-height: 1.02; letter-spacing: -0.03em; max-width: 14ch; text-wrap: balance; }
.contact h2 em { font-style: italic; color: var(--orange); }
.contact-sub { margin-top: clamp(1.5rem,calc(4 * var(--svh)),2.5rem); font-size: var(--fs-lead); color: #cfc8b8; max-width: 44ch; }
.contact-actions { display: flex; flex-wrap: wrap; gap: 1.25rem; align-items: center; margin-top: clamp(2rem,calc(5 * var(--svh)),3rem); }
.contact-email { font-family: var(--mono); font-size: 0.95rem; letter-spacing: 0.06em; border-bottom: 1px solid var(--orange); padding-bottom: 0.15rem; }

/* ─────────────────────────  FOOTER  ─────────────────────────────── */
.footer { background: var(--ink); color: #8d877a; padding: clamp(2rem,calc(5 * var(--svh)),3rem) clamp(1.25rem,5vw,6rem); border-top: 1px solid #2a2a28; font-family: var(--mono); font-size: var(--label); letter-spacing: 0.06em; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 1rem; }
.footer a { color: var(--orange); }

/* ─────────────────────────  MOTION SAFETY  ─────────────────────── */
/* base state of JS-animated bits so nothing is invisible without JS */
html.no-js .reveal-line > *, html.no-js [data-anim] { opacity: 1 !important; transform: none !important; }
/* with JS active, hide animated bits until the engine reveals them (no FOUC) */
html.js [data-anim] { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
  .hero-canvas { display: none !important; }
  .manifesto .statement .w { color: var(--fg) !important; }
  .scrollcue, .marquee { display: none; }
  [data-anim] { opacity: 1 !important; transform: none !important; }
  .card { position: relative; min-height: auto; }
}
