    html {
      scroll-padding-top: 6rem;
    }

    :root {
      --gold: #D4AF37;
      --ink: #030303;
      --paper: #d4d4d4;
    }

    body {
      font-family: 'Inter', sans-serif;
      background-color: #030303;
      color: #d4d4d4;
    }

    .font-display {
      font-family: 'Playfair Display', serif;
    }

    /* Linhas de título balanceadas: evita viúva de uma palavra na última linha
       dos títulos de seção. Progressivo — navegador sem suporte ignora. */
    h2, blockquote {
      text-wrap: balance;
    }

    /* Foco visível pra navegação por teclado, no idioma da marca (anel dourado).
       Sem isso o site fica com o anel padrão do navegador — azul sobre preto,
       fora do sistema — ou invisível, dependendo do motor. Só em :focus-visible,
       então clique/toque não ganha anel. */
    a:focus-visible,
    button:focus-visible,
    summary:focus-visible {
      outline: 2px solid rgba(212, 175, 55, 0.7);
      outline-offset: 3px;
    }

    /* FAQ: affordance de hover antes do clique — o item fechado responde ao
       mouse, sinalizando que abre. O aberto já tem a borda dourada. */
    #faq details:not([open]):hover {
      border-color: rgba(255, 255, 255, 0.18);
    }

    /* Scrollbar Styling */
    ::-webkit-scrollbar {
      width: 8px;
    }
    ::-webkit-scrollbar-track {
      background: #050505;
    }
    ::-webkit-scrollbar-thumb {
      background: #222;
      border-radius: 4px;
    }
    ::-webkit-scrollbar-thumb:hover {
      background: #333;
    }

    .hide-scrollbar::-webkit-scrollbar {
      display: none;
    }
    .hide-scrollbar {
      -ms-overflow-style: none;
      scrollbar-width: none;
    }

    /* Glassmorphism Panel */
    .glass-panel {
      background: rgba(10, 10, 10, 0.4);
      backdrop-filter: blur(12px);
      -webkit-backdrop-filter: blur(12px);
      border: 1px solid rgba(255, 255, 255, 0.05);
    }

    /* Watermark / Ghost Text */
    .ghost-text {
      color: transparent;
      -webkit-text-stroke: 1px rgba(255, 255, 255, 0.08);
    }

    /* Background Mesh & Animations */
    @keyframes grid-drift {
      0% { background-position: 0 0; }
      100% { background-position: 40px 40px; }
    }
    .animated-grid-bg {
      background-image: radial-gradient(circle at 1px 1px, rgba(255, 255, 255, 0.04) 1px, transparent 0);
      background-size: 40px 40px;
      animation: grid-drift 10s linear infinite;
    }

    @keyframes blob-drift {
      0%, 100% { transform: translate(0, 0) scale(1); }
      50% { transform: translate(24px, -18px) scale(1.06); }
    }
    .animate-blob {
      animation: blob-drift 12s ease-in-out infinite;
    }

    @keyframes ghost-drift {
      0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.6; }
      50% { transform: translate(-50%, -52%) scale(1.02); opacity: 0.85; }
    }
    .animate-ghost-drift {
      animation: ghost-drift 14s ease-in-out infinite;
    }

    @keyframes pulse-slow {
      0%, 100% { opacity: 0.4; transform: scale(1); }
      50% { opacity: 1; transform: scale(1.05); }
    }
    .animate-pulse-slow {
      animation: pulse-slow 4s ease-in-out infinite;
    }

    /* Rede de segurança em CSS puro, sem depender de nenhum JS rodar certo.
       Motivo de existir: um navegador real (relatado em 3 aparelhos diferentes,
       incluindo sem cache prévio) ficou com a animação de entrada presa em
       "pausada" mesmo depois do JS remover a classe que pausava — o resgate em
       JS (main.js) supõe que basta tirar a classe, mas isso não é garantia em
       todo motor de navegador. Cada bloco que entra com opacity:0 ganha uma
       SEGUNDA animação, sempre rodando (nunca pausada), que força opacity:1
       depois de um tempo fixo. As duas andam juntas no mesmo "animation:",
       por isso os valores de delay/duração/play-state sempre vêm em pares
       posicionais (entrada, resgate) — nunca um valor solto. */
    @keyframes force-visible-failsafe {
      to { opacity: 1; transform: none; filter: none; }
    }

    @keyframes float-up {
      0% { transform: translateY(20px); opacity: 0; }
      100% { transform: translateY(0); opacity: 1; }
    }
    .reveal-group > * {
      animation: float-up 1s ease-out forwards, force-visible-failsafe 0s linear 4s forwards;
      opacity: 0;
    }
    .reveal-group > *:nth-child(1) { animation-delay: 0.1s, 4s; }
    .reveal-group > *:nth-child(2) { animation-delay: 0.25s, 4s; }
    .reveal-group > *:nth-child(3) { animation-delay: 0.4s, 4s; }
    .reveal-group > *:nth-child(4) { animation-delay: 0.55s, 4s; }
    .reveal-group > *:nth-child(5) { animation-delay: 0.7s, 4s; }
    .reveal-group > *:nth-child(6) { animation-delay: 0.85s, 4s; }

    /* Mobile (≤1023px): pintura barata, obrigatório. Essa regra já existiu
       (commit 62897b6, "Congela fundo decorativo animado no mobile") e se perdeu
       num refactor — o sintoma voltou na hora: seção em branco ao rolar no iPhone.
       O motivo: cada seção tem grid de fundo com background-position animado
       (repaint contínuo) + blob gigante com filter: blur(120–150px) animando, e
       21 painéis com backdrop-filter. O WebKit do iOS rasteriza isso tão devagar
       que os tiles da seção seguinte não ficam prontos quando o scroll chega nela.
       Aqui: animação decorativa congelada, blur decorativo vira radial-gradient
       (mesmo visual de brilho difuso, custo ~zero) e vidro vira fundo sólido
       translúcido. Desktop mantém o efeito completo. NÃO REMOVER de novo. */
    @media (max-width: 1023px) {
      .animated-grid-bg,
      .animate-blob,
      .animate-ghost-drift {
        animation: none;
      }
      .decor-blob {
        filter: none;
        background: radial-gradient(circle closest-side, rgba(212, 175, 55, 0.85), rgba(212, 175, 55, 0.35) 55%, transparent 100%);
      }
      .decor-blob-white {
        background: radial-gradient(circle closest-side, rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0.35) 55%, transparent 100%);
      }
      .glass-panel {
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        background: rgba(10, 10, 10, 0.75);
      }
      #main-header.is-scrolled {
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        background-color: rgba(3, 3, 3, 0.92);
      }
    }

    /* Conteúdo abaixo da hero: SEM animação de entrada, ponto final. Histórico
       (ver git log deste bloco): 1) revelar ao rolar com pausar/resumir, 2)
       animação nova via IntersectionObserver, 3) resgate mais rápido, 4) animar
       tudo no carregamento escondido atrás do preloader. Cada uma quebrou de um
       jeito diferente em uso real. A última (nº4) foi filmada quebrando: a seção
       "Presente exclusivo" ficava em branco por ~1,5s bem depois do preloader já
       ter saído — não é mais pausar/resumir, é o WebKit adiando a pintura de
       conteúdo fora da tela (otimização de bateria/memória, mais agressiva em
       navegação privada) mesmo com a animação tecnicamente "rodando". A hero nunca
       teve esse problema por estar sempre na tela inicial; tudo abaixo dela já
       esteve fora da tela em algum momento. Não existe timer confiável contra
       isso, então a única correção real é não ter timer nenhum: o bloco nasce
       visível, sem opacity:0, sem animation — e a classe .animate-on-scroll foi
       removida do HTML de vez. Não reintroduzir entrada animada fora da hero. */

    /* Conic spin for Premium CTA */
    @keyframes conic-spin {
      to { transform: rotate(360deg); }
    }
    .animate-conic-spin {
      animation: conic-spin 2s linear infinite;
    }

    /* Shimmer Sweep Animation */
    @keyframes shimmer-sweep {
      from { transform: translateX(-100%) skewX(-15deg); }
      to { transform: translateX(200%) skewX(-15deg); }
    }
    .animate-shimmer-sweep {
      animation: shimmer-sweep 1.5s infinite;
      animation-play-state: paused;
    }
    .group:hover .animate-shimmer-sweep {
      animation-play-state: running;
    }

    /* Flashlight tracking card */
    .flashlight-card {
      position: relative;
    }
    .flashlight-card::before {
      content: "";
      position: absolute;
      inset: 0;
      background: radial-gradient(300px circle at var(--mouse-x, 50%) var(--mouse-y, 50%), rgba(212, 175, 55, 0.1), transparent 50%);
      opacity: 0;
      transition: opacity 0.5s;
      pointer-events: none;
      z-index: 1;
    }
    .flashlight-card:hover::before {
      opacity: 1;
    }

    /* Cronograma Timeline — nós numerados + linha com preenchimento (estilo Luminae, adaptado pro dark/gold) */
    .cronograma-section {
      position: relative;
      overflow-x: hidden;
    }
    .cronograma-track {
      position: relative;
    }
    .cronograma-stage {
      position: relative;
      display: flex;
      align-items: center;
      justify-content: center;
      overflow: hidden;
      padding-top: 3.5rem;
      padding-bottom: 3.5rem;
    }
    /* NÃO REINTRODUZIR PIN AQUI. O modo pinado (GSAP ScrollTrigger travando a
       seção na tela) foi removido em 25/08/2026: o pin vira position:fixed +
       spacer e no WebKit a seção "flutuava" por cima da seção anterior — mesmo
       padrão de todas as animações de scroll que já quebraram neste site.
       Hoje a seção fica no fluxo normal e o js/cronograma.js só atualiza
       --progress e data-state ao rolar. */
    .cronograma-viewport {
      position: relative;
    }

    .cronograma-timeline {
      position: relative;
      --progress: 0;
      --node-size: 52px;
    }
    /* Linha contínua (do centro do 1º nó ao centro do último), preenchimento por cima */
    .cronograma-line {
      position: absolute;
      top: calc(var(--node-size) / 2);
      bottom: calc(var(--node-size) / 2);
      left: calc(var(--node-size) / 2);
      width: 2px;
      background: rgba(255, 255, 255, 0.1);
      border-radius: 2px;
      overflow: hidden;
    }
    .cronograma-line-fill {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: calc(var(--progress, 0) * 100%);
      background: linear-gradient(180deg, var(--gold), #8a6f1f);
      border-radius: 2px;
      will-change: height;
    }
    .cronograma-steps {
      list-style: none;
      margin: 0;
      padding: 0;
      display: flex;
      flex-direction: column;
      gap: 2.25rem;
      position: relative;
      z-index: 2;
    }
    .cronograma-step {
      display: flex;
      align-items: flex-start;
      gap: 1.25rem;
    }
    .cronograma-node {
      position: relative;
      flex: 0 0 auto;
      width: var(--node-size);
      height: var(--node-size);
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      background: #0a0a0a;
      border: 1px solid rgba(255, 255, 255, 0.14);
      color: rgba(255, 255, 255, 0.4);
      font-family: 'Playfair Display', serif;
      font-weight: 600;
      font-size: 1rem;
      box-shadow: 0 0 0 6px #020202;
      transition: transform 0.55s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.45s ease, border-color 0.45s ease, color 0.45s ease, box-shadow 0.45s ease;
    }
    .cronograma-node-num {
      transition: opacity 0.3s ease;
    }
    .cronograma-node-check {
      position: absolute;
      font-size: 1.3rem;
      opacity: 0;
      transform: scale(0.5);
      color: #020202;
      transition: opacity 0.4s ease, transform 0.4s cubic-bezier(0.16, 1, 0.3, 1);
    }
    .cronograma-content {
      flex: 1;
      min-width: 0;
      padding-top: 0.35rem;
      transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1), transform 0.6s cubic-bezier(0.16, 1, 0.3, 1), filter 0.6s ease;
    }

    /* Estados ATIVO/CONCLUÍDO — setados via JS (data-state), valem sempre */
    .cronograma-step[data-state="active"] .cronograma-node {
      background: rgba(212, 175, 55, 0.1);
      border-color: var(--gold);
      color: var(--gold);
      transform: scale(1.1);
      box-shadow: 0 0 0 6px #020202, 0 0 0 11px rgba(212, 175, 55, 0.18);
    }
    .cronograma-step[data-state="done"] .cronograma-node {
      background: var(--gold);
      border-color: var(--gold);
      color: #020202;
    }
    .cronograma-step[data-state="done"] .cronograma-node-num {
      opacity: 0;
    }
    .cronograma-step[data-state="done"] .cronograma-node-check {
      opacity: 1;
      transform: scale(1);
    }

    /* Passos ainda não alcançados ficam suaves — só opacidade (sem translate
       nem blur: pintura barata, e o conteúdo continua legível se o leitor
       parar de rolar no meio). */
    .cronograma-section.is-ready .cronograma-step[data-state="idle"] .cronograma-content {
      opacity: 0.45;
    }
    .cronograma-section.is-ready .cronograma-step[data-state="active"] .cronograma-content,
    .cronograma-section.is-ready .cronograma-step[data-state="done"] .cronograma-content {
      opacity: 1;
    }

    /* Fallback estático (mobile/tablet, sem JS, ou "reduzir movimento"): tudo legível de uma vez */
    .cronograma-section:not(.is-ready) .cronograma-node {
      background: var(--gold);
      border-color: var(--gold);
      color: #020202;
    }
    .cronograma-section:not(.is-ready) .cronograma-node-check {
      display: none;
    }
    .cronograma-section:not(.is-ready) .cronograma-line-fill {
      height: 100%;
    }

    /* Nó um pouco menor no mobile, pra não encostar na borda */
    @media (max-width: 767px) {
      .cronograma-timeline {
        --node-size: 32px;
      }
      .cronograma-node {
        box-shadow: 0 0 0 3px #020202;
        font-size: 0.7rem;
      }
      .cronograma-node-check {
        font-size: 0.9rem;
      }
      .cronograma-steps {
        gap: 1.5rem;
      }
      .cronograma-step {
        gap: 0.85rem;
      }
    }

    @media (prefers-reduced-motion: reduce) {
      .cronograma-content,
      .cronograma-node {
        transition: none;
      }
      /* Animações infinitas param quando o visitante pediu menos movimento.
         O marquee congela mostrando o primeiro conjunto (o conteúdo continua
         legível); os fundos decorativos ficam estáticos. */
      .animate-marquee,
      .animate-conic-spin,
      .animate-shimmer-sweep,
      .animate-ping,
      .animated-grid-bg,
      .animate-blob,
      .animate-ghost-drift,
      .animate-pulse-slow {
        animation: none;
      }
    }

    /* Infinite Marquee */
    @keyframes marquee {
      0% { transform: translateX(0); }
      100% { transform: translateX(-50%); }
    }
    .animate-marquee {
      animation: marquee 25s linear infinite;
    }

    /* Header Scrolled Style */
    #main-header.is-scrolled {
      background-color: rgba(3, 3, 3, 0.75);
      backdrop-filter: blur(16px);
      -webkit-backdrop-filter: blur(16px);
      border-bottom-color: rgba(255, 255, 255, 0.05);
    }

    /* Subtle zoom on hover (imagem já vem preto-e-branco de fábrica — sem filter ao vivo,
       que era o que causava o artefato visual em algumas resoluções, ver 2026-08-24) */
    .premium-grayscale-transition {
      transform: translateZ(0) scale(1.05);
      backface-visibility: hidden;
      -webkit-backface-visibility: hidden;
      transition: transform 1.2s cubic-bezier(0.16, 1, 0.3, 1);
    }
    #hero:hover .premium-grayscale-transition {
      transform: translateZ(0) scale(1.08);
    }

    /* Título da Hero: revelação palavra por palavra (efeito exclusivo desse título,
       não usado em mais nenhum lugar do site — ver 2026-08-24). O JS (main.js) separa
       o texto em palavras e aplica .split-word-wrap/.split-word em cada uma; aqui só
       cancelamos a entrada padrão herdada de .reveal-group > * pra não duplicar animação. */
    #hero h1.hero-title {
      animation: none !important;
      opacity: 1;
    }
    .split-word-wrap {
      display: inline-block;
      overflow: hidden;
      vertical-align: bottom;
      /* Respiro pro descendente (j, ç, p, g): a janela de recorte de cada
         palavra termina na altura da linha, e com leading justo o descendente
         era cortado. Padding estende o recorte pra baixo e a margem negativa
         devolve o espaço, sem mexer no layout. */
      padding-bottom: 0.15em;
      margin-bottom: -0.15em;
    }
    .split-word {
      display: inline-block;
      opacity: 0;
      transform: translateY(110%);
      /* O delay de cada palavra (main.js) vem em par posicional "Xs, 4s" —
         o segundo valor é o resgate, ver .reveal-group acima. */
      animation: hero-word-slide-up 0.75s cubic-bezier(0.16, 1, 0.3, 1) forwards,
                 force-visible-failsafe 0s linear 4s forwards;
    }
    @keyframes hero-word-slide-up {
      to { transform: translateY(0); opacity: 1; }
    }
    @media (prefers-reduced-motion: reduce) {
      .split-word {
        animation: none;
        opacity: 1;
        transform: none;
      }
    }
