/* ═══════════════════════════════════════════════════════════════════════════
   rafaelgois.com — folha de estilo derivada de docs/design_system.html (v1.0)
   Sóbrio no ruído, audacioso nos gestos.
   Sem Tailwind, sem build: CSS autoral com tokens em :root.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── 1. TOKENS ─────────────────────────────────────────────────────────── */
:root {
  /* Cor — núcleo */
  --color-amber:        #FFB000;
  --color-amber-deep:   #E09A00;
  --color-amber-soft:   #FFD778;
  --color-amber-ink:    #8F5E00;
  --color-cream:        #FFFBEF;
  --color-cream-dark:   #F6EEDB;
  --color-paper:        #FFFDF7;
  --color-ink:          #2A2118;
  --color-ink-soft:     #5A4B3A;
  --color-ink-mute:     #7A6650;
  --color-line:         rgba(42, 33, 24, 0.14);
  --color-line-strong:  rgba(42, 33, 24, 0.32);

  /* Cor — feedback */
  --color-success:      #3D6B4B;
  --color-success-bg:   rgba(61, 107, 75, 0.10);
  --color-error:        #A4423B;
  --color-error-bg:     rgba(164, 66, 59, 0.09);

  /* Cor — interação */
  --color-focus:        #8F5E00;
  --color-selection:    rgba(255, 176, 0, 0.35);

  /* Gradientes */
  --grad-dawn: linear-gradient(135deg, #FFD778 0%, #FFB000 55%, #E09A00 100%);
  --grad-ink:  linear-gradient(160deg, #2A2118 0%, #40332a 100%);

  /* Espaçamento — base 4px */
  --sp-1: 0.25rem;  --sp-2: 0.5rem;   --sp-3: 0.75rem;  --sp-4: 1rem;
  --sp-6: 1.5rem;   --sp-8: 2rem;     --sp-12: 3rem;    --sp-16: 4rem;
  --sp-24: 6rem;    --sp-32: 8rem;

  /* Raios e bordas */
  --radius-xs: 2px; --radius-sm: 4px; --radius-md: 10px; --radius-lg: 18px;
  --radius-full: 999px;

  /* Elevação — sombras quentes */
  --shadow-1: 0 1px 3px rgba(90, 60, 10, 0.08);
  --shadow-2: 0 4px 16px rgba(90, 60, 10, 0.10), 0 1px 3px rgba(90, 60, 10, 0.06);
  --shadow-3: 0 16px 48px rgba(90, 60, 10, 0.14), 0 2px 8px rgba(90, 60, 10, 0.06);
  --shadow-amber: 0 10px 32px rgba(255, 176, 0, 0.30);

  /* Movimento */
  --dur-instant: 120ms; --dur-fast: 240ms; --dur-base: 450ms;
  --dur-slow: 800ms;    --dur-cinematic: 1400ms;
  --ease-gesture: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-breath:  cubic-bezier(0.65, 0, 0.35, 1);
  --ease-settle:  cubic-bezier(0.16, 1, 0.3, 1);

  /* Z-index — escala nomeada.
     O canvas 3D compartilhado (#three-composite-canvas) vive em --z-canvas: as
     seções opacas ficam acima dele; a dobra #box fica acima mas transparente,
     deixando os GLBs aparecerem por trás do seu conteúdo. */
  --z-canvas: 1;
  --z-section: 10;
  --z-box-content: 30;
  --z-sticky: 100;
  --z-overlay: 600;
  --z-menu: 700;
  --z-cursor: 900;

  /* Tipografia */
  --font-display: "Italiana", Didot, "Bodoni MT", "Times New Roman", serif;
  --font-body: "Manrope", "Avenir Next", "Segoe UI", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", "SFMono-Regular", Menlo, Consolas, monospace;

  --text-h1: clamp(2.75rem, 1.6rem + 5.2vw, 6.5rem);
  --text-h2: clamp(2rem, 1.35rem + 2.9vw, 4rem);
  --text-h3: clamp(1.5rem, 1.2rem + 1.4vw, 2.5rem);
  --text-h4: clamp(1.25rem, 1.1rem + 0.7vw, 1.75rem);
  --text-h5: clamp(1.05rem, 1rem + 0.35vw, 1.3rem);
  --text-h6: clamp(0.95rem, 0.9rem + 0.2vw, 1.1rem);
  --text-body-lg: clamp(1.05rem, 1rem + 0.3vw, 1.25rem);
  --text-body: 1rem;
  --text-body-sm: 0.875rem;
  --text-caption: 0.75rem;
  --text-overline: 0.6875rem;

  --measure: 68ch;
  --measure-narrow: 46ch;

  --container: 1152px;
  --container-wide: 1280px;
  --gutter: clamp(1.5rem, 5vw, 3rem);
}

/* ─── 2. RESET + BASE ───────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* `clip` (e não `hidden`) recorta o sangramento lateral das artes da dobra
     "fora da caixa" sem criar contexto de scroll — o pin do ScrollTrigger e
     position:sticky continuam funcionando. */
  overflow-x: clip;
}
body {
  background: var(--color-cream);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: 1.65;
  overflow-x: clip;
}
img, svg, canvas, video { display: block; max-width: 100%; }
img { height: auto; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }
input, textarea, select { font: inherit; color: inherit; }
::selection { background: var(--color-selection); color: var(--color-ink); }
:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
  border-radius: var(--radius-xs);
}

h1, h2, h3 { font-family: var(--font-display); font-weight: 400; line-height: 1.08; letter-spacing: 0.005em; }
h4, h5, h6 { font-family: var(--font-body); font-weight: 600; line-height: 1.3; }
h1 { font-size: var(--text-h1); }
h2 { font-size: var(--text-h2); text-wrap: balance; }
h3 { font-size: var(--text-h3); text-wrap: balance; }
h4 { font-size: var(--text-h4); }
h5 { font-size: var(--text-h5); }
h6 { font-size: var(--text-h6); text-transform: uppercase; letter-spacing: 0.12em; }
p { max-width: var(--measure); }

/* ─── 3. PAPÉIS DE TEXTO ────────────────────────────────────────────────── */
.text-body-lg { font-size: var(--text-body-lg); line-height: 1.6; }
.text-body-sm { font-size: var(--text-body-sm); line-height: 1.6; }
.text-caption { font-size: var(--text-caption); line-height: 1.5; color: var(--color-ink-mute); }
.text-label   { font-size: var(--text-body-sm); font-weight: 600; letter-spacing: 0.01em; }
.text-helper  { font-size: var(--text-caption); color: var(--color-ink-mute); }
.text-overline {
  font-family: var(--font-mono);
  font-size: var(--text-overline);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--color-amber-ink);
}
.text-quote { font-family: var(--font-display); font-size: var(--text-h4); line-height: 1.4; color: var(--color-ink-soft); }
.text-mono { font-family: var(--font-mono); }
.text-num { font-variant-numeric: tabular-nums; }
.u-soft { color: var(--color-ink-soft); }
.u-mute { color: var(--color-ink-mute); }
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ─── 4. ASSINATURA: O TRAÇO E O GRIFO ──────────────────────────────────── */
.sig-stroke { display: block; width: 100%; height: auto; overflow: visible; }
.sig-stroke path {
  fill: none;
  stroke: var(--color-amber);
  stroke-width: 7;
  stroke-linecap: round;
  stroke-dasharray: 320;
  stroke-dashoffset: 320;
}
.sig-stroke.is-drawn path { animation: sigDraw var(--dur-cinematic) var(--ease-settle) forwards; }
@keyframes sigDraw { to { stroke-dashoffset: 0; } }

.mark-amber {
  background-image: linear-gradient(104deg, transparent 0.5%, rgba(255,176,0,.55) 3%, rgba(255,176,0,.45) 96%, transparent 98%);
  background-size: 0% 0.62em;
  background-position: 0 78%;
  background-repeat: no-repeat;
  padding: 0 0.15em;
  transition: background-size var(--dur-slow) var(--ease-gesture);
}
.mark-amber.is-marked { background-size: 100% 0.62em; }

/* Grão de papel — textura global */
.grain::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: var(--z-cursor);
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ─── 5. LAYOUT ─────────────────────────────────────────────────────────── */
.wrap { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }
.wrap--wide { max-width: var(--container-wide); }

/* Seções opacas: acima do canvas 3D fixo. */
.section {
  position: relative;
  z-index: var(--z-section);
  background: var(--color-cream);
  padding-block: clamp(var(--sp-24), 12vh, var(--sp-32));
}
.section--alt { background: var(--color-cream-dark); }

.sec-head { margin-bottom: clamp(var(--sp-12), 7vh, var(--sp-24)); }
.sec-head__rule { height: 1px; background: var(--color-line); margin-bottom: var(--sp-8); transform-origin: left; }
.sec-head__title { margin-top: var(--sp-2); }
.sec-head__lede {
  margin-top: var(--sp-4);
  font-size: var(--text-body-lg);
  color: var(--color-ink-soft);
  max-width: var(--measure);
}

/* ─── 6. BOTÕES E LINKS ─────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 44px;
  padding: 0.65rem 1.6rem;
  font-size: var(--text-body-sm);
  font-weight: 700;
  letter-spacing: 0.02em;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  cursor: pointer;
  transition:
    transform var(--dur-fast) var(--ease-gesture),
    box-shadow var(--dur-fast) var(--ease-gesture),
    background var(--dur-fast) var(--ease-gesture),
    color var(--dur-fast) var(--ease-gesture),
    border-color var(--dur-fast) var(--ease-gesture);
}
.btn:active { transform: translateY(1px) scale(0.99); transition-duration: var(--dur-instant); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; transform: none; box-shadow: none; }
.btn__arrow { transition: transform var(--dur-fast) var(--ease-gesture); }
.btn:hover .btn__arrow { transform: translateX(4px); }

.btn--primary { background: var(--color-amber); color: var(--color-ink); }
.btn--primary:hover:not(:disabled) { background: var(--color-amber-deep); transform: translateY(-2px); box-shadow: var(--shadow-amber); }

.btn--secondary { background: transparent; color: var(--color-ink); border-color: var(--color-line-strong); }
.btn--secondary:hover:not(:disabled) { background: var(--color-ink); color: var(--color-cream); border-color: var(--color-ink); transform: translateY(-2px); box-shadow: var(--shadow-2); }

.btn--ghost { background: transparent; color: var(--color-ink-soft); padding-inline: 0.6rem; }
.btn--ghost:hover:not(:disabled) { color: var(--color-ink); background: rgba(255, 176, 0, 0.12); }

.btn--block { width: 100%; }
.btn--sm { min-height: 36px; padding: 0.35rem 1rem; font-size: var(--text-caption); }

/* Link com sublinhado-gesto: entra pela esquerda, sai pela direita */
.link-line {
  position: relative;
  font-weight: 600;
  padding-bottom: 2px;
}
.link-line::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 2px;
  background: var(--color-amber);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--dur-base) var(--ease-gesture);
}
.link-line:hover::after, .link-line:focus-visible::after { transform: scaleX(1); transform-origin: left; }

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--text-body-sm);
  font-weight: 600;
  color: var(--color-ink);
  min-height: 44px;
}
.link-arrow span:last-child { transition: transform var(--dur-fast) var(--ease-gesture); }
.link-arrow:hover span:last-child { transform: translateX(5px); }
.link-arrow:hover { color: var(--color-amber-ink); }

/* ─── 7. BADGES ─────────────────────────────────────────────────────────── */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.22rem 0.7rem;
  font-size: var(--text-caption);
  font-weight: 600;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-line);
  background: var(--color-paper);
  color: var(--color-ink-soft);
}
.badge--mono { font-family: var(--font-mono); font-weight: 500; font-size: 0.68rem; letter-spacing: 0.06em; }
.badge__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--color-amber); flex-shrink: 0; }
.badge__dot--pulse { animation: pulse 2s var(--ease-breath) infinite; }
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 176, 0, 0.5); }
  50% { box-shadow: 0 0 0 6px rgba(255, 176, 0, 0); }
}

.ic { width: 24px; height: 24px; color: currentColor; }
.ic--sm { width: 16px; height: 16px; }
.ic--lg { width: 32px; height: 32px; }

/* ─── 8. NAVBAR ─────────────────────────────────────────────────────────── */
.navbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-6);
  padding: var(--sp-6) var(--gutter);
  transition:
    padding var(--dur-base) var(--ease-gesture),
    background var(--dur-base) var(--ease-gesture),
    box-shadow var(--dur-base) var(--ease-gesture);
}
.navbar.is-scrolled {
  padding-block: var(--sp-3);
  background: rgba(255, 251, 239, 0.88);
  backdrop-filter: blur(12px) saturate(140%);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  box-shadow: var(--shadow-1);
}
.navbar__logo { font-family: var(--font-display); font-size: 1.5rem; line-height: 1; }
.navbar__logo em { font-style: normal; color: var(--color-amber); }
.navbar__links { display: flex; gap: clamp(var(--sp-6), 3vw, var(--sp-12)); }
.navbar__links .link-line { font-size: var(--text-body-sm); font-weight: 500; }
.navbar__burger {
  display: none;
  width: 44px; height: 44px;
  align-items: center; justify-content: center;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-sm);
  transition: border-color var(--dur-fast) var(--ease-gesture), background var(--dur-fast) var(--ease-gesture);
}
.navbar__burger:hover { border-color: var(--color-amber); background: rgba(255, 176, 0, 0.1); }

/* ─── 9. MENU MOBILE ────────────────────────────────────────────────────── */
.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: var(--z-menu);
  background: var(--color-cream);
  display: none;
  flex-direction: column;
}
.mobile-menu.is-open { display: flex; }
.mobile-menu__head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--sp-4) var(--sp-6);
  border-bottom: 1px solid var(--color-line);
}
.mobile-menu__brand { font-family: var(--font-display); font-size: 1.4rem; }
.mobile-menu__brand em { font-style: normal; color: var(--color-amber); }
.mobile-menu__close {
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-sm);
}
.mobile-menu__body {
  flex: 1;
  display: flex; flex-direction: column; justify-content: center;
  gap: var(--sp-2);
  padding: var(--sp-8) var(--sp-6);
  overflow-y: auto;
}
.mobile-menu__link {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-6);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
  min-height: 64px;
  transition: border-color var(--dur-fast) var(--ease-gesture), background var(--dur-fast) var(--ease-gesture);
}
.mobile-menu__link:hover, .mobile-menu__link:focus-visible { border-color: var(--color-amber); background: rgba(255, 176, 0, 0.08); }
.mobile-menu__link h3 { font-size: 1.4rem; }
.mobile-menu__link .mobile-menu__num { font-family: var(--font-mono); font-size: 0.62rem; color: var(--color-amber-ink); letter-spacing: 0.16em; }
.mobile-menu__link--cta { background: var(--color-amber); border-color: var(--color-amber); }
.mobile-menu__link--cta:hover { background: var(--color-amber-deep); border-color: var(--color-amber-deep); }
.mobile-menu__foot {
  display: flex; justify-content: center; gap: var(--sp-4);
  padding: var(--sp-6);
  border-top: 1px solid var(--color-line);
}
.mobile-menu__social {
  width: 48px; height: 48px;
  display: grid; place-items: center;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-sm);
  transition: background var(--dur-fast) var(--ease-gesture), border-color var(--dur-fast) var(--ease-gesture), transform var(--dur-fast) var(--ease-gesture);
}
.mobile-menu__social:hover { background: var(--color-amber); border-color: var(--color-amber); transform: translateY(-2px); }

/* ─── 10. HERO CINEMATOGRÁFICO ──────────────────────────────────────────────
   Técnica da referência docs/aurelia-studios-72.aura.build: uma seção alta
   (.hero__track) com um palco sticky (.hero__stage). O progresso de scroll da
   seção é suavizado por lerp e alimenta TODAS as camadas — incluindo o teclado
   3D. Sem pin do ScrollTrigger: sticky puro, mais barato e sem pin-spacer. */
.hero {
  position: relative;
  z-index: var(--z-section);
  /* Sem fundo próprio: o teclado 3D vive no canvas fixo em --z-canvas, atrás. */
  background: transparent;
}
.hero__track { height: 460svh; }
.hero__stage {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  display: grid;
  place-items: center;
}

/* Camera rig — recebe o translate/scale/rotate global do "movimento de câmera" */
.hero__rig {
  position: absolute;
  inset: -10%;
  z-index: 0;
  pointer-events: none;
  will-change: transform;
}
.hero__bg { position: absolute; inset: 0; will-change: transform, filter; }
.hero__bg canvas { width: 100%; height: 100%; }

/* Textura de fundo da dobra — relevo em baixo-relevo cor de marfim, como a
   referência docs/aurelia-studios-72.aura.build: o fundo "respira" para os
   lados conforme os capítulos alternados (esquerda/direita) entram em cena
   (ver bgImage em site.js). Maior que a viewport para o pan lateral nunca
   expor borda; opacidade baixa para ficar textura, não foto.
   Fixa e fora do .hero__rig, com z abaixo de --z-canvas: o canvas WebGL do
   teclado (que limpa com alpha 0) pinta por cima dela, então o teclado 3D
   aparece na frente da textura em vez de atrás. Começa oculta (opacity 0) —
   só o motor cinematográfico em site.js a acende, e apenas enquanto a dobra
   do hero está em tela, então não vaza para as seções seguintes. */
.hero__bg-image {
  position: fixed;
  inset: -22%;
  z-index: 0;
  pointer-events: none;
  background-image: url("https://res.cloudinary.com/dn454izoh/image/upload/f_auto,q_auto,w_2200/v1785193132/textured_engineering_hero_background_hxi79m.png");
  background-size: cover;
  background-position: center;
  opacity: 0;
  will-change: transform, opacity;
}

.hero__light,
.hero__rays,
.hero__fog { position: absolute; inset: 0; pointer-events: none; }
.hero__light {
  background: radial-gradient(circle at 50% 48%, rgba(255, 176, 0, 0.34), transparent 58%);
  will-change: transform, opacity;
}
.hero__rays {
  background: repeating-linear-gradient(
    102deg,
    rgba(255, 215, 120, 0.16) 0 2px,
    transparent 2px 46px
  );
  -webkit-mask-image: radial-gradient(ellipse at 50% 40%, #000 10%, transparent 68%);
  mask-image: radial-gradient(ellipse at 50% 40%, #000 10%, transparent 68%);
  will-change: transform, opacity;
}
.hero__fog--back {
  background: radial-gradient(ellipse 70% 50% at 25% 65%, rgba(255, 215, 120, 0.34), transparent 70%);
  will-change: transform;
}
.hero__fog--front {
  background: radial-gradient(ellipse 60% 45% at 78% 32%, rgba(255, 251, 239, 0.6), transparent 72%);
  will-change: transform, opacity;
}

.hero__vignette {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(ellipse at 50% 45%, transparent 34%, rgba(255, 251, 239, 0.8) 100%);
}
/* Flash do "impacto" — o beat em que o teclado se remonta */
.hero__flash {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  opacity: 0;
  background: radial-gradient(circle at 50% 50%, rgba(255, 176, 0, 0.55), rgba(255, 251, 239, 0) 65%);
  will-change: opacity;
}

.hero__scenes {
  position: relative;
  z-index: 3;
  width: min(92vw, 68rem);
  text-align: center;
}

.hero-chapter { padding-block: var(--sp-8); }
.js .hero-chapter {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding-block: 0;
  will-change: transform, opacity, filter;
}
.js .hero-chapter--rest { position: relative; }

/* Capítulo I: centralizado, menor, servindo de abertura para a sequência.
   Capítulos II e III: ancorados à esquerda e à direita respectivamente,
   como na referência docs/aurelia-studios-72.aura.build — o texto entra vindo
   do seu lado e continua o gesto para fora ao sair. */
.hero:not(.is-flow) .hero-chapter[data-side] {
  place-items: end start;
  padding: 0 var(--gutter) clamp(var(--sp-12), 14vh, var(--sp-24));
}
.hero:not(.is-flow) .hero-chapter[data-side="right"] { place-items: end end; }
.hero:not(.is-flow) .hero-chapter[data-side] .hero-chapter__over,
.hero:not(.is-flow) .hero-chapter[data-side] .hero-chapter__line {
  text-align: left;
  margin-inline: 0;
}
.hero:not(.is-flow) .hero-chapter[data-side="right"] .hero-chapter__over,
.hero:not(.is-flow) .hero-chapter[data-side="right"] .hero-chapter__line {
  text-align: right;
}

/* Capítulos II e III: legendas menores coladas ao canto da viewport — como as
   asserções curtas ("Every horizon hides a story") da referência, em vez do
   mesmo porte do título central. Escapam da caixa centralizada (68rem) para
   respirar rente à borda real da tela. */
.hero:not(.is-flow) .hero-chapter[data-side].hero-chapter--minor {
  width: 100vw;
  left: 50%;
  right: auto;
  margin-left: -50vw;
  padding-bottom: clamp(var(--sp-10), 11vh, var(--sp-16));
}
.hero-chapter--minor .hero-chapter__line {
  font-size: clamp(1.4rem, 0.85rem + 2vw, 2.5rem);
  max-width: 15ch;
  line-height: 1.22;
}

/* Capítulo III: mesmo porte menor dos demais, mas com mais fôlego horizontal —
   a frase é mais longa que a do Capítulo II e pede mais largura de linha. */
.hero-chapter[data-chapter="2"] .hero-chapter__line {
  max-width: 28ch;
}

/* Capítulo I: a frase estava quebrando em linhas demais (texto muito
   "vertical") — mais largura pra ela respirar na horizontal. */
.hero-chapter[data-chapter="1"] .hero-chapter__line {
  max-width: 26ch;
}

/* Capítulo I: é o primeiro texto que a página mostra — merece um porte maior.
   Mesmo Italiana do resto do site (nome, navbar), só que numa escala mais
   generosa e com mais respiro entre letras, para abrir a sequência sem
   introduzir uma fonte estranha ao resto da identidade. */
.hero-chapter[data-chapter="0"] .hero-chapter__line {
  font-size: clamp(2.1rem, 1rem + 4vw, 4rem);
  line-height: 1.22;
  letter-spacing: 0.01em;
  max-width: 20ch;
}

.hero-chapter__over {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--color-amber-ink);
  margin-bottom: var(--sp-4);
}
/* Capítulo I: um pouco mais de respiro entre as letras do que os demais. */
.hero-chapter[data-chapter="1"] .hero-chapter__over {
  letter-spacing: 0.34em;
}
.hero-chapter__line {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 1rem + 4.4vw, 4.6rem);
  line-height: 1.14;
  max-width: 22ch;
  margin-inline: auto;
  text-wrap: balance;
}
.hero-chapter__line .w { display: inline-block; will-change: transform, opacity; }

.hero-rest__name {
  font-family: var(--font-display);
  font-size: clamp(3rem, 1.2rem + 8.4vw, 8rem);
  line-height: 0.98;
}
.hero-rest__name em { font-style: normal; position: relative; white-space: nowrap; display: inline-block; }
.hero-rest__name .sig-stroke { position: absolute; left: 4%; bottom: -0.16em; width: 94%; z-index: -1; }
/* No hero cinematográfico o traço é desenhado pelo progresso do scroll (site.js),
   não pela animação CSS — por isso a transição fica desligada aqui. No fluxo
   mobile (.is-flow) não há motor por-frame, então a animação CSS via
   .sig-stroke.is-drawn (disparada em buildHeroFlow) segue ativa. */
.js .hero:not(.is-flow) .hero-rest__name .sig-stroke path { animation: none; }
.hero-rest__role {
  margin-top: var(--sp-4);
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--color-ink-mute);
}
.hero-rest__tag {
  margin: var(--sp-6) auto 0;
  font-size: var(--text-body-sm);
  color: var(--color-ink-soft);
  max-width: 34rem;
  text-wrap: pretty;
}
.hero-rest__actions {
  display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-3);
  margin-top: var(--sp-8);
}
.hero-rest__status { margin-top: var(--sp-8); display: flex; justify-content: center; }

/* HUD — contador de capítulo + barra de progresso (padrão da referência) */
.hero__hud {
  position: absolute;
  left: var(--gutter); right: var(--gutter); bottom: var(--sp-6);
  z-index: 4;
  display: flex; align-items: center; gap: var(--sp-4);
  font-family: var(--font-mono);
  font-size: var(--text-overline);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-ink-mute);
  pointer-events: none;
}
.hero__hud-chapter { color: var(--color-amber-ink); font-weight: 500; white-space: nowrap; }
.hero__hud-label { white-space: nowrap; }
.hero__hud-bar {
  flex: 1;
  height: 2px;
  background: var(--color-line);
  border-radius: var(--radius-full);
  overflow: hidden;
}
.hero__hud-bar i {
  display: block;
  height: 100%;
  background: var(--color-amber);
  transform: scaleX(0);
  transform-origin: left;
  will-change: transform;
}

.hero__cue {
  position: absolute;
  left: 50%; bottom: calc(var(--sp-6) + 2.5rem);
  transform: translateX(-50%);
  z-index: 4;
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-2);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--color-ink-mute);
  pointer-events: none;
}
.hero__cue-line { width: 1px; height: 44px; background: var(--color-line-strong); position: relative; overflow: hidden; }
.hero__cue-line::after {
  content: "";
  position: absolute; left: 0; top: -50%;
  width: 100%; height: 50%;
  background: var(--color-amber);
  animation: cueDrop 2.2s var(--ease-breath) infinite;
}
@keyframes cueDrop { 0% { top: -50%; } 60%, 100% { top: 110%; } }

/* Fallback (mobile / reduced-motion): tudo em fluxo, sem sticky nem palco. */
.hero.is-flow .hero__track { height: auto; }
.hero.is-flow .hero__stage {
  position: static;
  height: auto;
  display: block;
  overflow: visible;
  padding: calc(var(--sp-24) + var(--sp-8)) 0 var(--sp-16);
}
.hero.is-flow .hero__scenes { width: 100%; }
.hero.is-flow .hero-chapter {
  position: relative;
  inset: auto;
  display: block;
  opacity: 1;
  padding-inline: var(--gutter);
  margin-bottom: var(--sp-16);
}
/* Assinatura: ocupa quase a primeira tela inteira, como um cartão de abertura —
   garante que o Capítulo I comece abaixo da dobra, revelado só ao rolar, em
   vez de já entrar parcialmente visível no load. */
.hero.is-flow .hero-chapter--rest {
  min-height: 82svh;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Pop de entrada da assinatura no load — puro CSS (não GSAP), para não
   disputar opacity/transform/filter com o tween de saída escrubado pelo
   scroll em buildHeroFlow (site.js). Roda uma vez e termina antes de o
   usuário rolar até o ponto em que a saída começa a agir. */
.hero.is-flow .hero-chapter--rest > div {
  animation: heroRestIn 900ms var(--ease-gesture) 150ms backwards;
}
@keyframes heroRestIn {
  from { opacity: 0; transform: translateY(24px); filter: blur(6px); }
  to   { opacity: 1; transform: translateY(0); filter: blur(0); }
}
/* Capítulos I–III em fluxo: cada um ocupa boa parte da tela, um de cada vez,
   para que a entrada/saída (site.js) tenha espaço para ser lida em vez de
   os três ficarem empilhados e visíveis ao mesmo tempo. */
.hero.is-flow .hero-chapter[data-chapter]:not(.hero-chapter--rest) {
  min-height: 62svh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.hero.is-flow .hero-chapter[data-chapter] > div { width: 100%; }
.hero.is-flow .hero__rig { inset: 0; }
.hero.is-flow .hero__hud,
.hero.is-flow .hero__cue,
.hero.is-flow .hero__flash { display: none; }
.hero.is-flow .hero__vignette { background: radial-gradient(ellipse at 50% 20%, transparent 30%, rgba(255, 251, 239, 0.8) 100%); }

/* ─── 11. SOBRE — a história em três atos (scroll horizontal) ──────────── */
.about-scroll__pin {
  margin-top: clamp(var(--sp-12), 6vh, var(--sp-16));
}
.about-scroll__track {
  display: flex;
  flex-direction: column;
  gap: clamp(var(--sp-16), 10vh, var(--sp-24));
  padding-inline: var(--gutter);
}
.about-panel {
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
  align-items: center;
  text-align: center;
}
.about-panel__media { width: min(100%, 320px); }
.about-panel__text { text-align: left; width: 100%; max-width: var(--measure); }

/* Linha torta ao fundo — "a vida segue suas próprias linhas tortas". No
   desktop pinado ela é horizontal (about-curve-svg); no fluxo vertical do
   mobile vira uma linha vertical mais simples atrás da coluna de miniaturas
   (about-curve-svg--mobile). Reduced-motion não usa nenhuma das duas: os
   atos já têm respiro de sobra sem ela. */
.about-curve-svg, .about-curve-svg--mobile { display: none; }
.about-hud { display: none; }
.about-stepper { display: none; }
.about-curve-path {
  fill: none;
  stroke: var(--color-amber);
  stroke-linecap: round;
  stroke-linejoin: round;
}
.about-curve-path--main { stroke-width: 3.5; opacity: 0.4; }
.about-curve-path--mobile { stroke-width: 3; opacity: 0.35; }

/* Deriva lenta da linha — só transform: barato e composto pela GPU. */
.about-curve-drift {
  animation: curveDrift 20s var(--ease-breath) infinite;
  transform-box: fill-box;
  transform-origin: center;
}
.about-curve-drift--main{ animation-duration: 19s; animation-delay: -6s; }
.about-curve-drift--mobile{ animation-duration: 16s; animation-delay: -3s; }

@keyframes curveDrift {
  0%, 100% { transform: translate(0, 0) rotate(0deg); }
  50%      { transform: translate(-1.1%, 1.4%) rotate(-0.35deg); }
}

@media (min-width: 900px) {
  .about-scroll.is-horizontal .about-scroll__pin {
    position: relative;
    height: 100vh;
    overflow: hidden;
    display: flex;
    align-items: center;
    margin-top: clamp(var(--sp-16), 8vh, var(--sp-24));
  }
  .about-scroll.is-horizontal .about-curve-svg {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    pointer-events: none;
  }
  /* HUD do pin: mesmo padrão do hero (capítulo + label + barra de progresso),
     atualizado em site.js conforme o ato mais próximo do centro do pin. */
  .about-scroll.is-horizontal .about-hud {
    display: flex;
    z-index: 3;
  }
  .about-scroll.is-horizontal .about-scroll__track {
    position: relative;
    z-index: 1;
    flex-direction: row;
    flex-wrap: nowrap;
    width: max-content;
    gap: clamp(var(--sp-16), 8vw, var(--sp-24));
    /* Painel I nasce fora da tela, à direita — o primeiro gesto do usuário
       já é "puxar" a história para dentro do quadro, igual aos demais atos. */
    padding-left: 22vw;
    padding-right: clamp(var(--sp-8), 8vw, var(--sp-24));
  }
  .about-scroll.is-horizontal .about-panel {
    flex: 0 0 min(78vw, 900px);
    flex-direction: row;
    text-align: left;
    gap: clamp(var(--sp-8), 4vw, var(--sp-16));
  }
  .about-scroll.is-horizontal .about-panel--reverse { flex-direction: row-reverse; }
  .about-scroll.is-horizontal .about-panel__media { flex: 0 0 min(34vw, 340px); width: min(34vw, 340px); }
  .about-scroll.is-horizontal .about-panel__text { flex: 1; padding-left: var(--sp-8); }

  /* Cada ato tem sua própria composição — nada de espelhamento uniforme. */
  .about-scroll.is-horizontal .about-panel--i {
    flex-basis: min(88vw, 1040px);
    align-items: center;
    margin-top: -2vh;
  }
  .about-scroll.is-horizontal .about-panel--i .about-panel__media {
    /* Mais estreito que os outros atos: a proporção alta do cluster (retrato
       + miniaturas acima/abaixo) já dá altura de sobra — precisa de menos
       largura para não estourar o pin de 100vh. */
    flex-basis: min(36vw, 360px); width: min(36vw, 360px);
  }
  .about-scroll.is-horizontal .about-panel--i .about-panel__text {
    padding-left: var(--sp-10);
  }

  .about-scroll.is-horizontal .about-panel--ii {
    flex-basis: min(84vw, 960px);
    align-items: flex-start;
    margin-top: 5vh;
  }
  .about-scroll.is-horizontal .about-panel--ii .about-panel__media {
    flex-basis: min(40vw, 400px); width: min(40vw, 400px);
  }
  .about-scroll.is-horizontal .about-panel--ii .about-panel__text { padding-top: var(--sp-8); }

  .about-scroll.is-horizontal .about-panel--iii {
    flex-basis: min(76vw, 880px);
    align-items: center;
    margin-top: -1vh;
  }
  .about-scroll.is-horizontal .about-panel--iii .about-panel__media {
    flex-basis: min(32vw, 320px); width: min(32vw, 320px);
  }

  /* Marcador lateral dos três atos — destaca o ato ativo enquanto o scroll
     horizontal avança (site.js alterna a classe is-active). */
  .about-scroll.is-horizontal .about-stepper {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-2);
    position: absolute;
    right: var(--gutter);
    top: 50%;
    transform: translateY(-50%);
    z-index: 3;
    pointer-events: none;
  }
}

.about-stepper__item {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  letter-spacing: 0.1em;
  color: var(--color-ink-mute);
  opacity: 0.4;
  transition: opacity var(--dur-base) var(--ease-gesture), color var(--dur-base) var(--ease-gesture);
}
.about-stepper__item.is-active { color: var(--color-amber-ink); opacity: 1; }
.about-stepper__rule { width: 1px; height: var(--sp-6); background: var(--color-line-strong); }

.act { position: relative; padding-left: var(--sp-8); overflow: hidden; }
.act__roman {
  position: absolute;
  left: -0.1em; top: -0.1em;
  display: block;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: clamp(4.5rem, 6.5vw, 7rem);
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--color-ink);
  opacity: 0.035;
  pointer-events: none;
  user-select: none;
  z-index: 0;
  transform-origin: 20% 30%;
}
.act--now .act__roman { color: var(--color-amber); opacity: 0.06; }
.act__num, .act__title, .act__text { position: relative; z-index: 1; }
.act__num {
  font-family: var(--font-mono);
  font-size: var(--text-overline);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--color-amber-ink);
}
.act__title { font-family: var(--font-display); font-size: var(--text-h3); margin-top: var(--sp-1); }
.act__text { margin-top: var(--sp-3); color: var(--color-ink-soft); font-size: var(--text-body-lg); }

#about .sec-head__lede { font-size: var(--text-body-sm); }
#about .act__title { font-size: clamp(1.25rem, 1.05rem + 0.9vw, 1.85rem); }
#about .act__text { font-size: var(--text-body-sm); }

#skills .sec-head__lede {
  margin-top: var(--sp-2);
  font-size: var(--text-body-sm);
}

#projects .sec-head__lede { font-size: var(--text-body-sm); }

.about__portrait { position: relative; }
.about__portrait img {
  width: 100%;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
}
.about__portrait figcaption {
  margin-top: var(--sp-4);
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  color: var(--color-ink-mute);
  letter-spacing: 0.04em;
}
.about__portrait::before {
  content: "";
  position: absolute;
  inset: auto -6% -5% 12%;
  height: 62%;
  border-radius: var(--radius-lg);
  background: var(--grad-dawn);
  opacity: 0.22;
  z-index: -1;
}

/* Cluster de retrato (Atos I e II): principal ao centro, miniaturas soltas
   "flutuando" ao redor — tocam de leve a borda da foto principal, sem nunca
   cobrir o rosto nem se empilhar uma sobre a outra. Os modificadores de
   posição/proporção (--top, --bottom, --ii-a etc.) precisam do mesmo peso de
   especificidade da regra base (.about__portrait--cluster + 1 classe) para
   conseguirem vencer width/aspect-ratio — por isso todos ficam com o mesmo
   prefixo ".about__portrait--cluster", não soltos. */
.about__portrait--cluster {
  overflow: visible;
  position: relative;
  padding-top: 6%;
  padding-bottom: 6%;
}
.about__portrait--cluster::before {
  inset: 10% 6% 10% 6%;
  height: auto;
}
.about__portrait--cluster .about__portrait-main {
  position: relative;
  z-index: 2;
  display: block;
  width: 100%;
  /* Mesma proporção alta e elegante dos retratos simples dos outros atos —
     corta só um pouco das laterais e deixa o enquadramento mais limpo. */
  aspect-ratio: 0.66;
  object-fit: cover;
}
.about__portrait--cluster .about__portrait-sat {
  position: absolute;
  z-index: 3;
  width: 44%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-2);
  border: 2px solid rgba(255, 251, 239, 0.95);
}
.about__portrait--cluster .about__portrait-sat--top {
  left: -15%;
  top: 2%;
  transform: rotate(-7deg);
}
.about__portrait--cluster .about__portrait-sat--bottom {
  right: -9%;
  bottom: 2%;
  width: 72%;
  /* Proporção real da foto (4000×2250) — na horizontal, sem cortar nada. */
  aspect-ratio: 16 / 9;
  transform: rotate(6deg);
}

/* Mesmo elemento âmbar (var(--grad-dawn)) que espia atrás do retrato
   principal, só que aplicado a cada miniatura dos três atos — bem mais
   discreto, opacidade baixa e o desvio de posição pequeno, pra só espiar
   por uma fresta atrás de cada uma. */
.about__portrait--cluster .about__portrait-sat-glow {
  position: absolute;
  z-index: 2;
  border-radius: var(--radius-sm);
  background: var(--grad-dawn);
  opacity: 0.14;
}
.about__portrait--cluster .about__portrait-sat-glow--top {
  left: -19%;
  top: -2%;
  width: 44%;
  aspect-ratio: 3 / 4;
  transform: rotate(-7deg);
}
.about__portrait--cluster .about__portrait-sat-glow--bottom {
  right: -13%;
  bottom: -2%;
  width: 72%;
  aspect-ratio: 16 / 9;
  transform: rotate(6deg);
}

/* Ato II: mesma lógica, espelhada (o media fica do lado direito do painel
   invertido) e com uma terceira miniatura extra. */
.about__portrait--cluster .about__portrait-sat--ii-a {
  width: 38%;
  left: -16%;
  top: 2%;
  transform: rotate(-6deg);
}
.about__portrait--cluster .about__portrait-sat--ii-b {
  right: -16%;
  bottom: 2%;
  width: 58%;
  /* Proporção real do rascunho (4000×3000) — na horizontal, sem cortar. */
  aspect-ratio: 4 / 3;
  transform: rotate(6deg);
}
.about__portrait--cluster .about__portrait-sat--ii-c {
  width: 34%;
  left: -10%;
  bottom: 4%;
  z-index: 4;
  transform: rotate(-4deg);
}
.about__portrait--cluster .about__portrait-sat-glow--ii-a {
  left: -20%;
  top: -2%;
  width: 38%;
  aspect-ratio: 3 / 4;
  transform: rotate(-6deg);
}
.about__portrait--cluster .about__portrait-sat-glow--ii-b {
  right: -20%;
  bottom: -2%;
  width: 58%;
  aspect-ratio: 4 / 3;
  transform: rotate(6deg);
}
.about__portrait--cluster .about__portrait-sat-glow--ii-c {
  left: -14%;
  bottom: 0%;
  width: 34%;
  aspect-ratio: 3 / 4;
  transform: rotate(-4deg);
}

/* Ato III: mesma lógica do Ato I (media à esquerda, sem inversão), mas com
   as satélites mais afastadas no eixo X em relação à imagem principal. */
.about__portrait--cluster .about__portrait-sat--iii-a {
  left: -15%;
  top: 2%;
  transform: rotate(-7deg);
}
.about__portrait--cluster .about__portrait-sat--iii-b {
  right: -15%;
  bottom: 2%;
  width: 48%;
  /* Proporção real da foto (3024×4032). */
  aspect-ratio: 3024 / 4032;
  transform: rotate(6deg);
}
.about__portrait--cluster .about__portrait-sat-glow--iii-a {
  left: -19%;
  top: -2%;
  width: 44%;
  aspect-ratio: 3 / 4;
  transform: rotate(-7deg);
}
.about__portrait--cluster .about__portrait-sat-glow--iii-b {
  right: -19%;
  bottom: -2%;
  width: 48%;
  aspect-ratio: 3024 / 4032;
  transform: rotate(6deg);
}
.about__portrait--cluster figcaption { position: relative; z-index: 1; }

/* Todo retrato/miniatura da timeline "Sobre mim" abre em tela cheia ao
   clicar — inclusive as satélites, que por isso perdem o pointer-events:none
   que tinham antes (ver .about__portrait--cluster .about__portrait-sat). */
.about__portrait img { cursor: zoom-in; }
.about-lightbox {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-8);
  background: rgba(24, 16, 6, 0.88);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.25s ease, visibility 0.25s ease;
}
.about-lightbox.is-open { opacity: 1; visibility: visible; }
.about-lightbox__img {
  display: block;
  max-width: min(90vw, 1100px);
  max-height: 88vh;
  width: auto;
  height: auto;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-3);
  cursor: zoom-out;
  transform: scale(0.94);
  transition: transform 0.25s ease;
}
.about-lightbox.is-open .about-lightbox__img { transform: scale(1); }
.about-lightbox__close {
  position: absolute;
  top: var(--sp-6);
  right: var(--sp-6);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.3);
  background: rgba(0, 0, 0, 0.35);
  color: var(--color-cream);
  font-family: var(--font-mono);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.about-lightbox__close:hover { background: rgba(0, 0, 0, 0.55); }

/* ─── 12. DOBRA #box — "Pensando fora da caixa" ─────────────────────────
   Sem fundo opaco: os GLBs desenham no canvas fixo compartilhado (z: 1) e
   aparecem por trás deste HTML. Portado de style.css com a paleta nova. */
#box {
  position: relative;
  z-index: var(--z-box-content);
  min-height: 120svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--sp-8) var(--gutter);
}
.three-composite-root { position: fixed; inset: 0; z-index: var(--z-canvas); }
#three-composite-canvas { display: block; width: 100%; height: 100%; }
/* Âncora de viewport do teclado: define o recorte (scissor) da camada 'hero'
   no canvas compartilhado. Não desenha nada por si. */
#hero-3d-container { position: fixed; inset: 0; z-index: var(--z-canvas); pointer-events: none; }

.box-left-bottom-3d-panel,
.box-left-top-3d-panel,
.box-right-bottom-3d-panel,
.box-right-top-3d-panel {
  position: absolute;
  top: 0;
  width: 46%;
  height: 100%;
  pointer-events: none;
}
.box-left-bottom-3d-panel, .box-left-top-3d-panel { left: 0; }
.box-right-bottom-3d-panel, .box-right-top-3d-panel { right: 0; }
.box-left-bottom-3d-panel, .box-right-bottom-3d-panel { z-index: 5; }
.box-left-top-3d-panel, .box-right-top-3d-panel { z-index: 6; }
.box-left-bottom-3d-panel canvas,
.box-left-top-3d-panel canvas,
.box-right-bottom-3d-panel canvas,
.box-right-top-3d-panel canvas { display: block; width: 100%; height: 100%; }

.box-center { position: relative; z-index: 40; width: 100%; max-width: 56rem; margin-inline: auto; }
.box-center__stage { position: relative; width: 100%; }
.box-headline {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%) rotate(-5deg);
  z-index: 1;
  pointer-events: none;
  font-family: var(--font-body);
  font-weight: 900;
  font-size: clamp(3.5rem, 1.1rem + 12vw, 11rem);
  line-height: 1.12;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  text-align: center;
  color: var(--color-ink);
  max-width: 90vw;
  white-space: nowrap;
}
.box-moldura { display: block; position: relative; z-index: 2; pointer-events: none; width: 100%; }

/* Desembaralhar da headline: trecho ainda embaralhado fica âmbar e discreto,
   trecho já resolvido na palavra real "acende" na tinta cheia — o contraste
   entre os dois é o que vende a leitura de "decodificando enquanto rola". */
.box-headline__char--out { color: var(--color-amber-ink); opacity: 0.6; }
.box-headline__char--in { color: var(--color-ink); opacity: 1; }

#box-left-img {
  position: absolute; left: 0; top: 50%;
  max-height: clamp(22rem, 58vh, 42rem);
  width: auto; z-index: 30;
  will-change: transform, opacity;
}
#box-right-img {
  position: absolute; right: 0; top: 50%;
  max-height: clamp(7rem, 18vh, 13rem);
  width: auto; z-index: 50;
  will-change: transform, opacity;
}
#box-icaro {
  position: absolute; top: 50%; left: 40%;
  max-height: clamp(14rem, 38vh, 28rem);
  width: auto; z-index: 35;
  will-change: transform, opacity;
}

/* ─── 13. MANIFESTO — a seção 100% âmbar ────────────────────────────────── */
.manifesto {
  isolation: isolate;
  background:
    radial-gradient(ellipse 110% 70% at 50% -15%, rgba(255, 253, 247, 0.5) 0%, transparent 55%),
    radial-gradient(ellipse 70% 55% at 0% 100%, rgba(255, 215, 120, 0.55) 0%, transparent 55%),
    radial-gradient(ellipse 65% 50% at 100% 90%, rgba(224, 154, 0, 0.55) 0%, transparent 50%),
    linear-gradient(168deg, var(--color-amber-soft) 0%, var(--color-amber) 48%, var(--color-amber-deep) 100%);
}
.manifesto {
  position: relative;
  z-index: var(--z-section);
  overflow: hidden;
  padding-block: clamp(var(--sp-24), 16vh, var(--sp-32));
}
.manifesto::before {
  content: "";
  position: absolute;
  inset: -35% -15% auto 30%;
  width: min(70vw, 42rem);
  aspect-ratio: 1;
  background: radial-gradient(
    circle,
    rgba(255, 253, 247, 0.58) 0%,
    rgba(255, 215, 120, 0.28) 38%,
    transparent 68%
  );
  pointer-events: none;
  z-index: 0;
  animation: manifestoGlow 14s var(--ease-breath) infinite alternate;
}
.manifesto::after {
  content: "";
  position: absolute;
  inset: auto -20% -45% -20%;
  height: 75%;
  background:
    radial-gradient(ellipse 48% 58% at 28% 78%, rgba(255, 215, 120, 0.6) 0%, transparent 70%),
    radial-gradient(ellipse 42% 52% at 72% 88%, rgba(255, 253, 247, 0.4) 0%, transparent 68%),
    radial-gradient(ellipse 80% 40% at 50% 100%, rgba(224, 154, 0, 0.35) 0%, transparent 60%);
  pointer-events: none;
  z-index: 0;
  animation: manifestoGlow 18s var(--ease-breath) infinite alternate-reverse;
}
@keyframes manifestoGlow {
  from { transform: translate3d(0, 0, 0) scale(1); opacity: 0.82; }
  to   { transform: translate3d(-2.5%, 3%, 0) scale(1.1); opacity: 1; }
}
.manifesto__inner { position: relative; z-index: 1; text-align: center; }

/* Aspas decorativa: sobe atrás do overline, encolhida e girada, e se acomoda
   no lugar quando a seção entra — um floreio que assina o "manifesto" antes
   mesmo da citação aparecer. */
.manifesto__mark {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(5rem, 3rem + 8vw, 11rem);
  line-height: 1;
  color: var(--color-ink);
  opacity: 0.4;
  margin-bottom: clamp(-2.5rem, -1rem - 4vw, -1rem);
}
.js .manifesto__mark { opacity: 0; transform: scale(0.7) rotate(-8deg); }
.js.no-anim .manifesto__mark { opacity: 0.4; transform: none; }
.manifesto__over { color: var(--color-ink); opacity: 0.62; }
.manifesto__quote {
  font-family: var(--font-display);
  font-size: clamp(2rem, 0.9rem + 5.4vw, 5.2rem);
  line-height: 1.1;
  color: var(--color-ink);
  max-width: 26ch;
  margin: var(--sp-6) auto 0;
  text-wrap: balance;
}
.manifesto__quote .w { display: inline-block; will-change: transform, opacity, filter; }
.manifesto__cite {
  position: relative;
  display: inline-block;
  margin: var(--sp-4) auto 0;
  font-size: var(--text-body-sm);
  letter-spacing: 0.04em;
  color: var(--color-ink);
  opacity: 0.62;
}
.manifesto__cite-stroke {
  position: absolute;
  left: 0;
  bottom: -0.5em;
  width: 100%;
  height: 0.6em;
}
.manifesto__cite-stroke path {
  stroke: var(--color-ink);
  stroke-width: 2.5;
  stroke-dasharray: 200;
  stroke-dashoffset: 200;
}
.manifesto__proof {
  margin: clamp(var(--sp-16), 10vh, var(--sp-24)) auto 0;
  max-width: 36rem;
  color: var(--color-ink);
  font-size: var(--text-body-sm);
  line-height: 1.65;
  opacity: 0.86;
}
.manifesto__cta { margin-top: var(--sp-8); display: flex; justify-content: center; }
.manifesto .btn--secondary { border-color: rgba(42, 33, 24, 0.45); }
.manifesto .btn--secondary:hover { background: var(--color-ink); color: var(--color-amber); }

/* ─── 14. HABILIDADES — a constelação ───────────────────────────────────── */
/* Sem fundo próprio (como .hero): o teclado 3D atravessa os espaços vazios
   entre os blocos de habilidade — ver hero-3d.js. Com o fundo opaco herdado
   de .section, o canvas fixo ficava tampado atrás da dobra inteira. */
#skills { background: transparent; }

/* Mesma textura do .hero__bg-image (ver seção 10), mesma receita: fixa e
   abaixo do --z-canvas, para o teclado 3D pintar por cima dela em vez de
   atrás. Aqui o pan lateral não segue o lado do texto — segue o teclado 3D,
   que alterna direita → esquerda → direita ao cruzar os três blocos (ver
   initSkillsBg em site.js, sincronizado com os mesmos ScrollTriggers que
   movem o teclado em hero-3d.js). Começa oculta; só o scroll acende. */
.skills__bg-image {
  position: fixed;
  inset: -22%;
  z-index: 0;
  pointer-events: none;
  background-image: url("https://res.cloudinary.com/dn454izoh/image/upload/f_auto,q_auto,w_2200/v1785193132/textured_engineering_hero_background_hxi79m.png");
  background-size: cover;
  background-position: center;
  opacity: 0;
  will-change: transform, opacity;
}

/* Atmosfera que evita o teclado 3D "duro" sobre o fundo — mesma receita do
   hero (ver .hero__light/.hero__fog/.hero__vignette, seção 10): neblina e
   luz quente ficam ACIMA do canvas 3D (--z-canvas: 1) e abaixo do conteúdo
   da seção, pintando por cima do teclado com cor translúcida em vez de
   deixá-lo como um recorte nítido sobre a textura. O vinhete por cima de
   tudo esmaece as bordas retas da área renderizada contra o creme da
   seção. Fixas, fade e drift lento controlados por initSkillsBg em site.js. */
.skills__fog,
.skills__light {
  position: fixed;
  inset: -16%;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  will-change: transform, opacity;
}
.skills__light {
  background: radial-gradient(circle at 50% 46%, rgba(255, 176, 0, 0.32), transparent 58%);
}
.skills__fog--back {
  background: radial-gradient(ellipse 68% 50% at 30% 60%, rgba(255, 215, 120, 0.32), transparent 70%);
}
.skills__fog--front {
  background: radial-gradient(ellipse 60% 45% at 74% 34%, rgba(255, 251, 239, 0.6), transparent 72%);
}
.skills__vignette {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(ellipse at 50% 46%, transparent 36%, rgba(255, 251, 239, 0.85) 100%);
  will-change: opacity;
}

.skills__wrapper { position: relative; }
#skills-svg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; }
#skills-svg path {
  fill: none;
  stroke: var(--color-amber);
  stroke-width: 2.5;
  stroke-linecap: round;
  opacity: 0.85;
  filter: drop-shadow(0 0 5px rgba(255, 176, 0, 0.45));
}
.skills-path__tip {
  fill: var(--color-amber);
  filter: drop-shadow(0 0 7px rgba(255, 176, 0, 0.9));
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-gesture);
}
.skills-path__tip.is-active { opacity: 1; }
.skills__nodes { position: relative; z-index: 1; display: grid; gap: clamp(var(--sp-16), 12vh, var(--sp-32)); }

.skill-node { display: flex; }
.skill-node[data-align="right"] { justify-content: flex-end; }
.skill-node__content { position: relative; width: 100%; max-width: 34rem; }
/* Numeral romano gigante e quase invisível atrás do bloco — mesmo motivo do
   .act__roman na dobra "Sobre mim", aqui marcando a grande repartição
   (frontend / backend / ofício) em vez do ato. */
.skill-node__roman {
  position: absolute;
  left: -0.05em;
  top: -0.22em;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: clamp(4.5rem, 3vw + 3rem, 7rem);
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--color-ink);
  opacity: 0.035;
  pointer-events: none;
  user-select: none;
  z-index: 0;
}
.skill-node__head, .skill-node__list { position: relative; z-index: 1; }
.skill-node__head { display: flex; align-items: baseline; gap: var(--sp-4); }
.skill-node__num {
  font-family: var(--font-mono);
  font-size: clamp(2.5rem, 1rem + 5vw, 5rem);
  font-weight: 500;
  line-height: 1;
  color: var(--color-amber);
  user-select: none;
}
.skill-node__title { font-family: var(--font-display); font-size: var(--text-h3); }
/* Palavras do título entram de lado como no hero (ver .hero-chapter__line
   .w, seção 10) — precisa de inline-block para o transform pegar. Animado
   por initSkillNodeReveals em site.js. */
.skill-node__title .w { display: inline-block; will-change: transform, opacity; }
.skill-node__lede { margin-top: var(--sp-2); color: var(--color-ink-soft); font-size: var(--text-body-sm); }
.skill-node__list { margin-top: var(--sp-6); display: grid; gap: var(--sp-2); }

.skill-item {
  display: block;
  padding: var(--sp-3);
  margin-inline: calc(var(--sp-3) * -1);
  border-radius: var(--radius-md);
}
.skill-item__name {
  display: block;
  font-weight: 600;
  font-size: var(--text-body);
}

/* ─── 15. TRABALHOS — lista editorial ────────────────────────────────────
   Inspirado em listas de "journal" editorial: linhas separadas por um
   filete (hairline), e a linha em hover se destaca das demais com um
   preenchimento cheio que sangra até a borda do viewport — mesmo
   --grad-ink usado no footer (seção 17) — enquanto as outras permanecem
   discretas, só texto sobre o fundo da seção. Numeral romano fica ao lado
   do título (não atrás, como .act__roman / .skill-node__roman — seções 11
   e 14): aqui a caixa do título só tem a altura de uma linha, então um
   numeral grande centralizado por cima ficava cortado em foco e virava
   uma mancha ilegível no hover. */
.works__list { border-top: 1px solid var(--color-line); }

.work-row {
  position: relative;
  isolation: isolate;
  display: grid;
  gap: var(--sp-4);
  padding-block: clamp(var(--sp-8), 6vw, var(--sp-16));
  border-bottom: 1px solid var(--color-line);
  text-align: center;
  transition: border-color var(--dur-base) var(--ease-gesture);
}
@media (min-width: 900px) {
  .work-row {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    gap: clamp(var(--sp-8), 4vw, var(--sp-16));
  }
  .work-row__body { text-align: left; }
}
.work-row:hover { border-color: transparent; }

/* Sangramento até a borda do viewport (left:50% + width:100vw +
   translateX(-50%)): html/body já usam overflow-x:clip (seção 2) para a
   textura da dobra #box, então esse sangramento não cria scroll horizontal. */
.work-row::before {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  left: 50%;
  width: 100vw;
  transform: translateX(-50%) scaleY(0.92);
  background: var(--grad-ink);
  z-index: -1;
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-gesture), transform var(--dur-base) var(--ease-gesture);
}
.work-row:hover::before { opacity: 1; transform: translateX(-50%) scaleY(1); }

.work-row__head {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(var(--sp-4), 3vw, var(--sp-8));
}
.work-row__roman {
  flex: none;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: clamp(2.5rem, 2vw + 1.75rem, 4rem);
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--color-amber-soft);
  opacity: 0.7;
  user-select: none;
  transition: color var(--dur-base) var(--ease-gesture), opacity var(--dur-base) var(--ease-gesture);
}
.work-row:hover .work-row__roman { color: var(--color-amber); opacity: 1; }

.work-row__title {
  position: relative;
  z-index: 1;
  font-family: var(--font-display);
  font-size: var(--text-h3);
  transition: color var(--dur-base) var(--ease-gesture);
}
.work-row:hover .work-row__title { color: var(--color-cream); }

.work-row__body { position: relative; z-index: 1; }
.work-row__lede {
  color: var(--color-ink-soft);
  font-size: var(--text-body);
  transition: color var(--dur-base) var(--ease-gesture);
}
.work-row:hover .work-row__lede { color: rgba(255, 251, 239, 0.78); }

.work-row__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-6);
  font-size: var(--text-body-sm);
  font-weight: 600;
  color: var(--color-amber-ink);
  transition: color var(--dur-base) var(--ease-gesture);
}
.work-row__cta .btn__arrow { transition: transform var(--dur-fast) var(--ease-gesture); }
.work-row:hover .work-row__cta { color: var(--color-amber); }
.work-row:hover .work-row__cta .btn__arrow { transform: translateX(5px); }

/* ─── 15b. TRABALHOS REAIS — três cases em scroll horizontal ──────────────
   Mesma gramática da dobra "Sobre mim" (seção 11): no desktop a dobra fica
   pinada e os cases deslizam na horizontal, cada um com imagem + texto —
   nada de card grande fechado. O que essa dobra tem a mais é o fio: uma
   rota que se desenha conforme o scroll avança, com uma cabeça luminosa na
   ponta do traço e três paradas (uma por case) que acendem quando o projeto
   chega ao centro. O traço-fantasma por baixo mostra o caminho inteiro
   desde o começo, então dá pra ver que a linha ainda vai crescer.
   O fio assume a cor do case ativo — --cases-accent é trocada por JS
   (initCasesScroll, reveal.js) a partir do --case-accent de cada painel.
   Repouso (mobile / prefers-reduced-motion / sem JS): pilha vertical, com o
   fio virando uma trilha vertical na lateral. */
.cases-scroll {
  --cases-accent: var(--color-amber);
  --cases-rail: clamp(2.25rem, 9vw, 3.25rem);
}
.cases-scroll__pin { position: relative; margin-top: clamp(var(--sp-8), 5vh, var(--sp-16)); }
.cases-scroll__track {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: clamp(var(--sp-16), 9vh, var(--sp-24));
  padding-inline: var(--gutter);
}

/* ── O case: imagem + texto, sem moldura de card ───────────────────────── */
.case-panel { display: flex; flex-direction: column; gap: var(--sp-6); }

.case-panel__media { position: relative; }
/* Mancha na cor do projeto espiando atrás da janela — mesmo elemento de
   .about__portrait::before, mas como nó real (não pseudo) porque o parallax
   de cursor (initCasesParallax) precisa movê-la em velocidade diferente da
   moldura pra ler como profundidade. */
.case-panel__glow {
  position: absolute;
  inset: 9% -4% -9% 4%;
  border-radius: var(--radius-md);
  background: var(--grad-dawn);
  opacity: 0.22;
  z-index: 0;
  pointer-events: none;
}
.case-panel__glow--green { background: linear-gradient(135deg, #BFE8A8 0%, #5FA55C 55%, #35723C 100%); }
.case-panel__glow--red { background: linear-gradient(135deg, #F7B8A0 0%, #D9614A 55%, #A83A2C 100%); }
/* Neon lê mais forte que os outros tons na mesma faixa — por isso mais baixo. */
.case-panel__glow--neon { background: linear-gradient(135deg, #D6F26B 0%, #8FCB2E 55%, #4E8F1E 100%); opacity: 0.17; }

/* --case-accent: a cor de marca do projeto, exposta pro painel inteiro — é
   o que o pontinho da lista, o traço do kicker e (via --cases-accent) o fio
   ao fundo leem. Só em elementos gráficos: em texto esses tons não teriam
   contraste suficiente sobre o creme, então o kicker segue no âmbar-tinta. */
.case-panel--green { --case-accent: #5FA55C; }
.case-panel--red { --case-accent: #D9614A; }
.case-panel--neon { --case-accent: #6FA524; }
/* Tons da página de sistemas de controle: o aço do painel e a ferrugem do
   chão de fábrica, na mesma lógica de acento-por-projeto acima. */
.case-panel__glow--steel { background: linear-gradient(135deg, #B7CFE4 0%, #4B7BA8 55%, #2C5478 100%); }
.case-panel__glow--rust { background: linear-gradient(135deg, #F0C9A5 0%, #C2703A 55%, #8A4620 100%); }
.case-panel--steel { --case-accent: #4B7BA8; }
.case-panel--rust { --case-accent: #C2703A; }
/* Tons da página de aplicações sob medida — três atos do mesmo projeto, cada
   um com seu acento, na mesma lógica de cor-por-painel acima. */
.case-panel__glow--indigo { background: linear-gradient(135deg, #C3C3F2 0%, #5B5BD6 55%, #34348F 100%); }
.case-panel__glow--teal { background: linear-gradient(135deg, #A8DED8 0%, #2E8B84 55%, #175A55 100%); }
.case-panel__glow--plum { background: linear-gradient(135deg, #E7B9D2 0%, #9A4F7A 55%, #632F4D 100%); }
.case-panel--indigo { --case-accent: #5B5BD6; }
.case-panel--teal { --case-accent: #2E8B84; }
.case-panel--plum { --case-accent: #9A4F7A; }

/* Janelinha de navegador: barra com os três pontos + endereço real do
   projeto, e a captura abaixo definindo a própria altura (print de site
   raramente cai exatamente em 16/9 — forçar aspect-ratio sobraria faixa
   vazia ou apertaria o enquadramento). */
.case-panel__frame {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--color-line);
  background: var(--color-paper);
  box-shadow: var(--shadow-2);
  /* Sem transition em transform: o parallax de cursor escreve `transform`
     a cada frame via GSAP — uma transição na mesma propriedade brigaria
     com ele e deixaria o gesto arrastado. */
  transition: box-shadow var(--dur-base) var(--ease-gesture);
}
.case-panel:hover .case-panel__frame { box-shadow: var(--shadow-3); }
.case-panel__bar {
  position: relative;
  flex: none;
  display: flex;
  align-items: center;
  height: 2rem;
  padding-left: 3.2rem;
  padding-right: var(--sp-3);
  border-bottom: 1px solid var(--color-line);
  background: var(--color-cream-dark);
}
.case-panel__bar::before {
  content: "";
  position: absolute;
  left: var(--sp-3);
  top: 50%;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-line-strong);
  box-shadow: 11px 0 var(--color-line-strong), 22px 0 var(--color-line-strong);
  transform: translateY(-50%);
}
.case-panel__url {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  color: var(--color-ink-mute);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.case-panel__frame img { width: 100%; height: auto; }

/* Variante foto — sistemas de controle. Esses projetos rodam dentro da
   planta: não têm endereço público para a barra do navegador, e o registro
   que existe deles é fotografia (o terminal no posto, o painel na parede),
   não captura de tela. Some a barra, e o recorte passa a ser 16/10 fixo —
   as fotos vêm em proporções diferentes (algumas em pé) e sem isso um painel
   ficaria três vezes mais alto que o vizinho. */
.case-panel__frame--photo img {
  aspect-ratio: 16 / 10;
  object-fit: cover;
  object-position: center;
}

/* Selo de confidencialidade no lugar do "Ver projeto": sistema interno não
   tem link para mostrar, e dizer isso é mais honesto que um botão morto. */
.case-panel__seal {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  letter-spacing: 0.08em;
  color: var(--color-ink-mute);
}
.case-panel__seal::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--case-accent, var(--color-amber));
  flex: none;
}

/* ── O texto do case ───────────────────────────────────────────────────── */
.case-panel__text { position: relative; padding-left: var(--sp-8); }
/* Numeral-fantasma atrás do texto — mesmo motivo de .act__roman (Sobre mim)
   e .deliver-mod__watermark, na escala do painel. */
.case-panel__roman {
  position: absolute;
  left: -0.08em; top: -0.22em;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: clamp(3.75rem, 5.5vw, 6rem);
  line-height: 1;
  color: var(--color-ink);
  opacity: 0.045;
  pointer-events: none;
  user-select: none;
  z-index: 0;
}
.case-panel__kicker,
.case-panel__name,
.case-panel__desc,
.case-panel__points,
.case-panel__foot { position: relative; z-index: 1; }
.case-panel__kicker {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  font-family: var(--font-mono);
  font-size: var(--text-overline);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--color-amber-ink);
}
.case-panel__kicker::before {
  content: "";
  flex: none;
  height: 2px;
  width: 1.75rem;
  background: var(--case-accent, var(--color-amber));
  transition: width var(--dur-base) var(--ease-gesture);
}
.case-panel:hover .case-panel__kicker::before { width: 3.25rem; }
.case-panel__name {
  margin-top: var(--sp-2);
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 1.3rem + 1.8vw, 3rem);
  line-height: 1.06;
}
.case-panel__desc {
  margin-top: var(--sp-3);
  max-width: 34ch;
  font-size: var(--text-body-lg);
  line-height: 1.45;
  color: var(--color-ink);
  text-wrap: balance;
}
.case-panel__points { margin-top: var(--sp-6); display: grid; gap: var(--sp-2); }
.case-panel__points li {
  position: relative;
  padding-left: var(--sp-4);
  max-width: 40ch;
  color: var(--color-ink-soft);
  font-size: var(--text-body-sm);
  line-height: 1.55;
}
.case-panel__points li::before {
  content: "";
  position: absolute;
  left: 0.15rem;
  top: 0.62em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--case-accent, var(--color-amber));
}
.case-panel__foot {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-6);
  margin-top: var(--sp-4);
}
.case-panel__tech {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  letter-spacing: 0.08em;
  color: var(--color-ink-mute);
}

/* ── O fio: traço, cabeça e paradas ────────────────────────────────────── */
.cases-curve-svg,
.cases-curve-svg--mobile,
.cases-curve-head,
.cases-curve-stop { display: none; }
.cases-curve-path {
  fill: none;
  stroke: var(--cases-accent);
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: stroke var(--dur-slow) var(--ease-gesture);
  /* O viewBox estica os dois eixos em proporções diferentes (preserveAspectRatio:
     none), então sem isso o stroke-width herdaria essa distorção — mais fino
     nos trechos horizontais do traço do que nos verticais. non-scaling-stroke
     aplica a espessura já em px de tela, igual em qualquer trecho da curva. */
  vector-effect: non-scaling-stroke;
}
.cases-curve-path--main { stroke-width: 3px; opacity: 0.5; }
.cases-curve-path--mobile { stroke-width: 3px; opacity: 0.45; }
/* O caminho inteiro, quase apagado: mostra pra onde a linha ainda vai. */
.cases-curve-path--ghost,
.cases-curve-path--ghost-mobile {
  stroke: var(--color-ink);
  opacity: 0.07;
  transition: none;
}
.cases-curve-path--ghost { stroke-width: 1.5px; }
.cases-curve-path--ghost-mobile { stroke-width: 1.5px; }

/* Cabeça luminosa na ponta do traço — posicionada por JS sobre o próprio
   path (translate em px, relativo ao pin). O anel de fora respira devagar,
   mesmo gesto de --ease-breath usado nos outros elementos "vivos". */
.cases-curve-head {
  position: absolute;
  top: 0; left: 0;
  width: 12px; height: 12px;
  margin: -6px 0 0 -6px;
  border-radius: 50%;
  background: var(--cases-accent);
  opacity: 0;
  z-index: 0;
  pointer-events: none;
  transition: background var(--dur-slow) var(--ease-gesture), opacity var(--dur-base) var(--ease-gesture);
}
.cases-curve-head::after {
  content: "";
  position: absolute;
  inset: -8px;
  border-radius: 50%;
  border: 1px solid var(--cases-accent);
  opacity: 0.4;
  animation: casesHeadBreath 2.6s var(--ease-breath) infinite;
}
@keyframes casesHeadBreath {
  0%, 100% { transform: scale(1); opacity: 0.4; }
  50%      { transform: scale(1.45); opacity: 0.1; }
}

/* Paradas do fio: uma por case, apagadas até o traço chegar nelas. Ficam
   atrás dos painéis (z-index 0) — aparecem nos vãos entre um case e outro,
   como marcos da rota, sem competir com a leitura. */
.cases-curve-stop {
  position: absolute;
  top: 0; left: 0;
  width: 2.15rem; height: 2.15rem;
  margin: -1.075rem 0 0 -1.075rem;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--color-line);
  background: var(--color-cream-dark);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  color: var(--color-ink-mute);
  opacity: 0.5;
  z-index: 0;
  pointer-events: none;
  transition:
    opacity var(--dur-base) var(--ease-gesture),
    border-color var(--dur-base) var(--ease-gesture),
    color var(--dur-base) var(--ease-gesture),
    transform var(--dur-base) var(--ease-gesture);
}
.cases-curve-stop.is-reached {
  opacity: 1;
  border-color: var(--cases-accent);
  color: var(--color-ink);
  box-shadow: 0 0 0 4px rgba(255, 176, 0, 0.08);
}

/* ── Desktop: imagem ao lado do texto (vale também no repouso, sem pin) ── */
@media (min-width: 900px) {
  .case-panel {
    flex-direction: row;
    align-items: center;
    gap: clamp(var(--sp-8), 4vw, var(--sp-16));
  }
  .case-panel--reverse { flex-direction: row-reverse; }
  .case-panel__media { flex: 0 0 46%; }
  .case-panel__text { flex: 1; min-width: 0; }

  /* ── Desktop com scroll horizontal (a dobra pinada) ──────────────────── */
  .cases-scroll.is-horizontal .cases-scroll__pin {
    height: 100vh;
    overflow: hidden;
    display: flex;
    align-items: center;
    margin-top: clamp(var(--sp-12), 6vh, var(--sp-16));
  }
  /* O fio mora numa faixa centralizada verticalmente no pin (não presa ao
     rodapé): cruza por trás dos cases — z-index abaixo de .cases-scroll__track
     (1) e de .case-panel__frame (1) — em vez de correr por baixo do
     conteúdo, então pode ocupar o centro sem cobrir texto nem imagem. */
  .cases-scroll.is-horizontal .cases-curve-svg {
    display: block;
    position: absolute;
    top: 50%;
    left: 0;
    right: 0;
    transform: translateY(-50%);
    width: 100%;
    height: clamp(170px, 26vh, 290px);
    z-index: 0;
    pointer-events: none;
  }
  .cases-scroll.is-horizontal .cases-curve-head { display: block; }
  .cases-scroll.is-horizontal .cases-curve-stop { display: grid; }
  .cases-scroll.is-horizontal .cases-scroll__track {
    flex-direction: row;
    flex-wrap: nowrap;
    width: max-content;
    /* Bem maior que o vão interno do case (imagem↔texto, abaixo): numa tela
       larga aparecem pedaços de dois cases ao mesmo tempo, e é essa
       diferença de respiro — junto com a cor de acento — que diz quais tela
       e texto são do mesmo projeto. */
    gap: clamp(var(--sp-16), 13vw, 14rem);
    /* O primeiro case nasce fora da tela, à direita: o primeiro gesto do
       usuário já é puxar o projeto pra dentro do quadro, igual aos outros. */
    padding-left: 20vw;
    padding-right: clamp(var(--sp-8), 8vw, var(--sp-24));
  }
  .cases-scroll.is-horizontal .case-panel {
    flex: 0 0 min(84vw, 1020px);
    align-items: center;
    gap: clamp(var(--sp-6), 2.5vw, var(--sp-12));
  }
  .cases-scroll.is-horizontal .case-panel__media { flex: 0 0 min(44vw, 520px); width: min(44vw, 520px); }
  .cases-scroll.is-horizontal .case-panel__text { flex: 1; max-width: 44ch; }

  /* Cada case tem sua própria composição — nada de espelhamento uniforme. */
  .cases-scroll.is-horizontal .case-panel--i { margin-top: -3vh; }
  .cases-scroll.is-horizontal .case-panel--ii {
    flex-basis: min(88vw, 1080px);
    margin-top: 4vh;
  }
  .cases-scroll.is-horizontal .case-panel--ii .case-panel__media {
    flex-basis: min(47vw, 560px); width: min(47vw, 560px);
  }
  .cases-scroll.is-horizontal .case-panel--iii {
    flex-basis: min(80vw, 980px);
    margin-top: -1vh;
  }
  .cases-scroll.is-horizontal .case-panel--iii .case-panel__media {
    flex-basis: min(41vw, 490px); width: min(41vw, 490px);
  }
}

/* ── Mobile: pilha vertical com o fio correndo na lateral ──────────────── */
@media (max-width: 899px) {
  .cases-curve-svg--mobile {
    display: block;
    position: absolute;
    top: 0;
    left: var(--gutter);
    width: var(--cases-rail);
    height: 100%;
    z-index: 0;
    pointer-events: none;
  }
  .cases-scroll__track {
    padding-left: calc(var(--gutter) + var(--cases-rail) + var(--sp-2));
    gap: clamp(var(--sp-12), 8vh, var(--sp-16));
  }
  .case-panel__text { padding-left: var(--sp-6); }
  .case-panel__desc { font-size: var(--text-body); }
  .case-panel__url { font-size: 0.64rem; }
  /* No case II o HTML inverte texto/imagem (para o row-reverse do desktop).
     Sem o reverse, a coluna do mobile exporia essa ordem crua e um case
     começaria pelo texto enquanto os outros começam pela tela. Traz a
     imagem de volta pro topo visualmente, sem mexer na ordem de leitura
     (DOM) para leitor de tela. */
  .case-panel--reverse .case-panel__media { order: -1; }

  /* Mesma variação orgânica do desktop (lá é baseRotate, via JS, porque
     convive com o parallax de scroll) — aqui, sem parallax, um giro fixo e
     bem pequeno por CSS já basta pra tirar o alinhamento perfeitinho. */
  .case-panel--i .case-panel__media { transform: rotate(-1.1deg); }
  .case-panel--ii .case-panel__media { transform: rotate(0.9deg); }
  .case-panel--iii .case-panel__media { transform: rotate(-0.7deg); }
}

/* Transição "wipe" em tela cheia — um círculo cresce a partir de um ponto
   até cobrir a tela, a troca acontece por baixo enquanto ela está coberta, e
   o círculo só se apaga depois. Usado hoje na navegação entre páginas
   (#page-wipe, index.html); escala/posição vêm por GSAP inline, aqui só o
   estado de repouso. */
.case-wipe {
  position: fixed;
  top: 0;
  left: 0;
  width: 2.5rem;
  height: 2.5rem;
  margin-top: -1.25rem;
  margin-left: -1.25rem;
  border-radius: 50%;
  background: var(--color-amber);
  transform: scale(0);
  opacity: 1;
  pointer-events: none;
  z-index: 950;
  will-change: transform, opacity;
}

/* ─── STACK TÍPICA — preenchimento de fundo da dobra ──────────────────────
   A dobra é só texto + grade, sem foto — reaproveita o vocabulário que o
   resto do site já usa pra dar corpo a uma seção "vazia": o glow radial
   âmbar pontual de .closing-cta/.hero__light (dois, em cantos
   opostos, pra dar profundidade sem virar um flood só) e um glifo-fantasma
   gigante e quase invisível (mesmo motivo de .deliver-mod__watermark /
   .stack-cell__watermark, só que em escala de seção): um "</>" de código,
   coerente com o assunto da dobra ("como eu construo"). Tudo abaixo do
   conteúdo (z-index 0) e não-interativo. */
.stack-section { position: relative; overflow: hidden; }
.stack-section > .wrap { position: relative; z-index: 1; }

.stack-section__glow {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  top: -12%;
  left: -8%;
  width: min(46vw, 34rem);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 176, 0, 0.16) 0%, transparent 68%);
}
.stack-section__glow--alt {
  top: auto;
  left: auto;
  bottom: -18%;
  right: -10%;
  width: min(50vw, 38rem);
  background: radial-gradient(circle, rgba(255, 215, 120, 0.22) 0%, transparent 70%);
}

.stack-section__glyph {
  position: absolute;
  z-index: 0;
  top: -6%;
  right: -6%;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: clamp(9rem, 5rem + 14vw, 18rem);
  line-height: 1;
  color: var(--color-ink);
  opacity: 0.028;
  pointer-events: none;
  user-select: none;
  white-space: nowrap;
}

@media (max-width: 899px) {
  .stack-section__glyph { top: -3%; font-size: clamp(6rem, 4rem + 16vw, 11rem); }
}

/* ─── STACK TÍPICA — grade editorial com numeral-fantasma ────────────────
   Referência: seis tecnologias em grade 3 colunas × 2 linhas, cada uma com
   seu algarismo romano em serifa grande e quase transparente atrás do
   nome (mesmo motivo de .deliver-mod__watermark, seção 16), separadas por
   uma única régua horizontal entre as duas linhas. Ordem do DOM é I→VI e
   a grade usa grid-auto-flow:column pra empilhar os pares (I/II, III/IV,
   V/VI) em cada coluna — sem precisar reordenar nada por breakpoint. */
.stack-grid { position: relative; margin-top: clamp(var(--sp-16), 9vh, var(--sp-24)); }

.stack-grid__divider {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1px;
  background: var(--color-line-strong);
  transform-origin: left;
}

.stack-grid__list {
  position: relative;
  z-index: 1;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-rows: repeat(2, auto);
  grid-auto-flow: column;
  column-gap: clamp(var(--sp-6), 4vw, var(--sp-12));
  row-gap: clamp(var(--sp-12), 7vw, var(--sp-24));
}

.stack-cell { position: relative; }

/* Numeral fica atrás do nome (não empilhado acima dele) — mesmo truque de
   .deliver-mod__watermark: glifo grande e quase transparente, levemente
   deslocado pra trás/acima do texto, que fica por cima (z-index) o
   cobrindo na maior parte. Discreto por design: opacidade baixa e sem
   disputar leitura com o nome/legenda. */
.stack-cell__watermark {
  position: absolute;
  top: -0.3em;
  left: -0.04em;
  font-family: var(--font-display);
  font-size: clamp(3rem, 1.5rem + 4.5vw, 4.75rem);
  line-height: 0.8;
  color: var(--color-ink);
  opacity: 0.09;
  pointer-events: none;
  user-select: none;
  z-index: 0;
}

.stack-cell__name {
  position: relative;
  z-index: 1;
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-h4);
  color: var(--color-ink);
}

.stack-cell__desc {
  position: relative;
  z-index: 1;
  display: block;
  margin-top: var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  letter-spacing: 0.02em;
  color: var(--color-ink-mute);
}

.stack-cell:hover .stack-cell__name { color: var(--color-amber-ink); }
.stack-cell:hover .stack-cell__watermark { opacity: 0.14; }

@media (max-width: 899px) {
  .stack-grid__divider { display: none; }
  .stack-grid__list {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    grid-auto-flow: row;
    row-gap: 0;
  }
  .stack-cell {
    padding-top: var(--sp-4);
    padding-bottom: clamp(var(--sp-8), 5vw, var(--sp-12));
    border-bottom: 1px solid var(--color-line);
  }
  .stack-cell--06 { border-bottom: none; }
  .stack-cell__watermark { font-size: clamp(2.5rem, 1.5rem + 8vw, 3.75rem); }
}

/* Fechamento — clara, não o mergulho escuro que tinha antes (fica
   melhor pra essa página: o creme mais denso separa a dobra do fundo sem
   pesar visualmente, mesmo truque do .section--alt). O âmbar segue como
   acento pontual (stroke, halo, botão) — o flood cheio fica reservado pro
   .manifesto, que essa página já usa em "Por que isso importa". */
.closing-cta {
  position: relative;
  z-index: var(--z-section);
  overflow: hidden;
  background: var(--color-cream-dark);
  color: var(--color-ink);
  padding-block: clamp(var(--sp-24), 16vh, var(--sp-32));
  text-align: center;
}
.closing-cta__halo {
  position: absolute;
  right: -10%;
  top: -30%;
  width: min(60vw, 40rem);
  aspect-ratio: 1;
  background: radial-gradient(circle, rgba(255, 176, 0, 0.18) 0%, transparent 65%);
  pointer-events: none;
  z-index: 0;
  transform-origin: 35% 35%;
}
.closing-cta__inner { position: relative; z-index: 1; max-width: 36rem; }
.closing-cta__stroke { width: clamp(120px, 20vw, 220px); margin: 0 auto var(--sp-6); }
.closing-cta__over { color: var(--color-ink-mute); }
.closing-cta__title {
  margin-top: var(--sp-4);
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 1.3rem + 4vw, 3.75rem);
  line-height: 1.1;
  color: var(--color-ink);
}
.closing-cta__title .w { display: inline-block; will-change: transform, opacity, filter; }
.closing-cta__lede {
  margin: var(--sp-4) auto 0;
  max-width: 32ch;
  color: var(--color-ink-soft);
  font-size: var(--text-body);
}
.closing-cta__action {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3);
  margin-top: var(--sp-8);
}
.closing-cta__action .btn {
  width: 100%;
  box-sizing: border-box;
}
@media (max-width: 32rem) {
  .closing-cta__action { grid-template-columns: 1fr; }
}

/* ─── 15c. PÁGINAS DE TRABALHO — hero narrativo ───────────────────────────
   A dobra de abertura de sites-institucionais.html é o MESMO palco
   cinematográfico do hero do index.html (seção 10): seção alta + palco
   sticky, um progresso suavizado por lerp movendo câmera, névoa, luz,
   capítulos e HUD. Por isso ela veste `.hero` inteiro — nada aqui redefine o
   motor, só registra as diferenças da versão de trabalho:

   · cinco capítulos em vez de quatro → trilho mais longo;
   · sem teclado 3D na frente da textura → o fundo é a protagonista (aparece
     mais forte, ver reveal.js) e a vinheta fecha um pouco mais para segurar
     o contraste do texto;
   · a capa é capa de página (numeral romano, filete, overline, H1, lede e
     ações), não a assinatura pessoal do index;
   · cada porquê entra colado ao seu capítulo como uma nota
     (.hero-chapter__note), no lugar da antiga lista .reason-block. */
.hero--work .hero__track { height: 560svh; }

/* Sem o teclado 3D no meio da cena, a textura pode aparecer mais — e a
   vinheta compensa fechando um pouco mais nas bordas, com um véu extra no
   topo para o texto nunca disputar com a navbar fixa. */
.hero--work .hero__vignette {
  background:
    linear-gradient(to bottom, rgba(255, 251, 239, 0.72) 0%, transparent 20%),
    radial-gradient(ellipse at 50% 45%, transparent 26%, rgba(255, 251, 239, 0.88) 96%);
}

/* ── Capa (capítulo de repouso) ─────────────────────────────────────────── */
.hero--work .hero-chapter--rest > div { position: relative; }

/* Numeral da categoria — mesmo motivo-fantasma de .act__roman /
   .skill-node__roman, aqui centralizado atrás do título como a marca d'água
   de uma capa. Exceção deliberada ao mono dos outros numerais: nesta escala
   as hastes do mono viram retângulos sólidos atrás do título; o display
   (mesmo Italiana do H1) mantém o traço fino e o numeral continua fantasma.
   Fica em z-index negativo dentro do próprio capítulo — que já é contexto de
   empilhamento por causa do will-change —, então nunca sobe sobre o texto. */
.hero-rest__roman {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -54%);
  font-family: var(--font-display);
  font-size: clamp(11rem, 27vw, 25rem);
  line-height: 1;
  letter-spacing: 0.04em;
  color: var(--color-ink);
  opacity: 0.07;
  pointer-events: none;
  user-select: none;
  z-index: -1;
}

/* Filete curto acima do overline: o eco centralizado do .sec-head__rule das
   outras dobras. Cresce na entrada da capa (reveal.js). */
.hero-rest__rule {
  display: block;
  width: 4.5rem;
  height: 1px;
  margin: 0 auto var(--sp-6);
  background: var(--color-line-strong);
  transform-origin: center;
}
.hero-rest__over {
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--color-amber-ink);
  margin-bottom: var(--sp-4);
}
/* "Sites Institucionais" é bem mais longo que "Rafael Gois": mesmo display,
   escala menor, para caber em duas linhas sem estourar a caixa. */
.hero--work .hero-rest__name {
  font-size: clamp(2.4rem, 1rem + 6vw, 5.6rem);
  line-height: 1.02;
}
.hero--work .hero-rest__tag { max-width: 40rem; }

/* ── Capítulos ──────────────────────────────────────────────────────────── */
/* Capítulos I e IV: cartões de título centralizados — abrem e fecham a
   história no mesmo porte, com o mesmo Italiana do resto do site. */
.hero--work .hero-chapter[data-chapter="busca"] .hero-chapter__line,
.hero--work .hero-chapter[data-chapter="continuidade"] .hero-chapter__line {
  font-size: clamp(2rem, 1rem + 3.8vw, 3.9rem);
  line-height: 1.18;
  letter-spacing: 0.01em;
  max-width: 22ch;
}
/* Capítulos II e III (nos cantos): a frase é mais longa que as asserções
   curtas do index, então ganham mais largura de linha que os 15ch padrão. */
.hero--work .hero-chapter[data-chapter="credibilidade"] .hero-chapter__line { max-width: 24ch; }
.hero--work .hero-chapter[data-chapter="clareza"] .hero-chapter__line { max-width: 21ch; }

/* Nota do porquê — o que era um .reason-block da lista antiga, agora colado
   ao capítulo que o justifica. Sem caixa nem cartão: só o ícone em círculo
   (mesmo desenho de .reason-block__icon) e duas linhas de texto, para não
   pesar sobre a textura de fundo. Entra depois da frase, no scrub do próprio
   capítulo (reveal.js). */
.hero-chapter__note {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-4);
  max-width: 44ch;
  margin: clamp(var(--sp-8), 5.5vh, var(--sp-12)) auto 0;
  text-align: left;
  will-change: transform, opacity;
}
.hero-chapter__note-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  flex-shrink: 0;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-line-strong);
  background: var(--color-cream);
  color: var(--color-amber-ink);
}
.hero-chapter__note-icon .ic { width: 20px; height: 20px; }
.hero-chapter__note-text {
  font-size: var(--text-body-sm);
  line-height: 1.55;
  color: var(--color-ink-soft);
}
.hero-chapter__note-text strong {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--color-ink);
  margin-bottom: var(--sp-2);
}

/* No palco (desktop), a nota acompanha o lado do capítulo: à esquerda ela
   fica colada à borda esquerda; à direita, espelha o ícone e o alinhamento —
   o mesmo gesto de "encostar no canto" do texto. */
.hero--work:not(.is-flow) .hero-chapter[data-side] .hero-chapter__note { margin-inline: 0; }
.hero--work:not(.is-flow) .hero-chapter[data-side="right"] .hero-chapter__note {
  flex-direction: row-reverse;
  text-align: right;
  margin-left: auto;
}

/* ── Repouso: fluxo vertical (mobile / prefers-reduced-motion) ──────────── */
.hero--work.is-flow .hero-rest__roman {
  font-size: clamp(9rem, 42vw, 16rem);
  opacity: 0.04;
}
.hero--work.is-flow .hero-chapter__note { max-width: 34rem; }

/* "O que é entregue" — dossiê editorial, não card de SaaS. Cada módulo é um
   verbete de índice: numeral-fantasma em serifa gigante no fundo, número de
   índice em mono, título com máscara de cortina (revelada por JS), corpo
   largo pra leitura confortável. Grid assimétrica de 12 colunas — cada
   módulo ocupa colunas diferentes, ecoando o respiro/deslocamento de uma
   página editorial em vez do alinhamento repetitivo de uma grade de cards.
   Entrada é feita por timeline dedicada em reveal.js (não pelo [data-reveal]
   genérico); os estados iniciais abaixo ficam junto da seção 19. */
.deliver-index { margin-top: clamp(var(--sp-8), 5vw, var(--sp-12)); }

.deliver-mod {
  position: relative;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  row-gap: var(--sp-4);
  padding-block: clamp(var(--sp-12), 6vw, var(--sp-24));
}
.deliver-mod__rule {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 1px;
  background: var(--color-line);
  transform-origin: left;
}
.deliver-mod__watermark {
  position: absolute;
  z-index: 0;
  font-family: var(--font-display);
  font-size: clamp(7.5rem, 3rem + 16vw, 15rem);
  line-height: 0.8;
  color: var(--color-amber-ink);
  opacity: 0.09;
  pointer-events: none;
  user-select: none;
}
/* Numeral sempre do mesmo lado do conteúdo do módulo (ver alternância de
   grid abaixo): ímpares à esquerda, pares à direita. */
.deliver-mod--01 .deliver-mod__watermark { top: -0.32em; left: -0.05em; }
.deliver-mod--02 .deliver-mod__watermark { top: -0.18em; right: -0.05em; text-align: right; }
.deliver-mod--03 .deliver-mod__watermark { bottom: -0.3em; left: -0.07em; }
.deliver-mod--04 .deliver-mod__watermark { bottom: -0.22em; right: -0.05em; text-align: right; }
.deliver-mod--05 .deliver-mod__watermark { top: -0.15em; left: 6%; }

.deliver-mod__num {
  position: relative;
  z-index: 1;
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: var(--text-body-sm);
  letter-spacing: 0.06em;
  color: var(--color-amber-ink);
}
.deliver-mod__content { position: relative; z-index: 1; }
.deliver-mod__head { display: flex; align-items: center; gap: var(--sp-3); }
.deliver-mod__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  flex-shrink: 0;
  border-radius: var(--radius-full);
  background: rgba(255, 176, 0, 0.14);
  color: var(--color-amber-ink);
}
.deliver-mod__content h3 { font-family: var(--font-body); font-weight: 700; font-size: var(--text-h5); }
.deliver-mod__mask { display: block; overflow: hidden; }
.deliver-mod__mask-line { display: block; will-change: transform; }
.deliver-mod__body { margin-top: var(--sp-3); }
.deliver-mod__body p { max-width: 50ch; color: var(--color-ink-soft); font-size: var(--text-body-sm); line-height: 1.65; }
.deliver-mod__proof {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-4);
  padding-left: var(--sp-4);
  border-left: 2px solid var(--color-amber);
  font-family: var(--font-mono);
  font-size: var(--text-body-sm);
  font-weight: 600;
  color: var(--color-amber-ink);
}
.deliver-mod__stars { display: inline-flex; gap: 2px; }
.deliver-mod__stars .ic { width: 13px; height: 13px; fill: var(--color-amber); stroke: var(--color-amber-deep); }

/* Chip do módulo 01 — endereço de e-mail num cartão delicado, ancorado à
   direita/embaixo do bloco (respiro assimétrico como a referência). */
.deliver-mod__chip {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  align-self: start;
  margin-top: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
  background: rgba(255, 253, 247, 0.6);
  backdrop-filter: blur(6px);
  color: var(--color-ink-soft);
}
.deliver-mod__chip .ic { color: var(--color-amber-ink); }
.deliver-mod__chip code { font-family: var(--font-mono); font-size: var(--text-caption); letter-spacing: 0.02em; }

/* Proof do módulo 04 — cartão com QR ao lado do texto, o momento mais
   "objeto físico" do índice (a plaquinha real que vai no balcão). */
.deliver-mod__proof--qr {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  margin-top: var(--sp-6);
  padding: var(--sp-4) var(--sp-6);
  max-width: 24rem;
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
  background: rgba(255, 253, 247, 0.5);
}
.deliver-mod__proof--qr .ic { width: 2.25rem; height: 2.25rem; flex-shrink: 0; color: var(--color-amber-ink); }
.deliver-mod__proof--qr span { font-family: var(--font-mono); font-size: var(--text-caption); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-ink); }

@media (min-width: 800px) {
  .deliver-mod { grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: clamp(var(--sp-6), 3vw, var(--sp-8)); }
  .deliver-mod__num { grid-row: 1; padding-top: 0.3em; }
  .deliver-mod__content { grid-row: 1; }

  /* Zigue-zague estrito: ímpares (01, 03, 05) com conteúdo à esquerda,
     pares (02, 04) com conteúdo à direita — numeral sempre colado ao
     conteúdo, do mesmo lado. */
  .deliver-mod--01 .deliver-mod__num,
  .deliver-mod--03 .deliver-mod__num,
  .deliver-mod--05 .deliver-mod__num { grid-column: 1 / 3; }
  .deliver-mod--01 .deliver-mod__content,
  .deliver-mod--03 .deliver-mod__content,
  .deliver-mod--05 .deliver-mod__content { grid-column: 3 / 8; }

  .deliver-mod--02 .deliver-mod__content,
  .deliver-mod--04 .deliver-mod__content { grid-column: 6 / 11; }
  .deliver-mod--02 .deliver-mod__num,
  .deliver-mod--04 .deliver-mod__num { grid-column: 11 / 13; }

  /* Espelho de verdade para os módulos à direita — não basta deslocar a
     coluna: o título, o ícone e o parágrafo têm que colar na borda direita
     do bloco (perto do numeral), senão o olho lê tudo ancorado à esquerda
     da própria coluna e o conjunto parece "centralizado" em vez de à
     direita. Ícone migra pra depois do título; texto vira rio à direita
     (ragged-left) e cada caixa ganha margin-left:auto pra empurrar contra
     a borda — o oposto exato do que os ímpares fazem à esquerda. */
  .deliver-mod--02 .deliver-mod__content,
  .deliver-mod--04 .deliver-mod__content { text-align: right; }
  .deliver-mod--02 .deliver-mod__head,
  .deliver-mod--04 .deliver-mod__head { justify-content: flex-end; }
  .deliver-mod--02 .deliver-mod__icon,
  .deliver-mod--04 .deliver-mod__icon { order: 2; }
  .deliver-mod--02 .deliver-mod__content h3,
  .deliver-mod--04 .deliver-mod__content h3 { order: 1; }
  .deliver-mod--02 .deliver-mod__body p,
  .deliver-mod--04 .deliver-mod__body p { margin-left: auto; }
  .deliver-mod--04 .deliver-mod__proof--qr { margin-left: auto; flex-direction: row-reverse; text-align: right; }

  .deliver-mod--01 .deliver-mod__chip { grid-column: 9 / 13; grid-row: 1; align-self: end; }
}

@media (max-width: 799px) {
  .deliver-mod__num { font-size: 1.5rem; }
}

/* ─── 16. CONTATO ───────────────────────────────────────────────────────── */
.contact__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(var(--sp-12), 6vw, var(--sp-16));
}
@media (min-width: 900px) { .contact__grid { grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); } }

.contact__block-head { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-8); }
.contact__block-head .rule { height: 2px; width: 2rem; background: var(--color-amber); }

.contact-form { display: grid; gap: var(--sp-6); }

.field { display: grid; gap: var(--sp-2); }
.field__label { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-2); }
.field__bar { position: relative; }
.field__bar::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 2px;
  background: var(--color-amber);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-base) var(--ease-gesture);
}
.field__bar:focus-within::after { transform: scaleX(1); }
.field__control {
  width: 100%;
  min-height: 44px;
  padding: 0.6rem 0.2rem;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--color-line-strong);
  border-radius: 0;
  color: var(--color-ink);
  transition: border-color var(--dur-fast) var(--ease-gesture);
}
.field__control::placeholder { color: var(--color-ink-mute); opacity: 0.7; }
.field__control:hover { border-bottom-color: var(--color-ink-soft); }
.field__control:focus { outline: none; }
textarea.field__control { resize: vertical; min-height: 120px; line-height: 1.6; }

/* Status do formulário — classes exigidas por contact-form.js */
.contact-form-status {
  font-size: var(--text-body-sm);
  line-height: 1.5;
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
}
.contact-form-status--success { color: var(--color-success); background: var(--color-success-bg); border-color: rgba(61, 107, 75, 0.25); }
.contact-form-status--error { color: var(--color-error); background: var(--color-error-bg); border-color: rgba(164, 66, 59, 0.25); }
.contact-form-status__mailto { color: inherit; text-decoration: underline; }

.contact-info__list { display: grid; gap: var(--sp-8); }
.contact-item { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--sp-4); align-items: start; }
.contact-item__rule { height: 1px; width: 2rem; background: var(--color-line-strong); margin-top: 0.85rem; transition: width var(--dur-base) var(--ease-gesture), background var(--dur-base) var(--ease-gesture); }
.contact-item:hover .contact-item__rule { width: 3rem; background: var(--color-amber); }
.contact-item h3 { font-family: var(--font-body); font-weight: 600; font-size: var(--text-h5); }
.contact-item__links { display: grid; gap: var(--sp-1); margin-top: var(--sp-2); }
.contact-info__ornament {
  display: flex; align-items: center; justify-content: center; gap: var(--sp-4);
  margin-top: var(--sp-12);
  padding-top: var(--sp-8);
  border-top: 1px solid var(--color-line);
}
.contact-info__ornament .line { height: 1px; width: 4rem; background: var(--color-line-strong); }
.contact-info__ornament .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-amber); }

/* ─── 17. FOOTER ────────────────────────────────────────────────────────── */
.site-footer {
  position: relative;
  z-index: var(--z-section);
  background: var(--grad-ink);
  color: var(--color-cream);
  padding: clamp(var(--sp-16), 10vh, var(--sp-24)) 0 var(--sp-8);
  overflow: hidden;
}
.site-footer::after {
  content: "";
  position: absolute; right: -8%; top: -25%;
  width: 46%; aspect-ratio: 1;
  background: radial-gradient(circle, rgba(255, 176, 0, 0.22), transparent 65%);
  pointer-events: none;
}
.site-footer__inner { position: relative; }
.site-footer__name {
  font-family: var(--font-display);
  font-size: clamp(2.6rem, 1rem + 8vw, 7rem);
  line-height: 0.98;
}
.site-footer__name em { font-style: normal; color: var(--color-amber); }
.site-footer__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-8);
  margin-top: clamp(var(--sp-12), 8vh, var(--sp-16));
}
@media (min-width: 720px) { .site-footer__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.site-footer h4 {
  font-family: var(--font-mono);
  font-size: var(--text-overline);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255, 251, 239, 0.5);
  margin-bottom: var(--sp-4);
}
.site-footer__grid ul { display: grid; gap: var(--sp-2); }
.site-footer__grid a, .site-footer__grid p { color: rgba(255, 251, 239, 0.78); font-size: var(--text-body-sm); }
.site-footer__grid a:hover { color: var(--color-cream); }
.site-footer .link-line { color: rgba(255, 251, 239, 0.78); }
.site-footer__bottom {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--sp-4);
  margin-top: clamp(var(--sp-12), 8vh, var(--sp-16));
  padding-top: var(--sp-8);
  border-top: 1px solid rgba(255, 251, 239, 0.14);
  font-size: var(--text-caption);
  color: rgba(255, 251, 239, 0.5);
}

/* ─── 18. CURSOR CUSTOM ─────────────────────────────────────────────────── */
.cursor__dot, .cursor__ring {
  position: fixed;
  top: 0; left: 0;
  border-radius: 50%;
  pointer-events: none;
  z-index: var(--z-cursor);
  opacity: 0;
}
.cursor__dot { width: 7px; height: 7px; background: var(--color-amber); }
/* Escala do anel (repouso/hover/press) é controlada via GSAP em initCursor
   (site.js) — ele já é dono do `transform` por causa do quickTo que segue o
   mouse, então só as propriedades abaixo (não-transform) mudam por CSS. */
.cursor__ring {
  width: 34px; height: 34px;
  border: 1.5px solid var(--color-amber-ink);
  background: transparent;
  transition: border-color var(--dur-slow) var(--ease-breath), background var(--dur-slow) var(--ease-breath);
}
body.has-custom-cursor.is-cursor-hover .cursor__ring {
  border-color: var(--color-amber);
  background: rgba(255, 176, 0, 0.14);
}
@media (hover: hover) and (pointer: fine) {
  body.has-custom-cursor, body.has-custom-cursor a, body.has-custom-cursor button { cursor: none; }
}

/* ─── 19. REVELAÇÕES ────────────────────────────────────────────────────── */
/* O estado escondido só existe quando há JS para revelar (classe .js posta
   inline no <head>). Sem JS, o conteúdo aparece normalmente. */
.js [data-reveal] { opacity: 0; transform: translateY(28px); }
.js.no-anim [data-reveal] { opacity: 1; transform: none; }

/* Timeline bespoke do "O que é entregue" (reveal.js) — cada peça do módulo
   entra em seu próprio momento, não como bloco único. */
.js .deliver-mod__watermark { opacity: 0; transform: scale(0.85); }
.js .deliver-mod__num { opacity: 0; transform: translateY(24px); }
.js .deliver-mod__icon { opacity: 0; transform: scale(0.5) rotate(-18deg); }
.js .deliver-mod__mask-line { transform: translateY(110%); }
.js .deliver-mod__body p,
.js .deliver-mod__proof,
.js .deliver-mod__chip { opacity: 0; transform: translateY(28px); }
.js.no-anim .deliver-mod__watermark { opacity: 0.09; transform: none; }
.js.no-anim .deliver-mod__num,
.js.no-anim .deliver-mod__icon,
.js.no-anim .deliver-mod__body p,
.js.no-anim .deliver-mod__proof,
.js.no-anim .deliver-mod__chip { opacity: 1; transform: none; }
.js.no-anim .deliver-mod__mask-line { transform: none; }

/* Células de "Stack típica" — stagger dedicado (initStackGrid), não o
   [data-reveal] genérico. A régua entre as duas linhas usa [data-rule],
   então já herda a animação de scaleX genérica lá de cima. */
.js .stack-cell { opacity: 0; transform: translateY(24px); }
.js.no-anim .stack-cell { opacity: 1; transform: none; }

/* Fechamento ("Próximo passo") — timeline dedicada em reveal.js. */
.js .closing-cta__halo { opacity: 0; }
.js .closing-cta__over,
.js .closing-cta__lede,
.js .closing-cta__action .btn { opacity: 0; transform: translateY(20px); }
.js .closing-cta__title { overflow: hidden; opacity: 0; }
.js.no-anim .closing-cta__halo,
.js.no-anim .closing-cta__over,
.js.no-anim .closing-cta__lede,
.js.no-anim .closing-cta__action .btn,
.js.no-anim .closing-cta__title { opacity: 1; transform: none; }
.js.no-anim .closing-cta__title { overflow: visible; }

/* ─── 20. DEPOIMENTOS (oculto — reativar removendo [hidden]) ─────────────── */
.testimonials__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-8);
}
@media (min-width: 900px) { .testimonials__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.testimonial-item {
  padding: var(--sp-8);
  border-radius: var(--radius-md);
  background: var(--color-paper);
  border: 1px solid var(--color-line);
  box-shadow: var(--shadow-1);
}
.testimonial-item blockquote { font-family: var(--font-display); font-size: var(--text-h5); line-height: 1.5; color: var(--color-ink-soft); }
.testimonial-item figcaption { display: flex; align-items: center; gap: var(--sp-3); margin-top: var(--sp-6); }
.testimonial-item__avatar { width: 42px; height: 42px; border-radius: 50%; background: var(--grad-dawn); flex-shrink: 0; }
[hidden] { display: none !important; }

/* ─── 21. RESPONSIVO ────────────────────────────────────────────────────── */
@media (max-width: 899px) {
  .navbar__links, .navbar__cta { display: none; }
  .navbar__burger { display: flex; }

  /* O 3D é desktop-only (≥900px, igual ao gate de three-entry.js):
     no mobile o hero e a dobra viram composição 2D. */
  .three-composite-root,
  #hero-3d-container,
  .box-left-bottom-3d-panel, .box-left-top-3d-panel,
  .box-right-bottom-3d-panel, .box-right-top-3d-panel,
  #box-left-img, #box-right-img, #box-icaro { display: none; }

  #box { min-height: 0; padding-block: var(--sp-24); }
  /* Mantém nowrap: o texto tem que extrapolar a moldura no mobile também,
     igual à piada visual do desktop. Mas o corpo precisa ficar bem menor que
     no desktop — em telas estreitas o clamp anterior (até 6.5rem) fazia cada
     linha ("PENSANDO", "DA CAIXA") passar da largura da viewport, cortando
     nas bordas da tela (não só na moldura) e criando um "arrastão" horizontal
     visual conforme a headline se desembaralhava durante o scroll. */
  .box-headline { font-size: clamp(2.6rem, 1.6rem + 7vw, 4rem); }

  .skill-node[data-align="right"] { justify-content: flex-start; }
  #skills-svg { display: none; }

  .skills__nodes { gap: var(--sp-16); }
  .skill-node__list { gap: 0; }

  /* Sobre mim: no mobile os três atos empilham. Miniatura ao lado do texto
     em vez do retrato em corpo inteiro repetido três vezes — era isso que
     inflava a dobra na vertical. */
  .about-scroll__pin { position: relative; }
  /* Linha torta vertical atrás da coluna de miniaturas — versão mobile do
     fio que corre atrás dos atos no desktop. Sem pin: ela só ocupa a altura
     real do track e se desenha conforme o scroll passa pela seção
     (site.js). Largura igual à da miniatura para ficar "encaixada" atrás
     dela, aparecendo só nos vãos entre um ato e outro. */
  .about-curve-svg--mobile {
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    width: clamp(4.5rem, 22vw, 6.5rem);
    height: 100%;
    z-index: 0;
    pointer-events: none;
  }
  .about-scroll__track { position: relative; z-index: 1; gap: var(--sp-12); }
  .about-panel {
    flex-direction: row;
    align-items: flex-start;
    text-align: left;
    gap: var(--sp-4);
  }
  .about-panel__media { width: clamp(4.5rem, 22vw, 6.5rem); flex: 0 0 auto; }
  .about-panel__text { padding-top: var(--sp-1); }
  /* No Ato II o HTML inverte texto/imagem (para o row-reverse do desktop) —
     sem o reverse, o row simples do mobile expõe essa ordem crua e o texto
     nasce colado à esquerda, sem o recuo da miniatura como nos Atos I e III.
     Força a miniatura de volta para o início visualmente, sem mexer na
     ordem de leitura (DOM) para leitor de tela. */
  .about-panel--reverse .about-panel__media { order: -1; }
  .about__portrait figcaption { display: none; }
  .act { padding-left: var(--sp-6); }

  /* Cluster do Ato I: no mobile a coluna é estreita demais para as satélites. */
  .about-panel--i .about-panel__media {
    width: clamp(5.5rem, 28vw, 8rem);
  }
  .about__portrait--cluster { padding: 0; }
  .about__portrait-sat { display: none; }
}

@media (min-width: 900px) {
  .skills__nodes { gap: clamp(var(--sp-24), 18vh, 16rem); }
}

/* ─── 22. REDUCED MOTION ────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .sig-stroke path { stroke-dashoffset: 0 !important; }
  .mark-amber { background-size: 100% 0.62em; }
  .js [data-reveal] { opacity: 1; transform: none; }
  .js .manifesto__mark { opacity: 0.4; transform: none; }
  .js .closing-cta__halo,
  .js .closing-cta__over,
  .js .closing-cta__lede,
  .js .closing-cta__action .btn,
  .js .closing-cta__title { opacity: 1; transform: none; }
  .js .closing-cta__title { overflow: visible; }
  .hero__cue-line::after { animation: none; }
  .cursor__dot, .cursor__ring { display: none; }
}

/* ─── 23. PRINT ─────────────────────────────────────────────────────────── */
@media print {
  .navbar, .hero__cue, .mobile-menu, .cursor__dot, .cursor__ring,
  .three-composite-root, .hero__bg-image, .grain::after { display: none !important; }
  body { background: #fff; color: #000; }
  .section, .manifesto, .site-footer { background: #fff !important; color: #000 !important; padding-block: 1.5rem; }
}

/* ─── 24. ÂNCORAS ───────────────────────────────────────────────────────── */
/* A navbar é fixa: âncoras precisam de folga para não ficar sob ela. */
section[id], header[id] { scroll-margin-top: 88px; }

/* Em contextos centralizados, o max-width de `p` desloca o texto para a
   esquerda: a caixa é mais estreita que o container. margin-inline:auto
   recentra a caixa antes de o text-align agir. */
.hero__stage p,
.manifesto__inner p { margin-inline: auto; }

/* ─── 25. LEGIBILIDADE SOBRE O TECLADO 3D ───────────────────────────────────
   O teclado desenha atrás do texto do hero. Um halo creme mantém o contraste
   do texto sem precisar de véu opaco (que apagaria o 3D). */
.hero-chapter__line,
.hero-rest__name,
.hero-rest__tag,
.hero-rest__role,
.hero-rest__over,
.hero-chapter__note-text,
.hero-chapter__over {
  text-shadow: 0 2px 20px rgba(255, 251, 239, 0.95), 0 0 56px rgba(255, 251, 239, 0.8);
}
