/* MATRIZ — Homepage. Editorial, anti-corporate, machine-literate.
   Built on global tokens in colors_and_type.css */

@import url("colors_and_type.css");

* { box-sizing: border-box; }
*::selection { background: var(--mz-cinabre); color: var(--mz-white); }
html { scroll-behavior: auto; }
html, body { overflow-x: clip; }
/* Removed scroll-behavior: smooth. With it on, every JS-initiated
   window.scrollBy in the manifesto's rubber-band loop was being
   animated by the browser over ~300ms, queueing animations while the
   user kept scrolling — net effect: scroll appeared to accumulate
   momentum globally as more scrolls fired. Instant scrolling for
   programmatic ops keeps pullback predictable; native momentum
   scrolling on touch devices is unaffected (that's browser-level). */

body {
  margin: 0;
  font-family: var(--font-serif);
  color: var(--mz-white);
  background: var(--mz-black);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
body.is-locked { overflow: hidden; }

a { color: inherit; text-decoration: none; }

/* Sections need a scroll-margin so anchored jumps don't hide under the
   fixed dark header that appears after scroll. */
section { scroll-margin-top: 80px; }

/* ───────── LAYOUT SHELL ───────── */
.shell { max-width: 1440px; margin: 0 auto; padding: 0 80px; }
section { position: relative; padding: 120px 0; }
.dark { background: var(--mz-black); color: var(--mz-white); }

/* ───────── HEADER (fixed, scroll-reveal) ─────────
   Black header that materializes once the hero wordmark has scaled away.
   Three-cell grid: MATRIZ · Contato (center, cinabre) · hamburger → drawer.
   Starts hidden + lifted; .is-visible (toggled by scroll JS) reveals it. */
.nav {
  position: fixed; top: 0; left: 0; right: 0;
  z-index: 100;
  background: var(--mz-black);
  color: var(--mz-white);
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
  opacity: 0;
  transform: translateY(-12px);
  pointer-events: none;
  transition: opacity 260ms var(--ease-out), transform 260ms var(--ease-out);
}
.nav.is-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.nav-inner {
  display: grid;
  /* Duas células desde a remoção do Contato: marca à esquerda, hambúrguer à direita. */
  grid-template-columns: 1fr auto;
  align-items: center;
  max-width: 1440px; margin: 0 auto;
  padding: 0 80px;
  height: 64px;
  gap: 24px;
}
.nav-mark {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 20px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--mz-white);
  justify-self: start;
  line-height: 1;
  transition: color var(--dur-fast) var(--ease-out);
}
.nav-mark:hover { color: var(--mz-cinabre); }
.nav-cta {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--mz-cinabre);
  justify-self: center;
  white-space: nowrap;
  display: inline-flex; align-items: center; gap: 8px;
  transition: color var(--dur-fast) var(--ease-out);
}
.nav-cta:hover { color: var(--mz-white); }
.nav-cta .arr { font-size: 13px; }
.nav-toggle {
  justify-self: end;
  background: transparent;
  border: 0; cursor: pointer;
  padding: 12px 4px;
  display: flex; flex-direction: column; gap: 5px;
}
.nav-toggle span {
  display: block;
  width: 28px; height: 2px;
  background: var(--mz-white);
  transition: background var(--dur-fast) var(--ease-out);
}
.nav-toggle:hover span { background: var(--mz-cinabre); }

/* ───────── NAV DRAWER (right slide-in) ───────── */
.nav-drawer {
  position: fixed; inset: 0;
  z-index: 200;
  pointer-events: none;
}
.nav-drawer[data-open="true"] { pointer-events: auto; }
.nav-drawer-scrim {
  position: absolute; inset: 0;
  background: rgba(0, 0, 0, 0.6);
  opacity: 0;
  transition: opacity 300ms var(--ease-out);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}
.nav-drawer[data-open="true"] .nav-drawer-scrim { opacity: 1; }
.nav-drawer-panel {
  position: absolute; right: 0; top: 0; bottom: 0;
  width: min(640px, 60vw);
  background: var(--mz-paper);
  color: var(--mz-black);
  display: flex; flex-direction: column;
  transform: translateX(100%);
  transition: transform 380ms cubic-bezier(0.22, 1, 0.36, 1);
  box-shadow: -24px 0 40px rgba(0, 0, 0, 0.25);
}
.nav-drawer[data-open="true"] .nav-drawer-panel { transform: translateX(0); }
.nav-drawer-head {
  display: flex; align-items: center; justify-content: space-between;
  height: 64px;
  padding: 0 56px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.15);
}
.nav-drawer-eyebrow {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 10px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: rgba(0, 0, 0, 0.6);
}
.nav-drawer-close {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  background: transparent;
  border: 0; cursor: pointer;
  color: var(--mz-black);
  padding: 0;
  transition: color var(--dur-fast) var(--ease-out);
}
.nav-drawer-close:hover { color: var(--mz-cinabre); }
.nav-drawer-links {
  flex: 1;
  padding: 60px 56px;
  display: flex; flex-direction: column;
  justify-content: center;
  gap: 16px;
}
.nav-drawer-links a {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(48px, 7vw, 88px);
  text-transform: uppercase;
  line-height: 0.95;
  letter-spacing: -0.01em;
  color: var(--mz-black);
  transition: color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.nav-drawer-links a:hover {
  color: var(--mz-cinabre);
  transform: translateX(6px);
}
.nav-drawer-links a.accent { color: var(--mz-cinabre); }
.nav-drawer-links a.accent:hover { color: var(--mz-black); }
.nav-drawer-foot {
  padding: 22px 56px 32px;
  border-top: 1px solid rgba(0, 0, 0, 0.15);
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 14px;
  color: rgba(0, 0, 0, 0.65);
}

/* ───────── HERO ─────────
   Two-layer setup: .hero-scroll is a tall (220vh) outer surface that
   captures scroll; .hero is position:sticky pinned at top:0 for 100vh
   while the user moves through that surface. --hp (0→1, set by JS)
   advances across the captured scroll, so the headline beats have
   generous time to read — the page "pulls focus" even on fast scrolls.
   Stage for matrix-rain canvas + giant wordmark + editorial headline. */
.hero-scroll {
  position: relative;
  height: 470vh; /* runway dos 3 atos — longo: a travessia pede tempo */
  background: var(--mz-black);
  /* Override the global section padding — the hero-scroll IS a
     <section>, so without this it inherits 120px 0 and leaves an
     unwanted black band above the rain canvas. */
  padding: 0;
}
.hero {
  position: sticky; top: 0;
  height: 100vh;
  min-height: 100vh;
  display: flex; flex-direction: column;
  /* Padding removed — the .shell child handles its own equal top/bottom
     padding so the inner layout (eyebrow + MATRIZ + headline + sub)
     reads as one balanced composition, not three blocks stacked
     against the edges. */
  padding: 0;
  overflow: hidden;
  background: var(--mz-black);
}
/* Default --hp on :root so unset state renders as if no scroll; JS sets the
   real value on documentElement during scroll. Keeping the default at :root
   (rather than on .hero) is critical — declaring --hp on .hero would block
   the JS-set value from cascading into the hero subtree.
   --ip is the intro progress: 0 at rest, ramps to ~0.62 on first arm so the
   hero copy reveals beat-by-beat WITHOUT requiring scroll. Word --t reads
   max(--hp, --ip) — scroll catches up + takes over as the user scrolls. */
:root { --hp: 0; --ip: 0; }
.hero-rain {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
  pointer-events: none;
  z-index: 0;
  /* Dim the whole rain layer so it sits behind the white copy
     without competing for attention — like the user said, a
     black-transparent filter between the animation and the text. */
  opacity: 0.45;
}
.hero-fade {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 55%;
  background: linear-gradient(to bottom,
    rgba(0, 0, 0, 0)   0%,
    rgba(0, 0, 0, 0.65) 55%,
    var(--mz-black)    100%);
  pointer-events: none;
  z-index: 1;
}
/* The hero .shell carries the inner padding so the composition reads
   balanced. Equal top/bottom padding clamps with vh so taller monitors
   get more breathing room. The eyebrow + MATRIZ "top group" sit at the
   top of the padded box; the headline + sub "bottom group" sit at the
   bottom — pushed down by margin-top:auto on .hero-bottom. The empty
   middle is the intentional breath between the two groups. */
.hero .shell {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; flex: 1;
  padding-top: clamp(56px, 7vh, 96px);
  padding-bottom: clamp(56px, 7vh, 96px);
}

.hero-top {
  display: flex; align-items: flex-start; justify-content: space-between;
  padding-top: 0;
  /* Generous separation between the eyebrow and MATRIZ — they're two
     distinct beats of the top group, not stacked label+title. */
  margin-bottom: clamp(40px, 6vh, 80px);
  flex: 0 0 auto;
}
/* ── ESTÚDIO DO FUTURO eyebrow ──
   Initial: visibility:hidden until .fonts-ready (handled in head style).
   Once fonts ready, the eyebrow becomes visible but the inner
   .hero-eyebrow-text is collapsed to max-width:0 with overflow:hidden,
   so no characters are visible. When body.is-armed fires (first
   scroll/touch/wheel/keydown), max-width transitions to its measured
   natural width (set on --eyebrow-w by JS on load) over ~1.1s — the
   text "writes" left to right. A 1px caret blinks alongside while it
   writes; afterwards it keeps blinking.

   max-width instead of clip-path: clip-path transitions are flaky
   across rendering paths (some snapshot tools and intermediate
   transitions render the property as a frozen initial value). width
   animation is rock-solid. */
.hero-eyebrow {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--mz-white);
  line-height: 1;
}
.hero-eyebrow-text {
  display: inline-block;
  overflow: hidden;
  white-space: nowrap;
  /* Initial collapsed state. JS replaces this with the live width
     during the reveal animation; once revealed the inline style takes
     over. */
  max-width: 0;
  vertical-align: bottom;
}
.hero-eyebrow-caret {
  display: inline-block;
  width: 1px;
  height: 11px;
  margin-left: 6px;
  background: currentColor;
  /* Invisible until armed; then it blinks. */
  opacity: 0;
  vertical-align: -1px;
}
body.intro-eyebrow .hero-eyebrow-caret {
  animation: heroCaretBlink 820ms steps(2, end) infinite;
}
@keyframes heroCaretBlink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0; }
}

/* Middle band — MATRIZ wordmark. flex: 0 so it doesn't stretch; we
   want the empty space between MATRIZ and the bottom headline to read
   as deliberate breath, not auto-fill. */
.hero-mark {
  flex: 0 0 auto;
  display: flex; flex-direction: column; justify-content: flex-start;
  min-height: 0;
  padding: 0;
  margin-top: 0;
}
.hero-word {
  font-family: var(--font-display);
  /* Brand guide (matriz_brand.md): wordmark = Integral CF BOLD, untouchable.
     Heavy 900 é voz de hook, não de wordmark — era o peso errado aqui. */
  font-weight: 700;
  /* Cap with min(vw, vh) so on short viewports the wordmark scales DOWN
     with viewport height too — stops it from crowding out hero-bottom. */
  font-size: clamp(80px, min(17vw, 30vh), 280px);
  line-height: 0.85;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  color: var(--mz-white);
  margin: 0;
  text-wrap: balance;
}
.hero-deck {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(14px, 1.5vw, 18px);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--mz-white);
  margin: clamp(14px, 2.2vh, 24px) 0 0;
}
.hero-mark-rule,
.hero-mark-credits { display: none; }

/* Bottom 1/3 — headline + sub. margin-top:auto pushes this group to
   the bottom of the padded .shell, leaving symmetric breathing room
   above (between MATRIZ and the headline) and below (between sub and
   the section edge). */
.hero-bottom {
  position: relative;
  display: grid; grid-template-columns: minmax(0, 1fr) 240px;
  gap: 60px; align-items: end;
  padding: 0;
  flex: 0 0 auto;
  margin-top: auto;
}
.hero-headline {
  font-family: var(--font-display);
  /* Apoio nao grita mais que o protagonista: Bold como o wordmark,
     hierarquia expressa por TAMANHO (ratio ~5.6x). Frame em 2 pesos. */
  font-weight: 700;
  font-size: clamp(30px, 3.8vw, 50px);
  /* A touch more line-height so the four-line block doesn't feel cramped. */
  line-height: 1.08;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  margin: 0;
  perspective: 800px;
}
.hero-headline em {
  font-style: normal;
  color: var(--mz-gray-300);
}
.hero-headline .land { color: var(--mz-white); }

/* Per-word exit — each word falls + dissolves into the matrix rain below,
   staggered by its --i index. The rain consumes the type. Window per word
   is 0.32 of --hp; stagger 0.06 between words means the headline finishes
   exiting around --hp ≈ 0.62, well within the hero's morph range. Each
   word also tilts forward on rotateX so the fall feels physical, like a
   card edge slipping out from a stack. */
/* Per-beat entrance driven by scroll. Page loads with all beats invisible
   (--hp = 0); as the user scrolls through .hero-scroll, each beat fades
   up + into place, staggered by --i. Stagger 0.10 > window 0.08, so a
   beat is fully visible before the next one starts — deliberate rhythm,
   no overlap. Six beats (0–5) finish entering by --hp ≈ 0.58, leaving
   ~42% of the scroll as dwell time for reading. */
.hero-deck .word,
.hero-headline .word,
.hero-sub .word {
  display: inline-block;
  --start: calc(var(--i, 0) * 0.10);
  /* Driver is the larger of the scroll-driven --hp and the intro --ip,
     so on first touch the intro auto-reveals all six beats; once the
     user scrolls past where --hp surpasses --ip, scroll takes over
     monotonically. No double-fire, no flicker. */
  --driver: max(var(--hp, 0), var(--ip, 0));
  --t: max(0, min(1, calc((var(--driver) - var(--start)) / 0.08)));
  opacity: var(--t);
  transform: translateY(calc((1 - var(--t)) * 16px));
  will-change: opacity, transform;
}

.hero-sub {
  /* Dual-voice da marca: serif sussurra PERGUNTAS; fatos falam em Integral.
     'Entregas rápidas / Sem call' são fatos — viram etiqueta de spec. */
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  line-height: 2.1;
  color: var(--mz-gray-300);
  margin: 0;
  max-width: 240px;
  justify-self: end;
  text-align: right;
  text-wrap: pretty;
  /* No extra position offset — the parent .hero-bottom is already
     pushed to the bottom of the padded .shell, so the sub doesn't
     need a manual nudge to feel anchored. */
  position: relative;
  top: 0;
}
.hero-sub strong {
  font-style: italic; font-weight: 400;
  color: var(--mz-white);
}

/* ───────── SECTION HEADERS ─────────
   Title + optional italic sub. One hairline below. currentColor lets it work
   on both dark and paper bgs. */
.section-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  padding-bottom: 22px;
  border-bottom: 1px solid currentColor;
  margin-bottom: 80px;
  gap: 24px;
}
.section-title {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(26px, 3.4vw, 48px);
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: -0.005em;
  margin: 0;
}
.section-sub {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(14px, 1.2vw, 18px);
  color: rgba(255, 255, 255, 0.7);
  margin: 0;
  white-space: nowrap;
}
.manifesto .section-sub { color: rgba(0, 0, 0, 0.7); }

/* ───────── SHARED FRAME SYSTEM ─────────
   Used by every major section (Ofício, Trabalho, Jornal, Manifesto,
   Contato, Footer). Two hairline bands at top/bottom of the section
   carrying a Roman-numeral eyebrow, a flexing hairline rule, and a
   meta caption — reads like a print-shop ticket / engineering drawing
   title block. All colors come from currentColor so the same markup
   works on dark and paper sections. */

.frame-band {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 26px 80px;
  flex: 0 0 auto;
}
.frame-band-top { border-bottom: 1px solid currentColor; }
.frame-band-bot { border-top: 1px solid currentColor; }
/* Hairlines that frame the bands themselves are full-strength
   currentColor; we soften it visually with a half-alpha overlay on top
   only when the section needs it. Default works for dark sections. */
.frame-band[data-soft="true"] { border-color: rgba(255, 255, 255, 0.18); }
.frame-band[data-soft="true"].frame-band-top { border-bottom-color: rgba(255, 255, 255, 0.18); }
.frame-band[data-soft="true"].frame-band-bot { border-top-color: rgba(255, 255, 255, 0.18); }
/* Paper variant — half-alpha black hairline. */
.frame-band[data-tone="paper"] { border-color: rgba(0, 0, 0, 0.18); }
.frame-band[data-tone="paper"] .frame-rule { background: rgba(0, 0, 0, 0.22); }
.frame-band[data-tone="paper"] .frame-meta { color: rgba(0, 0, 0, 0.7); }

.frame-eyebrow {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  white-space: nowrap;
}
.frame-rule {
  flex: 1;
  height: 1px;
  background: rgba(255, 255, 255, 0.22);
}
.frame-meta {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--mz-gray-300);
  white-space: nowrap;
}

/* ── Generic sticky-pin pattern ──
   A tall outer surface (.pin-scroll, ~260vh) holds an inner 100vh
   sticky child (.pin-sticky). JS writes 0→1 --p into .pin-sticky as
   the user scrolls through the outer surface. Inside, the layout is:

     [.pin-sticky]
       [.frame-dots]                  background plate (z-index 0)
       [.frame-corners]               L-brackets (z-index 1)
       [.frame-band-top]              header band (the "title")
       [.pin-stage .frame-content]    actual content (flex: 1, scroll-revealed)
       [.frame-band-bot]              footer band

   The bands stay visually fixed at top/bottom of the viewport while the
   stage content develops with --p. Same shape as the hero scroll capture
   and the flow section — every major content section uses this. */
[data-pin-scroll] {
  position: relative;
  /* 260vh: 100vh sticky window + 160vh of captured scroll for the
     internal --p to tick through. Tuned so beats land at a comfortable
     pace and the user feels a deliberate pause, not a scroll-jack. */
  height: 260vh;
}
[data-pin-sticky] {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  --p: 0;
  background: inherit;
  overflow: hidden;
}
.pin-stage {
  flex: 1 1 auto;
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  z-index: 2;
}

/* ── Section-corner register marks ──
   Four tiny L-shaped marks bracketing the section, like printer's
   registration tooling. Sit inside .frame-corners as an absolute
   overlay; the section itself must be position: relative. */
.frame-corners {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}
.frame-corners span {
  position: absolute;
  width: 18px;
  height: 18px;
  border-color: currentColor;
  opacity: 0.4;
}
.frame-corners span:nth-child(1) { top: 12px; left: 12px; border-top: 1px solid; border-left: 1px solid; }
.frame-corners span:nth-child(2) { top: 12px; right: 12px; border-top: 1px solid; border-right: 1px solid; }
.frame-corners span:nth-child(3) { bottom: 12px; left: 12px; border-bottom: 1px solid; border-left: 1px solid; }
.frame-corners span:nth-child(4) { bottom: 12px; right: 12px; border-bottom: 1px solid; border-right: 1px solid; }

/* ── Subtle dotted-grid background plate ──
   Drop in as <div class="frame-dots"></div> inside a section to add a
   sparse dot pattern matching the flow stage. Section must be
   position: relative; .frame-dots covers it with z-index: 0. */
.frame-dots {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image: radial-gradient(circle at 1px 1px, rgba(255, 255, 255, 0.14) 0.9px, transparent 1.3px);
  background-size: 28px 28px;
}
.frame-dots[data-tone="paper"] {
  background-image: radial-gradient(circle at 1px 1px, rgba(0, 0, 0, 0.18) 0.9px, transparent 1.3px);
}

/* All section content above the dots/corners */
.frame-content { position: relative; z-index: 2; }

/* ═══════════════════════════════════════════════════════════════════
   SECTION 2 — Inline station expansions
   Each station has a .station-expand block (cards strip + CTA) that
   opens via data-stage as the user scrolls past the cascade. Opens
   CUMULATIVELY: once a station's --t reaches 1 it stays 1, so
   stations 1 → 2 → 3 → 4 each open in turn and stay open through
   the rest of the pin. The diagonal absolute layout still wraps
   stations during the cascade, but each station's expand body
   grows inline, pushing visual elements below it down via the
   container's natural overflow scroll.

   Note: with absolute-positioned stations, neighbouring stations
   won't be pushed by an expansion. This is a known limitation of
   the diagonal layout — the user-facing effect is that each
   station's box grows in place to reveal cards + CTA; visually
   adjacent stations are kept off the same vertical band via the
   diagonal positions, so the overlap risk is minimal at moderate
   expand heights. */
.station-expand {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 2vh, 24px);
  margin-top: 0;
  /* min-width:0 critical for the cards strip translation to work.
     Without it, flex items get min-width:auto = their min-content
     size, which propagates the cards-strip natural width (~800px)
     up through every ancestor, sizing the examples-window to match
     the strip → strip.scrollWidth - window.clientWidth = 0 → no
     translation possible AND wider containers push title/desc
     text past the viewport. */
  min-width: 0;
}
.station-expand[data-stage] {
  /* Open height + opacity scale with data-stage --t. Once --t hits 1
     (past the --end of the window) it stays 1 → cumulative open. */
  max-height: calc(var(--t) * 460px);
  opacity: var(--t);
  margin-top: calc(var(--t) * 14px);
  /* Override the generic [data-stage] translateY which would shake
     the body during open. */
  transform: none;
}

.station-cta {
  display: inline-flex; align-items: center; gap: 14px;
  background: transparent;
  color: var(--mz-white);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(11px, 1.1vw, 14px);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: clamp(14px, 1.6vw, 20px) clamp(20px, 2.4vw, 32px);
  border: 1px solid var(--mz-white);
  text-decoration: none;
  align-self: flex-start;
  transition: background var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out),
              gap var(--dur-base) var(--ease-out);
}
.station-cta:hover {
  background: var(--mz-white);
  color: var(--mz-black);
  gap: 22px;
}
.station-cta .arr {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 14px;
  line-height: 1;
}

/* ═══════════════════════════════════════════════════════════════════
   SECTION 2 — O OFÍCIO (4 chapter pins, one per movement)
   New structure: each movement (Marca, Presença, Plataforma,
   Automação) is its own pin-scroll chapter. Inside each chapter's
   sticky: head (node + title + italic desc) ALWAYS visible, plus
   reveal-on-scroll promise → horizontal cards strip → CTA.
   ═══════════════════════════════════════════════════════════════════ */
.oficio {
  position: relative;
  background: var(--mz-black);
  color: var(--mz-white);
  padding: 0;
}
/* Each chapter is its own pin. 150vh = 50vh of captured scroll for
   the reveal cascade (promise → cards → CTA). */
.oficio-chapter { position: relative; height: 150vh; }
.oficio-sticky {
  position: sticky; top: 0;
  height: 100vh;
  display: flex; flex-direction: column;
  background: var(--mz-black);
  overflow: hidden;
  --p: 0;
}
.oficio-stage {
  flex: 1 1 auto;
  display: flex; flex-direction: column;
  justify-content: center;
  gap: clamp(20px, 3vh, 40px);
  padding: clamp(32px, 5vh, 64px) clamp(24px, 6vw, 80px);
  max-width: 1200px;
  width: 100%;
  margin: 0 auto;
}
.oficio-head {
  display: flex; align-items: flex-start;
  gap: clamp(20px, 3vw, 32px);
}
.oficio-node {
  display: grid; place-items: center;
  width: clamp(48px, 5vw, 64px);
  height: clamp(48px, 5vw, 64px);
  background: var(--mz-white);
  color: var(--mz-black);
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(16px, 1.6vw, 20px);
  letter-spacing: 0.02em;
  flex-shrink: 0;
}
.oficio-titles { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.oficio-title {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(40px, 5.4vw, 72px);
  line-height: 0.9;
  letter-spacing: -0.005em;
  text-transform: uppercase;
  margin: 0;
}
.oficio-desc {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(14px, 1.15vw, 17px);
  line-height: 1.45;
  color: var(--mz-gray-300);
  margin: 0;
  max-width: 540px;
  text-wrap: pretty;
}
/* The client-voice promise — heavier, dominant, white. Reveals on
   scroll via its data-stage window. */
.oficio-promise {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(18px, 1.9vw, 26px);
  line-height: 1.25;
  letter-spacing: -0.005em;
  color: var(--mz-white);
  margin: 0;
  max-width: 720px;
}

/* ── Examples horizontal strip ──
   3:4 vertical cards in a row. 3 fit comfortably in the visible
   window; the strip overflows horizontally to expose ~2 more cards
   on swipe. A black fade on the right edge hints there's more to
   scroll. Touch / trackpad horizontal scroll is native. */
.oficio-examples {
  position: relative;
  width: 100%;
}
/* The frame wraps the scrollable window so the fade overlay can sit
   on top of it (the scroller scrolls horizontally; the fade stays
   fixed to the right edge of the visible viewport). */
.examples-frame {
  position: relative;
  width: 100%;
  min-width: 0;
}
.examples-frame::after {
  content: "";
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: clamp(50px, 10vw, 100px);
  background: linear-gradient(to right, transparent 0%, var(--mz-black) 90%);
  pointer-events: none;
  z-index: 3;
}
.examples-window {
  width: 100%;
  min-width: 0;
  overflow: hidden;       /* clip — no manual scroll */
}
.examples-strip {
  will-change: transform;
  transition: transform 0.05s linear;
  /* JS sets transform: translateX(-N px) every frame based on the
     station's --p window. Cards 1-3 visible at strip's start, cards
     3-5 visible when strip is fully translated. */
}
.examples-window::-webkit-scrollbar { display: none; }
.examples-strip {
  display: flex;
  gap: clamp(12px, 1.5vw, 20px);
  padding-right: clamp(60px, 12vw, 140px); /* room so the rightmost card can be seen past the fade */
  align-items: flex-start;
}
.example-card {
  flex: 0 0 auto;
  width: clamp(150px, 22vw, 240px);
  aspect-ratio: 3 / 4;
  padding: clamp(14px, 1.4vw, 20px);
  display: flex; flex-direction: column; justify-content: space-between;
  text-decoration: none;
  font-family: var(--font-display);
  color: inherit;
  position: relative;
  overflow: hidden;
  scroll-snap-align: start;
  transition: transform var(--dur-base) var(--ease-out);
}
.example-card:hover { transform: translateY(-4px); }
.card-code {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(16px, 1.6vw, 22px);
  line-height: 1;
  letter-spacing: -0.005em;
}
.card-caption {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(12px, 1vw, 14px);
  margin: 0;
}
/* Reuse the tile variant styles for the cards (paper / dark / hatch / outline). */
.example-card[data-variant="paper-solid"] { background: var(--mz-paper); color: var(--mz-black); }
.example-card[data-variant="dark-outline"] { background: transparent; color: var(--mz-white); border: 1px solid rgba(255,255,255,0.55); }
.example-card[data-variant="dark-hatch"] {
  background:
    repeating-linear-gradient(45deg,
      rgba(255,255,255,0.22) 0,
      rgba(255,255,255,0.22) 0.5px,
      transparent 0.5px,
      transparent 9px);
  color: var(--mz-white);
  border: 1px solid rgba(255,255,255,0.5);
}
.example-card[data-variant="paper-rule"] {
  background: var(--mz-paper);
  color: var(--mz-black);
}
.example-card[data-variant="paper-rule"]::before {
  content: "";
  position: absolute;
  left: 16px; right: 16px;
  top: 50%; transform: translateY(-50%);
  height: 56%;
  background-image: repeating-linear-gradient(0deg,
    rgba(0,0,0,0.35) 0,
    rgba(0,0,0,0.35) 1px,
    transparent 1px,
    transparent 7px);
  pointer-events: none;
}
/* Right-edge fade overlay — sits over the window, doesn't trap clicks */
.oficio-examples::after {
  content: "";
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: clamp(40px, 8vw, 90px);
  background: linear-gradient(to right, transparent, var(--mz-black) 85%);
  pointer-events: none;
  z-index: 2;
}

/* CTA at the bottom of each chapter */
.oficio-cta {
  display: inline-flex; align-items: center; gap: 14px;
  background: transparent;
  color: var(--mz-white);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(11px, 1.1vw, 14px);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: clamp(14px, 1.6vw, 20px) clamp(20px, 2.4vw, 32px);
  border: 1px solid var(--mz-white);
  align-self: flex-start;
  text-decoration: none;
  transition: background var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out),
              gap var(--dur-base) var(--ease-out);
}
.oficio-cta:hover {
  background: var(--mz-white);
  color: var(--mz-black);
  gap: 22px;
}
.oficio-cta .arr { font-family: var(--font-serif); font-weight: 400; font-size: 14px; line-height: 1; }

/* Mobile tweaks for oficio chapters */
@media (max-width: 720px) {
  .oficio-chapter { height: 160vh; }
  .oficio-stage {
    padding: clamp(40px, 6vh, 80px) 24px;
    gap: clamp(18px, 2.5vh, 28px);
  }
  .oficio-head { gap: 16px; }
  .oficio-node {
    width: 44px; height: 44px;
    font-size: 14px;
  }
  .oficio-title { font-size: clamp(34px, 9vw, 50px); }
  .oficio-desc { font-size: 14px; }
  .oficio-promise { font-size: clamp(17px, 4.4vw, 22px); }
  .example-card { width: clamp(140px, 38vw, 180px); padding: 14px; }
  .card-code { font-size: 16px; }
  .card-caption { font-size: 12px; }
  .oficio-cta {
    font-size: 11px;
    padding: 14px 20px;
  }
}

/* ───────── LEGACY SECTION 2 (kept for reference, hidden) ─────────
   A tall scroll surface (.flow-scroll) with an interior 100vh sticky
   (.flow-sticky). The four services live on one schematic — abstract
   filled-square nodes wired by rectilinear hairlines, framed by top +
   bottom editorial bands. JS writes a 0→1 --p into .flow-sticky; every
   [data-stage] (each node, each connection, each station eyebrow / title
   / phrase) maps that progress through its own [--start, --end] window
   to a local --t that drives opacity + transform. The whole site reads
   at one rhythm — this section uses the same cadence as the hero's
   per-word reveal, just spread across four service "movements". */

.flow {
  position: relative;
  background: var(--mz-black);
  color: var(--mz-white);
  padding: 0;
  /* No overflow: hidden here — it breaks position: sticky on
     descendants in some browser configurations. The SVG self-clips to
     its viewBox; the dotted grid + connections won't bleed. */
}
.flow-scroll {
  position: relative;
  /* 950vh: ~850vh of captured scroll. Pin extended significantly so
     each station's scroll + expand phase has enough scroll distance
     (~85vh per phase, ~130vh of dwell time on each opened station)
     — the user can actually read each expansion instead of being
     pushed through. */
  height: auto;
}

/* The jornal section's only --p-driven effect is the news-list scroll
   through .journal-window. Trimmed from 160 → 130vh so the scroll
   through news lands quicker. */
.jornal-scroll { height: 130vh; }
/* Same idea for trabalho — single row of tiles slides into the
   .work-window. Trimmed from 160 → 130vh so the scroll-through is
   snappier (less finger travel per row of cards entering). */
.work-scroll { height: 130vh; }

/* Manifesto gets EXTENDED pin time — content reveals finish at
   --p≈0.42 (pulled earlier proportionally, so the content flow speed
   in actual scroll px matches the original 260vh pin); the remaining
   ~58% of pin is the "cranking" buffer where the user has to keep
   scrolling while the centre square does several more turns before
   the section releases and contato approaches. */
.manifesto-scroll { height: 380vh; }

.flow-sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--mz-black);
  --p: 0;
}

/* ── Stage — the interior between the two bands. Holds the
   absolutely-positioned HTML stations and their illustration
   counterparts. The dotted grid is a CSS background-image — no SVG
   pattern, avoids distortion when the stage stretches to a non-square
   aspect. Connection lines that used to live here have been removed
   (the user dropped them); the stations stand on their own. ── */
.flow-stage {
  position: relative;
  flex: 1 1 auto;
  margin: 0;
  overflow: hidden;
  background-image: radial-gradient(circle at 1px 1px, rgba(255, 255, 255, 0.20) 0.9px, transparent 1.3px);
  background-size: 24px 24px;
  /* The .stations-track child is what JS translates upward to keep
     the currently-expanded station in viewport. flow-stage stays
     fixed-size; the track is the moving content. */
}
.stations-track {
  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
  padding: clamp(40px, 5vh, 80px) clamp(24px, 5vw, 64px);
  gap: clamp(40px, 6vh, 80px);
  /* No CSS transition — the focus-track JS lerps the translateY each
     frame for fluid motion regardless of scroll velocity. Adding a
     CSS transition here would fight with the per-frame JS values. */
  will-change: transform;
}

/* ── Station illustrations ──
   One per movement, positioned on the opposite side of the stage from
   the matching station's text. Each occupies ~40% of the stage width
   (left or right half) so the empty lateral half of the composition
   is filled by the shape work rather than dead negative space. The
   SVG inside scales-to-fit; on shorter stages the illustration drops
   in height proportionally.

   Stations 0,2 → text-left, illus-right.
   Stations 1,3 → text-right, illus-left.

   Hidden on mobile (the brief: "just in the desktop"). */
.station-illus {
  display: none;             /* Hidden in the simplified layout */
  position: absolute;
  width: 38%;
  max-width: 520px;
  color: var(--mz-white);
  pointer-events: none;
}
.station-illus svg {
  display: block;
  width: 100%;
  height: auto;
}
/* Anchor each illustration at the vertical midline of its station — the
   station-i top values are 10/32/56/78%, with body height ~140px; we
   use translateY(-50%) on a top-anchor that sits at the station's
   midline so SVG vertical centering matches the text it's paired
   with regardless of stage height. */
.station-illus[data-i="0"] { top: 18%; right: 4%; transform: translateY(-50%); }
.station-illus[data-i="1"] { top: 40%; left:  4%; transform: translateY(-50%); }
.station-illus[data-i="2"] { top: 64%; right: 4%; transform: translateY(-50%); }
.station-illus[data-i="3"] { top: 86%; left:  4%; transform: translateY(-50%); }

/* Container-level fade — runs concurrent with the inner shape cascade
   so the whole "drawing" feels like it leans in from the outer edge.
   The base rule sets translateY(-50%) for vertical centering; the
   data-stage rule composes translateX *after* it so the lateral
   slide still animates while the vertical anchor stays correct. */
.station-illus[data-stage] {
  /* Direction of entrance: stations 0,2 (illus on right) come in from
     the right; stations 1,3 (illus on left) come in from the left. We
     drive this via two extra CSS custom properties scoped to each
     illus, multiplied by (1 - --t) for the slide-in distance. */
  --illus-dir: 1;
  opacity: var(--t);
  transform: translateY(-50%) translateX(calc((1 - var(--t)) * 28px * var(--illus-dir)));
}
.station-illus[data-i="1"][data-stage],
.station-illus[data-i="3"][data-stage] {
  --illus-dir: -1;
}

/* Individual shapes inside the illustrations. Each shape is a filled
   white primitive (triangle / rect) OR a hairline-stroked wavy path
   for movement 04. They reveal with a slight lateral travel matching
   the illustration's direction, plus opacity, beat-by-beat. */
.illus-shape {
  fill: var(--mz-white);
}
.illus-shape[data-stage] {
  opacity: var(--t);
  /* Each shape slides in laterally a small distance from the side
     opposite the corresponding text. Inherits --illus-dir from the
     parent <aside>. */
  transform: translateX(calc((1 - var(--t)) * 14px * var(--illus-dir, 1)));
  transform-box: fill-box;
  transform-origin: center;
}

/* Movement 04 — wavy lines. Path-based instead of filled rect; we
   "draw" the path via stroke-dashoffset for the building-line feel,
   AND keep the lateral slide. Override the global data-stage rule's
   opacity-only fade so the stroke draws cleanly. */
.illus-shape--wave {
  fill: none;
  stroke: var(--mz-white);
  stroke-width: 6;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
}
.illus-shape--wave[data-stage] {
  opacity: 1;
  stroke-dashoffset: calc(100 - var(--t, 0) * 100);
  /* Keep the small lateral slide inherited from the generic rule above
     (the [data-stage] transform). */
}

/* ── Stations — HTML editorial fragments absolutely positioned on the
   stage. Each carries its own white node-square at the "incoming" side
   of the block. Stations 0+2 face right (node on the left); 1+3 face
   left (node on the right). The four stations sit at alternating
   X-sides and at evenly-spaced Y positions (10/32/56/78%) so the
   connections form clean L-shapes through the empty Y corridors
   between them. ── */
.station {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: clamp(20px, 2.5vw, 32px);
  max-width: 900px;
  width: 100%;
  /* All stations are always at full opacity — the list of 4
     movements should be readable from the start, not dimmed
     while waiting for expansion. The .is-active class still
     marks the focused one but with a subtle background only. */
  padding: clamp(12px, 1.5vh, 20px) clamp(12px, 1.5vw, 20px);
  border-radius: 2px;
  transition: background-color 0.45s var(--ease-out);
}
.station.is-active {
  background-color: rgba(255, 255, 255, 0.035);
}
/* Stations now stack vertically in the .stations-track flex column.
   Diagonal positioning removed — each is a flow item. The zigzag
   feel is preserved on desktop by alternating side via align-self +
   row-reverse for odd indices. */
.station[data-i="0"], .station[data-i="2"] { align-self: flex-start; }
.station[data-i="1"], .station[data-i="3"] { align-self: flex-end; flex-direction: row-reverse; text-align: right; }

/* The node-square — small white block with the movement number. This is
   the abstract anchor that the connection lines plug into. */
.station-node {
  display: grid;
  place-items: center;
  width: 56px; height: 56px;
  background: var(--mz-white);
  color: var(--mz-black);
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 18px;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}

.station-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.station-eyebrow {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 10px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--mz-gray-300);
  padding-top: 4px;
}
.station-title {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(36px, 4.4vw, 60px);
  line-height: 0.9;
  letter-spacing: -0.005em;
  text-transform: uppercase;
  margin: 0;
}
.station-desc {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  /* Light editorial supporting line. Sits LAST in the block now —
     after title + promise — so it reads as the "deliver detail"
     under the benefit hook. */
  font-size: clamp(14px, 1.15vw, 17px);
  line-height: 1.45;
  color: var(--mz-gray-300);
  /* Extra breathing room above — visual gear-shift between the
     client-voice promise above and the designer-voice editorial
     detail below. Marks the two voices as distinct units. */
  margin: 14px 0 0;
  max-width: 340px;
  text-wrap: pretty;
}

/* Per-block benefit hook in client vocabulary. Sits in the MIDDLE
   of the block — between title and desc — so the block reads like
   a news lede:
     TITLE     (label)               — display 900, white, biggest
     PROMISE   (benefit hook)        — display 700, white, mid
     DESC      (editorial detail)    — italic serif, gray, light
   Title + promise pair tight at top as the headline+deck; the
   gray italic desc closes underneath as the supporting body. */
.station-promise {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(16px, 1.5vw, 20px);
  line-height: 1.3;
  letter-spacing: -0.003em;
  color: var(--mz-white);
  /* Tight under the title — they read as a single headline+deck
     unit, with the visual break happening below the promise. */
  margin: 2px 0 0;
  max-width: 380px;
  text-wrap: pretty;
}
.station-promise[data-stage] {
  transform: translateY(calc((1 - var(--t)) * 10px));
}

/* ── Stage animation — global [data-stage] rule reads --p from
   .flow-sticky and computes each element's local --t. Default is
   fade-up; per-element tweaks below. ── */
[data-stage] {
  --t: max(0, min(1, calc((var(--p, 0) - var(--start, 0)) * 1 / max(0.001, calc(var(--end, 1) - var(--start, 0))))));
  opacity: var(--t);
  transform: translateY(calc((1 - var(--t)) * 12px));
  will-change: opacity, transform;
}
.station-eyebrow[data-stage] { transform: translateY(calc((1 - var(--t)) * 6px)); }
.station-title[data-stage]   { transform: translateY(calc((1 - var(--t)) * 18px)); }
.station-desc[data-stage]    { transform: translateY(calc((1 - var(--t)) * 10px)); }

/* Node-square fades + scales in. Origin: the connection-line side of the
   square — feels like the line "plants" the node when it arrives. */
.station-node[data-stage] {
  transform: scale(calc(0.78 + var(--t) * 0.22));
  transform-origin: center;
}

/* ───── Section-level data-stage overrides ─────
   Bigger lift for high-impact elements (tiles, h2 words), smaller for
   small text (journal lede, meta). Per-section overrides ride the
   generic [data-stage] rule. */

/* Trabalho — tiles lift + scale a touch as they enter. */
.tile[data-stage] {
  transform: translateY(calc((1 - var(--t)) * 24px));
}
.tile[data-stage] .tile-art {
  transform: scale(calc(0.96 + var(--t) * 0.04));
  transform-origin: center;
  transition: none;
}

/* Jornal — rows slide in from below. */
.journal-row[data-stage] {
  transform: translateY(calc((1 - var(--t)) * 18px));
}

/* CTA — headline per-word reveal (mirrors the hero); button + eyebrow
   ride the same scroll cadence. */
.cta h2 .word[data-stage] {
  transform: translateY(calc((1 - var(--t)) * 24px));
}
.cta h2 em[data-stage] {
  transform: translateY(calc((1 - var(--t)) * 24px));
}
.cta-btn[data-stage] {
  transform: translateY(calc((1 - var(--t)) * 14px));
}

/* Manifesto cells — pop in. */
.mz-cell[data-stage] {
  opacity: var(--t);
  transform-origin: center;
  transform-box: fill-box;
  transform: scale(calc(0.4 + var(--t) * 0.6));
}

/* Manifesto rotating square — lives in the centre hole of the 3×3 grid.
   Fades in via its own [data-stage] window, then ROTATES continuously
   with the section's --p (not its local --t), so it spins for the whole
   pin duration. Pivots around its own centre via transform-box: fill-box. */
.mz-spin {
  transform-box: fill-box;
  transform-origin: center;
  fill: var(--mz-black);
}
.mz-spin[data-stage] {
  opacity: var(--t);
  /* 540deg total — a full revolution plus a 180° land, so it ends
     visually "flipped" rather than back where it started. */
  transform: rotate(calc(var(--p, 0) * 540deg)) scale(calc(0.55 + var(--t) * 0.45));
}

/* ───────── SECTION 3 — TRABALHO (pinned matrix) ─────────
   3×3 grid of tiles, scaled down to fit inside one 100vh viewport
   between top/bottom bands. Tiles cascade in beat-by-beat as --p ticks
   across the section's pin-scroll. */
.work {
  position: relative;
  background: var(--mz-black);
  color: var(--mz-white);
  padding: 0;
}
.work .pin-stage {
  justify-content: center;
  align-items: center;
  /* Trimmed back down: the matrix is now tall vertical cards that
     should dominate the pin-stage. Minimum padding so the black
     bands above and below the grid are tight, not breathy. */
  padding: clamp(20px, 3vh, 44px) 40px;
  gap: clamp(20px, 3vh, 36px);
}
/* Work window — same pattern as .journal-window. Fixed height set by
   JS (the natural height of the first 3 tile rows). With overflow:
   hidden, the 4th row stays clipped at the bottom until the user
   scrolls; the inner .work-grid then translates upward by --p ×
   --max-shift, revealing the 4th row from below. */
.work-window {
  flex: 0 0 auto;
  position: relative;
  overflow: hidden;
  width: 100%;
  max-width: clamp(360px, 40vh, 480px);
  margin: 0 auto;
  /* Taller fallback because tiles are now 3:4 vertical cards — 3
     rows visible take ~60vh on most viewports. JS overrides on load. */
  height: clamp(420px, 62vh, 640px);
}
/* Bottom fade-to-black overlay — new tiles emerge from darkness
   instead of popping in cleanly. Sits at the bottom of the window,
   between the visible grid and the "Ver arquivo" button below.
   Lighter than the previous 38% so the bottom row isn't half-eaten
   by darkness — the fade hints at the boundary without burying
   tiles that should still be legible. */
.work-window::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 26%;
  background: linear-gradient(to top,
    var(--mz-black) 0%,
    rgba(0, 0, 0, 0.55) 55%,
    transparent 100%);
  pointer-events: none;
  z-index: 2;
}
.work-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(12px, 1.4vh, 20px);
  width: 100%;
  /* Normal flow — the grid's natural height is 4 rows tall. The
     parent .work-window's explicit height (CSS fallback + JS-set
     precise) is shorter than that, so overflow:hidden clips the
     bottom row. transform translates the grid upward to reveal it. */
  transform: translateY(calc(-1 * var(--p, 0) * var(--max-shift, 0px)));
  will-change: transform;
}
.tile {
  display: flex; flex-direction: column;
  gap: 8px;
  text-decoration: none;
  color: inherit;
}
.tile-art {
  /* Vertical card aspect (3:4) — taller than wide, like trading
     cards. Fills more vertical space in the work-window so the
     matrix dominates the pin-stage and the black bands above/below
     shrink. */
  aspect-ratio: 3 / 4;
  padding: clamp(10px, 1.4vh, 16px);
  display: flex; flex-direction: column; justify-content: space-between;
  position: relative;
  overflow: hidden;
  transition: background-color var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out);
}
.tile-eyebrow {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.75;
  position: relative; z-index: 1;
}
.tile-code {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(15px, 1.4vw, 22px);
  line-height: 0.95;
  letter-spacing: -0.01em;
  position: relative; z-index: 1;
}

/* Variant: paper-solid — cream block on dark page */
.tile[data-variant="paper-solid"] .tile-art {
  background: var(--mz-paper);
  color: var(--mz-black);
}
.tile[data-variant="paper-solid"]:hover .tile-art { background: #FFFFFF; }

/* Variant: dark-outline — just a hairline frame */
.tile[data-variant="dark-outline"] .tile-art {
  background: transparent;
  color: var(--mz-white);
  border: 1px solid rgba(255, 255, 255, 0.55);
}
.tile[data-variant="dark-outline"]:hover .tile-art {
  border-color: var(--mz-white);
  background: rgba(255, 255, 255, 0.04);
}

/* Variant: dark-hatch — diagonal hatch pattern across frame */
.tile[data-variant="dark-hatch"] .tile-art {
  background:
    repeating-linear-gradient(45deg,
      rgba(255, 255, 255, 0.22) 0,
      rgba(255, 255, 255, 0.22) 0.5px,
      transparent 0.5px,
      transparent 9px);
  color: var(--mz-white);
  border: 1px solid rgba(255, 255, 255, 0.5);
}
.tile[data-variant="dark-hatch"]:hover .tile-art {
  border-color: var(--mz-white);
}

/* Variant: paper-rule — cream with horizontal rules across the middle */
.tile[data-variant="paper-rule"] .tile-art {
  background: var(--mz-paper);
  color: var(--mz-black);
}
.tile[data-variant="paper-rule"] .tile-art::before {
  content: "";
  position: absolute;
  left: 22px; right: 22px;
  top: 50%; transform: translateY(-50%);
  height: 56%;
  background-image: repeating-linear-gradient(0deg,
    rgba(0, 0, 0, 0.35) 0,
    rgba(0, 0, 0, 0.35) 1px,
    transparent 1px,
    transparent 7px);
  pointer-events: none;
}
.tile[data-variant="paper-rule"]:hover .tile-art { background: #FFFFFF; }

.tile-label {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 8px;
}
.tile-code-small {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 9px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--mz-white);
}
.tile-caption {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 11px;
  color: rgba(255, 255, 255, 0.8);
  text-align: right;
  text-wrap: balance;
}

.work-footer {
  margin-top: 0;
  display: flex; justify-content: flex-end;
  width: 100%;
  max-width: clamp(420px, 50vh, 580px);
}
.btn-paper {
  display: inline-flex; align-items: center; gap: 14px;
  background: var(--mz-paper);
  color: var(--mz-black);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  padding: 20px 32px;
  transition: background-color var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out),
              gap var(--dur-base) var(--ease-out);
}
.btn-paper:hover {
  background: var(--mz-cinabre);
  color: var(--mz-white);
  gap: 22px;
}
.btn-paper .arr { font-size: 14px; line-height: 1; }

/* ───────── SECTION 4 — MANIFESTO (pinned paper island) ─────────
   Same pin pattern: bands top + bottom, matrix illustration + body
   text reveal beat-by-beat as --p ticks. The 3×3 matrix has TWO
   missing cells (centre + top-right corner); a smaller .mz-spin square
   sits in the centre hole and rotates continuously with --p — "absence
   in motion". */
.manifesto {
  position: relative;
  background: var(--mz-paper);
  color: var(--mz-black);
  padding: 0;
}
.manifesto [data-pin-sticky] { background: var(--mz-paper); }
.manifesto .pin-stage {
  justify-content: center;
  padding: clamp(40px, 6vh, 80px) clamp(40px, 6vw, 96px);
}
.manifesto .grid {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(48px, 8vw, 120px);
  align-items: center;
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
}
.manifesto-illus {
  aspect-ratio: 1 / 1;
  max-width: 480px;
}
.manifesto-illus svg { width: 100%; height: 100%; display: block; }
.manifesto-body {
  display: flex; flex-direction: column;
  gap: 28px;
  max-width: 460px;
}
.manifesto-body p {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 19px;
  line-height: 1.55;
  margin: 0;
  text-wrap: pretty;
}
.manifesto-body p em { font-style: italic; }
.manifesto-link {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  border-bottom: 1px solid currentColor;
  align-self: flex-start;
  padding-top: 4px;
  display: inline-flex; gap: 8px; align-items: center;
  transition: gap var(--dur-base) var(--ease-out);
  margin-top: 12px;
}
.manifesto-link:hover { gap: 16px; }
.manifesto-link .arr { font-family: var(--font-serif); font-weight: 400; font-size: 14px; }

/* ───────── SECTION 5 — JORNAL (pinned list rows) ─────────
   Editorial rows divided by hairlines, revealed beat-by-beat as --p
   ticks. Cols: issue label · glyph · title + lede · read affordance.
   Hover paints title + action cinabre. */
.jornal {
  position: relative;
  background: var(--mz-black);
  color: var(--mz-white);
  padding: 0;
  /* Jornal-specific background pattern: thin diagonal hairlines
     (45°) repeating subtly across the section. Distinct from the
     dot-grid plate used elsewhere — gives the jornal its own
     editorial texture (newspaper-rule feel). */
  background-image: repeating-linear-gradient(
    45deg,
    transparent 0,
    transparent 26px,
    rgba(255, 255, 255, 0.05) 26px,
    rgba(255, 255, 255, 0.05) 27px
  );
}
.jornal .pin-stage {
  justify-content: center;
  /* Tighter vertical padding — the news window now holds 4 rows and
     should fill more of the pin-stage so the black bands above and
     below shrink. */
  padding: clamp(20px, 3vh, 48px) clamp(40px, 6vw, 96px);
}
/* Fixed-height window sized to show EXACTLY 3 rows. flex: 0 0 auto
   so it doesn't stretch — combined with .pin-stage's
   justify-content: center, the window centers vertically inside the
   pin and leaves equal breathing black space above and below.
   JS measures the height of the first 3 rows on load (so font wrap
   and SVG glyphs are accounted for) and sets the explicit height. */
.journal-window {
  flex: 0 0 auto;
  position: relative;
  overflow: hidden;
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
}
.journal-list {
  display: flex; flex-direction: column;
  width: 100%;
  position: absolute;
  top: 0; left: 0; right: 0;
  /* --p cascades from the parent [data-pin-sticky]; --max-shift is set
     by JS once per resize. Multiplied = the list's translateY drag
     across the pin window. */
  transform: translateY(calc(-1 * var(--p, 0) * var(--max-shift, 0px)));
  will-change: transform;
}
.journal-row {
  display: grid;
  grid-template-columns: 200px 80px 1fr 80px;
  align-items: center;
  gap: 32px;
  padding: 36px 16px;
  margin: 0 -16px;
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  text-decoration: none;
  color: inherit;
  transition: background-color var(--dur-fast) var(--ease-out);
}
.journal-row:last-child { border-bottom: 1px solid rgba(255, 255, 255, 0.15); }
.journal-row:hover { background: rgba(255, 255, 255, 0.03); }
.journal-row:hover .journal-title,
.journal-row:hover .journal-action { color: var(--mz-cinabre); }

.journal-issue {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.65);
}
.journal-glyph {
  width: 56px; height: 56px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.03);
  display: grid; place-items: center;
}
.journal-glyph svg { width: 32px; height: 32px; color: var(--mz-white); }
.journal-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(20px, 2.2vw, 30px);
  line-height: 1.15;
  text-transform: uppercase;
  letter-spacing: -0.005em;
  margin: 0 0 8px;
  transition: color var(--dur-fast) var(--ease-out);
}
.journal-lede {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 16px;
  color: rgba(255, 255, 255, 0.85);
  margin: 0;
  text-wrap: pretty;
}
.journal-action {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-align: right;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-out);
}

/* ───────── SECTION 6 — CONTACT CTA (pinned) ─────────
   Same pin pattern as every other content section: outer surface tall
   (260vh), inner sticky child 100vh, content reveals beat-by-beat as
   --p ticks via [data-stage] windows. Matches the rhythm of the rest
   of the page so the user gets one consistent scroll cadence end to
   end. */
.cta {
  position: relative;
  background: var(--mz-black);
  color: var(--mz-white);
  padding: 0;
  text-align: center;
  /* No overflow: hidden — it would establish .cta as the containing
     block / scroll context for [data-pin-sticky] inside, breaking
     position: sticky. Sticky must see the window as its scrolling
     ancestor for --p to track the user's scroll. */
}
.cta .pin-stage {
  justify-content: center;
  align-items: center;
  padding: clamp(40px, 6vh, 80px) clamp(24px, 6vw, 80px);
  text-align: center;
  gap: 0;
}
.cta .pin-stage > * { width: 100%; max-width: 900px; }
.cta-eyebrow {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.22em;
  color: var(--mz-gray-500);
  text-transform: uppercase;
  margin: 0 0 28px;
}
.cta h2 {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(48px, 10vw, 110px);
  line-height: 0.92;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  margin: 0 0 40px;
  text-wrap: balance;
}
.cta h2 .word { display: inline-block; }
.cta h2 em {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  text-transform: none;
  letter-spacing: -0.01em;
  color: var(--mz-gray-300);
  display: inline-block;
}
.cta-btn {
  display: inline-flex; align-items: center; gap: 16px;
  background: var(--mz-cinabre);
  color: var(--mz-white);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 26px 44px;
  border: 1px solid var(--mz-cinabre);
  cursor: pointer;
  transition: background var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out), gap var(--dur-base) var(--ease-out);
}
.cta-btn:hover {
  background: var(--mz-black);
  border-color: var(--mz-white);
  gap: 24px;
}
.cta-btn svg { width: 18px; height: 18px; }
.cta-email {
  display: block;
  margin-top: 32px;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 16px;
  color: var(--mz-gray-300);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.cta-email:hover { border-bottom-color: var(--mz-gray-300); color: var(--mz-white); }
.cta-meta {
  margin-top: 40px;
  display: flex; justify-content: center; gap: 56px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--mz-gray-500);
}
.cta-meta .ok { color: var(--mz-white); }
.cta-meta .ok::before {
  content: "";
  display: inline-block;
  width: 6px; height: 6px; background: var(--mz-white);
  margin-right: 10px; vertical-align: 1px;
}

/* ── Bottom-band channels (was footer "Canais" column) ──
   Three links spaced across the closing band, in the same typographic
   key as the band's eyebrow/meta. The band is also the host for the
   vertical MATRIZ wordmark — extra padding-top reserves room for the
   rotated wordmark above the channels without bleeding into the cta
   content above. */
.cta-channels {
  position: relative;
  justify-content: space-between;
  align-items: flex-end;
  gap: clamp(16px, 4vw, 56px);
  flex-wrap: wrap;
  /* 110px top reserves vertical space for the rotated wordmark
     (font-size 20 → ~100px tall after rotation). bottom 26 keeps the
     channels' original spacing. */
  padding-top: 110px;
  padding-bottom: 26px;
}
.cta-channel {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--mz-gray-300);
  white-space: nowrap;
  border-bottom: 1px solid transparent;
  transition: color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.cta-channel:hover {
  color: var(--mz-white);
  border-bottom-color: var(--mz-white);
}
.cta-channel em {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  margin-right: 6px;
  color: var(--mz-gray-500);
}

/* ── Vertical MATRIZ signature ──
   Identical to the original footer foot-sig — same position, size,
   rotation, no transparency. Bottom-right of the pin-sticky; rotates
   so it reads top-to-bottom (M at top, Z near the corner). */
.cta-sig {
  /* Positioned absolute within .cta-channels (which is now
     position:relative). bottom:24 puts the wordmark's pivot (right
     bottom of its un-rotated box) 24px above the band's bottom edge —
     same baseline as the channels text. The rotated column then
     extends upward into the band's 110px top padding, which was
     reserved precisely for this. So the wordmark physically lives
     inside the page's bottom band: it cannot reach above into the
     cta content. */
  position: absolute;
  right: 100px;
  bottom: 24px;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 20px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--mz-white);
  transform: rotate(90deg);
  transform-origin: right bottom;
  line-height: 1;
  pointer-events: none;
  z-index: 3;
}

/* Kill the hairline divider above the channels band — the user wants
   the channels + MATRIZ vertical to read as one merged closing area,
   not as a section visibly separated from the cta content above. */
.cta-channels.frame-band-bot,
.cta-channels.frame-band-bot[data-soft="true"] {
  border-top: 0;
}

/* The contato pin-scroll captures EXACTLY one viewport of scroll for
   --p to tick across (the same pattern as everywhere else — 100vh of
   sticky + 100vh of captured). Without this, the default 260vh from
   [data-pin-scroll] left 100vh of "post-pin" scroll where the sticky
   un-pinned and slid up, exposing empty body background beneath —
   that was the "unneeded black space" the user reported. */
.cta-scroll { height: 200vh; }

/* ───────── SECTION 7 — FOOTER ───────── */
.foot {
  position: relative;
  background: var(--mz-black);
  color: var(--mz-white);
  padding: 0;
}
.foot .frame-content { padding: 100px 0 80px; }
.foot-top {
  display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: 56px;
  padding-bottom: 0;
}
.foot-lede {
  display: flex; flex-direction: column; gap: 24px;
  max-width: 380px;
}
.foot-lede .eyebrow {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--mz-gray-500);
}
.foot-lede p {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 17px;
  line-height: 1.5;
  margin: 0;
  color: var(--mz-gray-300);
}
.foot-col h4 {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin: 0 0 22px;
  color: var(--mz-gray-500);
}
.foot-col ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 12px; }
.foot-col a {
  font-family: var(--font-serif);
  font-size: 16px;
  line-height: 1.5;
  color: var(--mz-white);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-fast) var(--ease-out), opacity var(--dur-fast) var(--ease-out);
  padding-bottom: 1px;
}
.foot-col a:hover { opacity: 0.6; }
.foot-col a em {
  font-style: italic;
  color: var(--mz-gray-300);
  margin-right: 6px;
}

.foot-bottom {
  display: flex; justify-content: space-between; align-items: end;
  padding-top: 24px;
  border-top: 1px solid var(--mz-white);
}
.foot-copy {
  font-family: var(--font-serif);
  font-size: 13px;
  color: var(--mz-gray-300);
  margin: 0;
}
.foot-set {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--mz-gray-500);
}

/* Vertical wordmark signature — bottom right of footer */
.foot-sig {
  position: absolute;
  right: 80px;
  bottom: 80px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 30px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--mz-white);
  transform: rotate(90deg);
  transform-origin: right bottom;
  line-height: 1;
  pointer-events: none;
}

/* ───────── RESPONSIVE ───────── */
@media (max-width: 1100px) {
  .shell { padding: 0 56px; }
  .nav-inner { padding: 0 56px; }
  .foot-sig { right: 56px; bottom: 56px; }
  .hero-bottom { grid-template-columns: 1fr; gap: 32px; }
  .manifesto .grid { grid-template-columns: 1fr; gap: 64px; }
  .work-grid { grid-template-columns: repeat(3, 1fr); gap: 20px; }
  .journal-row { grid-template-columns: 160px 64px 1fr 70px; gap: 24px; }
  .foot-top { grid-template-columns: 1fr 1fr; gap: 56px 40px; }
  .row-scroll { /* legacy alias — no-op */ }
  .frame-band { padding: 22px 56px; }
  .flow-stage { margin: 0; }
  /* Pull stations closer to the diagram center so they don't crowd the edges. */
  .station { max-width: 240px; }
  .station-title { font-size: clamp(28px, 4.6vw, 40px); }
}
@media (max-width: 720px) {
  .shell { padding: 0 24px; }
  .nav-inner { padding: 0 24px; height: 56px; }
  .nav-mark { font-size: 17px; }
  .nav-cta { font-size: 10px; letter-spacing: 0.18em; }
  .nav-toggle span { width: 24px; }
  .nav-drawer-panel { width: 100%; }
  .nav-drawer-head { padding: 0 24px; height: 56px; }
  .nav-drawer-links { padding: 40px 24px; gap: 10px; }
  .nav-drawer-foot { padding: 18px 24px 28px; }

  section { padding: 80px 0; scroll-margin-top: 64px; }

  /* Hero — shorter scroll capture on mobile (160vh) so the user doesn't
     get trapped scrolling for too long, but still enough to give the
     beats their rhythm. The composition is deliberate three-group
     vertical stack:
       (top)    eyebrow ESTÚDIO DO FUTURO         · left-aligned
       (middle) MATRIZ wordmark                    · left, oversized anchor
       (...)    intentional negative space
       (bottom) headline (left) + sub (right)      · editorial asymmetry
     Mirrors the desktop's hero composition instead of collapsing
     everything to a flat left-aligned column. */
  .hero-scroll { height: 380vh; }
  .hero { padding: 0; }
  .hero .shell {
    padding-top: clamp(64px, 9vh, 112px);
    padding-bottom: clamp(48px, 7vh, 88px);
  }
  /* Bigger gap between the eyebrow and MATRIZ — they read as two
     deliberate beats of the top group, not stacked label+title. */
  .hero-top { margin-bottom: clamp(40px, 6vh, 72px); }
  .hero-mark { margin-top: 0; }
  /* Wordmark scaled up a touch and tightened — more anchor presence
     against the mobile viewport. */
  .hero-word {
    font-size: clamp(60px, 18vw, 104px);
    letter-spacing: -0.015em;
    line-height: 0.82;
  }
  /* Bottom group stays a single column on narrow screens, but
     preserves the desktop editorial asymmetry: headline left,
     italic sub right. The sub becomes a tight right-aligned
     margin note that signs off the composition. */
  .hero-bottom {
    grid-template-columns: 1fr;
    gap: 28px;
  }
  .hero-headline {
    font-size: clamp(28px, 8vw, 44px);
    line-height: 1.06;
    letter-spacing: -0.015em;
  }
  .hero-sub {
    justify-self: end;
    text-align: right;
    font-size: 15px;
    line-height: 1.4;
    max-width: 220px;
    top: 0;
  }

  .section-head { padding-bottom: 16px; margin-bottom: 56px; flex-wrap: wrap; }
  .section-sub { display: none; }

  /* ── Pin-sticky stays enabled on mobile too ──
     The user wants every scene to have the same scroll rhythm — pin,
     develop, release — on mobile as on desktop. So we KEEP every
     [data-pin-scroll] tall and every [data-pin-sticky] sticky. The
     unified JS driver reads each pin-sticky's live computed position
     and stays in pin-scroll progress mode. Just trim the captured
     scroll height a bit so mobile users aren't stuck scrolling for as
     long inside each pin. */
  [data-pin-scroll] { height: 220vh; }
  [data-pin-sticky] {
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: hidden;
  }
  /* Flow section: same pin-pattern; "lite" content rendered below. */
  .flow-scroll { height: 220vh; }
  .flow-sticky {
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: hidden;
  }
  /* Generic pin-stage padding for the small viewport. !important to
     override the desktop clamps inside each section's own rules. */
  .pin-stage {
    padding: 40px 24px !important;
    gap: 24px;
  }
  .work .pin-stage { padding: 40px 24px; }
  .work-grid { max-width: 100%; }
  .manifesto .pin-stage { padding: 56px 24px; }
  .manifesto .grid { grid-template-columns: 1fr; gap: 32px; }
  .manifesto-illus { max-width: 240px; margin: 0 auto; }
  .jornal .pin-stage { padding: 40px 24px; }
  .cta .pin-stage { padding: 56px 24px; }
  .cta .pin-stage > * { max-width: 100%; }
  .frame-band { padding: 16px 24px; gap: 14px; }
  .frame-eyebrow { font-size: 10px; letter-spacing: 0.18em; }
  .frame-meta { font-size: 9px; letter-spacing: 0.18em; }
  /* Hide the desktop illustrations on mobile — the "lite" version. */
  .station-illus { display: none; }

  .flow-stage {
    margin: 0;
    padding: 24px 24px 24px 80px;
    background-image: radial-gradient(rgba(255, 255, 255, 0.18) 0.8px, transparent 1px);
    background-size: 24px 24px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
  }
  /* Vertical thread on the left, threading through every node. */
  .flow-stage::before {
    content: "";
    position: absolute;
    left: 47px;
    top: 30px; bottom: 30px;
    width: 1px;
    background: rgba(255, 255, 255, 0.32);
  }

  /* Every station becomes an in-flow block, left-aligned, no transforms.
     The node-square moves above the text instead of beside it. */
  .station,
  .station[data-i="0"],
  .station[data-i="1"],
  .station[data-i="2"],
  .station[data-i="3"] {
    position: relative;
    top: auto; left: auto; right: auto;
    flex-direction: column;
    text-align: left;
    align-items: flex-start;
    transform: none;
    max-width: 100%;
    gap: 12px;
    margin-bottom: 14px;
  }
  .station:last-of-type { margin-bottom: 0; }

  /* Pull the node-square out to the left margin (where the vertical
     thread runs) so it sits ON the line. */
  .station-node {
    width: 38px; height: 38px;
    font-size: 13px;
    margin-left: -56px;
  }
  .station-body { gap: 6px; }
  .station-title { font-size: clamp(26px, 7.4vw, 36px); }
  /* New order on mobile: title → promise → desc. Promise tight under
     title (margin 2px), desc with extra breathing room above (margin
     12px) for the voice gear-shift. */
  .station-promise { font-size: 15px; max-width: 100%; margin-top: 2px; }
  .station-desc  { font-size: 13.5px; line-height: 1.4; max-width: 100%; margin-top: 12px; }

  /* Work tiles — 3-col 3-row matrix so all 9 tiles fit inside one
     pinned 100vh viewport on mobile (matches the desktop layout
     density). Smaller padding/codes so the squarer tiles still read. */
  .work-grid { grid-template-columns: repeat(3, 1fr); gap: 8px; }
  .tile-art { padding: 8px; }
  .tile-eyebrow { font-size: 8px; letter-spacing: 0.16em; }
  .tile-code { font-size: 13px; }
  .tile-code-small { font-size: 8px; letter-spacing: 0.16em; }
  .tile-caption { font-size: 9px; }

  /* Journal — stack each row into two text rows (issue+glyph, then title,
     then action) instead of a 4-col grid that overflows on narrow widths. */
  .journal-row {
    grid-template-columns: 48px 1fr auto;
    grid-template-areas:
      "glyph issue   action"
      "glyph title   title"
      "glyph lede    lede";
    gap: 6px 16px;
    padding: 22px 8px;
    margin: 0 -8px;
    align-items: start;
  }
  .journal-glyph { grid-area: glyph; width: 40px; height: 40px; align-self: center; }
  .journal-glyph svg { width: 24px; height: 24px; }
  .journal-issue { grid-area: issue; font-size: 9px; }
  .journal-title { grid-area: title; font-size: 18px; margin: 4px 0 0; }
  .journal-lede { grid-area: lede; font-size: 14px; }
  .journal-action { grid-area: action; font-size: 10px; }

  /* Manifesto + footer — stacked, padding-trimmed. */
  .manifesto .grid { gap: 48px; }
  .foot-top { grid-template-columns: 1fr; gap: 40px; padding-bottom: 64px; }
  .foot-sig { font-size: 20px; right: 24px; bottom: 48px; }

  /* CTA on mobile — main copy CENTER-aligned (the editorial
     composition reads as a centred poster). The bottom channels
     band is the only thing that flushes left, since it's a list of
     contact entries that needs a consistent left margin. */
  .cta { text-align: center; }
  .cta .pin-stage {
    padding: 56px 24px;
    align-items: center;
    text-align: center;
  }
  .cta .pin-stage > * { max-width: 100%; width: 100%; text-align: center; }
  .cta h2 { font-size: clamp(42px, 13vw, 72px); margin: 0 0 32px; }
  .cta-eyebrow { margin: 0 0 20px; font-size: 10px; letter-spacing: 0.18em; }
  .cta-btn { padding: 18px 26px; font-size: 12px; letter-spacing: 0.16em; gap: 12px; align-self: center; }
  .cta-btn svg { width: 16px; height: 16px; }
  .cta-email { font-size: 14px; margin-top: 20px; }
  .cta-meta { flex-direction: column; align-items: center; gap: 10px; margin-top: 28px; font-size: 9px; letter-spacing: 0.18em; }

  /* Bottom band on mobile — channels stack vertically as three
     LEFT-aligned rows (the only left-aligned element in the cta
     scene). Right column reserved for the vertical MATRIZ signature
     so the wordmark doesn't overlap with the channel text. */
  .cta-channels {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    padding: 24px 80px 22px 24px;
    flex-wrap: nowrap;
    text-align: left;
  }
  .cta-channel { font-size: 10.5px; letter-spacing: 0.14em; text-align: left; }
  .cta-sig {
    font-size: 12px;
    right: 30px;
    bottom: 20px;
  }
}


/* ═══════════════════════════════════════════════════════════════════
   SCENE 2 — FINAL CLEAN VERSION
   Native scroll, no pinning, no scroll-jacking. Stations stack in a
   normal flex column inside .stations-track. JS sets --t (0→1)
   per-station based on r.top in the viewport; CSS uses --t to drive
   max-height and opacity of .station-expand. As the user keeps
   scrolling past a fully-expanded station, JS also translates
   .examples-strip horizontally (cT 0→1).
   ═══════════════════════════════════════════════════════════════════ */

/* Re-enable the pin: .flow-scroll provides a tall scroll runway,
   .flow-sticky is the 100vh pinned stage. The user scrolls through
   the runway; the visual stays glued to the top, and JS reads the
   scroll progress to drive lead-in → per-station expansion + cards
   in a single timeline. */
.flow-scroll  { height: 520vh !important; }
.flow-sticky  {
  position: sticky !important;
  top: 0 !important;
  height: 100vh !important;
  overflow: hidden !important;
  display: flex !important;
  flex-direction: column !important;
  background: var(--mz-black);
  color: var(--mz-white);
}
.flow-stage   {
  background-image: none !important;
  padding: 0 !important;
  display: block !important;
  flex: 1 1 auto !important;
  overflow: hidden !important;
  position: relative !important;
}
.flow-stage::before { content: none !important; }

.oficio, .flow {
  background: var(--mz-black);
  color: var(--mz-white);
}

.stations-track {
  display: flex !important;
  flex-direction: column !important;
  /* Compact gap — JS controls the stuck duration / expansion timing
     via the scroll timeline, not via flow-spacing. With the global
     pin active, all 4 stations live inside a 100vh stage and JS
     translates the track vertically as each one becomes active. */
  gap: clamp(20px, 3vh, 44px);
  padding: clamp(20px, 3vh, 36px) clamp(24px, 5vw, 64px);
  max-width: 920px;
  margin: 0 auto;
  /* JS sets translate3d(0, var(--track-y, 0), 0) every frame during
     scroll. No CSS transition: JS owns the interpolation across the
     TRANSITION window, and a CSS transition on top would lag the
     visual behind the scroll. */
  transform: translate3d(0, var(--track-y, 0px), 0);
  will-change: transform;
}

/* Station — compact natural height (~180px). JS sets --t (0→1) as
   the user scrolls; CSS uses it to interpolate the expand panel's
   max-height and opacity smoothly. No CSS transitions on those — the
   --t value itself moves with scroll, giving a frame-perfect
   scroll-driven open/close. */
.station {
  --t: 0;
  display: flex !important;
  flex-direction: column !important;
  align-items: flex-start !important;
  gap: clamp(14px, 2vh, 22px);
  max-width: 100%;
  width: 100%;
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.6s var(--ease-out),
              transform 0.6s var(--ease-out);
  padding: 0 !important;
  background: transparent !important;
}
.station[data-i="0"], .station[data-i="2"] {
  align-self: stretch !important;
}
.station[data-i="1"], .station[data-i="3"] {
  align-self: stretch !important;
  flex-direction: column !important;
  text-align: left !important;
}
.station.is-visible {
  opacity: 1;
  transform: translateY(0);
}
.station.is-active { background: transparent !important; }

.station-body  { display: contents !important; }
.station-node  { margin-bottom: 4px; }

.station-promise,
.station-desc {
  opacity: 1 !important;
  transform: none !important;
}

/* Expand panel — driven by --t (set every frame by JS). The
   TRANSITION window in JS scrubs both the outgoing station's --t
   1→0 and the incoming station's --t 0→1 in parallel, so the
   collapse+expand visually crossfade with scroll. No CSS transition
   here — it would lag behind the continuous scrub.
   max-height in vh so the active station's total height (compact
   ~22vh + expand 55vh) stays inside the pinned stage (~86vh after
   the top/bottom bands). */
.station-expand {
  max-height: calc(var(--t, 0) * 55vh) !important;
  opacity: var(--t, 0) !important;
  overflow: hidden !important;
  margin-top: 0 !important;
  transform: none !important;
  transition: none !important;
  display: flex;
  flex-direction: column;
  gap: clamp(10px, 1.4vh, 18px);
  width: 100%;
  min-width: 0;
}

/* Cards strip — JS-driven translateX. As the user keeps scrolling
   vertically past a fully-expanded station, the strip slides left so
   later cards come into view. No native horizontal scroll, no swipe. */
.examples-frame {
  position: relative;
  width: 100%;
  min-width: 0;
}
.examples-frame::after {
  content: "";
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: clamp(40px, 8vw, 80px);
  background: linear-gradient(to right, transparent, var(--mz-black) 85%);
  pointer-events: none;
  z-index: 2;
}
.examples-window {
  width: 100%;
  min-width: 0;
  overflow: hidden;
}
.examples-strip {
  display: flex;
  gap: clamp(12px, 1.5vw, 20px);
  align-items: stretch;
  width: max-content;
  will-change: transform;
}
.example-card {
  flex: 0 0 auto;
}

.station-cta {
  align-self: flex-start;
  opacity: 1 !important;
  transform: none !important;
}


/* ───────── CASE SHOTS (ago 2026) ─────────
   Cards com trabalho real: imagem de fundo + scrim editorial preto
   nas bordas pra código e legenda respirarem sobre qualquer foto. */
.example-card[data-variant="shot"] {
  color: var(--mz-white);
  background-size: cover;
  background-position: center top;
  background-repeat: no-repeat;
  border: 1px solid rgba(255,255,255,0.35);
}
.example-card[data-variant="shot"]::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to bottom, rgba(0,0,0,0.55), transparent 34%),
    linear-gradient(to top, rgba(0,0,0,0.72), transparent 46%);
  pointer-events: none;
}
.example-card[data-variant="shot"] .card-code,
.example-card[data-variant="shot"] .card-caption {
  position: relative;
  z-index: 1;
  text-shadow: 0 1px 2px rgba(0,0,0,0.5);
}
.example-card[data-variant="shot"][data-fit="contain"] {
  background-size: 96% auto;
  background-position: center;
}


/* ───────── STACKS (pilhas de posts — Presença) ─────────
   Cada card é uma pilha: post da frente reto, os de trás levemente
   abertos. O leque abre conforme o scroll via --fan (0→1, escrito
   por JS no fim do index.html) e um pouco mais no hover. */
.example-card[data-variant="stack"] {
  color: var(--mz-white);
  border: 1px solid rgba(255,255,255,0.35);
}
.stack-pile { position: absolute; inset: 0; display: block; }
.stack-layer {
  position: absolute;
  inset: 12% 14%;
  display: block;
  background-size: cover;
  background-position: center;
  border: 1px solid rgba(250,247,240,0.9);
  box-shadow: 0 6px 18px rgba(0,0,0,0.38);
  transform-origin: 50% 88%;
  transition: transform 160ms var(--ease-out, ease-out);
}
/* repouso: pilha levemente aberta; --fan abre o leque no scroll */
.stack-layer[data-d="1"] { transform: rotate(calc(-2.5deg - var(--fan, 0) * 6deg))  translate(calc(var(--fan, 0) * -8%),  calc(var(--fan, 0) * -3%)); }
.stack-layer[data-d="2"] { transform: rotate(calc( 2.5deg + var(--fan, 0) * 6deg))  translate(calc(var(--fan, 0) *  8%),  calc(var(--fan, 0) * -5%)); }
.stack-layer[data-d="3"] { transform: rotate(calc(-4.5deg - var(--fan, 0) * 9deg))  translate(calc(var(--fan, 0) * -13%), calc(var(--fan, 0) * -8%)); }
.stack-layer[data-d="4"] { transform: rotate(calc( 4.5deg + var(--fan, 0) * 9deg))  translate(calc(var(--fan, 0) *  13%), calc(var(--fan, 0) * -10%)); }
.example-card[data-variant="stack"]:hover .stack-layer[data-d="0"] { transform: scale(1.02); }
/* código e legenda respiram sobre a pilha */
.example-card[data-variant="stack"]::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0,0,0,0.62), transparent 38%);
  pointer-events: none;
}
.example-card[data-variant="stack"] .card-code,
.example-card[data-variant="stack"] .card-caption {
  position: relative;
  z-index: 1;
  text-shadow: 0 1px 2px rgba(0,0,0,0.5);
}


/* ───────── STACK ROWS (Presença — pilhas horizontais, uma por linha) ─────────
   Cada linha é um leque horizontal: o post da frente à esquerda, os de trás
   deslocados pra direita, quase escondidos. --fan (0→1, escrito por JS no
   scroll) abre o leque e revela os de trás. */
.stacks-rows {
  display: flex;
  flex-direction: column;
  gap: clamp(14px, 1.8vw, 22px);
  width: 100%;
}
.stack-row { display: block; }
.stack-row-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 7px;
}
.stack-row-name {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(14px, 1.4vw, 18px);
  letter-spacing: -0.005em;
  text-transform: uppercase;
  color: var(--mz-white);
}
.stack-row-desc {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(11px, 1vw, 13px);
  color: var(--mz-white);
  opacity: 0.62;
}
.stack-row-rail {
  position: relative;
  display: block;
  --sw: clamp(150px, 22vw, 240px); /* mesma largura dos example-cards */
  overflow: visible;
  transform: translateX(var(--slidepx, 0px));
  transition: transform 200ms ease-out;
  height: calc(var(--sw) * 4 / 3); /* full vertical 3:4, igual aos cards */
}
.stack-item {
  position: absolute;
  top: 0;
  width: var(--sw);
  height: calc(var(--sw) * 4 / 3);
  background-size: cover;
  background-position: center;
  border: 1px solid rgba(250, 247, 240, 0.9);
  box-shadow: 7px 0 18px rgba(0, 0, 0, 0.32);
  left: calc(var(--i) * (0.14 + var(--fan, 0) * 0.36) * var(--sw));
  z-index: calc(20 - var(--i));
  transition: left 180ms ease-out;
}

/* stacks acompanham o tamanho mobile dos example-cards */
@media (max-width: 640px) {
  .stack-row-rail { --sw: clamp(140px, 38vw, 180px); }
}

/* estações com pilhas precisam de mais altura que o strip horizontal */
.station-expand:has(.stacks-rows) { max-height: calc(var(--t, 0) * 1400px) !important; }
/* nas estações com pilhas, a translação horizontal é por linha (driver JS),
   não do strip inteiro */
.examples-strip:has(.stacks-rows) {
  transform: none !important;
  display: block;
  width: 100%;
}

/* ═══════ A TRAVESSIA (fork hero) — fades dirigidos por --hp ═══════ */

/* O wordmark também atravessa: dissolve durante a curva, subindo de leve. */
.hero-word {
  --dis: max(0, min(1, calc((var(--hp, 0) - 0.28) / 0.28)));
  opacity: calc(1 - var(--dis));
  transform: translateY(calc(var(--dis) * -5vh));
}
/* O gradiente preto do rodapé sai de cena junto com a lavagem. */
.hero-fade {
  opacity: calc(1 - max(0, min(1, calc((var(--hp, 0) - 0.60) / 0.22))));
}
/* Na lavagem, o véu de 45% do canvas também se dissolve (0.45 → 1):
   sem isso o preto por trás escurecia o cinza final e o hero nunca
   chegava no rgb(196,192,186) em que o painel-eco começa — a emenda
   das duas telas ficava visível como um salto de tom. */
.hero-rain {
  opacity: calc(0.45 + 0.55 * max(0, min(1, calc((var(--hp, 0) - 0.64) / 0.30))));
}
/* Celular: véu mais leve (0.60) — a chuva ficava quase invisível mesmo
   com brilho no máximo; 0.70 passou do ponto. Casa com as trilhas no JS. */
@media (max-width: 720px) {
  .hero-rain {
    opacity: calc(0.60 + 0.40 * max(0, min(1, calc((var(--hp, 0) - 0.64) / 0.30))));
  }
}

/* A CLAREIRA — papel, silêncio, serif. */
.hero-clareira {
  position: absolute; inset: 0;
  z-index: 2;
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.clareira-line {
  --in: max(0, min(1, calc((var(--hp, 0) - 0.86) / 0.08)));
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(24px, 3vw, 38px);
  color: #1b1712;
  margin: 0;
  opacity: var(--in);
  transform: translateY(calc((1 - var(--in)) * 14px));
}
/* O quebrador de pose — a ponte pro trabalho, no pé da clareira. */
.clareira-cta {
  --in: max(0, min(1, calc((var(--hp, 0) - 0.93) / 0.05)));
  position: absolute;
  left: 0; right: 0;
  bottom: clamp(28px, 6vh, 64px);
  text-align: center;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(14px, 1.4vw, 17px);
  color: rgba(27, 23, 18, 0.72);
  margin: 0;
  opacity: var(--in);
  transform: translateY(calc((1 - var(--in)) * 8px));
}

/* Chrome do site (header/drawer) hibernam no fork hero-only: um header preto
   materializando sobre o papel quebraria o silêncio da clareira. Voltam
   quando a página crescer além do hero. */
.nav, .nav-drawer { display: none; }

/* ═══════════ O TRABALHO — papel, tinta, esteiras táteis ═══════════
   Nada se move sozinho aqui: o hero foi o gesto do estúdio, o trabalho
   é as mãos do visitante. Esteiras nativas (overflow-x + snap), imagens
   grandes com borda de tinta e sombra de papel, nomes Integral Bold,
   notas honestas em serif. */
.trabalho {
  background: var(--mz-paper);
  color: var(--mz-black);
  padding: clamp(56px, 9vh, 120px) 0 clamp(48px, 8vh, 100px);
}
.trabalho .shell { max-width: 1440px; margin: 0 auto; padding: 0 clamp(24px, 5vw, 80px); }

.trabalho-band {
  display: flex; align-items: baseline; gap: 18px;
  margin-bottom: clamp(40px, 7vh, 88px);
}
.trabalho-eyebrow {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.trabalho-rule { flex: 1; height: 1px; background: rgba(0,0,0,0.28); }
.trabalho-meta {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 13px;
  color: rgba(0,0,0,0.55);
  white-space: nowrap;
}

.caso { margin-bottom: clamp(56px, 9vh, 110px); }
.caso-head {
  display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap;
  margin-bottom: clamp(14px, 2.4vh, 24px);
}
.caso-nome {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(24px, 3vw, 40px);
  letter-spacing: -0.01em;
  text-transform: uppercase;
  margin: 0;
}
.caso-nota {
  font-family: var(--font-serif);
  font-size: clamp(13px, 1.2vw, 15.5px);
  color: rgba(0,0,0,0.62);
  margin: 0;
}

.caso-strip {
  display: flex;
  gap: clamp(14px, 1.6vw, 24px);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  padding: 4px 4px 18px;      /* respiro pra sombra não clipar */
  scrollbar-width: none;
  cursor: grab;
}
.caso-strip::-webkit-scrollbar { display: none; }
.caso-strip:active { cursor: grabbing; }
.caso-strip img,
.caso-strip video {
  flex: 0 0 auto;
  height: clamp(240px, 42vh, 440px);
  width: auto;
  max-width: none;
  scroll-snap-align: start;
  border: 1px solid rgba(0, 0, 0, 0.85);
  box-shadow: var(--shadow-paper, 2px 2px 0 0 #B4B4B4);
  background: var(--mz-white);
  display: block;
}

.trabalho-fim {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-top: clamp(48px, 8vh, 96px);
  padding-top: 22px;
  border-top: 1px solid rgba(0,0,0,0.28);
}
.fim-mark {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.04em;
}
.fim-meta {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 13px;
  color: rgba(0,0,0,0.55);
}


/* ═══════════ A HISTÓRIA — mundo horizontal ═══════════ */
.hist-scroll {
  position: relative;
  height: 1400vh;                 /* runway: clareira + 4 cenas com dwell */
  background: var(--mz-paper);
  /* Sem o override, o padding global de <section> (120px 0) abre uma
     FAIXA de papel entre o cinza do hero e o cinza do painel-eco — a
     emenda aparecia como corte de cena. Zero: cinza encosta em cinza. */
  padding: 0;
}
.hist-sticky {
  position: sticky; top: 0;
  height: 100vh;
  overflow: hidden;
}
.hist-track {
  display: flex;
  height: 100%;
  width: 300vw;
  will-change: transform;
}
.cena {
  flex: 0 0 100vw;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(28px, 5vw, 96px);
  padding: 0 clamp(20px, 4vw, 72px);
  box-sizing: border-box;
}
.cena-caption { max-width: 34ch; order: 2; }
.cena[data-cena="2"] .cena-caption { order: 0; } /* alterna o lado */
.cap-num {
  display: block;
  font-family: "JetBrains Mono", monospace;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(0,0,0,0.45);
  margin-bottom: 12px;
}
.cap-texto {
  font-family: var(--font-serif);
  font-size: clamp(17px, 1.9vw, 25px);
  line-height: 1.5;
  color: var(--mz-black);
  margin: 0;
}
.cap-texto em { font-style: italic; color: rgba(0,0,0,0.55); }

/* ─── o aparelho ─── */
.iphone {
  position: relative;
  flex: 0 0 auto;
  /* largura EXPLÍCITA (não aspect-ratio): imune ao stretch do flex,
     o aparelho nunca vira prancha horizontal */
  --ph: min(74vh, 660px);
  height: var(--ph);
  width: calc(var(--ph) * 0.474);
  background: #050505;
  border-radius: 46px;
  box-shadow: 0 24px 60px -24px rgba(0,0,0,0.45), inset 0 0 0 2px #1c1c1c;
  padding: 10px;
  box-sizing: border-box;
}
.iphone-ilha {
  position: absolute;
  top: 20px; left: 50%;
  transform: translateX(-50%);
  width: 84px; height: 24px;
  background: #050505;
  border-radius: 13px;
  z-index: 5;
}
.iphone-screen {
  position: relative;
  width: 100%; height: 100%;
  border-radius: 36px;
  overflow: hidden;
  background: #fff;
}

/* ─── perfil insta-like (conteúdo fictício, marcas do estúdio) ─── */
.ig-perfil { position: absolute; inset: 0; opacity: 0; }
.ig-strip { position: absolute; left: 0; right: 0; top: 0; will-change: transform; }
.ig-nav {
  display: flex; align-items: center; justify-content: space-between;
  padding: 40px 14px 10px;
  font-family: system-ui, sans-serif;
}
.ig-nav b { font-size: 14px; font-weight: 700; color: #111; }
.ig-nav span { color: #111; letter-spacing: 2px; }
.ig-head { display: flex; align-items: center; gap: 8px; padding: 6px 14px 10px; }
.ig-avatar {
  flex: 0 0 auto;
  width: 68px; height: 68px;
  border-radius: 50%;
  background-size: cover; background-position: center;
  border: 1px solid rgba(0,0,0,0.12);
  margin-right: 6px;
}
.ig-stat { flex: 1; text-align: center; font-family: system-ui, sans-serif; font-size: 10.5px; color: #333; }
.ig-stat b { display: block; font-size: 14px; color: #111; }
.ig-bio { padding: 0 14px 10px; font-family: system-ui, sans-serif; }
.ig-bio b { display: block; font-size: 12.5px; color: #111; }
.ig-bio i { display: block; font-style: normal; font-size: 11px; color: #8a8a8a; margin: 1px 0 3px; }
.ig-bio span { display: block; font-size: 11.5px; line-height: 1.45; color: #262626; }
.ig-link {
  display: block;
  position: relative;
  margin-top: 5px;
  font-size: 11.5px; font-weight: 600;
  color: #00376b;
  text-decoration: none;
  width: fit-content;
}
.ig-cta { display: flex; gap: 6px; padding: 2px 14px 12px; font-family: system-ui, sans-serif; }
.ig-cta span {
  flex: 1; text-align: center;
  font-size: 11.5px; font-weight: 600; color: #111;
  background: #efefef; border-radius: 7px; padding: 7px 0;
}
.ig-cta .segue { background: #0095f6; color: #fff; }
.ig-highlights { display: flex; gap: 12px; padding: 2px 14px 14px; }
.ig-highlights span {
  width: 52px; height: 52px; border-radius: 50%;
  background-size: cover; background-position: center;
  border: 2px solid #fff; box-shadow: 0 0 0 1px #c7c7c7;
}
.ig-tabs { border-top: 1px solid #dbdbdb; padding: 8px 0; display: flex; justify-content: center; }
.ig-tabs i { width: 16px; height: 16px; border: 1.6px solid #111; border-radius: 2px; display: block;
  background: linear-gradient(#111 0 0) 50% 0/1.6px 100% no-repeat, linear-gradient(#111 0 0) 0 50%/100% 1.6px no-repeat; }
.ig-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; }
.ig-grid span { aspect-ratio: 1; background-size: cover; background-position: center; background-color: #eee; }

/* post aberto (o "clique") */
.ig-post {
  position: absolute; inset: 0;
  background: #fff;
  opacity: 0;
  transform: translateY(26px);
  will-change: opacity, transform;
  display: flex; flex-direction: column;
}
.ig-post-top { display: flex; align-items: center; gap: 8px; padding: 42px 12px 10px; font-family: system-ui, sans-serif; }
.mini-avatar { width: 30px; height: 30px; border-radius: 50%; background-size: cover; background-position: center; }
.ig-post-top b { font-size: 12.5px; color: #111; }
.ig-post-img { flex: 0 0 auto; aspect-ratio: 1; background-size: cover; background-position: center; }
.ig-post-acts { display: flex; gap: 14px; padding: 10px 12px 6px; font-size: 18px; color: #111; }
.ig-post-acts i { font-style: normal; }
.ig-post-meta { padding: 0 12px; font-family: system-ui, sans-serif; }
.ig-post-meta b { display: block; font-size: 11.5px; color: #111; margin-bottom: 3px; }
.ig-post-meta span { font-size: 11.5px; color: #262626; line-height: 1.4; }

/* cena 2 — zoom na bio */
.zoom-stage { position: absolute; inset: 0; transform-origin: 34% 46%; will-change: transform; }
.ig-topo { position: absolute; inset: 0; background: #fff; opacity: 0; }
.cena[data-cena="2"] .ig-link::after {
  content: "";
  position: absolute; inset: -7px -10px;
  border: 2px solid var(--mz-cinabre, #E63946);
  border-radius: 999px;
  transform: rotate(-1.6deg) scale(var(--anel, 0));
  opacity: var(--anel, 0);
  pointer-events: none;
}

/* cena 3 — o beco */
.becoapp { background: #000; color: #fff; display: flex; flex-direction: column; }
.beco-topo { display: flex; align-items: center; justify-content: space-between; padding: 44px 16px 12px; }
.beco-topo b { font-family: "Space Mono", monospace; font-size: 10px; letter-spacing: 0.14em; }
.beco-logo { font-family: "Archivo", sans-serif; font-weight: 900; font-stretch: 125%; font-size: 14px; }
.beco-janela { flex: 1; overflow: hidden; position: relative; }
.beco-lista { position: absolute; left: 14px; right: 14px; top: 4px; display: flex; flex-direction: column; gap: 10px; will-change: transform; }
.bc {
  border: 1px solid rgba(255,255,255,0.5);
  border-radius: 12px;
  background: #0a0a0a;
  box-shadow: 3px 3px 0 #1f1f1f;
  padding: 13px 14px;
}
.bc b { display: block; font-family: "Archivo", sans-serif; font-weight: 900; font-stretch: 125%; font-size: 13.5px; letter-spacing: -0.01em; }
.bc i { display: block; margin-top: 4px; font-family: "Space Mono", monospace; font-style: normal; font-size: 8px; letter-spacing: 0.1em; text-transform: uppercase; color: #949494; }
.bc--banca { border-color: rgba(255,255,255,0.85); }
.bc--banca i { color: #bdbdbd; }
.beco-railzao {
  display: flex; gap: 18px; align-items: baseline;
  padding: 10px 16px 22px;
  font-family: "Archivo", sans-serif; font-weight: 900; font-stretch: 125%;
  font-size: 27px; letter-spacing: -0.03em;
  white-space: nowrap; overflow: hidden;
}
.beco-railzao span { color: rgba(255,255,255,0.16); transition: color 400ms ease; }
.beco-railzao .r-on { color: #fff; }

/* fecho curto depois do mundo horizontal */
.saga-fim {
  display: flex; align-items: baseline; gap: 18px;
  background: var(--mz-paper); color: var(--mz-black);
  padding: 26px clamp(24px, 5vw, 80px) 34px;
  border-top: 1px solid rgba(0,0,0,0.28);
}
.saga-fim .fim-mark { font-family: var(--font-display); font-weight: 700; font-size: 15px; letter-spacing: 0.04em; }
.saga-fim .fim-linha { flex: 1; font-family: var(--font-serif); font-style: italic; font-size: 13px; color: rgba(0,0,0,0.55); }
.saga-fim .fim-meta { font-family: var(--font-serif); font-style: italic; font-size: 13px; color: rgba(0,0,0,0.55); }

@media (max-width: 880px) {
  .cena { flex-direction: column; gap: 18px; padding-top: 8vh; }
  .cena-caption { order: 0 !important; text-align: center; }
  .iphone { --ph: min(62vh, 560px); }
  .cena { align-items: center; }
}


/* ═══ SAGA v2 — ajustes e novos palcos ═══ */
.hist-track { width: 500vw; }   /* eco + 4 cenas */

/* painel 0 — eco da clareira: cena 1 mora à direita desta tela */
.cena--eco { justify-content: center; }
.cena--eco .eco { text-align: center; display: flex; flex-direction: column; align-items: center; gap: 0; }
.cena--eco .clareira-line { position: static; }
.cena--eco .clareira-cta { position: static; margin-top: clamp(24px, 5vh, 48px); }

/* cena 1 — correções: círculos de verdade, feed 3:4, post inteiro */
.ig-highlights span { flex: 0 0 auto; }
.ig-grid span { aspect-ratio: 3 / 4; }
.ig-nav { padding: 16px 14px 10px; }
.ig-post-top { padding: 16px 12px 10px; }
.ig-post-img { aspect-ratio: 3 / 4; }

/* cena 2 — palco: telefone + anotação da matriz + browser */
.c2-palco { position: relative; display: flex; align-items: center; gap: clamp(24px, 3vw, 56px); }
.c2-seta {
  position: absolute;
  left: -170px; top: 96px;
  width: 210px; height: 150px;
  pointer-events: none;
  z-index: 3;
}
.c2-seta path {
  stroke: var(--mz-cinabre, #E63946);
  stroke-width: 2.5;
  stroke-linecap: round;
}
.seta-path {
  stroke-dasharray: 400;
  stroke-dashoffset: calc(400 * (1 - var(--draw, 0)));
}
.seta-ponta { opacity: max(0, calc((var(--draw, 0) - 0.85) / 0.15)); }
.c2-nota {
  position: absolute;
  left: -196px; top: 58px;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 14.5px;
  color: var(--mz-cinabre, #E63946);
  margin: 0;
  opacity: 0;
  white-space: nowrap;
  z-index: 3;
}
.c2-browser {
  flex: 0 0 auto;
  width: min(42vw, 620px);
  border: 1px solid rgba(0,0,0,0.85);
  box-shadow: var(--shadow-paper, 2px 2px 0 0 #B4B4B4);
  background: #fff;
  opacity: 0;
  will-change: opacity, transform;
}
.c2-sites { position: relative; aspect-ratio: 16 / 10; }
.c2-site {
  position: absolute; inset: 0;
  opacity: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  background:
    repeating-linear-gradient(0deg, rgba(0,0,0,0.05) 0 1px, transparent 1px 28px),
    var(--mz-paper);
}
.c2-site b {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(18px, 2vw, 30px);
  letter-spacing: -0.01em;
  text-transform: uppercase;
  color: var(--mz-black);
}
.c2-site span {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(0,0,0,0.5);
}
.c2-site i {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 12px;
  color: rgba(0,0,0,0.4);
}

/* cena 3 — chip de endereço do app */
.beco-topo { padding: 18px 16px 6px; }
.beco-sub { display: flex; justify-content: flex-end; padding: 0 16px 8px; }
.beco-chip {
  font-family: "Space Mono", monospace;
  font-size: 8px;
  letter-spacing: 0.12em;
  color: #bdbdbd;
  border: 1px solid #2e2e2e;
  background: #141414;
  border-radius: 8px;
  padding: 6px 9px;
}


/* cena 2 v2 — o canal próprio abre DENTRO do aparelho (gramática do
   post da cena 1: bio → anel → o site sobe cobrindo a tela) */
.site-view {
  position: absolute; inset: 0;
  background: #fff;
  opacity: 0;
  transform: translateY(30px);
  will-change: opacity, transform;
  display: flex; flex-direction: column;
  z-index: 4;
}
.sv-bar {
  display: flex; align-items: center; gap: 7px;
  padding: 18px 14px 10px;
  border-bottom: 1px solid rgba(0,0,0,0.15);
  background: var(--mz-paper);
}
.sv-bar i {
  width: 7px; height: 7px; border-radius: 50%;
  border: 1px solid rgba(0,0,0,0.5);
}
.sv-bar b {
  font-family: "JetBrains Mono", monospace;
  font-weight: 400;
  font-size: 10px;
  letter-spacing: 0.05em;
  color: rgba(0,0,0,0.6);
}
.sv-body {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  background:
    repeating-linear-gradient(0deg, rgba(0,0,0,0.05) 0 1px, transparent 1px 26px),
    var(--mz-paper);
  background-size: cover;
  background-position: center top;
}
.sv-body b {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(16px, 1.6vw, 22px);
  letter-spacing: -0.01em;
  text-transform: uppercase;
  color: var(--mz-black);
}
.sv-body span {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(0,0,0,0.5);
}
.sv-body i {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 11.5px;
  color: rgba(0,0,0,0.4);
}

/* ═══ SAGA v3 — sites inteiros, o balcão (notebook), o Beco abrindo casas ═══ */

/* cena 2: o print full-page rola dentro do corpo do "browser" */
.sv-body { position: relative; overflow: hidden; background: #fff; display: block; }
.sv-img { position: absolute; left: 0; top: 0; width: 100%; height: auto; display: block; will-change: transform; }

/* cena 3: o notebook */
.cena[data-cena="4"] .cena-caption { order: 0; }   /* alterna o lado: 1 dir, 2 esq, 3 dir, 4 esq */
.cena--dash { overflow: hidden; }   /* a base do notebook (margem negativa) não vaza pro painel vizinho */
.laptop {
  flex: 0 0 auto;
  width: min(58vw, 860px);
  position: relative;
}
.laptop-screen {
  position: relative;
  aspect-ratio: 16 / 10;
  background: #0a0a0a;
  border: 9px solid #111;
  border-bottom-width: 14px;
  border-radius: 16px 16px 6px 6px;
  overflow: hidden;
  box-shadow: 0 30px 70px -30px rgba(0,0,0,0.55), inset 0 0 0 1px #262626;
}
.laptop-screen::before {
  /* câmera */
  content: ""; position: absolute; top: 3px; left: 50%; width: 5px; height: 5px;
  margin-left: -2.5px; border-radius: 50%; background: #2a2a2a; z-index: 3;
}
.dash {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center top;
  opacity: 0;
  transform-origin: 50% 35%;
  will-change: opacity, transform;
}
.laptop-base {
  height: 14px;
  margin: 0 -4%;
  background: linear-gradient(#3a3a3a, #171717);
  border-radius: 0 0 16px 16px;
  box-shadow: 0 16px 30px -18px rgba(0,0,0,0.6);
  position: relative;
}
.laptop-base i {
  position: absolute; left: 50%; top: 0; width: 15%; height: 5px;
  transform: translateX(-50%); background: #0d0d0d; border-radius: 0 0 6px 6px;
}

/* cena 4: a casa acende na lista, a página sobe e rola */
.bc { transition: border-color 400ms ease, box-shadow 400ms ease, background 400ms ease; }
.bc--marca.bc--on { border-color: #fff; box-shadow: 4px 4px 0 #fff; background: #141414; }
.beco-page {
  position: absolute; inset: 0;
  background: #000;
  opacity: 0;
  transform: translateY(30px);
  overflow: hidden;
  z-index: 4;
  will-change: opacity, transform;
}
.beco-page img { position: absolute; left: 0; top: 0; width: 100%; height: auto; display: block; will-change: transform; }

@media (max-width: 880px) {
  .laptop { width: 92vw; }
  /* cena 2 no celular: a anotação não cabe ao lado — vira legenda em
     cima do aparelho, e a seta (que apontava de fora) sai */
  .c2-palco { flex-direction: column; gap: 10px; }
  .c2-seta { display: none; }
  .c2-nota { position: static; order: -1; text-align: center; white-space: normal; }
}
/* ritmo no celular: hero mais curto (era 380vh), saga mais longa */
@media (max-width: 720px) {
  .hero-scroll { height: 260vh; }
  .hist-scroll { height: 1700vh; }
}
