/* Casca do site: preloader, painéis, hero, contato e o dossiê impresso.
   Tudo que é leitura do portfólio — cards, lentes, dossiê — vive em atlas.css. */

:root {
    --bg-color: #050507;
    --text-primary: #ffffff;
    --text-secondary: #a0a0a0;
    --accent: #ffffff;
    /* Cor de destaque, editável em /admin > Site > Tema. applyTheme() sobrescreve
       esta propriedade no :root e tudo que a usa repinta de uma vez. */
    --accent-live: #00ff88;
    --glass-bg: rgba(255, 255, 255, 0.03);
    --glass-border: rgba(255, 255, 255, 0.08);
    --glass-blur: 16px;
    --font-main: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --ease: cubic-bezier(0.23, 1, 0.32, 1);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
    background-color: var(--bg-color);
    color: var(--text-primary);
    font-family: var(--font-main);
    -webkit-font-smoothing: antialiased;
    overflow: hidden;
    /* dvh acompanha a barra de endereço do celular; 100vh a ignora e cortava o
       rodapé de cada painel no Safari e no Chrome do Android. */
    height: 100vh;
    height: 100dvh;
    width: 100%;
}

button { font: inherit; color: inherit; }
a { color: inherit; }

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

#preloader {
    position: fixed; inset: 0; z-index: 9999;
    background: var(--bg-color);
    display: flex; align-items: center; justify-content: center;
    transition: opacity 0.8s var(--ease);
}
.loader-content { text-align: center; }
.loader-logo { font-size: 2rem; font-weight: 600; margin-bottom: 20px; letter-spacing: -0.05em; }

/* A largura da barra é escrita pelo JS a cada etapa real do carregamento —
   não existe mais animação de duração fixa fingindo progresso. */
.loader-track { width: 140px; height: 2px; margin: 0 auto; background: rgba(255,255,255,0.12); overflow: hidden; }
.loader-line { width: 0%; height: 100%; background: var(--accent-live); }
.loader-pct {
    margin-top: 12px; font-size: 0.7rem; letter-spacing: 0.25em;
    color: var(--text-secondary); font-variant-numeric: tabular-nums;
}

/* scaleX em vez de width: largura animada é layout a cada quadro de rolagem;
   transform é só composição. */
.scroll-progress {
    position: fixed; top: 0; left: 0; height: 3px; width: 100%;
    background: var(--accent-live); z-index: 9998;
    transform: scaleX(0); transform-origin: left center; will-change: transform;
}

/* ══════════════════════════════════════════════════════════════ painéis ═══ */

main#horizontal-scroll {
    display: flex; flex-direction: row;
    height: 100vh; height: 100dvh; width: 100%;
    overflow-x: auto; overflow-y: hidden;
    /* Sem scroll-snap no desktop: conflitaria com o lerp do JS. */
    scrollbar-width: none; -ms-overflow-style: none;
}
main#horizontal-scroll::-webkit-scrollbar { display: none; }

.panel {
    flex: 0 0 100vw; height: 100%; position: relative;
    display: flex; align-items: center; justify-content: center;
    /* Padding superior maior que o .fixed-header (top:40px) para o conteúdo
       nunca ser centralizado por baixo dele em telas baixas. */
    padding: clamp(96px, 13vh, 140px) 5vw clamp(40px, 8vh, 72px);
}
.projects-panel { align-items: stretch; padding-block: clamp(88px, 12vh, 128px) clamp(28px, 5vh, 48px); }

.fixed-header {
    position: fixed; top: 40px; left: 5vw; right: 5vw; z-index: 10;
    display: flex; justify-content: space-between;
    mix-blend-mode: difference;
}

.logo { font-weight: 600; letter-spacing: -0.05em; font-size: 1.5rem; position: relative; }
.glitch { position: relative; color: white; }
.glitch::before, .glitch::after {
    content: attr(data-text); position: absolute; top: 0; left: 0;
    width: 100%; height: 100%; background: var(--bg-color);
}
/* clip é propriedade legada e a GPU não sabe compor a animação: cada quadro
   voltava para a thread principal. clip-path faz o mesmo recorte e é composta. */
/* O glitch só roda com o hero na tela (html.hero-visible, marcado pelo main.js)
   ou sob o ponteiro. O logo mora no cabeçalho FIXO: animado sem parar, ele
   piscava por cima de todas as seções — projetos, dossiê, contato. Parado, os
   pseudo-elementos ficam recolhidos e o logo é só texto. */
.glitch::before, .glitch::after { clip-path: inset(50% 0 50% 0); }
.glitch::before { left: 2px; text-shadow: -1px 0 #ff00c1; }
.glitch::after { left: -2px; text-shadow: -1px 0 #00fff9; }
html.hero-visible .glitch::before, html.hero-visible .glitch::after,
.glitch:hover::before, .glitch:hover::after {
    animation: glitch 5s infinite linear alternate-reverse;
}
@keyframes glitch {
    0%        { clip-path: inset(58% 0 34% 0); }
    5%        { clip-path: inset(20% 0 72% 0); }
    10%       { clip-path: inset(78% 0 8% 0); }
    15%       { clip-path: inset(6% 0 88% 0); }
    20%       { clip-path: inset(44% 0 46% 0); }
    25%, 100% { clip-path: inset(50% 0 50% 0); }
}

.nav-link {
    position: relative; color: var(--text-primary); text-decoration: none;
    font-size: 0.85rem; letter-spacing: 0.04em; padding-bottom: 3px;
    opacity: 0.7; transition: opacity 0.3s var(--ease);
}
.nav-link:hover { opacity: 1; }
/* Filete que cresce da esquerda em vez de aparecer inteiro de uma vez. */
.nav-link::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
    background: currentColor; transform: scaleX(0); transform-origin: left;
    transition: transform 0.4s var(--ease);
}
.nav-link:hover::after { transform: scaleX(1); }

/* ══════════════════════════════════════════════════════════════ tipografia ═ */

/* O teto de 4rem fazia uma linha de ~27 caracteres estourar os 704px úteis do
   card e cair para uma terceira linha — e como cada idioma tem comprimento
   diferente, o card pulava de altura a cada troca. */
h1 {
    font-size: clamp(1.75rem, 4.2vw, 3.05rem);
    font-weight: 300; line-height: 1.12; margin-bottom: 1.5rem; letter-spacing: -0.03em;
}
h2 { font-size: 1.5rem; font-weight: 400; margin-bottom: 2rem; color: var(--text-secondary); }
.subtitle { color: var(--text-secondary); font-size: 1.1rem; max-width: 500px; line-height: 1.5; }

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

.glass-card {
    background: var(--glass-bg);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border); border-radius: 12px;
    padding: 3rem; box-shadow: 0 20px 40px rgba(0,0,0,0.2);
    width: 100%; max-width: 100%;
}
.hero-card { max-width: 800px; }

/* Em tela de toque o desfoque sai. backdrop-filter sobre um canvas que anima a
   cada quadro obriga a GPU a refazer o blur inteiro a cada quadro — no celular
   era metade do custo da rolagem. O vidro vira um fundo quase opaco. */
@media (hover: none), (max-width: 768px) {
    .glass-card {
        backdrop-filter: none; -webkit-backdrop-filter: none;
        background: rgba(10, 11, 15, 0.86);
    }
}

/* ══════════════════════════════════════════════════════════════════ hero ══ */

.hero-meta { display: flex; align-items: center; gap: 12px; margin-bottom: 1rem; }
.status-indicator {
    display: inline-flex; align-items: center; gap: 7px;
    font-size: 0.75rem; color: var(--accent-live);
    text-transform: uppercase; letter-spacing: 0.1em;
}
/* O pulso era um box-shadow animado — propriedade que a GPU não compõe, então
   o anel repintava na thread principal a cada quadro, para sempre. Agora é um
   pseudo-elemento em transform + opacity, ambos compostos. */
.status-dot { position: relative; width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.status-dot::after {
    content: ''; position: absolute; inset: 0; border-radius: 50%; background: currentColor;
    animation: statusPulse 2.4s var(--ease) infinite; will-change: transform, opacity;
}
.status-indicator.is-off { color: var(--text-secondary); }
.status-indicator.is-off .status-dot::after { animation: none; opacity: 0; }
@keyframes statusPulse {
    0%   { transform: scale(1);   opacity: 0.55; }
    70%  { transform: scale(3.2); opacity: 0; }
    100% { transform: scale(3.2); opacity: 0; }
}

/* Sem transição em color/border-color: são propriedades que a GPU não compõe. */
.lang-indicator {
    font-size: 0.65rem; letter-spacing: 0.18em; color: var(--text-secondary);
    border: 1px solid var(--glass-border); border-radius: 3px;
    padding: 2px 7px; font-variant-numeric: tabular-nums;
}
.lang-indicator.switching { color: var(--accent-live); border-color: color-mix(in srgb, var(--accent-live) 35%, transparent); }

/* min-height reserva as duas linhas para o card não pular a cada troca. */
.hero-headline { min-height: 2.6em; }
/* O texto encosta na BASE da área reservada: quando o idioma da vez ocupa
   menos linhas que o mais longo, o respiro fica acima, sob a etiqueta do
   idioma, e não como um vão entre o título e o subtítulo. */
.headline-anim { display: flex; flex-direction: column; justify-content: flex-end; }
.headline-anim .line { display: block; }
.headline-anim .line:empty::before { content: '\200b'; }
.scramble-char { color: var(--accent-live); opacity: 0.65; }

/* No desktop a navegação é horizontal, então o indicador varre para a direita —
   a direção do gesto que ele está pedindo. */
.scroll-hint {
    display: flex; align-items: center; gap: 14px; margin-top: 2.25rem;
    font-size: 0.65rem; letter-spacing: 0.24em; text-transform: uppercase; color: var(--text-secondary);
}
.scroll-hint .line { position: relative; width: 88px; height: 1px; background: var(--glass-border); overflow: hidden; flex: none; }
.scroll-hint .line::after {
    content: ''; position: absolute; inset: 0;
    background: linear-gradient(90deg, transparent, var(--accent-live), transparent);
    animation: hintSweep 2.8s var(--ease) infinite;
}
@keyframes hintSweep { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }

@media (max-width: 768px) {
    /* No celular o gesto é vertical: a varredura desce em vez de atravessar. */
    .scroll-hint .line { width: 1px; height: 34px; }
    .scroll-hint .line::after {
        background: linear-gradient(180deg, transparent, var(--accent-live), transparent);
        animation-name: hintSweepDown;
    }
    @keyframes hintSweepDown { 0% { transform: translateY(-100%); } 100% { transform: translateY(100%); } }
}

/* Grid em vez de flex-wrap: com flex, um valor longo como "Presidente Prudente"
   empurrava o último item para uma linha só dele, ocupando a largura inteira. */
.stat-rail {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(104px, 1fr)); gap: 1px;
    margin-top: 2.5rem; background: var(--glass-border);
    border-block: 1px solid var(--glass-border);
}
.stat-rail:empty { display: none; }
.stat { background: var(--bg-color); padding: 12px 14px 13px; display: flex; flex-direction: column; gap: 4px; }
.stat-key { font-size: 0.58rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-secondary); }
.stat-value {
    font-size: 0.98rem; font-weight: 600; letter-spacing: -0.01em; line-height: 1.25;
    overflow-wrap: anywhere; font-variant-numeric: tabular-nums;
}
.stat-value.is-accent { color: var(--accent-live); }

/* ═══════════════════════════════════════════════════════════════ contato ══ */

.form-card { width: 100%; max-width: 500px; }
.input-group { margin-bottom: 1.5rem; }

label {
    display: block; font-size: 0.75rem; text-transform: uppercase;
    color: var(--text-secondary); margin-bottom: 0.5rem; letter-spacing: 0.05em;
}
input, textarea, select {
    width: 100%; max-width: 100%; background: rgba(0,0,0,0.3);
    border: 1px solid var(--glass-border); color: white; padding: 12px;
    font-family: var(--font-main); border-radius: 4px; transition: 0.3s; resize: vertical;
}
textarea { min-height: 80px; max-height: 400px; }
input:focus, textarea:focus, select:focus { outline: none; border-color: var(--accent); background: rgba(0,0,0,0.5); }

.submit-btn {
    width: 100%; padding: 15px; background: white; color: black;
    border: none; font-weight: 600; cursor: pointer; border-radius: 4px; transition: 0.3s;
}
.submit-btn:hover { background: #e0e0e0; transform: scale(0.98); }
.submit-btn:disabled { opacity: 0.5; cursor: default; transform: none; }

.social-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 1.75rem; }
.social-row:empty { display: none; }
.social-link {
    font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--text-secondary); text-decoration: none;
    border: 1px solid var(--glass-border); border-radius: 4px; padding: 7px 13px;
    transition: color 0.3s, border-color 0.3s, background 0.3s;
}
.social-link:hover {
    color: var(--text-primary);
    border-color: color-mix(in srgb, var(--accent-live) 40%, transparent);
    background: color-mix(in srgb, var(--accent-live) 7%, transparent);
}

.toast {
    position: fixed; bottom: 30px; right: 30px; z-index: 100;
    background: white; color: black; padding: 15px 25px; border-radius: 4px; font-weight: 600;
    transform: translateY(0); transition: 0.4s var(--ease);
    box-shadow: 0 10px 30px rgba(0,0,0,0.5);
}
.toast.hidden { transform: translateY(100px); opacity: 0; }

/* ═════════════════════════════════════════════════════════════ revelação ══ */

/* Só esconde se o JS estiver mesmo rodando: sem a classe .js — script quebrado,
   módulo bloqueado — o conteúdo aparece normalmente. */
html.js [data-reveal] {
    opacity: 0; transform: translateY(26px);
    transition: opacity 0.75s var(--ease), transform 0.75s var(--ease);
}
html.js [data-reveal].is-revealed { opacity: 1; transform: none; }

/* Botões magnéticos voltam sozinhos ao centro quando o ponteiro sai. */
.magnetic { transition: transform 0.35s var(--ease); }

:focus-visible { outline: 2px solid var(--accent-live); outline-offset: 3px; border-radius: 2px; }

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

.print-only { display: none; }

/* ══════════════════════════════════════════════════════════════ mobile ════ */

@media (max-width: 768px) {
    main#horizontal-scroll {
        flex-direction: column; overflow-y: auto; overflow-x: hidden;
        /* proximity, e não mandatory: o painel de projetos é mais alto que a
           tela, e o snap obrigatório arrancava o visitante do meio da lista
           de volta para o topo do painel. */
        scroll-snap-type: y proximity;
    }
    .panel { flex: none; height: auto; min-height: 90vh; min-height: 90dvh; padding: 100px 20px; scroll-snap-align: start; }
    .projects-panel { min-height: 100vh; min-height: 100dvh; padding-bottom: 56px; }
    .glass-card { padding: 1.75rem 1.4rem; }

    /* Cabeçalho do celular: barra de verdade, sem mix-blend-mode. Com o blend
       "difference" o logo e o botão invertiam de cor passando sobre os cards
       — a parte "esquisita" da rolagem. Transparente no topo, sólido depois
       de 24px, recolhe ao descer e volta ao primeiro gesto para cima. */
    .fixed-header {
        top: 0; left: 0; right: 0; align-items: center;
        padding: calc(12px + env(safe-area-inset-top)) 20px 12px;
        mix-blend-mode: normal;
        border-bottom: 1px solid transparent;
        transition: transform 0.38s var(--ease), background-color 0.3s var(--ease), border-color 0.3s var(--ease);
    }
    .fixed-header.is-solid { background-color: rgba(5, 5, 7, 0.92); border-bottom-color: var(--glass-border); }
    .fixed-header.is-tucked { transform: translateY(-100%); }
    .logo { font-size: 1.3rem; }
    .nav-link {
        padding: 8px 14px; border: 1px solid var(--glass-border); border-radius: 999px;
        font-size: 0.78rem; opacity: 1; background: rgba(255,255,255,0.03);
    }
    .nav-link::after { display: none; }
    .panel { padding-top: calc(84px + env(safe-area-inset-top)); }

    /* Hero alinhado ao topo, e não ao centro: com o cartão centralizado, cada
       mudança de altura (fonte chegando, idioma trocando) movia o topo junto —
       era quase todo o CLS do celular (0,19 medido). Quatro linhas de título
       reservadas desde o primeiro quadro: é o que o idioma mais longo ocupa
       em 375 px, então a reserva medida pelo JS não cresce depois. */
    .intro-panel { align-items: flex-start; }
    .headline-anim { min-height: 4.48em; }
    /* 16px evita o zoom automático do iOS ao focar o formulário de contato. */
    input, textarea, select { font-size: 16px; }
    .toast { left: 16px; right: 16px; bottom: calc(16px + env(safe-area-inset-bottom)); }
}

/* ══════════════════════════════════════════════════════════════ impressão ══
   Ctrl+P converte o site horizontal num dossiê A4. As regras dos cards e do
   dossiê de projeto ficam em atlas.css, junto do que elas descrevem. */

@media print {

    @page { size: A4; margin: 18mm 16mm 16mm; }

    html, body {
        background: #fff !important; color: #14161a !important;
        width: auto !important; height: auto !important; overflow: visible !important;
        font-size: 10.5pt; line-height: 1.5;
        -webkit-print-color-adjust: exact; print-color-adjust: exact;
    }
    html.custom-cursor, html.custom-cursor * { cursor: auto !important; }

    /* --- remove todo o cromo de tela --- */
    #preloader, #stage, .scroll-progress, .toast, .scroll-hint, .fixed-header,
    .hero-meta, #contactForm, .headline-anim, .social-row {
        display: none !important;
    }

    /* No papel entra o texto real do headline, não o idioma que estava na tela. */
    .hero-headline { min-height: 0 !important; }
    .hero-headline .sr-only {
        position: static; width: auto; height: auto; margin: 0;
        overflow: visible; clip: auto; white-space: normal;
    }

    .print-only { display: block; }

    /* --- scroll horizontal vira fluxo de documento --- */
    main#horizontal-scroll { display: block !important; width: auto !important; height: auto !important; overflow: visible !important; }
    .panel {
        display: block !important; flex: none !important;
        width: auto !important; height: auto !important; min-height: 0 !important;
        padding: 0 !important; margin: 0 0 10mm;
    }
    .glass-card {
        background: none !important; backdrop-filter: none !important;
        -webkit-backdrop-filter: none !important;
        border: none !important; box-shadow: none !important; border-radius: 0 !important;
        padding: 0 !important; max-width: none !important; transform: none !important;
    }

    /* --- cabeçalho do documento --- */
    .print-head { border-bottom: 1.5pt solid #14161a; padding-bottom: 4mm; margin-bottom: 7mm; }
    .print-name { font-size: 26pt; font-weight: 600; letter-spacing: -0.04em; line-height: 1; }
    .print-role { font-size: 9pt; text-transform: uppercase; letter-spacing: 0.18em; color: #5a626e; margin-top: 3mm; }
    .print-contact { font-size: 9pt; color: #3c4350; margin-top: 4mm; display: flex; flex-wrap: wrap; gap: 0 5mm; }
    .print-contact span::before {
        content: ''; display: inline-block; width: 3pt; height: 3pt;
        background: #00a35c; border-radius: 50%; margin-right: 2mm; vertical-align: middle;
    }

    .print-section-label {
        font-size: 8pt; text-transform: uppercase; letter-spacing: 0.2em; color: #8a919c;
        border-bottom: 0.5pt solid #d8dce2; padding-bottom: 2mm; margin-bottom: 5mm; break-after: avoid;
    }

    /* --- perfil --- */
    .intro-panel h1 {
        font-size: 15pt !important; font-weight: 400; line-height: 1.35;
        color: #14161a !important; margin: 0 0 3mm; letter-spacing: -0.01em; max-width: 150mm;
    }
    .intro-panel .subtitle { font-size: 10pt; color: #5a626e !important; max-width: 150mm; }

    /* --- barra de métricas ---
       Na tela o rail é um truque: o fundo do container aparece pelos gaps de 1px
       e vira a grade, com cada .stat pintada da cor do site por cima. No papel
       isso saía como cinco tijolos #050507 sólidos com texto cinza dentro — os
       "itens destacados com fundo preto". A estrutura continua a mesma, só
       troca a tinta: o container vira o filete e as células viram papel. */
    .stat-rail {
        background: #d8dce2 !important; gap: 0.5pt !important;
        border-block: 0.5pt solid #d8dce2 !important;
        margin-top: 6mm !important;
        grid-template-columns: repeat(auto-fit, minmax(26mm, 1fr)) !important;
        break-inside: avoid;
    }
    .stat { background: #fff !important; padding: 2.5mm 3mm 3mm !important; gap: 1mm !important; }
    .stat-key { font-size: 7pt; letter-spacing: 0.14em; color: #8a919c !important; }
    .stat-value { font-size: 9.5pt; color: #14161a !important; }
    /* Verde de impressão, o mesmo do marcador de contato — o accent da tela pode
       ser qualquer cor vinda do /admin, inclusive uma que some no papel. */
    .stat-value.is-accent { color: #00a35c !important; }

    .contact-panel { break-inside: avoid; page-break-inside: avoid; }
    .contact-panel h2 { display: none; }

    .print-footer {
        margin-top: 8mm; padding-top: 4mm; border-top: 0.5pt solid #d8dce2;
        font-size: 8pt; color: #8a919c; display: flex; justify-content: space-between; gap: 5mm;
    }
}
