/* =========================================================
   Vitoria & João, 07.11.2026
   Paleta: Branco, dourado, verde oliva
   ========================================================= */

:root {
    --branco: #fbfaf6;
    --branco-puro: #ffffff;
    --creme: #f3efe6;
    --oliva: #6b7a3a;
    --oliva-escuro: #4e5a29;
    --oliva-claro: #a3ad7b;
    --dourado: #c9a24a;
    --dourado-escuro: #a67f2e;
    --dourado-claro: #e3c97a;
    --texto: #2e2e2e;
    --texto-suave: #6b6b6b;
    --sombra: 0 10px 30px rgba(46, 46, 46, 0.08);

    --fonte-script: "Great Vibes", cursive;
    --fonte-serif: "Cormorant Garamond", Georgia, serif;
    --fonte-sans: "Montserrat", system-ui, -apple-system, sans-serif;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

/* Qualquer mensagem de erro tem que parar ABAIXO do menu, nunca atrás dele.
   O menu é sticky, então uma âncora que caia na altura exata da mensagem a
   deixa coberta: a pessoa rola até o lugar certo e continua sem ver o aviso.
   Isto vale mesmo sem JavaScript, e é a rede de segurança do bloco de rolagem
   em assets/js/main.js. */
[role="alert"] { scroll-margin-top: 6rem; }
.secao { scroll-margin-top: 5rem; }

body {
    margin: 0;
    font-family: var(--fonte-sans);
    color: var(--texto);
    background: var(--branco);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
    font-family: var(--fonte-serif);
    font-weight: 400;
    letter-spacing: 0.02em;
    color: var(--oliva-escuro);
    margin: 0 0 0.5em;
}

h1 { font-size: clamp(2.5rem, 6vw, 5rem); }
h2 { font-size: clamp(1.8rem, 3.5vw, 2.8rem); text-align: center; }

.script {
    font-family: var(--fonte-script);
    font-weight: 400;
    color: var(--dourado-escuro);
    line-height: 1;
}

.eyebrow {
    font-family: var(--fonte-sans);
    text-transform: uppercase;
    letter-spacing: 0.3em;
    font-size: 0.75rem;
    /* Era --oliva com peso normal. Letra fina, clara e com muito espaçamento
       não sobrevive a uma foto atrás, por mais halo que se ponha: sobra pouco
       traço para o halo abraçar. Cor mais escura (7.13 contra 4.50) e peso
       maior dão corpo à letra, e é isso que resolve. */
    color: rgba(255,255,255,0.94);
    font-weight: 600;
    margin: 0 0 0.5em;
}

a { color: var(--oliva-escuro); text-decoration: none; }
a:hover { color: var(--dourado-escuro); }

/* =========================================================
   NAV
   ========================================================= */
.nav {
    position: sticky;
    top: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.9rem 1.5rem;
    background: rgba(251, 250, 246, 0.92);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid rgba(201, 162, 74, 0.15);
}

.nav-logo {
    font-size: 2rem;
    color: var(--dourado-escuro);
}

.nav-links {
    display: flex;
    gap: 1.8rem;
    align-items: center;
}

.nav-links a {
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    color: var(--texto);
    transition: color .2s ease;
}

.nav-links a:hover { color: var(--dourado-escuro); }

.nav-links .cta {
    background: var(--oliva);
    color: var(--branco-puro);
    padding: 0.6rem 1.1rem;
    border-radius: 999px;
    transition: background .2s ease,
                transform .22s cubic-bezier(0.2, 0.8, 0.3, 1),
                box-shadow .22s cubic-bezier(0.2, 0.8, 0.3, 1);
}
.nav-links .cta:hover { background: var(--oliva-escuro); color: #fff; }

.nav-toggle {
    display: none;
    flex-direction: column;
    gap: 5px;
    background: transparent;
    border: 0;
    cursor: pointer;
    padding: 6px;
}
.nav-toggle span {
    width: 26px; height: 2px; background: var(--oliva-escuro);
    transition: transform .25s, opacity .25s;
}

@media (max-width: 860px) {
    .nav-toggle { display: flex; }
    .nav-links {
        position: absolute; top: 100%; left: 0; right: 0;
        flex-direction: column; gap: 0;
        background: var(--branco);
        border-bottom: 1px solid rgba(201,162,74,0.2);
        max-height: 0; overflow: hidden;
        transition: max-height .3s ease;
    }
    .nav-links.aberto { max-height: 80vh; padding: 1rem 0; }
    .nav-links a { padding: 0.9rem 1.5rem; width: 100%; }
    .nav-links .cta { margin: 0.5rem 1.5rem; text-align: center; }
}

/* =========================================================
   HERO
   ========================================================= */
.hero {
    min-height: 90vh;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 3rem 1.5rem;
    background: var(--branco);
    position: relative;
    isolation: isolate;   /* prende os z-index do hero, não vazam para a página */
}

/* Foto do casal desfocada ao fundo. O desfoque é gravado no arquivo, não
   aplicado por CSS: filter: blur() em imagem de tela cheia repinta a cada
   scroll e trava o celular. Assim custa zero de processamento. */
.hero-fundo {
    position: absolute;
    inset: 0;
    z-index: -2;
    overflow: hidden;
}
.hero-fundo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 32%;   /* mantém o casal no enquadramento */
    display: block;
}

/* Véu sobre a foto: sem ele o texto oliva sobre folhagem verde some.
   Os dois gradientes originais continuam aqui, agora por cima da imagem.

   Mora no ::after do .hero-fundo, e NÃO no ::before do .hero, porque o hero
   já usava ::before e ::after para a moldura dourada dos cantos. Declarar um
   segundo .hero::before não cria outro pseudo-elemento: as regras se fundem,
   e o véu virou um quadrado cinza de 140x140 no canto, herdando a largura da
   moldura. Um elemento só tem um ::before, e este aqui já tinha dono. */
.hero-fundo::after {
    content: "";
    position: absolute;
    inset: 0;
    /* Escurece de leve nas pontas em vez de clarear. A foto continua nítida e
       inteira; o que muda é o texto, que passa a ser claro. */
    background: linear-gradient(180deg,
        rgba(24,26,20,0.34) 0%,
        rgba(24,26,20,0.10) 35%,
        rgba(24,26,20,0.12) 65%,
        rgba(24,26,20,0.42) 100%);
}

/* Halo atrás das letras do topo.
   
   Sombra escura colada no contorno de cada letra clara. A foto varia de
   folhagem escura a roupa branca, e é sobre a roupa branca que a letra clara
   sumiria: a sombra garante uma borda escura ali, sem depender de escurecer
   a foto inteira.

   Várias sombras empilhadas de propósito: uma só, larga, fica fraca demais;
   empilhando, a borda fecha perto da letra e some longe. */
.hero-conteudo .eyebrow,
.hero-conteudo .hero-titulo,
.hero-conteudo .hero-data,
.hero-conteudo .hero-local,
.hero-conteudo .boas-vindas {
    /* Só sombra aqui. Cor fica com cada elemento: este seletor tem duas
       classes e venceria o .hero-titulo, que tem uma, pintando o título de
       branco sem ninguém pedir. */
    text-shadow:
      0 0 1px rgba(12,14,10,1),
      0 0 2px rgba(12,14,10,1),
      0 0 4px rgba(12,14,10,1),
      0 0 9px rgba(12,14,10,0.95),
      0 0 18px rgba(12,14,10,0.6);
}

/* Título é enorme e vazado: precisa de halo mais largo para o miolo das
   curvas não deixar a folhagem escura aparecer entre os traços. */
.hero-conteudo .hero-titulo {
    text-shadow:
      0 0 2px  rgba(12,14,10,1),
      0 0 6px  rgba(12,14,10,0.98),
      0 0 14px rgba(12,14,10,0.88),
      0 0 28px rgba(12,14,10,0.55);
}

.hero::before, .hero::after {
    content: "";
    position: absolute;
    width: 140px; height: 140px;
    border: 1px solid var(--dourado);
    opacity: 0.35;
}
.hero::before { top: 5%; left: 4%; border-right: 0; border-bottom: 0; }
.hero::after { bottom: 5%; right: 4%; border-left: 0; border-top: 0; }

.hero-conteudo {
    max-width: 720px;
    position: relative;
    isolation: isolate;
}

/* Clarão atrás do BLOCO de texto, e não do hero inteiro.
   
   O texto cai justo em cima do casal, que é a parte da foto com mais variação
   de luz: nenhuma cor de letra funciona sobre isso, e halo sozinho não vence.
   Chapar o hero todo resolve e apaga a foto, que foi a versão rejeitada.
   
   Aqui o clarão tem o tamanho do texto, com borda bem difusa: a foto continua
   inteira em volta e some só onde ela atrapalharia a leitura. */
.hero-conteudo::before {
    content: "";
    position: absolute;
    z-index: -1;
    inset: -18% -26%;
    background: radial-gradient(ellipse at center,
        rgba(20,22,17,0.52) 0%,
        rgba(20,22,17,0.42) 34%,
        rgba(20,22,17,0.24) 54%,
        rgba(20,22,17,0.09) 70%,
        rgba(20,22,17,0) 88%);
    pointer-events: none;
}
.hero-titulo { color: var(--dourado-claro); margin: 0.2em 0; font-size: clamp(3.5rem, 10vw, 7rem); }

.hero-data {
    font-family: var(--fonte-serif);
    font-size: clamp(1.2rem, 2.5vw, 1.8rem);
    letter-spacing: 0.4em;
    color: rgba(255,255,255,0.94);
    font-weight: 600;
    margin: 0.5em 0 0.2em;
}
.hero-local {
    font-size: 0.9rem;
    color: rgba(255,255,255,0.88);
    font-weight: 500;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    margin-bottom: 2.5rem;
}

/* Countdown */
.countdown {
    display: flex;
    justify-content: center;
    gap: 1.2rem;
    margin: 2rem 0 2.5rem;
    flex-wrap: wrap;
}
.countdown > div {
    min-width: 80px;
    padding: 1rem 0.6rem;
    background: var(--branco-puro);
    border: 1px solid rgba(201,162,74,0.3);
    border-radius: 10px;
    box-shadow: var(--sombra);
}
.countdown strong {
    display: block;
    font-family: var(--fonte-serif);
    font-size: 2.2rem;
    color: var(--oliva-escuro);
    line-height: 1;
}
.countdown span {
    display: block;
    margin-top: 0.3rem;
    font-size: 0.7rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--texto-suave);
}

.boas-vindas {
    font-family: var(--fonte-serif);
    font-style: italic;
    font-size: 1.1rem;
    margin: 1.5rem 0;
    /* Vive dentro do hero, sobre a foto escura: cor escura sumiria. */
    color: rgba(255,255,255,0.93);
}

/* =========================================================
   BOTÕES
   ========================================================= */
.btn-primario {
    display: inline-block;
    background: var(--oliva);
    color: var(--branco-puro);
    padding: 0.9rem 2.2rem;
    border: 0;
    border-radius: 999px;
    font-family: var(--fonte-sans);
    font-size: 0.85rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.2em;
    cursor: pointer;
    /* Ease-out sem overshoot: sobe e assenta. Um botão saltitante destoaria
       do resto do site. O movimento em si mora no bloco de microinterações. */
    transition: background .2s ease,
                transform .22s cubic-bezier(0.2, 0.8, 0.3, 1),
                box-shadow .22s cubic-bezier(0.2, 0.8, 0.3, 1);
    box-shadow: 0 4px 14px rgba(107,122,58,0.25);
}
.btn-primario:hover {
    background: var(--oliva-escuro);
    color: #fff;
}

/* =========================================================
   SEÇÕES
   ========================================================= */
.secao {
    padding: 5rem 1.5rem;
    max-width: 1100px;
    margin: 0 auto;
}
.secao.alt {
    background: var(--creme);
    max-width: none;
    padding-left: 1.5rem;
    padding-right: 1.5rem;
}
.secao.alt > * { max-width: 1100px; margin-left: auto; margin-right: auto; }

.em-breve {
    text-align: center;
    color: var(--texto-suave);
    font-style: italic;
    font-family: var(--fonte-serif);
    font-size: 1.2rem;
}

/* =========================================================
   RODAPÉ
   ========================================================= */
.rodape {
    background: var(--oliva-escuro);
    color: var(--creme);
    text-align: center;
    padding: 3rem 1.5rem;
}
.rodape .script {
    font-size: 3rem;
    color: var(--dourado-claro);
    margin-bottom: 0.5rem;
}
.rodape p { margin: 0.3rem 0; font-size: 0.85rem; letter-spacing: 0.1em; }
.rodape a { color: var(--dourado-claro); }

/* =========================================================
   LOGIN
   ========================================================= */
.login-page {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem 1rem;
    background:
      radial-gradient(circle at 20% 20%, rgba(201,162,74,0.15), transparent 60%),
      radial-gradient(circle at 80% 80%, rgba(107,122,58,0.15), transparent 60%),
      var(--branco);
}

.login-box {
    background: var(--branco-puro);
    padding: 3rem 2.5rem;
    border-radius: 14px;
    max-width: 440px;
    width: 100%;
    text-align: center;
    box-shadow: var(--sombra);
    border: 1px solid rgba(201,162,74,0.2);
}

.login-box .script { font-size: 3.5rem; margin-bottom: 0.2em; }

.subtitulo {
    font-family: var(--fonte-serif);
    font-style: italic;
    color: var(--oliva-escuro);
    margin: 0 0 2rem;
    font-size: 1.1rem;
}

/* .form-codigo é o mesmo formulário embutido na seção de RSVP da home. */
.form-login,
.form-codigo { text-align: left; }

/* Na home ele não está dentro de um card, então precisa se centralizar sozinho. */
.form-codigo {
    max-width: 420px;
    margin: 2rem auto 0;
    background: var(--branco-puro);
    padding: 2rem;
    border-radius: 14px;
    border: 1px solid rgba(201,162,74,0.2);
    box-shadow: var(--sombra);
}

.form-login label,
.form-codigo label {
    display: block;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.25em;
    color: var(--oliva-escuro);
    margin-bottom: 0.5rem;
}
.form-login input,
.form-codigo input {
    width: 100%;
    padding: 0.9rem 1rem;
    border: 1px solid rgba(107,122,58,0.3);
    border-radius: 8px;
    font-family: var(--fonte-sans);
    font-size: 1rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    background: var(--branco);
    transition: border-color .2s ease, box-shadow .2s ease;
}
.form-login input:focus,
.form-codigo input:focus {
    outline: none;
    border-color: var(--dourado);
    box-shadow: 0 0 0 3px rgba(201,162,74,0.2);
}
.form-login .btn-primario,
.form-codigo .btn-primario { width: 100%; margin-top: 1.2rem; }

.form-login .erro,
.form-codigo .erro {
    color: #a23b2a;
    background: #fdecea;
    padding: 0.7rem 0.9rem;
    border-radius: 6px;
    margin: 1rem 0 0;
    font-size: 0.9rem;
}
.form-login .ajuda,
.form-codigo .ajuda {
    text-align: center;
    margin-top: 1.5rem;
    font-size: 0.8rem;
    color: var(--texto-suave);
}

/* =========================================================
   O GRANDE DIA, cerimônia e festa
   ========================================================= */
.secao-intro {
    text-align: center;
    max-width: 620px;
    margin: 0 auto 2.5rem;
    color: var(--texto-suave);
    font-family: var(--fonte-serif);
    font-size: 1.15rem;
}

.locais {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 1.8rem;
}

.local-card {
    background: var(--branco-puro);
    border: 1px solid rgba(201,162,74,0.25);
    border-radius: 14px;
    padding: 2.2rem 1.8rem;
    text-align: center;
    box-shadow: var(--sombra);
}

.local-rotulo {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.3em;
    color: var(--oliva);
    margin: 0 0 0.8rem;
}

.local-horario {
    font-family: var(--fonte-serif);
    font-size: 2.2rem;
    color: var(--dourado-escuro);
    line-height: 1;
    margin: 0 0 0.6rem;
}
/* Estado provisório: menor e discreto, pra não competir com o horário real. */
.local-horario--pendente {
    font-size: 1rem;
    font-style: italic;
    color: var(--texto-suave);
}

.local-nome {
    font-size: 1.35rem;
    margin: 0 0 0.6rem;
    color: var(--oliva-escuro);
}

.local-endereco {
    color: var(--texto-suave);
    font-size: 0.95rem;
    margin: 0 0 1.8rem;
}

.local-acoes {
    display: flex;
    gap: 0.7rem;
    justify-content: center;
    flex-wrap: wrap;
}

.btn-secundario {
    display: inline-block;
    padding: 0.7rem 1.4rem;
    border: 1px solid var(--oliva);
    border-radius: 999px;
    color: var(--oliva-escuro);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    /* Sombra de repouso quase invisível, mas necessária: sair de `none` faz a
       elevação aparecer de estalo em vez de crescer. */
    box-shadow: 0 1px 3px rgba(46, 46, 46, 0.07);
    transition: background .2s ease,
                color .2s ease,
                transform .22s cubic-bezier(0.2, 0.8, 0.3, 1),
                box-shadow .22s cubic-bezier(0.2, 0.8, 0.3, 1);
}
.btn-secundario:hover {
    background: var(--oliva);
    color: var(--branco-puro);
}

.rodape-sessao {
    margin-top: 1.5rem !important;
    font-size: 0.75rem !important;
    opacity: 0.75;
}

/* =========================================================
   RSVP
   ========================================================= */
.form-rsvp {
    max-width: 560px;
    margin: 0 auto;
    background: var(--branco-puro);
    padding: 2.2rem;
    border-radius: 14px;
    border: 1px solid rgba(201,162,74,0.2);
    box-shadow: var(--sombra);
}

.rsvp-resposta { border: 0; padding: 0; margin: 0 0 1.8rem; }
.rsvp-resposta legend {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.25em;
    color: var(--oliva-escuro);
    margin-bottom: 0.9rem;
    padding: 0;
}

.opcao {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.85rem 1rem;
    border: 1px solid rgba(107,122,58,0.3);
    border-radius: 8px;
    margin-bottom: 0.6rem;
    cursor: pointer;
    transition: border-color .2s ease, background .2s ease;
}
.opcao:hover { border-color: var(--dourado); }
/* :has() dá o destaque da opção marcada sem precisar de JS. Onde não houver
   suporte, o radio nativo já comunica o estado, degrada sem quebrar. */
.opcao:has(input:checked) {
    border-color: var(--oliva);
    background: rgba(107,122,58,0.06);
}
.opcao input { accent-color: var(--oliva); width: 18px; height: 18px; }

.rsvp-legenda {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.25em;
    color: var(--oliva-escuro);
    margin: 0 0 0.9rem;
}

.rsvp-nota {
    font-size: 0.85rem;
    color: var(--texto-suave);
    margin: -0.5rem 0 1rem;
}

/* No celular os três campos não cabem numa linha e o tipo/idade descem para
   a segunda. Aí a proximidade tem que dizer de quem é o quê: campos da MESMA
   pessoa ficam colados, e a distância entre pessoas é bem maior. Sem isso o
   "Criança / 6" abaixo de um nome parece pertencer ao nome de baixo. */
.rsvp-pessoa {
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
    margin-bottom: 1.5rem;
}
.rsvp-pessoa:last-of-type { margin-bottom: 0.6rem; }
.rsvp-pessoa input[type="text"] { flex: 1 1 12rem; min-width: 0; }
.rsvp-pessoa select { flex: 0 0 auto; }

/* Estreito de propósito: são no máximo dois dígitos. */
.rsvp-pessoa .rsvp-idade {
    flex: 0 0 5.5rem;
    width: 5.5rem;
    min-width: 0;
}

/* O atributo hidden precisa vencer o flex do container. */
.rsvp-pessoa [hidden] { display: none; }

.form-rsvp input[type="text"],
.form-rsvp input[type="number"],
.form-rsvp select,
.form-rsvp textarea {
    padding: 0.8rem 0.9rem;
    border: 1px solid rgba(107,122,58,0.3);
    border-radius: 8px;
    font-family: var(--fonte-sans);
    font-size: 0.95rem;
    background: var(--branco);
    color: var(--texto);
    transition: border-color .2s ease, box-shadow .2s ease;
}
.form-rsvp input[type="text"]:focus,
.form-rsvp input[type="number"]:focus,
.form-rsvp select:focus,
.form-rsvp textarea:focus {
    outline: none;
    border-color: var(--dourado);
    box-shadow: 0 0 0 3px rgba(201,162,74,0.2);
}

.rsvp-obs-label {
    display: block;
    margin: 1.6rem 0 0.5rem;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.25em;
    color: var(--oliva-escuro);
}
.form-rsvp textarea { width: 100%; resize: vertical; }
.form-rsvp .btn-primario { width: 100%; margin-top: 1.5rem; }

.form-rsvp .erro {
    color: #a23b2a;
    background: #fdecea;
    border-radius: 6px;
    padding: 0.8rem 1rem;
    margin: 0 0 1.5rem;
    font-size: 0.9rem;
}
.form-rsvp .erro p { margin: 0.2rem 0; }

.rsvp-sucesso {
    max-width: 560px;
    margin: 0 auto 2rem;
    background: rgba(107,122,58,0.08);
    border: 1px solid var(--oliva-claro);
    border-radius: 12px;
    padding: 1.4rem 1.6rem;
    text-align: center;
}
.rsvp-sucesso-titulo {
    font-family: var(--fonte-serif);
    font-size: 1.3rem;
    color: var(--oliva-escuro);
    margin: 0 0 0.3rem;
}
.rsvp-sucesso p { margin: 0; color: var(--texto-suave); font-size: 0.92rem; }

/* ---------------------------------------------------------
   Resposta registrada e pedidos de alteração

   Quatro estados, e a cor é o que os separa num relance:
   oliva para o que está resolvido, dourado para o que espera
   alguém, cinza para o que foi negado.
   --------------------------------------------------------- */
.rsvp-resumo,
.rsvp-pendente,
.rsvp-recusado,
.rsvp-liberado {
    max-width: 560px;
    margin: 0 auto 1.6rem;
    border-radius: 12px;
    padding: 1.4rem 1.6rem;
}

.rsvp-resumo {
    background: var(--branco-puro);
    border: 1px solid rgba(107,122,58,0.25);
    box-shadow: var(--sombra);
}
.rsvp-resumo-titulo,
.rsvp-pendente-titulo,
.rsvp-recusado-titulo,
.rsvp-liberado-titulo {
    font-family: var(--fonte-serif);
    font-size: 1.25rem;
    color: var(--oliva-escuro);
    margin: 0 0 0.6rem;
}
.rsvp-resumo p,
.rsvp-pendente p,
.rsvp-recusado p,
.rsvp-liberado p {
    margin: 0 0 0.5rem;
    color: var(--texto-suave);
    font-size: 0.92rem;
}
.rsvp-resumo-lista {
    list-style: none;
    padding: 0;
    margin: 0.4rem 0 0.8rem;
}
.rsvp-resumo-lista li {
    padding: 0.5rem 0;
    border-bottom: 1px solid rgba(107,122,58,0.12);
    font-size: 0.95rem;
    color: var(--texto);
}
.rsvp-resumo-lista li:last-child { border-bottom: 0; }
.rsvp-resumo-obs {
    font-style: italic;
    border-left: 2px solid var(--oliva-claro);
    padding-left: 0.8rem;
}

/* Esperando decisão dos noivos. */
.rsvp-pendente {
    background: rgba(201,162,74,0.08);
    border: 1px solid var(--dourado-claro);
}
.rsvp-pendente-titulo { color: var(--dourado-escuro); }

.rsvp-recusado {
    background: var(--creme);
    border: 1px solid rgba(46,46,46,0.12);
}
.rsvp-recusado-titulo { color: var(--texto); }

/* Liberado: mesma cor do sucesso, é uma boa notícia. */
.rsvp-liberado {
    background: rgba(107,122,58,0.08);
    border: 1px solid var(--oliva-claro);
}
.rsvp-nota-noivos {
    font-style: italic;
    border-left: 2px solid var(--oliva-claro);
    padding-left: 0.8rem;
    margin-top: 0.8rem !important;
}

/* O aviso de que a resposta vale uma vez só. Discreto, mas antes do botão. */
.rsvp-aviso-final {
    font-size: 0.82rem;
    color: var(--texto-suave);
    background: var(--creme);
    border-radius: 8px;
    padding: 0.8rem 1rem;
    margin: 1.4rem 0 0;
}

.form-alteracao {
    max-width: 560px;
    margin: 0 auto;
}
.form-alteracao textarea {
    width: 100%;
    resize: vertical;
    padding: 0.8rem 0.9rem;
    border: 1px solid rgba(107,122,58,0.3);
    border-radius: 8px;
    font-family: var(--fonte-sans);
    font-size: 0.95rem;
    background: var(--branco-puro);
    color: var(--texto);
}
.form-alteracao textarea:focus {
    outline: 0;
    border-color: var(--oliva);
    box-shadow: 0 0 0 3px rgba(107,122,58,0.12);
}
.form-alteracao .btn-secundario {
    margin-top: 1rem;
    background: none;
    cursor: pointer;
    font-family: var(--fonte-sans);
}
.form-alteracao .erro {
    background: rgba(180,60,60,0.08);
    border: 1px solid rgba(180,60,60,0.3);
    border-radius: 8px;
    padding: 0.8rem 1rem;
    margin-bottom: 1rem;
    color: #8c2f2f;
    font-size: 0.9rem;
}
.form-alteracao .erro p { margin: 0.2rem 0; }
/* Erro que aparece fora de um formulário, quando o próprio formulário não
   está na tela (resposta já registrada, pedido já em aberto). */
.erro-avulso {
    max-width: 560px;
    margin: 0 auto 1.6rem;
    background: rgba(180,60,60,0.08);
    border: 1px solid rgba(180,60,60,0.3);
    border-radius: 8px;
    padding: 0.9rem 1.2rem;
    color: #8c2f2f;
    font-size: 0.9rem;
    text-align: center;
}
.erro-avulso p { margin: 0.2rem 0; }

.ajuda-motivo {
    font-size: 0.85rem;
    color: var(--texto-suave);
    margin: 0.3rem 0 0.8rem;
}

/* =========================================================
   MICROINTERAÇÕES DOS BOTÕES

   Três regras que o "levantar" não pode quebrar:
   1. Touch, :hover gruda depois do toque e o botão fica levantado à toa.
   2. Movimento, quem pediu menos animação no sistema recebe só a cor.
   3. Teclado, quem navega por Tab precisa enxergar onde está.
   ========================================================= */

/* O levantar é exclusivo de quem tem mouse de verdade. */
@media (hover: hover) and (pointer: fine) {
    .btn-primario:hover {
        transform: translateY(-2px);
        box-shadow: 0 8px 22px rgba(107, 122, 58, 0.32);
    }
    /* 3px em vez de 2px, e sombra bem mais forte: aqui o movimento compete com
       o preenchimento de fundo, então precisa de mais curso pra se ler igual. */
    .btn-secundario:hover {
        transform: translateY(-3px);
        box-shadow: 0 10px 20px rgba(107, 122, 58, 0.3);
    }
    /* A nav é sticky e compacta: 1px dá vida sem desalinhar a barra. */
    .nav-links .cta:hover {
        transform: translateY(-1px);
        box-shadow: 0 5px 14px rgba(107, 122, 58, 0.3);
    }
}

/* Pressionar assenta de volta. Vale também em touch, é o retorno de que o
   toque registrou. Rápido de propósito: demora aqui passa sensação de travado. */
.btn-primario:active,
.btn-secundario:active,
.nav-links .cta:active {
    transform: translateY(0);
    box-shadow: 0 2px 6px rgba(107, 122, 58, 0.2);
    transition-duration: .08s;
}

/* Foco por teclado: precisa aparecer sem depender de hover. */
.btn-primario:focus-visible,
.btn-secundario:focus-visible,
.nav-links .cta:focus-visible {
    outline: 2px solid var(--dourado-escuro);
    outline-offset: 3px;
}

/* Por último de propósito: mesma especificidade das regras acima, então a
   ordem no arquivo é o que garante que este bloco vença. */
@media (prefers-reduced-motion: reduce) {
    .btn-primario,
    .btn-secundario,
    .nav-links .cta {
        transition: background .2s ease, color .2s ease;
    }
    .btn-primario:hover,
    .btn-secundario:hover,
    .nav-links .cta:hover,
    .btn-primario:active,
    .btn-secundario:active,
    .nav-links .cta:active {
        transform: none;
    }
}

/* =========================================================
   Galeria do ensaio

   São 92 fotos em orientações misturadas. Grade de colunas em vez de grid
   retangular: assim retrato e paisagem convivem sem cortar ninguém pela
   metade nem deixar buraco branco entre as linhas.
   ========================================================= */
.galeria {
    column-count: 4;
    column-gap: 10px;
    max-width: 1100px;
    margin: 0 auto;
}
.galeria-item {
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    margin: 0 0 10px;
    break-inside: avoid;   /* sem isto a coluna parte a foto ao meio */
    border-radius: 6px;
    overflow: hidden;
    line-height: 0;
    position: relative;
}
.galeria-item img {
    width: 100%;
    /* height:auto anula o atributo height do HTML na hora de desenhar, mas o
       navegador já usou os dois para reservar o espaço antes de carregar. */
    height: auto;
    display: block;
    /* Cinza de espera para a página não pular conforme cada foto chega. */
    background: var(--creme);
    transition: transform .35s cubic-bezier(0.2, 0.8, 0.3, 1), filter .3s ease;
}
.galeria-item:hover img,
.galeria-item:focus-visible img { transform: scale(1.04); filter: brightness(1.06); }
.galeria-item:focus-visible { outline: 2px solid var(--oliva); outline-offset: 3px; }

@media (max-width: 900px) { .galeria { column-count: 3; } }
@media (max-width: 600px) { .galeria { column-count: 2; column-gap: 7px; } .galeria-item { margin-bottom: 7px; } }

/* ---------- visor ---------- */
.visor {
    position: fixed;
    inset: 0;
    z-index: 100;
    background: rgba(26, 28, 22, 0.94);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}
.visor[hidden] { display: none; }
.visor-palco {
    margin: 0;
    max-width: 100%;
    max-height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .7rem;
}
.visor-palco img {
    max-width: min(94vw, 1400px);
    /* Desconta a legenda para a foto nunca passar da altura da tela. */
    max-height: calc(100vh - 5rem);
    width: auto;
    height: auto;
    object-fit: contain;
    border-radius: 3px;
}
.visor-palco figcaption {
    color: rgba(255,255,255,.72);
    font-size: .78rem;
    letter-spacing: .12em;
    font-variant-numeric: tabular-nums;
}
.visor-fechar, .visor-nav {
    position: absolute;
    background: rgba(255,255,255,.1);
    border: 0;
    color: #fff;
    cursor: pointer;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background .2s ease;
}
.visor-fechar:hover, .visor-nav:hover { background: rgba(255,255,255,.24); }
.visor-fechar:focus-visible, .visor-nav:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.visor-fechar {
    top: 1rem; right: 1rem;
    width: 42px; height: 42px;
    font-size: 1.6rem; line-height: 1;
}
.visor-nav {
    top: 50%; transform: translateY(-50%);
    width: 46px; height: 46px;
    font-size: 2rem; line-height: 1;
}
.visor-ant  { left: 1rem; }
.visor-prox { right: 1rem; }

@media (max-width: 600px) {
    /* No celular as setas ficam embaixo, longe do polegar que segura o
       aparelho, e o gesto de arrastar vira o jeito principal de navegar. */
    .visor-nav { top: auto; bottom: 1rem; transform: none; width: 52px; height: 52px; }
    .visor-ant  { left: 22%; }
    .visor-prox { right: 22%; }
    .visor-palco img { max-height: calc(100vh - 9rem); }
}

@media (prefers-reduced-motion: reduce) {
    .galeria-item img { transition: none; }
    .galeria-item:hover img, .galeria-item:focus-visible img { transform: none; }
}

/* ---------- galeria recolhida ----------
   92 fotos de uma vez viram uma parede: o convidado rola muito e nunca chega
   no RSVP, que é o que a gente precisa que ele faça. Mostra as primeiras e
   deixa quem quiser abrir o resto.

   A classe .recolhida é posta pelo JavaScript, não pelo PHP. Sem script, o
   botão não funcionaria, então nesse caso a galeria aparece inteira. */
.galeria-envelope { position: relative; }

.galeria-envelope.recolhida .galeria {
    /* Duas linhas de retratos em 4 colunas. Menos que isso não dá vontade de
       abrir, mais que isso já é a parede que a gente veio evitar. */
    max-height: 820px;
    overflow: hidden;
}

/* Desbotado no pé: sem ele o corte parece a página ter acabado, e ninguém
   procura um botão para algo que não parece continuar. */
.galeria-envelope.recolhida::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 160px;
    pointer-events: none;
    background: linear-gradient(180deg, rgba(243,239,230,0) 0%, var(--creme) 92%);
}

.galeria-mais { text-align: center; margin: 1.4rem 0 0; }
.galeria-mais button { cursor: pointer; font-family: var(--fonte-sans); }
.galeria-mais button[hidden] { display: none; }

@media (max-width: 700px) {
    /* Foto horizontal cortada para retrato perde as pontas e sobra o meio, que
       aqui é a roupa clara dos dois: vira um cinza chapado. Subindo o recorte
       entram os rostos e a folhagem, que é o que faz a foto valer. */
    .hero-fundo img { object-position: 52% 18%; }
}

@media (max-width: 600px) {
    /* No celular a tela é estreita e alta: recolher em vh deixaria pouquíssima
       foto à mostra. Altura fixa dá umas duas linhas em qualquer aparelho. */
    /* 460px mostrava duas fotos e parecia defeito. 790 dá três linhas de
       duas em qualquer aparelho. */
    .galeria-envelope.recolhida .galeria { max-height: 790px; }
    .galeria-envelope.recolhida::after { height: 120px; }
}

/* ---------- lista de quem vem, com nome já escrito ----------
   O convidado não digita nome: ele desmarca quem não vai. O lugar de quem
   falta não passa para outra pessoa, então não existe campo para acrescentar
   gente. */
.rsvp-convidado {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .8rem;
    flex-wrap: wrap;
    padding: .75rem .9rem;
    margin-bottom: .6rem;
    background: var(--branco-puro);
    border: 1px solid rgba(107,122,58,0.25);
    border-radius: 8px;
    transition: opacity .2s ease, border-color .2s ease, background .2s ease;
}

/* Quem foi desmarcado continua visível, e apagado. Sumir com a linha faria a
   pessoa achar que perdeu o nome. */
.rsvp-convidado.nao-vem {
    opacity: .55;
    background: var(--creme);
    border-color: rgba(46,46,46,0.12);
}
.rsvp-convidado.nao-vem .rsvp-nome { text-decoration: line-through; }

.rsvp-marca {
    display: flex;
    align-items: center;
    gap: .6rem;
    cursor: pointer;
    flex: 1 1 12rem;
    min-width: 0;
}
/* Alvo grande o bastante para o dedo: caixa de 16px é o motivo de metade dos
   erros de marcação em celular. */
.rsvp-marca input[type="checkbox"] {
    width: 22px; height: 22px;
    flex: 0 0 auto;
    accent-color: var(--oliva);
    cursor: pointer;
}
.rsvp-nome {
    font-size: 1rem;
    color: var(--texto);
    line-height: 1.3;
}

.rsvp-detalhe { display: flex; gap: .5rem; align-items: center; flex: 0 0 auto; }
.rsvp-detalhe select { flex: 0 0 auto; }
.rsvp-detalhe .rsvp-idade { width: 5.5rem; flex: 0 0 auto; }
.rsvp-detalhe [hidden] { display: none; }

@media (max-width: 600px) {
    .rsvp-convidado { align-items: flex-start; }
    .rsvp-marca { flex-basis: 100%; }
    .rsvp-detalhe { width: 100%; }
    .rsvp-detalhe select { flex: 1 1 auto; }
}

/* =========================================================
   LISTA DE PRESENTES, vitrine na home

   Contraste conferido contra o creme da seção (#f3efe6) e contra o branco do
   card (#ffffff), porque a grade vive nos dois fundos:
     --texto        #2e2e2e sobre #ffffff  13.6:1
     --texto-suave  #6b6b6b sobre #ffffff   5.3:1
     --oliva-escuro #4e5a29 sobre #ffffff   7.5:1
   Nada de texto informativo em --oliva-claro ou --dourado-claro: eles ficam
   abaixo de 4.5:1 em qualquer um dos dois fundos e só servem de enfeite.
   ========================================================= */
.presentes-grade {
    display: grid;
    /* auto-fit com minmax dá 3 colunas no desktop, 2 no tablet e 1 no celular
       sem media query. O mínimo é 260px porque abaixo disso o nome do item
       começa a quebrar em três linhas e a barra fica menor que o texto. */
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 1.5rem;
}

.presente-card {
    display: flex;
    flex-direction: column;
    background: var(--branco-puro);
    border: 1px solid rgba(201,162,74,0.25);
    border-radius: 14px;
    overflow: hidden;
    box-shadow: var(--sombra);
    transition: transform .22s cubic-bezier(0.2, 0.8, 0.3, 1),
                box-shadow .22s cubic-bezier(0.2, 0.8, 0.3, 1);
}

@media (hover: hover) and (pointer: fine) {
    .presente-card:hover {
        transform: translateY(-3px);
        box-shadow: 0 16px 34px rgba(46, 46, 46, 0.12);
    }
    
}



/* A caixa da foto tem altura própria e a imagem recorta dentro dela. Assim a
   grade não dança conforme cada arquivo chega, mesmo com proporções diferentes:
   as medidas do <img> reservam o espaço e o object-fit resolve o resto. */
.presente-foto {
    aspect-ratio: 3 / 2;
    background: var(--creme);
    overflow: hidden;
}
.presente-foto img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.presente-corpo {
    /* Cresce para empurrar o botão para baixo: com nomes de tamanhos
       diferentes, os botões da linha ficam todos na mesma altura. */
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    padding: 1.6rem 1.4rem 1.4rem;
}

.presente-nome {
    font-size: 1.3rem;
    line-height: 1.25;
    margin: 0 0 0.5rem;
    color: var(--oliva-escuro);
}

.presente-descricao {
    margin: 0 0 1.1rem;
    font-size: 0.9rem;
    color: var(--texto-suave);
}

/* Empurra o bloco de números para o pé do card, logo acima do botão. */
.presente-progresso { margin-top: auto; padding-top: 0.6rem; }

.presente-barra {
    height: 8px;
    border-radius: 999px;
    background: rgba(107,122,58,0.15);
    overflow: hidden;
}
.presente-barra-cheio {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--oliva), var(--dourado));
}
/* Com 0% a barra fica completamente vazia e parece elemento que não carregou.
   O fiapo de 3px mostra onde ela começa: "ninguém presenteou ainda" é
   informação, sumir da tela é defeito. */
.presente-barra-cheio { min-width: 3px; }

.presente-numeros {
    margin: 0.7rem 0 0.15rem;
    font-size: 0.95rem;
    color: var(--texto);
}
.presente-numeros strong { color: var(--oliva-escuro); }

.presente-falta {
    margin: 0 0 1.2rem;
    font-size: 0.85rem;
    color: var(--texto-suave);
}
.presente-falta--completo {
    color: var(--oliva-escuro);
    font-weight: 500;
}

/* No card o botão ocupa a largura toda: é o único alvo de toque ali, e no
   celular alvo largo é alvo que ninguém erra. */
.presente-btn {
    width: 100%;
    text-align: center;
    padding: 0.8rem 1rem;
    font-size: 0.78rem;
}

/* Desligado, mas legível: #4e5a29 sobre #f3efe6 dá 6.5:1. Um "disabled"
   cinza-claro padrão do navegador cairia para perto de 2:1 e ninguém
   conseguiria ler o que está escrito. */
.presente-btn:disabled {
    background: transparent;
    color: var(--oliva-escuro);
    border: 1px solid rgba(107,122,58,0.4);
    box-shadow: none;
    cursor: default;
    opacity: 1;
}

.presentes-livre {
    margin: 2.5rem auto 0;
    max-width: 620px;
    text-align: center;
    font-family: var(--fonte-serif);
    font-size: 1.1rem;
    color: var(--texto-suave);
}
.presentes-livre a {
    color: var(--oliva-escuro);
    border-bottom: 1px solid var(--dourado);
}
/* Dourado próprio, e não --dourado-escuro, por causa de contraste. O token
   dá 3,7:1 no branco e 3,2:1 no creme desta seção, abaixo dos 4,5:1 que o
   texto precisa para quem enxerga pouco, e o estado de hover é texto como
   qualquer outro. Este tom fica na mesma família e mede 5,5:1 no branco e
   4,8:1 no creme. Não mexi no token porque ele é usado pelo site inteiro. */
.presentes-livre a:hover { color: #856421; }

/* ---------------------------------------------------------
   O card sem o placar de arrecadação

   A barra de progresso, o "R$ 300,00 de R$ 2.500,00" e o "Faltam R$ 2.200,00"
   saíram do HTML por pedido do dono da festa. As regras deles continuam mais
   acima neste arquivo porque presentear.php ainda usa .presente-numeros e
   .presente-falta dentro do .presente-alvo, onde os números são o ponto: lá a
   pessoa precisa saber quanto vai pagar.

   O que sobrou no card é ilustração, nome, descrição, preço e botão. Com menos
   conteúdo o espaçamento antigo deixava um buraco entre a descrição e o botão,
   então o preço puxa o rodapé para baixo com margin-top: auto e os botões da
   linha continuam alinhados entre si, que era o que .presente-progresso fazia.
   --------------------------------------------------------- */

/* O card inteiro é branco, faixa e corpo, por pedido do dono do projeto: a
   faixa creme separava o desenho do nome como se fossem duas coisas, e não são.
   Sem a divisão, o desenho lê como parte do card e não como cabeçalho dele.
   Altura vem do padding mais os 72 pixels que o próprio <svg> declara, então
   ela existe antes de este arquivo chegar e a grade não remonta no meio do
   carregamento. */
.presente-ilustracao {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem 1rem;
    background: var(--branco-puro);
    /* O traço do desenho herda daqui: o SVG usa stroke="currentColor" e não tem
       cor nenhuma cravada dentro. Sobre branco o oliva ganha contraste em
       relação ao creme de antes, e o desenho já era decorativo de qualquer forma. */
    color: var(--oliva);
}

/* Sem isto o SVG ganha a linha de base do texto e sobra um fiapo de alguns
   pixels embaixo dele, o bastante para a faixa ficar torta ao lado da do card
   vizinho. */
.presente-ilustracao .ilustracao { display: block; }

/* Item completo tem o corpo creme, e a faixa branca acima dele já se distingue
   sozinha. A regra que invertia as duas cores saiu junto com a faixa creme:
   não fazia mais nada. */

/* A faixa já respira por conta própria, então o topo do corpo encolhe: com o
   padding antigo o nome ficava longe demais do desenho e o card esticava sem
   ganhar nada. */
.presente-corpo { padding: 1.3rem 1.4rem 1.4rem; }

/* Preço do presente, e só ele. É número parado, que não conta quanto entrou.
   Serifado e em oliva escuro (7,5:1 no branco, 6,5:1 no creme do item
   completo) porque ele é a informação de peso do card depois do nome.
   O margin-top: auto é o que empurra preço e botão para o pé do card. */
.presente-preco {
    margin: auto 0 1rem;
    /* Um fiapo só, e não os 0,6rem que o bloco antigo usava: a descrição já
       fecha com 1,1rem de margem embaixo, e somar os dois abria um buraco entre
       o texto e o preço que ficava evidente no celular, onde cada card é uma
       linha inteira e não tem card vizinho para disfarçar. */
    padding-top: 0.15rem;
    font-family: var(--fonte-serif);
    font-size: 1.35rem;
    line-height: 1.2;
    color: var(--oliva-escuro);
}

/* No celular a coluna é única e o card inteiro precisa caber na primeira
   dobra, senão o botão Presentear fica abaixo do fim da tela e a pessoa nem
   descobre que ele existe. A faixa aperta, o desenho continua legível. */
@media (max-width: 480px) {
    .presente-ilustracao { padding: 1.1rem 1rem; }
    .presente-corpo { padding: 1.1rem 1.2rem 1.2rem; }
    .presente-preco { font-size: 1.25rem; }
}

/* =========================================================
   PRESENTEAR.PHP, o fluxo do PIX
   ========================================================= */

/* O cabeçalho da home é sanfonado no celular e depende do botão de menu, que
   esta página não tem. Aqui são dois links só, e eles cabem em qualquer
   largura sem virar menu. */
.topo-simples { gap: 1rem; }
.topo-voltar {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    color: var(--texto);
    white-space: nowrap;
}
/* Mesmo motivo do hover em .presentes-livre a: 4,5:1 no estado de hover. */
.topo-voltar:hover { color: #856421; }

.presentear {
    max-width: 760px;
    margin: 0 auto;
    padding: 3rem 1.5rem 4rem;
}
.presentear h1 {
    font-size: clamp(1.9rem, 4.5vw, 2.8rem);
    text-align: center;
    margin-bottom: 1.5rem;
}
.presentear h2 { font-size: clamp(1.5rem, 3vw, 2rem); }

/* O .eyebrow da home é branco, porque nasceu em cima da foto do topo. Aqui o
   fundo é claro e ele precisa da versão escura: #4e5a29 sobre #fbfaf6 dá
   7.1:1, contra 1.1:1 do branco original, que sumiria por completo. */
.eyebrow-escuro { color: var(--oliva-escuro); text-align: center; }

.presente-passo { margin-bottom: 3rem; }
.presente-passo:last-of-type { margin-bottom: 0; }
.presente-passo--avisar {
    border-top: 1px solid rgba(201,162,74,0.3);
    padding-top: 2.5rem;
}

/* O item escolhido, repetido no topo do passo 1: quem chegou por um link
   precisa ver em que presente está mexendo antes de digitar valor nenhum. */
.presente-alvo {
    background: var(--branco-puro);
    border: 1px solid rgba(201,162,74,0.25);
    border-radius: 14px;
    padding: 1.6rem 1.5rem;
    margin-bottom: 2rem;
    box-shadow: var(--sombra);
}
/* Prefixado com .presentear porque `.presentear h2` já reserva um tamanho
   bem maior para os títulos de passo, e sem a especificidade extra o nome do
   item saía do tamanho de um cabeçalho de seção dentro de um card. */
.presentear .presente-alvo-nome { font-size: 1.4rem; margin: 0 0 0.5rem; text-align: left; }
.presente-alvo-descricao { margin: 0 0 1rem; color: var(--texto-suave); font-size: 0.92rem; }
.presente-alvo .presente-numeros { margin-bottom: 0.15rem; }
.presente-alvo .presente-falta { margin-bottom: 0; }

.presente-resumo {
    text-align: center;
    font-family: var(--fonte-serif);
    font-size: 1.3rem;
    color: var(--texto);
    margin: 0 0 2rem;
}
.presente-resumo strong { color: var(--oliva-escuro); }

.presente-explica {
    max-width: 560px;
    margin: 0 auto 1.8rem;
    text-align: center;
    color: var(--texto-suave);
    font-size: 0.95rem;
}

/* Mesmo desenho do formulário do RSVP: é a mesma pessoa preenchendo os dois,
   com dez minutos de diferença. */
.form-presente {
    max-width: 560px;
    margin: 0 auto;
    background: var(--branco-puro);
    padding: 2.2rem;
    border-radius: 14px;
    border: 1px solid rgba(201,162,74,0.2);
    box-shadow: var(--sombra);
}
/* O :not(.opcao) não é preciosismo. .opcao TAMBÉM é um <label>, e sem a
   exclusão as duas escolhas do passo 1 saíam em 12px, maiúsculas e com
   entreletra larga, como se fossem rótulo de campo: "PRESENTEAR O VALOR
   INTEIRO" vira quase ilegível nesse tamanho e some ao lado do resto. */
.form-presente label:not(.opcao) {
    display: block;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.2em;
    color: var(--oliva-escuro);
    margin: 1.2rem 0 0.5rem;
}
.form-presente label:not(.opcao):first-of-type { margin-top: 0; }
.form-presente input[type="text"],
.form-presente input[type="email"],
.form-presente input[type="tel"],
.form-presente textarea {
    width: 100%;
    padding: 0.8rem 0.9rem;
    border: 1px solid rgba(107,122,58,0.3);
    border-radius: 8px;
    font-family: var(--fonte-sans);
    font-size: 1rem;
    background: var(--branco);
    color: var(--texto);
    transition: border-color .2s ease, box-shadow .2s ease;
}
.form-presente textarea { resize: vertical; }
.form-presente input:focus,
.form-presente textarea:focus {
    outline: none;
    border-color: var(--dourado);
    box-shadow: 0 0 0 3px rgba(201,162,74,0.2);
}
.form-presente .btn-primario { width: 100%; margin-top: 1.6rem; }
.form-presente .ajuda {
    text-align: center;
    margin: 1rem 0 0;
    font-size: 0.8rem;
    color: var(--texto-suave);
}
/* "(opcional)" não pode gritar tanto quanto o nome do campo, mas continua
   precisando ser lido: #6b6b6b sobre branco dá 5.3:1. */
.opcional {
    text-transform: none;
    letter-spacing: 0;
    color: var(--texto-suave);
    font-weight: 400;
}

.presente-modo { border: 0; padding: 0; margin: 0 0 1.5rem; }
.presente-modo legend {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.25em;
    color: var(--oliva-escuro);
    margin-bottom: 0.9rem;
    padding: 0;
}
.presente-modo .opcao span { line-height: 1.35; }
.presente-modo .opcao strong { display: block; color: var(--oliva-escuro); }

.presente-campo-valor label { margin-top: 0; }
/* O "R$" fica DENTRO da moldura do campo, não como texto solto ao lado: assim
   ninguém digita "R$" de novo achando que precisa. Se digitar, o servidor
   limpa, mas a dúvida some antes. */
.campo-moeda {
    display: flex;
    align-items: center;
    border: 1px solid rgba(107,122,58,0.3);
    border-radius: 8px;
    background: var(--branco);
    transition: border-color .2s ease, box-shadow .2s ease;
}
.campo-moeda:focus-within {
    border-color: var(--dourado);
    box-shadow: 0 0 0 3px rgba(201,162,74,0.2);
}
.campo-moeda-simbolo {
    padding: 0 0.2rem 0 0.9rem;
    color: var(--texto-suave);
    font-size: 1rem;
}
.form-presente .campo-moeda input[type="text"] {
    border: 0;
    background: transparent;
    box-shadow: none;
    font-size: 1.15rem;
    letter-spacing: 0.02em;
}
.form-presente .campo-moeda input[type="text"]:focus { box-shadow: none; }

/* ---- o QR e o copia e cola ---- */
.pix-caixa {
    display: flex;
    flex-wrap: wrap;
    gap: 1.8rem;
    align-items: flex-start;
    background: var(--branco-puro);
    border: 1px solid rgba(201,162,74,0.25);
    border-radius: 14px;
    padding: 1.8rem;
    box-shadow: var(--sombra);
}
/* O QR precisa de fundo branco e de folga em volta para o leitor achar as
   bordas. O SVG já traz a zona de silêncio, o padding aqui é conforto visual. */
.pix-qr {
    flex: 0 0 auto;
    margin: 0 auto;
    line-height: 0;
    background: #fff;
    border-radius: 10px;
    padding: 0.4rem;
}
.pix-qr svg { display: block; width: 244px; height: 244px; }

.pix-instrucoes { flex: 1 1 260px; }
.pix-instrucoes ol { margin: 0; padding-left: 1.2rem; }
.pix-instrucoes li { margin-bottom: 0.6rem; font-size: 0.95rem; }
.pix-instrucoes li:last-child { margin-bottom: 0; }
.pix-instrucoes strong { color: var(--oliva-escuro); }

.pix-copia { max-width: 100%; margin-top: 1.5rem; }
.pix-copia label {
    display: block;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.2em;
    color: var(--oliva-escuro);
    margin-bottom: 0.5rem;
}
/* Monoespaçado e com quebra em qualquer caractere: o payload é uma string
   longa sem espaço nenhum, e sem o break-all ele estoura a largura da tela no
   celular em vez de quebrar em linhas. */
.pix-codigo {
    width: 100%;
    padding: 0.8rem 0.9rem;
    border: 1px solid rgba(107,122,58,0.3);
    border-radius: 8px;
    background: var(--branco);
    color: var(--texto);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.8rem;
    line-height: 1.5;
    word-break: break-all;
    resize: vertical;
}
.pix-codigo:focus {
    outline: none;
    border-color: var(--dourado);
    box-shadow: 0 0 0 3px rgba(201,162,74,0.2);
}
.pix-copia-acao { margin: 0.9rem 0 0; text-align: center; }
.pix-copia-acao button { cursor: pointer; font-family: var(--fonte-sans); }
.pix-copia-acao button[hidden] { display: none; }
/* Confirmação de que copiou: verde do site, não o azul de sistema. */
.pix-copia-acao button.copiado {
    background: var(--oliva);
    color: var(--branco-puro);
    border-color: var(--oliva);
}
.pix-copia .ajuda {
    margin: 0.8rem 0 0;
    font-size: 0.8rem;
    color: var(--texto-suave);
    text-align: center;
}

/* ---- obrigado e recados ---- */
.presente-obrigado,
.presente-recado {
    max-width: 560px;
    margin: 0 auto;
    text-align: center;
}
.presente-obrigado-texto {
    color: var(--texto);
    font-size: 1rem;
    margin: 0 0 1.1rem;
}
.presente-obrigado-texto strong { color: var(--oliva-escuro); }

.presente-referencia {
    margin: 1.8rem 0 0.4rem;
    font-size: 0.9rem;
    color: var(--texto-suave);
}
.presente-referencia strong {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 1.05rem;
    letter-spacing: 0.08em;
    color: var(--oliva-escuro);
}
.presente-obrigado .ajuda,
.presente-recado p {
    font-size: 0.85rem;
    color: var(--texto-suave);
}
.presente-recado p { font-size: 1rem; }
.presente-recado-acao { margin-top: 2rem; }

@media (max-width: 620px) {
    .presentear { padding: 2rem 1.1rem 3rem; }
    .form-presente { padding: 1.5rem 1.2rem; }
    .pix-caixa { padding: 1.2rem; gap: 1.2rem; }
    /* Empilhado, o QR vem primeiro e as instruções embaixo, que é a ordem em
       que a pessoa usa: aponta a câmera, depois confere o que apareceu. */
    .pix-qr { width: 100%; }
    .pix-qr svg { width: 100%; height: auto; max-width: 280px; margin: 0 auto; }
}

/* ---------------------------------------------------------
   Presente que já foi dado
   ---------------------------------------------------------
   O card continua branco e do mesmo tamanho dos outros, de propósito. A versão
   anterior pintava o corpo de bege, e o dono do projeto reclamou com razão: com
   a faixa do desenho branca em cima e o corpo bege embaixo, o card ficava
   partido ao meio, e bege não quer dizer "já foi" para ninguém que chega no
   site pela primeira vez.

   Preço riscado mais uma linha em dourado é a convenção que lista de casamento
   usa há décadas. Não precisa de legenda, e mantém os dezesseis cards iguais
   entre si: a grade não fica manchada de item para item.
   --------------------------------------------------------- */

.presente-preco--dado {
    /* O risco é o que comunica. Opacidade sozinha só afasta o número sem dizer
       por quê, e some para quem enxerga pouco. */
    text-decoration: line-through;
    /* 0.8, e não 0.5 como eu tinha posto primeiro: medi, e a 0.5 este texto cai
       para 2,35:1 sobre branco, bem abaixo dos 4,5:1 que texto pequeno exige.
       A 0.8 dá 4,50:1 e ainda recua o suficiente para o olho entender que aquele
       preço não vale mais. Preço continua sendo informação, não enfeite: quem
       chega depois quer saber quanto custava o presente que já foi dado. */
    opacity: 0.8;
}

.presente-dado {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    margin: 0;
    padding: 0.2rem 0;
    /* Dourado próprio, mais escuro que o --dourado-escuro da paleta: aquele dá
       3,69:1 sobre branco e reprova para texto pequeno. Este dá 5,52:1 e
       continua lendo como dourado ao lado dele. */
    color: #856320;
    font-size: 1.02rem;
    line-height: 1.35;
}

/* O coração é maciço, ao contrário das ilustrações, que são de traço: aqui ele
   é sinal e não desenho, e traço fino nesse tamanho some. */
.presente-dado svg { flex: none; }

/* =========================================================
   MURAL DE RECADOS E PLAYLIST

   As duas seções ficam abaixo do RSVP e usam o mesmo vocabulário visual do
   resto da home: cartão branco sobre o creme, serifada para o texto que a
   pessoa escreveu, sans para o que o site diz.

   Os seletores nascem como `.secao > .algo` de propósito. A regra
   `.secao.alt > *` lá em cima trava max-width em 1100px em todo filho direto
   da seção creme, e ela tem especificidade maior que uma classe sozinha: sem
   o `.secao >` na frente, o formulário ignorava o próprio max-width e nascia
   com 1100px de largura, com o campo de nome atravessando a tela inteira.
   ========================================================= */

/* Cartão de "deu certo" das seções novas. Mesmas medidas e mesmas cores do
   .rsvp-sucesso: é o mesmo aviso, em outra seção, e duas aparências para a
   mesma ideia fazem o convidado achar que aconteceu coisa diferente.
   Nome próprio, e não reuso do .rsvp-sucesso, para que mexer no visual do
   mural não mexa calado no do RSVP, que é a parte que não pode quebrar. */
.secao > .secao-ok {
    max-width: 620px;
    margin: 0 auto 2.5rem;
    background: rgba(107,122,58,0.08);
    border: 1px solid var(--oliva-claro);
    border-radius: 12px;
    padding: 1.4rem 1.6rem;
    text-align: center;
}
/* Duas classes no seletor, e não uma, de propósito: `.secao-ok p` logo abaixo
   pinta todo parágrafo da caixa de cinza, e vale 0,1,1 de especificidade
   contra os 0,1,0 de uma classe sozinha. Escrito do jeito óbvio, o título
   perdia o tamanho e a cor para a regra seguinte sem ninguém notar, que é
   exatamente o que acontece hoje com o .rsvp-sucesso-titulo lá em cima. */
.secao-ok .secao-ok-titulo {
    font-family: var(--fonte-serif);
    font-size: 1.3rem;
    color: var(--oliva-escuro);
    margin: 0 0 0.4rem;
}
/* Cor própria, mais escura que a --texto-suave da paleta, e o motivo é uma
   conta que eu tinha feito pela metade.
   
   Eu medi #6b6b6b contra o creme da seção e achei 4,64:1, o que passa. Só que
   este bloco não fica sobre o creme: ele fica sobre o CARTÃO, que tem um verde
   a 8% por cima do creme. O fundo real é #e8e6d8, e ali o mesmo cinza cai para
   4,25:1, abaixo dos 4,5:1 que texto pequeno exige.
   
   #616161 dá 4,94:1 sobre o cartão e 6,19:1 sobre branco, então passa nos dois
   lugares em que este bloco aparece. A lição, escrita para o próximo: medir
   contra o fundo que o olho vê, e não contra o da seção. */
.secao-ok p { margin: 0; color: #616161; font-size: 0.95rem; }

/* ---------- Os recados no ar ---------- */
.mural-lista {
    list-style: none;
    margin: 0 auto 1.5rem;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1.2rem;
}

/* Recolhida pelo main.js quando há recado demais para a home. O corte é por
   posição e não por altura: cartão cortado ao meio parece defeito de página,
   e ninguém clica em "ver mais" achando que a página está quebrada. */
.mural-lista.recolhida > li:nth-child(n+7) { display: none; }

.mural-cartao {
    background: var(--branco-puro);
    border: 1px solid rgba(201,162,74,0.2);
    border-radius: 14px;
    padding: 1.4rem 1.5rem;
    box-shadow: var(--sombra);
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
}

.mural-texto {
    margin: 0;
    font-family: var(--fonte-serif);
    font-size: 1.1rem;
    line-height: 1.55;
    color: var(--texto);
    /* Recado colado do WhatsApp vem com link e palavra quilométrica. Sem isto
       a palavra fura o cartão e empurra a grade para fora da tela no celular. */
    overflow-wrap: anywhere;
}

.mural-assinatura {
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.2rem 0.6rem;
    /* Empurra a assinatura para o rodapé do cartão: numa grade os cartões têm
       alturas diferentes, e sem isto o nome fica flutuando no meio de uns e
       colado no fim de outros. */
    margin-top: auto;
    padding-top: 0.2rem;
    border-top: 1px solid rgba(107,122,58,0.15);
}
/* 7,01:1 sobre o branco do cartão. */
.mural-autor {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--oliva-escuro);
    overflow-wrap: anywhere;
}
/* 5,33:1 sobre o branco do cartão. */
.mural-data { font-size: 0.8rem; color: var(--texto-suave); }

.secao > .mural-vazio,
.secao > .mural-nota {
    max-width: 620px;
    margin: 0 auto 2rem;
    text-align: center;
    color: var(--texto-suave);
}
.secao > .mural-vazio {
    font-family: var(--fonte-serif);
    font-size: 1.15rem;
    font-style: italic;
}
.secao > .mural-nota { font-size: 0.9rem; }

.secao > .mural-mais { text-align: center; margin: 0 0 2.5rem; }
/* Sem o botão na tela, o parágrafo vazio deixaria um buraco de 2,5rem entre a
   última fila de recados e o formulário. */
.mural-mais:has(> [hidden]) { margin: 0; }

/* O hidden tem que vencer a classe, e sozinho ele não vence.
   
   [hidden] é o seletor de atributo do navegador, com especificidade de classe.
   .btn-secundario também é classe, e vem depois no arquivo, então ela ganha o
   desempate e o display: inline-block volta. O resultado era um botão
   "Ver os N recados" visível na tela e inerte ao clique, que é a pior
   combinação possível: a pessoa clica, nada acontece, e ela conclui que o site
   está quebrado.
   
   Vale para qualquer botão do site que nasça escondido esperando o JavaScript,
   por isso não está preso ao mural. */
.btn-primario[hidden],
.btn-secundario[hidden] { display: none; }

/* ---------- Os dois formulários ---------- */
.secao > .form-mural,
.secao > .form-playlist {
    max-width: 620px;
    margin: 0 auto;
    text-align: left;
    background: var(--branco-puro);
    padding: 2rem;
    border-radius: 14px;
    border: 1px solid rgba(201,162,74,0.2);
    box-shadow: var(--sombra);
}

.form-mural-titulo {
    font-family: var(--fonte-serif);
    font-size: 1.4rem;
    color: var(--oliva-escuro);
    margin: 0 0 1.2rem;
    text-align: center;
}

.form-mural label,
.form-playlist label {
    display: block;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.25em;
    color: var(--oliva-escuro);
    margin-bottom: 0.5rem;
}
/* A etiqueta de opcional não pode virar caixa alta com 0.25em de espaçamento
   junto com o rótulo: vira ruído e some o que importa, que é a palavra
   "Artista". Fica minúscula, sem espaçamento e mais leve. */
.rot-opcional {
    text-transform: none;
    letter-spacing: 0.02em;
    color: var(--texto-suave);
    font-weight: 400;
}

.form-mural input[type="text"],
.form-mural textarea,
.form-playlist input[type="text"] {
    width: 100%;
    padding: 0.9rem 1rem;
    margin-bottom: 1.4rem;
    border: 1px solid rgba(107,122,58,0.3);
    border-radius: 8px;
    font-family: var(--fonte-sans);
    font-size: 1rem;
    background: var(--branco);
    color: var(--texto);
    transition: border-color .2s ease, box-shadow .2s ease;
}
.form-mural textarea { resize: vertical; line-height: 1.5; }
.form-mural input[type="text"]:focus,
.form-mural textarea:focus,
.form-playlist input[type="text"]:focus {
    outline: none;
    border-color: var(--dourado);
    box-shadow: 0 0 0 3px rgba(201,162,74,0.2);
}

.form-mural .btn-primario,
.form-playlist .btn-primario { width: 100%; }

/* Mesmas cores do erro do RSVP e do formulário de código: um erro do site
   parece a mesma coisa em qualquer seção. #8c2f2f sobre este fundo dá 6,7:1. */
.form-mural .erro,
.form-playlist .erro {
    background: rgba(180,60,60,0.08);
    border: 1px solid rgba(180,60,60,0.3);
    border-radius: 8px;
    padding: 0.8rem 1rem;
    margin: 0 0 1.4rem;
    color: #8c2f2f;
    font-size: 0.9rem;
}
.form-mural .erro p,
.form-playlist .erro p { margin: 0.2rem 0; }

.form-mural .ajuda,
.form-playlist .ajuda {
    text-align: center;
    margin: 1.2rem 0 0;
    font-size: 0.8rem;
    color: var(--texto-suave);
}

/* ---------- O embed do Spotify ---------- */
.secao > .playlist-embed {
    max-width: 620px;
    margin: 0 auto 2.5rem;
    /* O iframe vem com altura fixa de 380px no HTML. Reservar a mesma altura
       aqui evita que o resto da seção pule para baixo quando o Spotify termina
       de carregar, que no 4G da festa acontece bem depois do texto. */
    min-height: 380px;
}
.playlist-embed iframe { display: block; width: 100%; }

@media (max-width: 600px) {
    .mural-lista { grid-template-columns: 1fr; }
    .secao > .form-mural,
    .secao > .form-playlist { padding: 1.5rem 1.2rem; }
}
