/* =========================================================
   Bemorrow.today — o site depois do sol

   A estrutura é a do fantasy.co, seção por seção:
     intro      frase em duas vozes + marca de cliente que troca
     galeria    frase presa no meio, três colunas em paralaxe
     manifesto  coluna estreita que se abre em cinza
     painéis    palco de tela cheia que troca de mídia; títulos
                passam por cima acendendo letra a letra
     12 anos    mídia de tela cheia que escurece + frase de uma
                palavra por linha + trabalhos flutuando
     studio     frase centrada + a janela do sol, que cresce
     contato    o painel claro, que sobe com paralaxe

   Fundo preto. O céu da hero não aparece mais daqui para baixo
   (site.js desliga o .cosmos): ele só volta no fim, dentro da
   janela de .story, com um sol próprio.

   Movimento: só transform, opacity, filter e clip-path, sempre a
   partir de números que o site.js escreve. Os estados escondidos
   são gated por .has-js — sem JS nada fica invisível.
   ========================================================= */

:root{
  --ink:    #0A0A0B;

  /* a segunda voz das frases (o cinza do Fantasy). .5 sobre o preto
     dá 4.8:1 — passa até como texto de corpo, e as frases são display */
  --mute:   rgba(247,240,228,.5);
  --dim:    rgba(247,240,228,.52);
  --line:   rgba(247,240,228,.12);

  /* as duas medidas do Fantasy, reescaladas: a frase (41.7px em 1440)
     e o título de painel (116.7px em 1440) */
  --st:   clamp(1.65rem, 2.6vw + .25rem, 2.9rem);
  --mega: clamp(3rem, 8.1vw, 8.6rem);

  --bay:    clamp(96px, 16svh, 200px);
  --bay-lg: clamp(140px, 26svh, 300px);
}

/* ─────────────  O PRETO QUE SOBE  ─────────────
   O site começa 60svh antes do fim da descida e sobe por cima dela:
   o topo é um degradê de 42svh que vai do transparente ao preto, então
   o céu escurece em vez de ser cortado. Daí para baixo, preto chapado. */

.site{
  position: relative;
  margin-top: -60svh;
  background: linear-gradient(to bottom, rgba(0,0,0,0) 0, #000 42svh);
  /* enquanto o topo transparente passa por cima da hero, ele não pode
     roubar o clique do "start a project" que ainda está na tela */
  pointer-events: none;
}
.site > *{ pointer-events: auto; }
.site > .intro{ pointer-events: none; }
.intro__grid{ pointer-events: auto; }

.wrap{ max-width: 1440px; margin-inline: auto; padding-inline: var(--gutter); }

.sr{
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

section[id]{ scroll-margin-top: 0; }

/* a biblioteca de símbolos: existe só para ser referenciada */
.lib{ position: absolute; width: 0; height: 0; overflow: hidden; }
svg text{ font-family: var(--sans); }
svg .t-serif{ font-family: var(--display); }

/* ─────────────  A FRASE  ─────────────
   Uma grotesca só, em duas vozes: a primeira em creme, o resto em cinza. */

.st{
  margin: 0;
  font-family: var(--sans); font-weight: 500;
  font-size: var(--st); line-height: 1.1; letter-spacing: -.026em;
  color: var(--cream);
  text-wrap: pretty;
}
.st .t1{ color: var(--cream); }
.st .t2{ color: var(--mute); }

/* ── a frase partida ──
   site.js embrulha cada palavra (ou letra) num .u com o seu --i, põe o
   total em --n e o passo em --s, e escreve UM número por quadro: --m.
   Cada unidade decide sozinha se já chegou a vez dela — nenhuma classe
   trocada por quadro, nenhum listener por palavra. O texto inteiro
   continua num .sr para leitor de tela; o partido é aria-hidden.      */

.split .u{ display: inline-block; }
.split .wd{ display: inline-block; white-space: nowrap; }
.split .wd .u{ display: inline; }            /* letras: inline, para o kerning sobreviver */

.has-js .split .u{
  --lit: clamp(0, calc((var(--m, 1) * (var(--n) + var(--s)) - var(--i)) / var(--s)), 1);
  opacity: calc(.06 + var(--lit) * .94);
  filter: blur(calc((1 - var(--lit)) * 9px));
  transform: translate3d(0, calc((1 - var(--lit)) * .14em), 0);
}
.has-js .split .wd .u{ transform: none; filter: blur(calc((1 - var(--lit)) * 14px)); }
/* acesa por inteiro, a frase larga filter e transform: parada, ela não
   precisa de camada de efeito nenhuma (site.js põe .is-done) */
.has-js .split.is-done .u,
.has-js .split.is-done .wd .u{ opacity: 1; filter: none; transform: none; }

/* ─────────────  BOTÃO E LINK  ───────────── */

.btn{
  display: inline-flex; align-items: center; gap: .6em;
  padding: .86em 1.2em; border-radius: 10px;
  font-family: var(--sans); font-size: .92rem; font-weight: 500;
  line-height: 1; letter-spacing: -.005em;
  text-decoration: none; color: var(--cream);
  background: rgba(247,240,228,.14);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  transition: background-color .45s var(--ease), color .45s var(--ease), transform .45s var(--ease);
}
.btn i{ display: inline-block; font-style: normal; transition: transform .45s var(--ease); }
a.btn:hover, a.btn:focus-visible{ background: var(--cream); color: #000; }
a.btn:hover i, a.btn:focus-visible i{ transform: translateX(4px); }

.ln{
  position: relative; display: inline-flex; align-items: baseline; gap: .55em;
  padding-bottom: 4px; text-decoration: none; color: var(--cream);
  border-bottom: 1px solid var(--line);
  transition: color .45s var(--ease);
}
.ln::after{
  content: ''; position: absolute; left: 0; right: 0; bottom: -1px;
  height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: left center;
  transition: transform .55s var(--ease);
}
.ln:hover::after, .ln:focus-visible::after{ transform: scaleX(1); }
.ln span{ display: inline-block; transition: transform .45s var(--ease); }
.ln:hover span, .ln:focus-visible span{ transform: translateY(-3px); }

/* ─────────────  PEÇAS  ─────────────
   Toda peça de trabalho é um .tile: um retângulo escuro com a mídia em
   SVG por cima, recortada (slice) como uma foto seria. */

.tile{
  position: relative; margin: 0; overflow: hidden;
  aspect-ratio: var(--ar, 4/5);
  border-radius: clamp(10px, 1vw, 16px);
  background: #0E0E10;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.05);
}
.tile > svg{ position: absolute; inset: 0; display: block; width: 100%; height: 100%; }

.tile--violet { background: radial-gradient(120% 90% at 50% 18%, #2E2580 0%, #16123F 52%, #0A0918 100%); }
.tile--ember  { background: radial-gradient(90% 70% at 50% 56%, #4B2320 0%, #1C0E0E 58%, #0A0606 100%); }
.tile--lime   { background: radial-gradient(100% 90% at 70% 30%, #262B12 0%, #10120A 60%, #070805 100%); }
.tile--night { background: radial-gradient(100% 90% at 60% 30%, #0C2430 0%, #061218 60%, #030809 100%); }
.tile--ink    { background: #121214; }
.tile--orbital{ background: radial-gradient(100% 90% at 40% 40%, #3A1B0E 0%, #170C07 58%, #0A0605 100%); }
.tile--char   { background: radial-gradient(110% 100% at 50% 40%, #1A1C20 0%, #0D0E10 70%, #08090A 100%); }

/* as duas únicas animações dentro dos símbolos: pequenas, e desenhadas
   nas coordenadas do próprio símbolo (transform-box: view-box).
   Animação de SVG nunca roda no compositor, e basta uma na thread
   principal para o navegador recalcular todas as outras a cada quadro —
   as estrelas da hero junto. Então elas só andam enquanto alguma seção
   que as mostra está na tela (site.js põe .lib-live no <html>).
   A pausa vai por variável, não por seletor: cada <use> desenha uma
   cópia numa árvore de sombra, onde ".has-js .lm-rings" não alcança —
   mas a herança atravessa o <use>. */
.lm-rings{ transform-origin: 120px 268px; animation: breathe2 5.5s ease-in-out infinite alternate; }
.mk-h    { transform-origin: 300px 50px;  animation: tilt 4.6s ease-in-out infinite alternate; }
.lm-rings, .mk-h{ animation-play-state: var(--lib-play, running); }
.has-js:not(.lib-live) .site{ --lib-play: paused; }
@keyframes breathe2{ from{ transform: scale(.94); opacity: .7; } to{ transform: scale(1.05); opacity: 1; } }
@keyframes tilt    { from{ transform: rotate(-5deg); } to{ transform: rotate(7deg); } }

/* =========================================================
   01 · INTRO
   ========================================================= */

.intro{ padding: 40svh 0 var(--bay); }
.intro__grid{ display: grid; gap: 40px; align-items: start; }
@media (min-width: 861px){
  .intro__grid{ grid-template-columns: minmax(0, 1fr) auto; }
}
.intro__st{ max-width: 15.5em; }
.intro__st .t1{ display: block; }

/* a marca que troca sozinha: cinco logos tipográficos empilhados; um
   laço de CSS acende um por vez, e só enquanto a seção está na tela */
.marks{ position: relative; width: 13rem; height: 3.2rem; justify-self: end; }
.mark{
  position: absolute; right: 0; top: 0; height: 100%;
  display: inline-flex; align-items: center; gap: .32em;
  font-size: 1.75rem; line-height: 1; white-space: nowrap;
  color: var(--cream);
  opacity: 0;
}
.mark:first-child{ opacity: 1; }
.has-js .mark{
  opacity: 0;
  animation: markCycle 10s var(--ease) infinite both;
  animation-delay: calc(var(--i) * 2s);
  animation-play-state: paused;
}
.has-js .intro.is-live .mark{ animation-play-state: running; }
@keyframes markCycle{
  0%  { opacity: 0; filter: blur(8px); transform: translate3d(0, 10px, 0); }
  4%  { opacity: 1; filter: blur(0);   transform: none; }
  17% { opacity: 1; filter: blur(0);   transform: none; }
  21% { opacity: 0; filter: blur(8px); transform: translate3d(0, -10px, 0); }
  100%{ opacity: 0; filter: blur(8px); transform: translate3d(0, -10px, 0); }
}
.mark svg{ flex: none; width: .9em; height: .9em; color: #8C7DFF; }
.mark--aster  { font-weight: 600; letter-spacing: -.05em; }
.mark--lumen  { gap: .06em; font-weight: 400; letter-spacing: .07em; }
.mark--lumen i{ align-self: flex-start; margin-top: .62em; width: .26em; height: .26em; border-radius: 50%; background: #F6A57A; }
.mark--north  { font-family: var(--display); font-style: italic; font-size: 2.05rem; letter-spacing: -.01em; }
.mark--kite   { font-weight: 700; letter-spacing: -.065em; }
.mark--orbital{ font-weight: 600; letter-spacing: -.03em; }
.mark--orbital i{ width: .62em; height: .62em; border-radius: 50%; border: .15em solid #FF5A1F; }

/* =========================================================
   02 · WORK — a galeria presa
   A frase é sticky dentro de uma camada absoluta (.gal__layer): a grade
   rola em fluxo normal por baixo dela. A camada passa 80svh do fim da
   seção, então a frase segue presa no meio da tela enquanto as últimas
   peças sobem por ela, e só depois afunda e some no preto de baixo da
   grade (--go). Presa só até o fim da seção, ela subia junto com as
   últimas peças e sumia atrás do menu.

   Por que não margin-bottom: −100svh, o truque óbvio: com margem
   negativa o sticky só solta quando o TOPO dele chega ao fim da seção
   — a frase ficava parada no meio da tela depois de a galeria acabar,
   cortada pelo overflow. O overflow é clip, não hidden: hidden viraria
   contêiner de scroll e mataria o sticky. E clip só no x: no y ele
   cortaria a frase que passa do fim da seção.
   ========================================================= */

.gal{ position: relative; padding: 14svh 0 12svh; overflow-x: clip; }

.gal__layer{ position: absolute; inset: 0; z-index: 2; pointer-events: none; }
/* só com JS: sem ele ninguém apaga a frase, e presa assim ela ficaria
   parada em cima do manifesto. Sem JS, ela vai embora com a seção. */
.has-js .gal__layer{ bottom: -80svh; }
.gal__stick{
  position: sticky; top: 0;
  height: 100svh;
  display: grid; place-items: center;
}
/* a frase lê por cima de qualquer peça que passe atrás dela */
.gal__stick::before{
  content: ''; position: absolute; left: 50%; top: 50%;
  width: min(820px, 96vw); height: min(640px, 78svh);
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, rgba(0,0,0,.82) 0%, rgba(0,0,0,.56) 52%, rgba(0,0,0,0) 100%);
}
.gal__st{ position: relative; max-width: 6.2em; text-align: center; }   /* empilhada, como a do Fantasy */

/* a saída: site.js escreve --go (0 → 1) na camada presa quando a peça
   mais baixa já passou do meio da tela, e a frase afunda e some. --out
   é --go ao quadrado: devagar no começo, para ela entrar inteira no
   preto e só então se apagar. Afunda em em, na medida da letra. O véu
   de trás vai embora na primeira metade: sem peça atrás ele não tem o
   que escurecer, e o manifesto já vem subindo por baixo dele.
   Só durante a saída (.is-out) a frase e o véu ganham camada própria:
   aí opacity e transform mudam a cada quadro sem repintar nada — sem
   isso, o véu de 820×640 e a frase eram repintados quadro a quadro e a
   saída perdia bem mais quadros que o resto da página (medido a 144 Hz).
   Sem blur: toda variante testada com ele, com ou sem camada, perdia
   de duas a quatro vezes mais quadros que a página sem a saída. */
.gal__stick.is-out::before{ opacity: calc(1 - var(--go) * 2); will-change: opacity; }
.gal__stick.is-out .gal__st{
  --out: calc(var(--go) * var(--go));
  opacity: calc(1 - var(--out));
  transform: translate3d(0, calc(var(--out) * 1.6em), 0);
  will-change: opacity, transform;
}

/* o teto de 2560px só pega o ultrawide: em 3440px as três colunas
   esticavam até cada peça ocupar a altura da tela */
.gal__grid{
  position: relative; z-index: 1;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(12px, 1.6vw, 26px);
  max-width: 2560px; margin-inline: auto;
  padding-inline: clamp(12px, 1.6vw, 26px);
  align-items: start;
}
.gal__col{ display: grid; gap: clamp(12px, 1.6vw, 26px); will-change: transform; }

/* --g (0 → 1) é o progresso da seção inteira pela tela. Centrado em .5,
   a coluna do meio anda devagar (fica para trás) e a da direita corre.
   As três terminam perto uma da outra (medido em 1440×900: 159, 180 e
   162svh depois do topo da grade) — senão a do meio sobra sozinha. */
.gal__col--a{ transform: translate3d(0, calc((var(--g, .5) - .5) * -18svh), 0); }
.gal__col--b{ margin-top: 12svh; transform: translate3d(0, calc((var(--g, .5) - .5) * 16svh), 0); }
.gal__col--c{ margin-top: 12svh; transform: translate3d(0, calc((var(--g, .5) - .5) * -46svh), 0); }

/* =========================================================
   03 · MANIFESTO
   ========================================================= */

.mani{ padding: var(--bay-lg) 0 var(--bay-lg); }
.mani__grid{ position: relative; }
.mani__narrow{ display: block; max-width: 9.5em; }
.mani__wide  { display: block; max-width: 15em; }
.mani__thumb{
  position: absolute; right: var(--gutter); top: 4svh;
  width: clamp(150px, 17vw, 260px);
  transform: translate3d(0, calc((var(--mp, .5) - .5) * -30svh), 0);
}

/* =========================================================
   04 · CAPABILITIES — os painéis
   O palco é sticky numa camada absoluta do tamanho da seção (a mesma
   solução da galeria) e os cards rolam por cima. Cada card tem o texto
   no FIM dele, preso com sticky bottom: o texto entra por baixo,
   estaciona no pé da tela enquanto o card passa, e sai empurrado pelo
   próximo. O padding-top de 40svh é o respiro entre um título que sai
   e o que entra.
   ========================================================= */

.caps{ position: relative; }

.caps__layer{ position: absolute; inset: 0; z-index: 0; }
.caps__stage{
  position: sticky; top: 0;
  height: 100svh;
  overflow: hidden;
}

/* os painéis se empilham na ordem do HTML. O ativo e todos os de antes
   ficam opacos; os de depois, transparentes. Assim o próximo sempre
   aparece POR CIMA do atual, e voltar é o de cima sumindo — nunca há
   um instante com os dois pela metade e o preto vazando no meio. */
.pane{
  position: absolute; inset: 0;
  opacity: 0; visibility: hidden;
  transition: opacity 1s var(--ease), visibility 0s linear 1s;
}
.pane.is-on,
.pane.is-past{ opacity: 1; visibility: visible; transition: opacity 1s var(--ease), visibility 0s; }

.pane--brand  { background: radial-gradient(90% 90% at 72% 42%, #1D1F24 0%, #0E0F12 55%, #060607 100%); }
.pane--product{ background: linear-gradient(165deg, #20245C 0%, #2B3080 38%, #151744 72%, #0A0B22 100%); }
.pane--web    { background: radial-gradient(80% 90% at 72% 44%, #1F2610 0%, #0C0E07 58%, #050604 100%); }
.pane--case   { background: linear-gradient(150deg, #7262FF 0%, #4E3BE3 40%, #2D2192 75%, #1A1356 100%); }

/* o texto passa por cima: escurece o lado esquerdo e o pé */
.pane::after{
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(90deg, rgba(0,0,0,.52) 0%, rgba(0,0,0,.22) 34%, rgba(0,0,0,0) 58%),
    linear-gradient(0deg, rgba(0,0,0,.44) 0%, rgba(0,0,0,0) 40%);
}

.pa{ position: absolute; display: block; overflow: visible; }
.pa--mark { width: min(76vw, 126svh); aspect-ratio: 1; right: -9vw; top: calc(50% - min(38vw, 63svh)); }
.pa--ph1  { height: 78svh; aspect-ratio: 240 / 490; right: 31vw; top: 12svh; rotate: -9deg; filter: drop-shadow(0 34px 60px rgba(5,6,30,.55)); }
.pa--ph2  { height: 84svh; aspect-ratio: 240 / 490; right: 10vw; top: 8svh;  rotate: 7deg;  filter: drop-shadow(0 40px 70px rgba(5,6,30,.6)); }
/* o navegador sangra pela direita: o título mais largo do site ("Websites
   &" a 116px) termina em ~630px, e a borda esquerda dele fica em ~780px */
.pa--north{ width: 36vw; aspect-ratio: 640 / 420; right: 14vw; top: 8svh; opacity: .5;
            transform: perspective(1800px) rotateY(-20deg) rotateX(6deg); border-radius: .8vw; }
.pa--kite { width: 50vw; aspect-ratio: 640 / 420; right: -4vw; top: calc(50% - 14vw);
            transform: perspective(1800px) rotateY(-20deg) rotateX(6deg);
            border-radius: 1vw; box-shadow: 0 50px 140px rgba(0,0,0,.65); }
.pa--ph3  { height: 86svh; aspect-ratio: 240 / 490; right: 11vw; top: 7svh; rotate: 6deg; filter: drop-shadow(0 40px 70px rgba(20,10,70,.5)); }
.pa--card { width: 36vw; aspect-ratio: 340 / 214; right: 25vw; top: 50svh; rotate: -14deg;
            border-radius: 2.1vw; box-shadow: 0 40px 100px rgba(10,6,40,.55); }

/* os aparelhos flutuam — em translate, que é propriedade própria e não
   briga com o rotate/transform de cada um. Só no painel aceso. */
@keyframes float{ from{ translate: 0 -1.1svh; } to{ translate: 0 1.1svh; } }
.pane .pa{ animation: float 7s ease-in-out infinite alternate; animation-play-state: paused; }
.pane .pa + .pa{ animation-duration: 8.5s; animation-delay: -3s; }
.pane.is-on .pa{ animation-play-state: running; }
/* o primeiro painel nasce aceso (para quem não tem JS): longe da seção,
   nem ele flutua — é SVG, e anda na thread principal */
.has-js .caps:not(.is-live) .pane .pa{ animation-play-state: paused; }

.caps__cards{ position: relative; z-index: 1; }

.card{
  display: flex; flex-direction: column; justify-content: flex-end;
  min-height: 170svh;
  max-width: 1440px; margin-inline: auto;
  padding: 40svh var(--gutter) 0;
}
.card__in{
  position: sticky; bottom: 8svh;
  display: grid; justify-items: start;
  max-width: 46rem;
}
.card__n{ margin: 0 0 clamp(10px, 1.6svh, 18px); font-size: .92rem; font-weight: 500; color: var(--cream); }
.card__h{
  margin: 0; width: min-content;                 /* uma palavra por linha */
  font-family: var(--sans); font-weight: 500;
  font-size: var(--mega); line-height: .98; letter-spacing: -.038em;
  color: var(--cream);
}
.card__p{
  margin: clamp(22px, 3.4svh, 36px) 0 0; max-width: 25rem;
  font-size: 1.02rem; line-height: 1.55; color: var(--cream);
}
.card__tags{
  margin: 14px 0 0;
  font-size: .74rem; letter-spacing: .14em; text-transform: uppercase; color: var(--cream-2);
}
.card__tags i{ font-style: normal; padding: 0 .3em; color: var(--gold); }
.card .btn{ margin-top: 26px; }

/* =========================================================
   05 · TWELVE YEARS
   ========================================================= */

.yrs{ position: relative; padding-bottom: var(--bay); }

.yrs__media{
  position: relative; height: 104svh; overflow: hidden;
  background: radial-gradient(64% 58% at 54% 50%, #C86A48 0%, #7A3530 30%, #2A1418 60%, #0A0506 82%, #000 100%);
}
/* a mídia morre no preto: a frase começa por cima do fim dela */
.yrs__media::after{
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to bottom, rgba(0,0,0,0) 34%, rgba(0,0,0,.72) 72%, #000 100%);
}
.yrs__ph{
  position: absolute; left: calc(50% - 20.6svh); top: 9svh;
  height: 84svh; aspect-ratio: 240 / 490;
  rotate: -10deg;
  translate: 0 calc((var(--x, .5) - .5) * -18svh);
  filter: drop-shadow(0 40px 80px rgba(0,0,0,.55));
}
/* a legenda mora dentro do .yrs__body, logo depois da frase: no telefone
   em pé ela desce no fluxo, sempre abaixo da última linha (a 100svh fixos,
   como era, ela caía no meio da frase no iPhone SE). Nas telas maiores
   fica onde sempre esteve, a 60svh do topo da seção — o corpo começa em
   64svh, daí o −4svh */
.yrs__cap{
  position: absolute; left: var(--gutter); top: -4svh; margin: 0;
  font-size: .74rem; letter-spacing: .12em; text-transform: uppercase; color: var(--cream);
}

.yrs__body{
  position: relative; z-index: 2;
  margin-top: -40svh;
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: clamp(12px, 1.6vw, 26px);
}
.yrs__st{ grid-column: 5 / span 5; grid-row: 1 / span 2; align-self: start; }
.yrs__narrow{ display: block; max-width: 14.5em; }
.yrs__wide  { display: block; max-width: 14.5em; }

.ft{ position: relative; margin: 0; grid-row: 1; will-change: transform; }
.ft figcaption{
  margin-top: 14px;
  font-size: .74rem; letter-spacing: .12em; text-transform: uppercase; color: var(--cream);
}
.ft--a{ grid-column: 1 / span 3;  margin-top: 64svh; transform: translate3d(0, calc((var(--x, .5) - .5) * -30svh), 0); }
.ft--b{ grid-column: 10 / span 3; margin-top: 22svh; transform: translate3d(0, calc((var(--x, .5) - .5) * -54svh), 0); }
.ft--c{ grid-column: 10 / span 3; grid-row: 2; margin-top: 10svh; transform: translate3d(0, calc((var(--x, .5) - .5) * -22svh), 0); }

/* =========================================================
   06 · STUDIO — a frase e a janela do sol
   A janela é um recorte (clip-path: inset) sobre uma cena de tela
   cheia: --s = 0 é o retrato estreito do meio, --s = 1 é a tela
   inteira. O céu de dentro é próprio (.pstars + .psun, com as mesmas
   camadas .sun__* da hero); o .cosmos continua desligado.
   ========================================================= */

.story{ position: relative; padding-top: var(--bay); }
.story__st{ max-width: 18em; margin-inline: auto; text-align: center; }

.story__track{ position: relative; height: 290svh; margin-top: 16svh; }
.story__stick{ position: sticky; top: 0; height: 100svh; overflow: hidden; }

.story__win{
  /* o retrato do começo: até 520px de largura e 62% da altura */
  --ix: calc(50% - min(17vw, 260px));
  --iy: 19%;
  position: absolute; inset: 0; overflow: hidden;
  background:
    radial-gradient(62% 44% at 50% 44%, rgba(9,13,26,.34) 0%, transparent 72%),
    #000;
  clip-path: inset(calc(var(--iy) * (1 - var(--s, 1))) calc(var(--ix) * (1 - var(--s, 1)))
                    round calc(22px * (1 - var(--s, 1))));
}
.story__win::after{   /* a vinheta da hero, de novo */
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(116% 86% at 50% 42%, rgba(0,0,0,0) 32%, rgba(0,0,0,.46) 72%, rgba(0,0,0,.82) 100%);
}

.pstars{ position: absolute; inset: 0; }
.pstars span{
  position: absolute; left: var(--x); top: var(--y);
  width: var(--s); height: var(--s); border-radius: 50%;
  background: var(--c, #FFFFFF);
  box-shadow: 0 0 calc(var(--s) * 3) rgba(255,252,246,.42);
  animation: twinkle var(--t) ease-in-out infinite var(--d);
}
/* --a e o brilho, --k o fundo da pulsacao. As estrelas da hero gravam
   esses valores em cada <span> (styles.css: la elas sao reamostradas a
   cada quadro da descida); aqui sao 28, e so vivem nesta janela */
@keyframes twinkle{
  0%, 100%{ opacity: calc(var(--a, 1) * var(--k, .34)); }
  50%     { opacity: var(--a, 1); }
}

.psun{
  position: absolute; left: 50%; top: 44%;
  width: 24svh; height: 24svh;
  transform: translate(-50%, -50%) scale(calc(1.18 - var(--s, 1) * .18));
}

.story__kick{
  position: absolute; left: 0; right: 0; top: calc(44% - 23svh); z-index: 1;
  margin: 0; text-align: center;
  font-size: .72rem; letter-spacing: .26em; text-transform: uppercase; color: var(--cream-2);
}

/* os clientes trocam onde a hero tinha "today.": o mesmo degradê que
   pega a luz do sol no topo das letras */
.story__names{
  position: absolute; left: 0; right: 0; top: calc(44% + 15svh); z-index: 1;
  height: 1.1em; margin: 0;
  font-family: var(--display); font-size: clamp(2.3rem, 5.4vw, 5rem);
  line-height: 1; letter-spacing: -.02em; text-align: center;
}
.story__names span{
  position: absolute; left: 0; right: 0; top: 0;
  background: linear-gradient(180deg, #FFE7BD 0%, #F9DEB5 18%, var(--cream) 54%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.story__names span + span{ display: none; }                 /* sem JS: só o primeiro */
.has-js .story__names span + span{ display: block; }
/* cada nome tem 1.8s, e o laço dura nomes × 1.8s: sete nomes, 12.6s.
   Mudou a lista, mudam o laço e os pontos abaixo (0.5s, 1.44s e 1.8s
   do laço), senão sobra um buraco ou dois nomes se atropelam */
.has-js .story__names span{
  opacity: 0;
  animation: nameCycle 12.6s var(--ease) infinite both;
  animation-delay: calc(var(--i) * 1.8s);
}
@keyframes nameCycle{
  0%     { opacity: 0; filter: blur(10px); transform: translate3d(0, .16em, 0); }
  4%     { opacity: 1; filter: blur(0);    transform: none; }
  11.43% { opacity: 1; filter: blur(0);    transform: none; }
  14.29% { opacity: 0; filter: blur(10px); transform: translate3d(0, -.16em, 0); }
  100%   { opacity: 0; filter: blur(10px); transform: translate3d(0, -.16em, 0); }
}

/* fora da tela, a janela inteira para: estrelas, sol e nomes. Isso
   inclui a ignição do sol — ela só acontece quando se chega aqui.
   O ::before é onde o halo respira e a coroa gira (styles.css) */
.has-js .story:not(.is-live) .story__win *,
.has-js .story:not(.is-live) .story__win *::before{ animation-play-state: paused; }

/* =========================================================
   07 · CONTATO + RODAPÉ — o painel claro
   --f (0 → 1) é a entrada do painel: o conteúdo desce de −26% até o
   lugar (anda mais devagar que a página) e uma sombra de .88 se desfaz.
   ========================================================= */

.foot{
  position: relative; overflow: clip;
  background: var(--cream); color: var(--ink);
}
.foot::after{
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: #000; opacity: calc((1 - var(--f, 1)) * .88);
}
.foot__in{
  min-height: 92svh;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding-block: 24svh clamp(22px, 3.4svh, 36px);
  transform: translate3d(0, calc((1 - var(--f, 1)) * -26%), 0);
}
/* margin-inline: auto num item de flex coluna encolhe o item para o
   conteúdo e o centraliza: a largura tem de ser dita */
.foot__in > .wrap{ width: 100%; }
.foot :focus-visible{ outline-color: var(--ink); }

.ct__st{ max-width: 13em; }
.ct__st .t1{ color: var(--ink); }
.ct__st .t2{ color: rgba(10,10,11,.5); }
.ct__p{ margin: 24px 0 0; max-width: 40ch; font-size: 1rem; line-height: 1.65; color: rgba(10,10,11,.68); }
.ct__row{ display: flex; flex-wrap: wrap; align-items: center; gap: 18px 30px; margin-top: 34px; }
.ct__note{ margin: 26px 0 0; font-size: .74rem; letter-spacing: .14em; text-transform: uppercase; color: rgba(10,10,11,.6); }

/* o botão magnético: o de fora carrega o deslocamento que o JS
   interpola quadro a quadro (sem transição); o de dentro, o hover */
.ct__cta{
  display: inline-block; border-radius: 10px; text-decoration: none;
  transform: translate3d(var(--bx, 0px), var(--by, 0px), 0);
  will-change: transform;
}
.btn--ink{ padding: 1.02em 1.4em; background: var(--ink); color: var(--cream); -webkit-backdrop-filter: none; backdrop-filter: none; }
.ct__cta:hover .btn--ink, .ct__cta:focus-visible .btn--ink{ background: #000; transform: scale(1.03); }
.ct__cta:hover .btn--ink i, .ct__cta:focus-visible .btn--ink i{ transform: translateX(4px); }

.foot .ln{ color: var(--ink); border-bottom-color: rgba(10,10,11,.2); }

.fend{
  display: grid; align-items: baseline;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 1.4fr) auto auto;
  gap: 18px clamp(20px, 3vw, 48px);
  width: 100%;
  margin-top: clamp(64px, 12svh, 140px); padding-top: 22px;
  border-top: 1px solid rgba(10,10,11,.14);
  font-size: .86rem;
}
.fend__mark{ margin: 0; font-weight: 600; letter-spacing: -.015em; }
.fend__mark span{ font-weight: 400; color: rgba(10,10,11,.55); }
.clock, .fend__social{ display: flex; flex-wrap: wrap; gap: 6px 20px; margin: 0; padding: 0; list-style: none; }
.clock li{ display: flex; gap: 8px; color: rgba(10,10,11,.62); }
.clock b{ font-weight: 500; font-variant-numeric: tabular-nums; color: var(--ink); }
.fend__social a{ color: rgba(10,10,11,.66); text-decoration: none; transition: color .35s var(--ease); }
.fend__social a:hover{ color: var(--ink); }
.fend__copy{ margin: 0; color: rgba(10,10,11,.6); }
/* "Privacy": no meio do texto, só a cor não bastaria para ver que é link */
.fend__copy a{
  text-decoration: underline; text-decoration-thickness: 1px;
  text-decoration-color: rgba(10,10,11,.28); text-underline-offset: 3px;
  transition: color .35s var(--ease), text-decoration-color .35s var(--ease);
}
.fend__copy a:hover{ color: var(--ink); text-decoration-color: currentColor; }
.fend__top{ font-size: .86rem; }

/* no toque, os links do rodapé (16px de altura) ganham área de toque sem
   mudar de lugar: são inline, e padding vertical em inline não mexe na
   linha */
@media (pointer: coarse){
  .fend__social a, .fend__copy a{ padding-block: 10px; }
}

/* =========================================================
   RESPONSIVO
   ========================================================= */

@media (max-width: 1080px){
  .fend{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fend__top{ justify-self: start; }
}

@media (max-width: 860px){
  .marks{ justify-self: start; }
  .mark{ left: 0; right: auto; }

  .mani__thumb{ position: relative; right: auto; top: auto; margin-top: 44px; }

  .yrs__body{ display: block; margin-top: -34svh; }
  .yrs__st{ max-width: 100%; }
  .yrs__cap{ top: -10svh; }            /* os mesmos 60svh: aqui o corpo começa em 70svh */
  .ft{ width: 64%; margin-top: 12svh; }
  .ft--b{ margin-left: auto; }
  .ft--a, .ft--b, .ft--c{ transform: translate3d(0, calc((var(--x, .5) - .5) * -14svh), 0); }
}

/* painéis em tela em pé — telefone e tablet: a mídia sobe para a metade
   de cima e o texto estaciona no pé; o escurecimento vira todo de baixo
   para cima. Até 01/10/2026 isso valia só até 720px de largura, e o
   tablet em pé herdava o arranjo do desktop: os celulares de 80svh
   passavam por trás do texto, e as letras brancas sumiam na tela clara
   do app da Aster. As larguras têm teto em svh — no tablet (3:4) a conta
   só em vw descia a mídia até o texto; no telefone (9:19) quem manda
   continua sendo o vw, e nada mudou nele. O raio acompanha a largura da
   peça (o do próprio SVG: 12/640 no navegador, 20/340 no cartão). */
@media (orientation: portrait){
  .pane::after{
    background: linear-gradient(0deg, rgba(0,0,0,.72) 0%, rgba(0,0,0,.4) 42%, rgba(0,0,0,0) 66%);
  }
  .pa--mark { width: min(130vw, 86svh); right: -15vw; top: -4svh; }
  .pa--ph1  { height: 50svh; right: auto; left: 8vw; top: 7svh; }
  .pa--ph2  { height: 54svh; right: 6vw; top: 5svh; }
  .pa--north{ width: min(84vw, 56svh); right: -30vw; top: 6svh; }
  .pa--kite { width: min(96vw, 58svh); right: -8vw; top: 16svh; transform: perspective(1200px) rotateY(-14deg) rotateX(5deg); border-radius: calc(min(96vw, 58svh) * .019); }
  .pa--ph3  { height: 52svh; right: 8vw; top: 5svh; }
  .pa--card { width: min(66vw, 36svh); right: auto; left: 4vw; top: 30svh; border-radius: calc(min(66vw, 36svh) * .059); }
}

/* telefone em pé. Deitado, ele fica com o arranjo das telas largas e as
   regras de tela baixa, logo abaixo (a galeria em três colunas cabe; em
   duas, cada peça passava da altura da tela) */
@media (max-width: 720px) and (orientation: portrait){
  .intro{ padding-top: 40svh; }

  .gal__grid{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .gal__col--c{ display: none; }
  .gal__col--b{ margin-top: 20svh; }

  .card{ min-height: 150svh; padding-top: 36svh; }
  .card__in{ bottom: 6svh; }
  .card__p{ font-size: .96rem; }

  .yrs__ph{ height: 70svh; left: calc(50% - 17svh); top: 8svh; }
  /* a frase ocupa a largura toda: a legenda desce no fluxo, para o vão
     entre ela e o primeiro card, em vez de tentar caber ao lado */
  .yrs__cap{ position: static; margin-top: 4svh; }
  .ft{ width: 78%; }
  .ft--a{ margin-top: 11svh; }

  .story__win{ --ix: 11%; --iy: 21%; }
  .psun{ width: 19svh; height: 19svh; }

  .ct__row{ gap: 16px; }
  .fend{ grid-template-columns: minmax(0, 1fr); }
}

/* tela baixa: o telefone deitado. Uma palavra por linha, a 300–430px de
   altura, o bloco de texto passava da tela e o "01" e o começo do título
   ficavam atrás do menu. Aqui o painel vira duas colunas: o texto na
   metade da esquerda (46vw, o título em uma ou duas linhas) e a mídia na
   da direita — o celular da Aster e o cartão chegam um pouco para lá */
@media (max-height: 500px) and (orientation: landscape){
  :root{ --mega: clamp(2rem, 13svh, 3.4rem); }
  .card__in{ bottom: 5svh; max-width: 46vw; }
  .card__h{ width: auto; text-wrap: balance; }
  .card__n{ margin-bottom: 8px; }
  .card__p{ margin-top: 14px; font-size: .94rem; line-height: 1.5; }
  .card__tags{ margin-top: 10px; }
  .card .btn{ margin-top: 16px; }
  .pa--ph1 { right: 27vw; }
  .pa--card{ right: 10vw; }
}
/* e na tela baixa e estreita (568×320), as etiquetas saem: sem elas o
   texto cabe abaixo do menu */
@media (max-height: 500px) and (max-width: 620px) and (orientation: landscape){
  .card__tags{ display: none; }
}

/* =========================================================
   PREFERÊNCIAS
   Sem movimento, tudo chega ao estado final e legível. O site.js
   escreve --m = 1, --s = 1 e --f = 1; aqui caem os laços e as
   paralaxes, e o que era troca vira lista.
   ========================================================= */

@media (prefers-reduced-motion: reduce){
  /* a hero não se despede (o texto fica inteiro): o site começa depois
     dela, em vez de subir por cima e deixar o "today." aparecer no degradê */
  .site{ margin-top: 0; }
  .gal__col, .ft, .mani__thumb{ transform: none !important; }
  .has-js .gal__layer{ bottom: 0; }     /* a frase não se desfaz: sai com a seção */
  .yrs__ph{ translate: none !important; }
  .pane .pa, .lm-rings, .mk-h{ animation: none !important; }
  .foot__in{ transform: none; }
  .foot::after{ opacity: 0; }

  /* as marcas e os clientes param de trocar: viram lista */
  .has-js .mark{ animation: none !important; opacity: 0 !important; }
  .has-js .mark:first-child{ opacity: 1 !important; }
  .story__names{ height: auto; font-size: clamp(1.4rem, 2.6vw, 2.2rem); padding-inline: var(--gutter); }
  .has-js .story__names span{
    position: static; display: inline-block !important; margin: 0 .35em .2em;
    opacity: 1 !important; animation: none !important; filter: none !important;
  }
}
