/* ==========================================================================
   BASE
   Reset curto, tipografia, moldura fixa (nav, indicador, Green Dot),
   placeholders e os estados de animacao.
   REGRA DURA: nada nasce invisivel sem a classe anim-ready. Se o GSAP nao
   carregar, a pagina aparece inteira, estatica e legivel.
   ========================================================================== */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  /* o fundo do filme fica atras de tudo; as cenas trazem o proprio veu */
  color: var(--fg);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1, h2, h3, p, figure, blockquote, ol, ul { margin: 0; padding: 0; }
ol, ul { list-style: none; }
img, video { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }

::selection { background: var(--accent); color: #fff; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}

/* --- Lenis (scroll suave). Regras exigidas pela biblioteca. --- */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }

/* ==========================================================================
   TIPOGRAFIA
   ========================================================================== */

.display {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: var(--lh-tight);
  letter-spacing: var(--tr-tight);
  text-transform: uppercase;   /* o filme fala em caixa alta; a citacao e a excecao */
  text-wrap: balance;
}
.display--xl { font-size: var(--fs-xl); }
.display--lg { font-size: var(--fs-lg); }
.display--md { font-size: var(--fs-md); font-weight: 500; letter-spacing: -.02em; line-height: var(--lh-mid); }

.mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

.label,
.chapter,
.nav,
.hud {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  line-height: 1.4;
}

.body {
  font-size: var(--fs-body);
  color: var(--fg-2);
  max-width: 46ch;
}
.body--wide { max-width: 58ch; }

.lead {
  font-size: var(--fs-lead);
  color: var(--fg-2);
  max-width: 34ch;
  letter-spacing: -.01em;
}

.kicker {
  font-family: var(--font-mono);
  font-size: clamp(11px, 1vw, 14px);
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--fg-2);
}

/* Rotulo de capitulo. Aparece no topo de cada cena. */
.chapter {
  color: var(--fg-2);
  margin-bottom: var(--s5);
}
.chapter__n { color: var(--accent-ink); }

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding-inline: var(--gutter);
}

/* ==========================================================================
   AMBIENTE
   Grao finissimo e vinheta. Tira o branco morto sem virar textura.
   ========================================================================== */
.ambient {
  position: fixed;
  inset: 0;
  z-index: var(--z-ambient);
  pointer-events: none;
}
.ambient::before,
.ambient::after {
  content: "";
  position: absolute;
  inset: 0;
}
/* grao */
.ambient::before {
  opacity: .07;
  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='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* vinheta nas bordas, que fecha a tela e joga o olho para o centro */
.ambient::after {
  background: radial-gradient(120% 90% at 50% 45%, rgba(0,0,0,0) 42%, rgba(0,0,0,.55) 100%);
}

/* na secao clara a vinheta quase some, senao ela suja o cinza claro */
html.is-paper .ambient::after {
  background: radial-gradient(120% 90% at 50% 45%, rgba(0,0,0,0) 55%, rgba(0,0,0,.14) 100%);
}
html.is-paper .ambient::before { opacity: .04; }

/* ==========================================================================
   GREEN DOT
   1. sprite reutilizavel (o ponto inline, dentro do texto)
   2. camada fixa viajante (o ponto que atravessa o filme)
   ========================================================================== */

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

/* Ponto inline. Herda o tamanho da linha em que estiver. */
.gd {
  display: inline-block;
  width: 1em;
  height: 1em;
  fill: var(--accent);
  color: var(--accent);
}
.gd--sm { width: 7px; height: 7px; }
.gd--period {
  width: .28em;
  height: .28em;
  margin-left: .06em;
  vertical-align: baseline;
}

/* A camada viajante. Fica acima do conteudo e nunca captura clique. */
.dot-layer {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: var(--z-dot);
  pointer-events: none;
  overflow: visible;
}
.dot-shape { transform-box: fill-box; transform-origin: center; }
/* No ato escuro o ponto ganha um brilho de leve, como luz de projetor. */
html.is-ink .dot-shape { filter: drop-shadow(0 0 14px rgba(0, 184, 28, .55)); }
.dot-halo { transform-box: fill-box; transform-origin: center; opacity: 0; }

/* O pulso do capitulo 00. A classe entra e sai pelo JavaScript, entao o
   GSAP nunca disputa a mesma propriedade com o CSS. */
.dot-layer.is-pulsing .dot-shape { animation: dot-beat 2.8s var(--ease-soft) infinite; }
.dot-layer.is-pulsing .dot-halo  { animation: dot-ping 2.8s var(--ease-soft) infinite; }

@keyframes dot-beat {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.28); }
}
@keyframes dot-ping {
  0%   { transform: scale(.6); opacity: .55; }
  70%  { transform: scale(2.6); opacity: 0; }
  100% { transform: scale(2.6); opacity: 0; }
}

/* ==========================================================================
   NAVEGACAO
   Some quando o visitante desce, volta quando ele sobe. Nunca pesa na tela.
   ========================================================================== */
.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: var(--z-nav);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  padding: var(--s3) var(--gutter);
  color: var(--chrome-fg);
  transition: transform var(--t-mid) var(--ease),
              opacity var(--t-fast) var(--ease-soft),
              color var(--t-mid) var(--ease-soft);
  will-change: transform;
}
.nav.is-hidden { transform: translateY(-110%); opacity: 0; }

.nav__brand { display: inline-flex; align-items: center; gap: 10px; white-space: nowrap; }
.nav__links { display: flex; gap: var(--s4); }
.nav__links a { position: relative; color: var(--chrome-fg-2); transition: color var(--t-fast) var(--ease-soft); }
.nav__links a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -6px;
  width: 100%;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--t-fast) var(--ease);
}
.nav__links a:hover { color: var(--chrome-fg); }
.nav__links a:hover::after { transform: scaleX(1); }

/* ==========================================================================
   INDICADOR DE PROGRESSO
   Le a posicao real do documento, entao nunca mente.
   ========================================================================== */
.hud {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-hud);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--s3);
  padding: var(--s3) var(--gutter);
  color: var(--chrome-fg-2);
  transition: color var(--t-mid) var(--ease-soft), opacity var(--t-mid) var(--ease-soft);
}
.hud__chapter { justify-self: start; }
.hud__chapter #hudNum { color: var(--accent); }
.hud__pct { justify-self: end; }
.hud__bar {
  width: clamp(120px, 22vw, 320px);
  height: 1px;
  background: var(--chrome-rule);
  overflow: hidden;
}
.hud__bar i {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--accent);
  transform-origin: left;
}

/* ==========================================================================
   DEDICATORIA
   A quem o portfolio e enderecado. Aparece na abertura, no fecho e no
   rodape. E uma dedicatoria, nao uma marca do site: o logo entra pequeno,
   ao lado de uma linha que diz para quem.
   ========================================================================== */
.dedication {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.dedication--center { justify-content: center; }
.dedication__label {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--fg-2);
}
.dedication__logo {
  width: clamp(84px, 8.5vw, 122px);
  height: auto;
}
/* Nos dois pontos onde a dedicatoria aparece o fundo e escuro, entao o
   arquivo usado ja e a versao branca do logotipo. Nada de filtro invert
   aqui: inverter tambem trocaria o verde do ponto por roxo. A versao
   preta (deloitte.png) fica guardada para qualquer uso em fundo claro. */

/* ==========================================================================
   BOTOES
   ========================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 22px;
  border: 1px solid var(--rule);
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--fg);
  background: transparent;
  transition: border-color var(--t-fast) var(--ease-soft),
              color var(--t-fast) var(--ease-soft),
              gap var(--t-fast) var(--ease);
}
.btn:hover { border-color: var(--accent); color: var(--accent); gap: 16px; }
.btn__arrow { display: inline-block; transition: transform var(--t-fast) var(--ease); }
.btn:hover .btn__arrow { transform: translate(2px, -2px); }
.btn--big { padding: 20px 34px; font-size: clamp(11px, .9vw, 13px); }

/* ==========================================================================
   PLACEHOLDERS
   Molduras reservadas. Trocar por <img> ou <video> e trocar a figure inteira.
   ========================================================================== */
.ph {
  position: relative;
  width: 100%;
  background: var(--ph-fill);
  border: 1px solid var(--ph-line);
  display: grid;
  place-items: center;
  overflow: hidden;
}
.ph::before,
.ph::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}
/* fio diagonal discreto, marca de moldura reservada */
.ph::before {
  background:
    linear-gradient(to bottom right, transparent calc(50% - .5px), var(--ph-line) 50%, transparent calc(50% + .5px)),
    linear-gradient(to bottom left,  transparent calc(50% - .5px), var(--ph-line) 50%, transparent calc(50% + .5px));
  opacity: .28;
}
/* O rotulo mora no pe da moldura, como etiqueta de claquete. No centro
   ele batia de frente com o Green Dot na intro. */
.ph__tag {
  position: absolute;
  left: 0;
  bottom: 0;
  z-index: 1;
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--fg-2);
  background: var(--bg);
  padding: 8px 12px;
  text-align: left;
}
.ph--16x9   { aspect-ratio: 16 / 9; }
/* Moldura redonda: o motivo de circulo da marca aplicado na foto. */
.ph--circle { aspect-ratio: 1; border-radius: 50%; }
.ph--circle .ph__tag { position: static; background: transparent; text-align: center; }
.ph--4x5    { aspect-ratio: 4 / 5; }
.ph--4x3    { aspect-ratio: 4 / 3; }
.ph--portrait { aspect-ratio: 3 / 4; }
.ph--wide   { aspect-ratio: 3 / 2; }

/* Quando a midia real chega, a moldura de placeholder se apaga sozinha:
   sem fio tracejado, sem cruz, sem fundo. Vale para as fotos de hoje e
   para os mockups dos cases amanha. */
.ph:has(img),
.ph:has(video) {
  background: none;
  border-color: transparent;
}
.ph:has(img)::before,
.ph:has(video)::before { display: none; }

/* A midia real ocupa a moldura inteira. */
.ph > img,
.ph > video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ==========================================================================
   ESTADOS DE ANIMACAO
   Tudo abaixo so vale com anim-ready. Sem GSAP, nada disso existe.
   ========================================================================== */

/* Linha com mascara: o texto sobe de dentro de uma janela. */
.reveal .l { display: block; }
.anim-ready .reveal { opacity: 0; }
.anim-ready .reveal .l {
  overflow: hidden;
  padding-bottom: .14em;
  margin-bottom: -.14em;
}
.anim-ready .reveal .l__i { display: block; }

/* Palavra com mascara, para a frase da abertura. */
.anim-ready .hero__statement .w {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  padding-bottom: .14em;
  margin-bottom: -.14em;
}
.anim-ready .hero__statement .w__i { display: inline-block; }

/* Blocos de corpo entram e desbotam ao sair da tela. */
.anim-ready [data-fade] { opacity: 0; }

/* A frase da abertura entra depois do nome. */
.anim-ready .hero__statement { opacity: 0; }

/* ==========================================================================
   PLANO B (anim-off)
   Sem GSAP, ou com movimento reduzido, o filme vira um site longo e
   estatico: sem trilhas de scroll, sem quadros sobrepostos, tudo em fluxo
   normal e tudo legivel. Testado carregando a pagina com os CDNs fora do ar.
   ========================================================================== */
html.anim-off .track {
  height: auto;
  /* sem stage sticky, a marca d agua gigante passa a se posicionar pela
     trilha; entao o recorte precisa estar aqui tambem */
  overflow: hidden;
}
html.anim-off .stage {
  position: static;
  height: auto;
  min-height: 100vh;
  /* segue recortando: como a altura passa a ser automatica, a caixa cresce
     com o conteudo e o recorte so segura a marca d agua gigante na lateral */
  overflow: hidden;
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
}
/* na abertura, nome e frase deixam de dividir o mesmo lugar */
html.anim-off .hero__statement {
  position: static;
  margin-top: var(--s4);
  /* margin auto em item de flex cancela o stretch e centraliza a caixa */
  margin-inline: 0;
  max-width: none;
}
html.anim-off .scene--hero .stage { align-items: stretch; justify-content: flex-end; }
html.anim-off .intro__cue {
  position: static;
  margin-top: var(--s4);
  padding-inline: var(--gutter);
}

/* ==========================================================================
   RODAPE
   ========================================================================== */
.foot {
  padding: var(--s6) 0 var(--s5);
  border-top: 1px solid var(--rule-soft);
  color: var(--fg-2);
}
.foot__grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3) var(--s5);
  justify-content: space-between;
  font-size: var(--fs-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
}
.foot__note {
  margin-top: var(--s4);
  font-size: var(--fs-label);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  color: var(--accent-ink);
}
.foot a { border-bottom: 1px solid var(--rule); padding-bottom: 2px; }
.foot a:hover { color: var(--accent); border-color: var(--accent); }

/* ==========================================================================
   MOVIMENTO REDUZIDO
   Quem pediu menos movimento recebe a pagina inteira, parada e completa.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
  .dot-layer { display: none; }
}
