/* =========================================================================
   OPHIDIA — construída do Figma "Daily Hero 40 — Arkkhe".
   Duas seções de 1440 × 810 empilhadas, numa página que rola.

   `--px` vale um pixel do design, derivado da largura da seção, então a
   composição escala como uma peça só. Abaixo de 900px troca para `--px: 1px`
   e o layout vira coluna.

   Toda a geometria foi medida no render 2× exportado do Figma — a API estava
   devolvendo 429 até no endpoint de arquivo. Ver PLANO.md.
   ========================================================================= */

:root {
  --bg:      #000;
  --ink:     #fff;
  --display: "Bodoni Moda", Didot, "Times New Roman", serif;
  --sans:    "Syne", system-ui, -apple-system, "Segoe UI", sans-serif;
  --ease:    cubic-bezier(.22, .61, .36, 1);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; background: var(--bg); }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  overflow-x: hidden;
}

img, svg { display: block; max-width: 100%; height: auto; }
ul { list-style: none; margin: 0; padding: 0; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, p { margin: 0; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* O Figma posiciona texto pela altura de maiúscula. `text-box` é o equivalente
   em CSS: sem ele cada bloco nasce alguns px mais baixo do que o medido. */
@supports (text-box: trim-both cap alphabetic) {
  .brand, .nav a, .lede, .pitch, .cta span, .purity__line, .wordmark,
  .vault__label, .vault__title, .vault__note, .vial h3, .vial p, .rail {
    text-box: trim-both cap alphabetic;
  }
}

.skiplink {
  position: fixed; left: 16px; top: -60px; z-index: 100;
  padding: 10px 18px; border: 1px solid var(--ink);
  background: var(--bg); color: var(--ink);
  font-size: 13px; letter-spacing: .08em; text-transform: uppercase;
  transition: top .18s var(--ease);
}
.skiplink:focus-visible { top: 16px; }

:where(a, button):focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }


/* ================================================================ palco === */

/* O vídeo é fundo FIXO da página inteira. As seções passam por cima dele, cada
   uma com o próprio véu — no Vault o véu é forte, mas deixa o bicho aparecer. */
.backdrop {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: var(--bg);
}
.backdrop__media {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
  max-width: none;
}

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

.hero  { container-type: inline-size; position: relative; }
.vault { container-type: inline-size; position: relative; background: rgba(4,4,4,.80); }

/* `--px` é declarado aqui e consumido só daqui para dentro. Declarar num
   elemento que também tem `container-type` faria `cqw` resolver contra o
   container DE FORA — o erro silencioso clássico. */
.hero__in, .vault__in {
  --px: calc(100cqw / 1440);
  position: relative;
  height: calc(810 * var(--px));
  overflow: hidden;
}


/* ================================================================= hero === */

/* Medido no render: a foto vale 1,0 até y≈355 e cai para ~0,2 em y≈520,
   ficando constante daí para baixo. É o que abre espaço para o letreiro. */
.hero__veil {
  position: absolute; inset: 0;
  background: linear-gradient(to bottom,
    rgba(0,0,0,0)    43.8%,   /* y 355 */
    rgba(0,0,0,.10)  46.9%,   /* y 380 */
    rgba(0,0,0,.18)  50.6%,   /* y 410 */
    rgba(0,0,0,.44)  54.3%,   /* y 440 */
    rgba(0,0,0,.68)  58.0%,   /* y 470 */
    rgba(0,0,0,.80)  65.4%,   /* y 530 */
    rgba(0,0,0,.80)  100%);
}

.hero__rule {
  position: absolute;
  left: calc(88 * var(--px)); top: 0;
  width: 1px; height: 100%;
  background: rgba(255,255,255,.16);
}

/* -------------------------------------------------------------- barra --- */

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

.brand {
  position: absolute;
  left: calc(50 * var(--px)); top: calc(41 * var(--px));
  font-family: var(--display);
  font-size: calc(18.4 * var(--px));
  line-height: 1;
}

.bar__spark {
  position: absolute;
  left: calc(168 * var(--px)); top: calc(31 * var(--px));
  width: calc(13 * var(--px)); height: calc(13 * var(--px));
  color: var(--ink);
}

.bar__gem {
  position: absolute;
  left: calc(1363 * var(--px)); top: calc(34 * var(--px));
  width: calc(20 * var(--px)); height: calc(22 * var(--px));
  color: var(--ink);
}

/* As posições do menu no Figma são coordenadas soltas, não uma grade. */
.nav a {
  position: absolute;
  top: calc(42.5 * var(--px));
  font-size: calc(12.1 * var(--px));
  font-weight: 500;
  letter-spacing: calc(.35 * var(--px));
  text-transform: uppercase;
  opacity: .82;
  transition: opacity .2s var(--ease);
}
.nav a:hover { opacity: 1; }
.nav li:nth-child(1) a { left: calc(914 * var(--px)); }
.nav li:nth-child(2) a { left: calc(1060 * var(--px)); }
.nav li:nth-child(3) a { left: calc(1166 * var(--px)); }

.burger { display: none; }

/* ------------------------------------------------- trilhos laterais --- */

.rail {
  position: absolute;
  left: calc(54 * var(--px));
  writing-mode: vertical-rl;
  rotate: 180deg;                    /* faz o texto correr de baixo para cima */
  font-size: calc(11 * var(--px));
  letter-spacing: calc(1.2 * var(--px));
  opacity: .7;
}
.rail--mail { top: calc(331 * var(--px)); }
.rail--tel  { top: calc(661.5 * var(--px)); }

/* -------------------------------------------------------------- lede --- */

/* Três linhas alinhadas à direita em x=513, altura de maiúscula 45,
   passo 53,25. O tamanho e a entreletra saíram de resolver as duas coisas
   ao mesmo tempo contra a largura medida de cada linha. */
.lede {
  position: absolute;
  right: calc(927 * var(--px));       /* 1440 − 513 */
  top: calc(180 * var(--px));
  font-family: var(--display);
  font-size: calc(59.2 * var(--px));
  line-height: calc(53.25 * var(--px));
  letter-spacing: calc(-1.4 * var(--px));
  font-weight: 400;
  text-transform: uppercase;
  text-align: right;
  white-space: nowrap;
}

.lede__ne {
  position: absolute;
  left: calc(174 * var(--px)); top: calc(389 * var(--px));
  width: calc(16.5 * var(--px)); height: calc(16.5 * var(--px));
  color: var(--ink);
}

.pitch {
  position: absolute;
  left: calc(168.5 * var(--px)); top: calc(462 * var(--px));
  width: calc(272 * var(--px));
  font-size: calc(13 * var(--px));
  line-height: calc(21 * var(--px));
  opacity: .78;
}

/* Retângulo BRANCO sólido com texto preto — medido no render. A primeira
   versão saiu contornada e transparente, que é o oposto. */
.cta {
  position: absolute;
  left: calc(505 * var(--px)); top: calc(452 * var(--px));
  width: calc(228 * var(--px)); height: calc(52 * var(--px));
  display: flex;
  align-items: center;
  gap: calc(10 * var(--px));
  padding-inline: calc(26 * var(--px)) calc(21 * var(--px));
  background: #fff;
  color: #000;
  font-size: calc(12.1 * var(--px));
  font-weight: 500;
  letter-spacing: calc(.7 * var(--px));
  text-transform: uppercase;
  transition: background .25s var(--ease);
}
.cta span { white-space: nowrap; }   /* sem isto o rótulo quebra em duas linhas */
.cta svg { width: calc(17 * var(--px)); height: calc(17 * var(--px)); flex: 0 0 auto; }
.cta:hover { background: #ded9d2; }

/* ------------------------------------------------------- cartão purity --- */

.purity {
  position: absolute;
  left: calc(1088 * var(--px)); top: calc(440 * var(--px));
  width: calc(300 * var(--px)); height: calc(300 * var(--px));
  background: linear-gradient(135deg, rgba(255,255,255,.10), rgba(0,0,0,.45));
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  overflow: hidden;
}
.purity__orb {
  position: absolute;
  left: calc(36 * var(--px)); top: calc(60 * var(--px));
  width: calc(105 * var(--px)); height: calc(105 * var(--px));
}
.purity__ne {
  position: absolute;
  left: calc(217 * var(--px)); top: calc(37 * var(--px));
  width: calc(25 * var(--px)); height: calc(25 * var(--px));
  color: var(--ink);
}
.purity__line {
  position: absolute;
  left: calc(31 * var(--px)); top: calc(226.5 * var(--px));
  width: calc(240 * var(--px));
  font-size: calc(25.8 * var(--px));
  font-weight: 500;
  line-height: calc(25 * var(--px));
  letter-spacing: calc(-.95 * var(--px));
  text-transform: uppercase;
}

/* ---------------------------------------------------------- letreiro --- */

.wordmark {
  position: absolute;
  left: calc(70.5 * var(--px)); top: calc(612.5 * var(--px));
  font-family: var(--display);
  font-size: calc(242 * var(--px));
  line-height: 1;
  letter-spacing: calc(43.9 * var(--px));
  font-weight: 400;
  white-space: nowrap;
}


/* ================================================================ vault === */

.vault__label {
  position: absolute;
  left: calc(120 * var(--px)); top: calc(77 * var(--px));
  font-size: calc(12.1 * var(--px));
  font-weight: 500;
  letter-spacing: calc(1.78 * var(--px));
  text-transform: uppercase;
  opacity: .62;
}

.vault__title {
  position: absolute;
  left: calc(121 * var(--px)); top: calc(115.5 * var(--px));
  font-family: var(--display);
  font-size: calc(63.8 * var(--px));
  line-height: calc(66 * var(--px));
  letter-spacing: calc(-2 * var(--px));
  font-weight: 400;
}

.vault__note {
  position: absolute;
  left: calc(831 * var(--px)); top: calc(128 * var(--px));
  width: calc(350 * var(--px));
  font-size: calc(14 * var(--px));
  line-height: calc(22 * var(--px));
  opacity: .72;
}

/* Os três frascos: 376 de largura em x 120 / 532 / 944, vão de 36. */
.vials { position: absolute; left: calc(120 * var(--px)); top: calc(314 * var(--px)); display: flex; gap: calc(36 * var(--px)); }

.vial {
  position: relative;
  width: calc(376 * var(--px));
  height: calc(467 * var(--px));
  color: #14201a;
}

/* A "tampa": um segundo cartão atrás, RECUADO 7px de cada lado e 27px acima —
   medido no render (topo em y 1097, corpo em 1124, cor rgb(69,70,71)).
   Sem `overflow: hidden` no cartão: era ele que cortava a tampa inteira. */
.vial::before {
  content: "";
  position: absolute;
  left: calc(7 * var(--px)); right: calc(7 * var(--px));
  top: calc(-27 * var(--px)); height: calc(70 * var(--px));
  border-radius: calc(28 * var(--px));
  background: rgb(69,70,71);
  z-index: 0;
}

/* A face do cartão é uma camada própria, não o fundo do `.vial`.
   Empilhar por z-index NEGATIVO quebrou quando a animação de entrada entrou:
   `translate` — mesmo `0 0` — transforma o elemento em contexto de
   empilhamento, e aí a tampa passava a ser desenhada por cima da face. */
.vial::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: calc(28 * var(--px));
  background: linear-gradient(180deg, #b9b9ba 0%, #a9adaa 42%, #8b968f 72%, #61715f 100%);
  z-index: 1;
}

.vial > * { z-index: 2; }

/* Os PNGs vêm numa moldura de 356x292 com o frasco centrado; conferido contra
   a tinta do render, os três encaixam com a imagem em (11, 11). */
.vial img {
  position: absolute;
  left: calc(11 * var(--px)); top: calc(11 * var(--px));
  width: calc(356 * var(--px)); height: calc(292 * var(--px));
  object-fit: contain;
}

.vial h3 {
  position: absolute;
  left: calc(32 * var(--px)); top: calc(326 * var(--px));
  font-size: calc(22.7 * var(--px));
  font-weight: 500;
}

.vial p {
  position: absolute;
  left: calc(32 * var(--px)); top: calc(363 * var(--px));
  /* Entre 224 e 237: o cartão 1 quebra depois de "we" e os outros dois
     cabem numa linha só, exatamente como no design. */
  width: calc(230 * var(--px));
  font-size: calc(12.9 * var(--px));
  line-height: calc(23 * var(--px));
  opacity: .72;
}

.vial__go {
  position: absolute;
  right: calc(27 * var(--px)); bottom: calc(37 * var(--px));
  display: grid; place-items: center;
  width: calc(68 * var(--px)); height: calc(68 * var(--px));
  border: 1px solid rgba(20,32,26,.35);
  border-radius: 50%;
  transition: background .25s var(--ease);
}
.vial__go svg { width: calc(18 * var(--px)); height: calc(18 * var(--px)); }
.vial__go:hover { background: rgba(255,255,255,.28); }


/* ============================================================ a subida === */

/* No protótipo do Figma a cena não abre acesa: sobe do preto ao longo de uns
   segundos, e os elementos entram escalonados — foto, depois a marca, os
   trilhos laterais, o título, e por fim texto, botão e letreiro.

   Aqui a mesma coreografia, comprimida quase à metade. O protótipo leva ~5s até
   dar para ler a manchete; numa página que precisa vender, isso é tempo demais.

   `.js-intro` vem de um script inline no `<head>` — ver index.html. Sem ele nada
   fica escondido. E a entrada usa ANIMAÇÃO, não transição, para que o
   escalonamento não deixe `transition-delay` pendurado depois. */
.js-intro .backdrop__media,
.js-intro .bar,
.js-intro .hero__rule,
.js-intro .rail,
.js-intro .lede,
.js-intro .lede__ne,
.js-intro .pitch,
.js-intro .cta,
.js-intro .purity,
.js-intro .wordmark { opacity: 0; }

@keyframes acender { from { opacity: 0; } }

.lit .backdrop__media { opacity: 1; animation: acender 1.9s ease-out backwards; }
.lit .hero__rule      { opacity: 1; animation: acender  .9s ease-out 1.05s backwards; }
.lit .bar             { opacity: 1; animation: acender  .9s ease-out 1.20s backwards; }
.lit .rail            { opacity: 1; animation: acender  .9s ease-out 1.45s backwards; }
.lit .lede            { opacity: 1; animation: acender 1.1s ease-out 1.70s backwards; }
.lit .wordmark        { opacity: 1; animation: acender 1.3s ease-out 2.00s backwards; }
.lit .lede__ne        { opacity: 1; animation: acender  .8s ease-out 2.20s backwards; }
.lit .pitch           { opacity: 1; animation: acender  .8s ease-out 2.35s backwards; }
.lit .cta             { opacity: 1; animation: acender  .8s ease-out 2.50s backwards; }
.lit .purity          { opacity: 1; animation: acender  .9s ease-out 2.65s backwards; }


/* ========================================================= a revelação === */

/* No protótipo do Figma os frascos surgem quando o vídeo da cobra termina.
   Aqui a entrada é a mesma, e dispara pelo que vier primeiro: o fim da primeira
   volta do vídeo ou a seção entrar em vista ao rolar.

   O estado escondido só existe sob `.can-reveal`, que o script adiciona. Sem JS
   — ou com movimento reduzido — nada é escondido e a seção nasce montada. */
.vault__title, .vault__note, .vial {
  transition: opacity .85s var(--ease), translate .85s var(--ease);
}
.vault.can-reveal .vault__title,
.vault.can-reveal .vault__note { opacity: 0; translate: 0 26px; }
.vault.can-reveal .vial        { opacity: 0; translate: 0 46px; }

.vault.can-reveal.is-revealed .vault__title,
.vault.can-reveal.is-revealed .vault__note,
.vault.can-reveal.is-revealed .vial { opacity: 1; translate: 0 0; }

/* O escalonamento é o que faz parecer que eles emergem um a um. */
.vault.can-reveal.is-revealed .vault__note      { transition-delay: .08s; }
.vault.can-reveal.is-revealed .vial:nth-child(1) { transition-delay: .18s; }
.vault.can-reveal.is-revealed .vial:nth-child(2) { transition-delay: .30s; }
.vault.can-reveal.is-revealed .vial:nth-child(3) { transition-delay: .42s; }


/* ============================================================== celular === */

/* O sistema `--px` escala pela largura da seção: num telefone de 390px ele
   valeria 0,27, e o menu de 12px viraria 3px. Abaixo de 900px o layout sai do
   posicionamento absoluto e vira uma coluna comum. */
@media (max-width: 900px) {

  .hero__in, .vault__in {
    --px: 1px;
    height: auto;
    overflow: visible;
  }

  /* ------------------------------------------------------------ hero --- */

  .hero__in {
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    padding: 84px max(20px, 5vw) 0;
  }
  .hero__rule, .rail { display: none; }

  .hero__veil {
    background: linear-gradient(to bottom,
      rgba(0,0,0,.72) 0%, rgba(0,0,0,.45) 32%, rgba(0,0,0,.78) 62%, #000 92%);
  }

  .bar { position: absolute; inset: 0 max(20px, 5vw) auto; height: 84px; }
  .brand { left: 0; top: 30px; font-size: 22px; }
  .bar__spark, .bar__gem { display: none; }

  .burger {
    display: grid;
    position: absolute;
    right: 0; top: 28px;
    width: 34px; height: 34px;
    align-content: center; justify-items: end; gap: 5px;
  }
  .burger span { display: block; width: 22px; height: 1.5px; background: var(--ink); transition: translate .25s var(--ease), rotate .25s var(--ease), opacity .2s; }
  .burger[aria-expanded="true"] span:nth-child(1) { translate: 0 6.5px; rotate: 45deg; }
  .burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .burger[aria-expanded="true"] span:nth-child(3) { translate: 0 -6.5px; rotate: -45deg; }

  .nav {
    position: absolute;
    left: 0; right: 0; top: 84px;
    opacity: 0; visibility: hidden; translate: 0 -8px;
    transition: opacity .25s var(--ease), translate .25s var(--ease), visibility .25s;
  }
  .bar.is-open .nav { opacity: 1; visibility: visible; translate: 0 0; }
  .nav a { position: static; display: block; padding: 11px 0; font-size: 15px; letter-spacing: .1em; }

  .lede, .lede__ne, .pitch, .cta, .purity, .wordmark,
  .vault__label, .vault__title, .vault__note, .vials {
    position: relative;
    /* `inset: auto` é obrigatório: sem ele o `top`/`left` do desktop volta a
       valer como deslocamento relativo e joga tudo para fora da tela. */
    inset: auto;
    z-index: 1;
  }

  .lede {
    margin-top: 8vh;
    /* 13,8vw: a linha mais larga ("EVERYTHING") mede 6,39x o corpo na Bodoni
       Moda, e a 15vw ela encostava na borda direita. */
    font-size: min(13.8vw, 84px);
    line-height: .92;
    letter-spacing: -.02em;
    text-align: left;
    white-space: normal;
  }
  .lede__ne { margin: 26px 0 0; width: 18px; height: 18px; }
  .pitch { width: min(340px, 100%); margin-top: 20px; font-size: 14px; line-height: 22px; }

  .cta {
    width: max-content; height: 52px;
    margin-top: 26px;
    font-size: 12px;
  }

  .purity {
    width: 100%; height: auto;
    aspect-ratio: 1;
    margin-top: 40px;
    max-width: 360px;
  }
  .purity__orb { left: 12%; top: 20%; width: 35%; height: 35%; }
  .purity__ne  { left: auto; right: 8%; top: 12%; width: 24px; height: 24px; }
  .purity__line { left: 10%; right: 10%; top: auto; bottom: 12%; width: auto; font-size: 22px; line-height: 24px; }

  .wordmark {
    margin: 44px calc(max(20px, 5vw) * -1) 0;
    font-size: 19vw;
    letter-spacing: .055em;
    text-align: center;
  }

  /* ----------------------------------------------------------- vault --- */

  .vault__in { padding: 72px max(20px, 5vw); }

  .vault__label { font-size: 12px; letter-spacing: .16em; }
  .vault__title { margin-top: 18px; font-size: min(12vw, 60px); line-height: 1.04; letter-spacing: -.02em; }
  .vault__note  { width: min(420px, 100%); margin-top: 20px; font-size: 14px; line-height: 22px; }

  .vials { flex-direction: column; gap: 46px; margin-top: 44px; }

  /* O cartão volta a ser um bloco que flui: as partes saíram do absoluto. */
  .vial {
    width: 100%; height: auto;
    display: flex;
    flex-direction: column;
    padding: 18px 24px 26px;
  }
  .vial::before { left: 7px; right: 7px; top: -22px; height: 60px; }
  /* `relative`, não `static`: elemento estático fica sob a face do cartão. */
  .vial img { position: relative; inset: auto; width: 100%; height: auto; max-width: 320px; margin: 0 auto; }
  .vial h3  { position: relative; inset: auto; margin-top: 14px; font-size: 23px; }
  .vial p   { position: relative; inset: auto; width: auto; margin-top: 8px; padding-right: 84px; font-size: 13px; line-height: 21px; }
  .vial__go { right: 24px; bottom: 26px; width: 60px; height: 60px; }
}


/* ================================================= movimento reduzido === */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}
