/* ═══════════════════════════════════════════════════════════════════════
   TAMBORÉ 3 — sistema visual
   Direção: tipografia oversized de alto contraste, muito espaço negativo,
   grading cinematográfico. Tudo que é cor, escala ou ritmo mora no :root.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  /* ── paleta ───────────────────────────────────────────────────────── */
  --ink:        #06080D;   /* noite profunda — fundo de tudo            */
  --ink-soft:   #0C1119;
  --bone:       #F4EFE6;   /* texto principal                           */
  --bone-dim:   rgba(244, 239, 230, .58);
  --bone-faint: rgba(244, 239, 230, .30);
  --line:       rgba(244, 239, 230, .16);
  --brass:      #E3B27C;   /* acento quente — entardecer                */
  --brass-deep: #C08B52;
  --cool:       #8FB4D8;   /* acento frio — noite                       */

  /* ── tipografia ───────────────────────────────────────────────────── */
  --serif: 'Instrument Serif', 'Times New Roman', serif;
  --sans:  'Inter Tight', system-ui, -apple-system, sans-serif;
  --mono:  'JetBrains Mono', ui-monospace, 'SF Mono', monospace;

  --t-hero:    clamp(3.4rem, 12.2vw, 13rem);
  --t-display: clamp(2.3rem, 5.6vw, 5.6rem);
  --t-display-sm: clamp(2rem, 4.2vw, 4rem);
  --t-lede:    clamp(1.02rem, 1.32vw, 1.32rem);
  --t-body:    clamp(.94rem, 1.05vw, 1.06rem);
  --t-mono:    clamp(.66rem, .74vw, .74rem);

  /* ── ritmo ────────────────────────────────────────────────────────── */
  --gutter: clamp(1.5rem, 6vw, 7.5rem);
  --stack:  clamp(1.1rem, 2vw, 2rem);

  /* ── estado do palco (escrito por js/story.js) ────────────────────── */
  --scrim: .48;
  --vig:   .30;
  --spot:  0;
  --grade-warm: 0;
  --grade-cool: 0;
}

/* ═══════════════════════════ reset ═══════════════════════════ */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: auto;         /* o scroll suave é do Lenis, não do browser */
}

body {
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--sans);
  font-weight: 300;
  font-size: var(--t-body);
  line-height: 1.62;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Lenis mantém o scroll nativo do documento; nada de altura fixa aqui. */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }

img { display: block; max-width: 100%; height: auto; }
h1, h2, h3, p, dl, dd, figure, blockquote { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
button, input, textarea { font: inherit; color: inherit; }

::selection { background: var(--brass); color: var(--ink); }

:focus-visible {
  outline: 1px solid var(--brass);
  outline-offset: 4px;
  border-radius: 2px;
}

.mono {
  font-family: var(--mono);
  font-weight: 400;
  font-size: var(--t-mono);
  letter-spacing: .22em;
  text-transform: uppercase;
}

.serif { font-family: var(--serif); font-style: italic; font-weight: 400; }

.sep {
  display: inline-block;
  margin: 0 .7em;
  opacity: .4;
}
.sep::before { content: '·'; }

/* ═══════════════════════════ palco fixo ═══════════════════════════
   As fotos não rolam. A página rola sobre elas. É o que separa um
   passeio guiado de um carrossel de slides.                          */

.stage {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: var(--ink);
  pointer-events: none;
  contain: strict;
}

.stage__plates { position: absolute; inset: 0; }

.plate {
  position: absolute;
  inset: 0;
  opacity: 0;
  transform: scale(1.06);
  backface-visibility: hidden;
  visibility: hidden;
}

/* Só a cena em curso e as vizinhas imediatas ficam promovidas. `will-change`
   em 24 camadas de tela cheia custaria mais memória de compositor do que
   qualquer ganho — a dica vale justamente por ser escassa. */
.plate.is-live {
  visibility: visible;
  will-change: opacity, transform;
}

/* Profundidade de campo por classe, não por frame: o browser rasteriza o
   desfoque uma vez e a transição CSS cuida do resto. Animar `filter` a 60fps
   numa imagem de tela cheia rasterizaria de novo a cada quadro. */
body.fx-depth .plate.is-behind {
  filter: blur(5px) brightness(.86);
}
body.fx-depth .plate {
  transition: filter .9s cubic-bezier(.16, 1, .3, 1);
}

.plate img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focus, 50% 50%);
  /* placeholder LQIP fica atrás enquanto o JPEG grande decodifica */
  background-size: cover;
  background-position: var(--focus, 50% 50%);
}

/* Camada WebGL: a FOTOGRAFIA (com a câmera percorrendo cada ambiente) mais
   céu, sol, lua, estrelas, brumas e o glow das luzes.

   Blend normal, não `screen`: agora que a foto vive dentro do canvas, a soma
   de luz acontece no próprio buffer (o céu desenha com AdditiveBlending por
   cima da imagem). O canvas tem alpha, então enquanto uma textura não chegou
   a plate do DOM aparece por baixo como placeholder. */
.stage__gl {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity .8s ease;
}
body.gl-ready .stage__gl { opacity: 1; }

/* Com o canvas no ar, as plates viram só rede de segurança: nada de desfoque
   nem de promoção a camada própria para algo que está coberto. */
body.gl-ready .plate { will-change: auto; }
body.gl-ready .plate.is-behind { filter: none; }

/* Grading: quente no entardecer, frio à noite. Duas camadas somadas
   para não perder a saturação da foto original. */
.stage__grade {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(227,178,124, .55) 0%, rgba(192,139,82, .18) 55%, transparent 100%),
    linear-gradient(0deg,   rgba(20, 40, 74, .50) 0%,  rgba(24, 44, 80, .12) 60%,  transparent 100%);
  opacity: 1;
  mix-blend-mode: soft-light;
  /* os dois gradientes são controlados por máscara de opacidade em JS */
}
.stage__grade::before,
.stage__grade::after {
  content: '';
  position: absolute;
  inset: 0;
}
.stage__grade::before {
  background: linear-gradient(180deg, rgba(240,180,110,.60), rgba(200,120,60,.10) 62%, transparent);
  opacity: var(--grade-warm);
  mix-blend-mode: soft-light;
}
.stage__grade::after {
  background: linear-gradient(180deg, rgba(90,140,210,.42), rgba(20,40,80,.30) 70%, rgba(10,20,45,.35));
  opacity: var(--grade-cool);
  mix-blend-mode: soft-light;
}

/* Spot dramático — usado no home theater */
.stage__spot {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 62% 58% at 55% 52%, transparent 0%, rgba(4,6,10,.55) 62%, rgba(3,4,8,.88) 100%);
  opacity: var(--spot);
}

/* Scrim de legibilidade: sem ele, texto claro sobre foto clara não lê. */
.stage__scrim {
  position: absolute;
  inset: 0;
  opacity: var(--scrim);
  /* Duas camadas: uma vertical, que ancora topo e rodapé, e uma lateral do
     lado onde o texto mora. A lateral precisa ser bem mais forte do que
     parece necessário — a fachada em pleno dia é quase branca, e texto claro
     sobre ela some. */
  --dir: 90deg;
  background:
    linear-gradient(180deg, rgba(6,8,13,.74) 0%, rgba(6,8,13,.12) 32%, rgba(6,8,13,.22) 60%, rgba(6,8,13,.88) 100%),
    linear-gradient(var(--dir), rgba(6,8,13,.92) 0%, rgba(6,8,13,.70) 26%, rgba(6,8,13,.30) 52%, transparent 84%);
}
.stage--right .stage__scrim { --dir: 270deg; }
.stage--center .stage__scrim {
  background:
    linear-gradient(180deg, rgba(6,8,13,.70) 0%, rgba(6,8,13,.26) 38%, rgba(6,8,13,.36) 60%, rgba(6,8,13,.86) 100%),
    radial-gradient(ellipse 74% 62% at 50% 50%, rgba(6,8,13,.58), transparent 74%);
}

.stage__vignette {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 78% 74% at 50% 48%, transparent 42%, rgba(3,4,8,.9) 100%);
  opacity: var(--vig);
}

.stage__grain {
  position: absolute;
  inset: -50%;
  opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain 6s steps(6) infinite;
  will-change: transform;
}
@keyframes grain {
  0%   { transform: translate(0, 0) }
  20%  { transform: translate(-3%, 2%) }
  40%  { transform: translate(2%, -3%) }
  60%  { transform: translate(-2%, -2%) }
  80%  { transform: translate(3%, 1%) }
  100% { transform: translate(0, 0) }
}

/* ═══════════════════════════ preloader ═══════════════════════════ */

.preloader {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  background: var(--ink);
}

.preloader__inner { text-align: center; width: min(76vw, 26rem); }

.preloader__mark {
  font-family: var(--serif);
  font-size: clamp(1.9rem, 5vw, 3.2rem);
  letter-spacing: .1em;
  line-height: 1;
  margin-bottom: 1rem;
}

.preloader__sub {
  color: var(--bone-faint);
  margin-bottom: 2.4rem;
}

.preloader__track {
  height: 1px;
  background: var(--line);
  overflow: hidden;
}
.preloader__track i {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--brass);
  transform-origin: 0 50%;
}

body.is-loading { overflow: hidden; }
body.is-loading main, body.is-loading .topbar, body.is-loading .rail { opacity: 0; }

/* ═══════════════════════════ chrome ═══════════════════════════ */

.topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: clamp(1.1rem, 2.2vw, 2rem) var(--gutter);
  transition: transform .55s cubic-bezier(.16, 1, .3, 1);
}

/* Recolhe ao descer, volta ao subir. Além de tirar o chrome da frente da
   fotografia, evita a colisão com os números grandes da ficha técnica
   passando por baixo. Só transform — a opacidade é do preloader. */
.topbar.is-hidden { transform: translateY(-108%); }

/* Faixa própria atrás do chrome. `mix-blend-mode: difference` seria elegante
   sobre preto ou branco, mas a fotografia é quase toda meio-tom — e ali a
   diferença devolve exatamente o cinza que some contra o fundo. Um degradê
   curto e honesto resolve em qualquer cena. */
.topbar::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg, rgba(6,8,13,.62), rgba(6,8,13,.24) 55%, transparent);
  pointer-events: none;
}

.topbar__mark {
  display: flex;
  align-items: baseline;
  gap: .8rem;
  text-decoration: none;
  color: inherit;
}
.topbar__name {
  font-family: var(--serif);
  font-size: clamp(1.05rem, 1.5vw, 1.35rem);
  letter-spacing: .06em;
}
.topbar__loc { color: var(--bone-dim); }
@media (max-width: 640px) { .topbar__loc { display: none } }

/* Trilho de capítulos */
.rail {
  position: fixed;
  right: clamp(.9rem, 2vw, 2rem);
  top: 50%;
  transform: translateY(-50%);
  z-index: 40;
  padding: .9rem .6rem;
  border-radius: 999px;
  background: rgba(6, 8, 13, .28);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.rail__list { display: grid; gap: .55rem; justify-items: end; }

.rail__item a {
  display: flex;
  align-items: center;
  gap: .7rem;
  text-decoration: none;
  color: var(--bone);
  padding: .18rem 0;
}
.rail__label {
  font-family: var(--mono);
  font-size: .58rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  opacity: 0;
  transform: translateX(6px);
  transition: opacity .4s ease, transform .4s ease;
  white-space: nowrap;
}
.rail__tick {
  display: block;
  width: 16px;
  height: 1px;
  background: currentColor;
  opacity: .32;
  transition: width .5s cubic-bezier(.16,1,.3,1), opacity .4s ease;
}
.rail__item a:hover .rail__label,
.rail__item.is-active .rail__label { opacity: .85; transform: none; }
.rail__item a:hover .rail__tick { opacity: .7; width: 24px; }
.rail__item.is-active .rail__tick { opacity: 1; width: 32px; }

@media (max-width: 720px) { .rail { display: none } }

/* Legenda da foto ativa */
.caption {
  position: fixed;
  left: var(--gutter);
  bottom: clamp(1.1rem, 2.4vw, 2.2rem);
  z-index: 30;
  font-family: var(--mono);
  font-size: .6rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--bone-dim);
  max-width: min(70vw, 24rem);
  opacity: 0;
  pointer-events: none;
}
.caption::before {
  content: '';
  display: inline-block;
  width: 14px;
  height: 1px;
  background: var(--brass);
  vertical-align: middle;
  margin-right: .8rem;
}
@media (max-width: 720px) { .caption { display: none } }

/* ═══════════════════════════ botões ═══════════════════════════ */

.btn {
  --btn-bg: transparent;
  --btn-fg: var(--bone);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: .82rem 1.6rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--mono);
  font-size: var(--t-mono);
  letter-spacing: .18em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  overflow: hidden;
  transition: border-color .4s ease, color .4s ease;
}
.btn > span { position: relative; z-index: 1; }
.btn::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--bone);
  transform: scaleY(0);
  transform-origin: 50% 100%;
  transition: transform .55s cubic-bezier(.16,1,.3,1);
}
.btn:hover { border-color: transparent; color: var(--ink); }
.btn:hover::before { transform: scaleY(1); }

.btn--solid {
  background: var(--brass);
  border-color: var(--brass);
  color: var(--ink);
}
.btn--solid::before { background: var(--bone); }

/* ═══════════════════════════ capítulos ═══════════════════════════ */

main { position: relative; z-index: 10; }

.chapter {
  position: relative;
  /* --len é escrito por js/story.js a partir de data-len */
  height: calc(var(--len, 200) * 1vh);
}

.chapter__stick {
  position: sticky;
  top: 0;
  height: 100vh;
  display: grid;
  align-items: center;
  padding: clamp(6rem, 12vh, 9rem) var(--gutter) clamp(4.5rem, 10vh, 7rem);
}

/* Capítulos de conteúdo denso (ficha, contato) rolam de verdade: a altura
   passa a ser a do conteúdo, e o data-len vira apenas um piso. A timeline
   mestra mede o layout real, então crescer aqui não desalinha o resto. */
.chapter--sheet, .chapter--close {
  height: auto;
  min-height: calc(var(--len, 140) * 1vh);
}

.chapter__stick--flow {
  position: relative;
  height: auto;
  min-height: 100vh;
  align-content: center;
}

.copy { max-width: min(46rem, 92vw); }
.copy--left   { justify-self: start; }
.copy--right  { justify-self: end;    text-align: right; }
.copy--center { justify-self: center; text-align: center; }

/* O bloco que desfaz o alinhamento à direita em telas estreitas vive no fim
   desta seção, depois de .eyebrow, .lede e .notes — media query não soma
   especificidade, então quem vier por último vence. Ver "alinhamento
   responsivo" logo abaixo de .notes. */

/* ── eyebrow ── */
.eyebrow {
  display: flex;
  align-items: center;
  gap: .9rem;
  font-family: var(--mono);
  font-size: var(--t-mono);
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--bone-dim);
  margin-bottom: clamp(1.4rem, 3vw, 2.4rem);
}
.copy--right .eyebrow  { justify-content: flex-end; }
.copy--center .eyebrow { justify-content: center; }
.eyebrow .mono { color: var(--brass); }
.eyebrow .mono::after {
  content: '';
  display: inline-block;
  width: 26px;
  height: 1px;
  background: var(--brass);
  vertical-align: middle;
  margin-left: .9rem;
  opacity: .6;
}

/* ── títulos ── */

/* Halo de contraste. Raio largo e alpha baixo: não se lê como sombra, mas
   segura o serifado itálico em brass quando ele cai sobre uma parede clara
   e quente — exatamente onde o scrim sozinho não alcança. */
.h-hero, .h-display {
  text-shadow: 0 2px 44px rgba(4, 6, 11, .55), 0 1px 3px rgba(4, 6, 11, .26);
}
.lede, .notes li, .eyebrow, .pledge, .specs li, .figure dd {
  text-shadow: 0 1px 24px rgba(4, 6, 11, .58);
}

.h-hero {
  font-family: var(--serif);
  font-weight: 400;
  font-size: var(--t-hero);
  line-height: .92;
  letter-spacing: -.02em;
  margin: 0 0 clamp(2rem, 5vh, 4rem);
}
.h-hero .line { display: block; overflow: hidden; }
.h-hero .serif { font-style: italic; color: var(--brass); }

.h-hero--close { font-size: clamp(2.8rem, 8.4vw, 8rem); }

.h-display {
  font-family: var(--serif);
  font-weight: 400;
  font-size: var(--t-display);
  line-height: 1.02;
  letter-spacing: -.015em;
  margin: 0 0 clamp(1.4rem, 3vh, 2.4rem);
  text-wrap: balance;
}
.h-display--sm { font-size: var(--t-display-sm); }
.h-display .serif { color: var(--brass); }

/* linhas fatiadas para o stagger */
.split-line { display: block; overflow: hidden; }
.split-line > span { display: block; will-change: transform, opacity; }

/* palavras fatiadas */
.split-word {
  display: inline-block;
  will-change: transform, opacity;
}
.split-mask { display: inline-block; overflow: hidden; vertical-align: bottom; }

/* ── corpo ── */
.lede {
  font-size: var(--t-lede);
  line-height: 1.66;
  color: var(--bone-dim);
  max-width: 38ch;
  text-wrap: pretty;
}
.lede--center { margin-inline: auto; }
.lede--wide   { max-width: 52ch; }
.copy--right .lede { margin-left: auto; }

.hero { max-width: min(58rem, 94vw); }
.hero__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: clamp(1.6rem, 4vw, 4rem);
}

.hint {
  display: flex;
  align-items: center;
  gap: .9rem;
  color: var(--bone-faint);
  white-space: nowrap;
}
.hint__line {
  display: block;
  width: 40px;
  height: 1px;
  background: currentColor;
  transform-origin: 0 50%;
  animation: hint 2.6s cubic-bezier(.7,0,.3,1) infinite;
}
@keyframes hint {
  0%, 100% { transform: scaleX(.35); opacity: .4 }
  50%      { transform: scaleX(1);   opacity: 1 }
}

/* ── notas numeradas ── */
.notes {
  margin-top: clamp(1.8rem, 4vh, 3rem);
  display: grid;
  gap: .1rem;
  max-width: 34rem;
}
.notes li {
  display: flex;
  align-items: baseline;
  gap: 1.1rem;
  padding: .82rem 0;
  border-top: 1px solid var(--line);
  font-size: var(--t-body);
  color: var(--bone-dim);
}
.notes li:last-child { border-bottom: 1px solid var(--line); }
.notes .mono { color: var(--brass); flex: none; }
.copy--right .notes li { flex-direction: row-reverse; }

/* ── alinhamento responsivo ─────────────────────────────────────────────
   Abaixo de 860px não há largura para uma coluna à direita: o capítulo
   "gourmet" volta a alinhar à esquerda. Tudo que se alinhava à direita
   precisa voltar junto — inclusive o scrim, ou o degradê escurece o lado
   vazio e deixa o texto sobre a parte clara da foto.
   Este bloco fica depois das regras que ele desfaz: media query não soma
   especificidade, então a ordem no arquivo é o que decide.               */
@media (max-width: 860px) {
  .copy--right           { justify-self: start; text-align: left; }
  .copy--right .eyebrow  { justify-content: flex-start; }
  .copy--right .lede     { margin-left: 0; }
  .copy--right .notes li { flex-direction: row; }
  .stage--right .stage__scrim { --dir: 90deg; }
}

/* ═══════════════════════════ ficha técnica ═══════════════════════════ */

.sheet { width: min(76rem, 100%); margin-inline: auto; }
.sheet__head { margin-bottom: clamp(2.5rem, 6vh, 4.5rem); }

.figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
  gap: clamp(1.6rem, 3vw, 2.6rem);
  margin-bottom: clamp(3rem, 8vh, 6rem);
}
.figure { border-top: 1px solid var(--line); padding-top: 1.2rem; }
.figure__n {
  display: flex;
  align-items: baseline;
  gap: .3rem;
  font-family: var(--serif);
  font-size: clamp(2.6rem, 5vw, 4.6rem);
  line-height: .95;
  letter-spacing: -.02em;
}
.figure__pre { color: var(--bone-faint); font-size: .55em; }
.figure__u {
  font-family: var(--sans);
  font-weight: 300;
  font-size: clamp(.85rem, 1.1vw, 1.05rem);
  letter-spacing: .02em;
  color: var(--brass);
  margin-left: .18em;
}
.figure dd {
  margin-top: .85rem;
  color: var(--bone-faint);
  letter-spacing: .16em;
  line-height: 1.5;
}

.sheet__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
}
@media (max-width: 860px) { .sheet__grid { grid-template-columns: 1fr } }

.specs { display: grid; }
.specs li {
  padding: 1rem 0;
  border-top: 1px solid var(--line);
  color: var(--bone-dim);
  font-size: var(--t-body);
}
.specs li:last-child { border-bottom: 1px solid var(--line); }
.specs b { color: var(--bone); font-weight: 500; }

/* A vista aérea nasce com 311px de largura — é o que existe. Limitar a
   caixa ao tamanho nativo evita a interpolação que a deixaria borrada ao
   lado de fotos de 1620px. */
.plan {
  border: 1px solid var(--line);
  padding: .7rem;
  max-width: 340px;
  justify-self: end;
}
@media (max-width: 860px) { .plan { justify-self: start; } }
.plan img {
  width: 100%;
  filter: grayscale(.35) contrast(1.1) brightness(.85);
  mix-blend-mode: luminosity;
}
.plan figcaption {
  margin-top: .8rem;
  color: var(--bone-faint);
  text-align: center;
}

/* ═══════════════════════════ fechamento ═══════════════════════════ */

.close { width: min(72rem, 100%); margin-inline: auto; }

.pledge {
  margin: clamp(2rem, 5vh, 3.4rem) 0 clamp(2rem, 4vh, 3rem);
  padding-left: 1.4rem;
  border-left: 1px solid var(--brass);
  font-family: var(--serif);
  font-size: clamp(1.15rem, 1.8vw, 1.7rem);
  font-style: italic;
  line-height: 1.4;
  color: var(--bone);
}

/* ── formulário ── */
.form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.1rem, 2.4vw, 2rem);
  max-width: 46rem;
}
@media (max-width: 640px) { .form { grid-template-columns: 1fr } }
.field--wide, .form__foot, .form__note { grid-column: 1 / -1; }

.field { display: grid; gap: .55rem; }
.field label { color: var(--bone-faint); }
.field .opt { text-transform: none; letter-spacing: .06em; opacity: .7; }

.field input, .field textarea {
  width: 100%;
  padding: .8rem 0;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
  font-family: var(--sans);
  font-size: var(--t-body);
  font-weight: 300;
  resize: vertical;
  transition: border-color .4s ease;
}
.field input::placeholder, .field textarea::placeholder { color: var(--bone-faint); }
.field input:focus, .field textarea:focus {
  outline: none;
  border-bottom-color: var(--brass);
}
.field.is-invalid input, .field.is-invalid textarea { border-bottom-color: #C4665A; }

.form__foot {
  display: flex;
  flex-wrap: wrap;
  gap: .9rem;
  margin-top: .6rem;
}
.form__note { color: var(--bone-faint); min-height: 1.4em; }
.form__note.is-error { color: #D98B80; }

.footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: clamp(4rem, 10vh, 8rem);
  padding-top: 1.6rem;
  border-top: 1px solid var(--line);
  color: var(--bone-faint);
}
.footer a { color: inherit; text-decoration: none; transition: color .3s ease; }
.footer a:hover { color: var(--bone); }

/* ═══════════════════════════ estados iniciais de animação ═══════════════════════════ */

.js [data-reveal] { opacity: 0; transform: translateY(18px); }
.js .split-line > span { transform: translateY(105%); }
.js .split-word { opacity: 0; transform: translateY(85%); }

/* Sem WebGL o site continua inteiro — só perde a camada atmosférica. */
body.no-webgl .stage__gl { display: none; }
body.no-webgl .stage__grade { opacity: .8; }

/* ═══════════════════════════ acessibilidade ═══════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .stage__grain { animation: none; opacity: .03; }
  .hint__line { animation: none; transform: scaleX(1); }
  .js [data-reveal],
  .js .split-line > span,
  .js .split-word { opacity: 1 !important; transform: none !important; }
  * { scroll-behavior: auto !important; }
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  padding: 1rem 1.4rem;
  background: var(--bone);
  color: var(--ink);
}
.skip:focus { left: 1rem; top: 1rem; }
