:root {
  --grain: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 .16 0'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
  --grain-soft: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .3  0 0 0 0 .28  0 0 0 0 .15  0 0 0 .07 0'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
  --liner: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='30' height='30'><rect width='30' height='30' fill='%23E9E3CF'/><g fill='%239A9763' fill-opacity='.55'><ellipse cx='7' cy='9' rx='1.7' ry='4.3' transform='rotate(38 7 9)'/><ellipse cx='11' cy='10' rx='1.7' ry='4.3' transform='rotate(-22 11 10)'/><ellipse cx='22' cy='23' rx='1.7' ry='4.3' transform='rotate(38 22 23)'/><ellipse cx='26' cy='24' rx='1.7' ry='4.3' transform='rotate(-22 26 24)'/></g></svg>");
  /* Veludo, no lugar da trama de linho que havia aqui. A trama era um risco
     cruzado a cada 3px; no close a cena amplia o envelope umas 5x e aquilo
     virava grade de ~19px na tela. Veludo não tem nada que se repita:
     pelo fino + manchas largas e macias + luz rasante. */
  --nap: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='v'><feTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 .17 0'/></filter><rect width='140' height='140' filter='url(%23v)'/></svg>");
  --nuvem: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='c'><feTurbulence type='fractalNoise' baseFrequency='.014' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 .26 0'/></filter><rect width='140' height='140' filter='url(%23c)'/></svg>");
  --veludoluz: radial-gradient(118% 86% at 22% -8%, rgba(255,246,200,.22), rgba(255,246,200,.07) 34%, rgba(255,246,200,0) 66%),
               radial-gradient(96% 72% at 94% 106%, rgba(14,12,2,.28), rgba(14,12,2,0) 62%);
}

/* ---------------- casca do site (substitui as molduras do mockup) ---------------- */
body { margin: 0; background: #F3EFE6; color: #3d3b24; font-family: 'Cormorant Garamond', serif;
       -webkit-text-size-adjust: 100%;
       /* só desliza para baixo: nada de arrastar de lado nem de puxar a
          página na horizontal. No body e não no html de propósito — no html
          isto cortaria a propagação do overflow e o `body.fechado` abaixo
          deixaria de segurar a rolagem enquanto o envelope não abriu. */
       overflow-x: hidden; overscroll-behavior-x: none; }
/* enquanto o envelope nao foi aberto a pagina nao rola: a cena ocupa a tela toda */
body.fechado { overflow: hidden; height: 100svh; }
/* No iPhone as barras do Safari são translúcidas e mostram o que há por baixo:
   por baixo da de cima ficava o fundo creme do body, por baixo da de baixo o
   começo da página ("sábado, às 16 horas"). Com o envelope fechado tudo isso
   é veludo, e a página só existe depois de abrir. */
body.fechado { background: #56561c; }
body.fechado .page { visibility: hidden; }
/* 100% e nao 100vw: 100vw inclui a largura da barra de rolagem vertical, o que
   sobrava alguns pixels e fazia aparecer uma barra de rolagem horizontal */
.screen { width: 100%; height: 100svh; }
@supports not (height: 100svh) { .screen { height: 100vh; } }


/* ---------------- cena ---------------- */
.screen { position: relative; overflow: hidden; cursor: pointer; user-select: none;
          background: var(--grain-soft),
            radial-gradient(circle at 0% 0%, rgba(255,238,196,.95), rgba(255,238,196,0) 48%),
            radial-gradient(circle at 88% 18%, rgba(150,160,112,.30), transparent 26%),
            radial-gradient(circle at 12% 78%, rgba(132,142,96,.26), transparent 30%),
            radial-gradient(circle at 78% 88%, rgba(196,202,164,.45), transparent 28%),
            linear-gradient(165deg, #F5F1E3 0%, #E9EAD8 48%, #D8DCC4 100%); }
.world { position: absolute; inset: 0; transform-origin: 0 0; }
/* zoom, e não transform: scale(). O scale desenha o texto no tamanho pequeno do
   projeto (5px) e depois ESTICA a imagem — no navegador de verdade isso vira
   borrão, enquanto o vetor dos nomes continua nítido. Com zoom o navegador
   recalcula e desenha cada letra já no tamanho final. A geometria é a mesma:
   com origem no centro, scale(k) e zoom:k põem o palco exatamente no mesmo
   lugar e no mesmo tamanho. */
.stage { position: absolute; left: 50%; top: 50%; width: 280px; height: 610px; margin: -305px 0 0 -140px; zoom: var(--k, 1); z-index: 5; }

.rays { position: absolute; inset: 0; z-index: 2; pointer-events: none; mix-blend-mode: screen; }
.rays i { position: absolute; left: 6%; top: -30%; width: var(--w); height: 170%; transform-origin: 50% 0; rotate: var(--r);
          background: linear-gradient(90deg, transparent, rgba(255,236,190,var(--o)) 50%, transparent); animation: shimmer var(--d) ease-in-out infinite alternate; }
@keyframes shimmer { from { opacity: .35; } to { opacity: 1; } }
.motes { position: absolute; inset: 0; z-index: 14; pointer-events: none; }
.motes i { position: absolute; width: var(--s); height: var(--s); border-radius: 50%; background: rgba(255,250,228,.95); box-shadow: 0 0 6px 1px rgba(255,240,200,.8);
           animation: drift var(--d) ease-in-out infinite alternate, twinkle 3.2s ease-in-out infinite alternate; animation-delay: var(--dl); }
@keyframes drift { to { translate: var(--dx) var(--dy); } }
@keyframes twinkle { from { opacity: .15; } to { opacity: .9; } }

.fall { position: absolute; inset: 0; pointer-events: none; }
.fall.back { z-index: 1; } .fall.mid { z-index: 9; } .fall.front { z-index: 12; }   /* opacidade final no JS: o jardim entra com o recuo da câmera */
.f { position: absolute; top: 0; perspective: 220px; animation: fallY var(--dur) linear var(--dl) infinite; }
.f svg, .gi svg { display: block; width: 100%; height: 100%; animation: flutter var(--fl, 1.6s) ease-in-out infinite alternate; }
.fall.back .f { filter: blur(.7px); } .fall.front .f { filter: blur(2px); opacity: .7; }
@keyframes fallY {
  0% { translate: 0 -60px; } 25% { translate: var(--dx) calc(var(--h) * .25); } 50% { translate: calc(var(--dx) * -.5) calc(var(--h) * .5); }
  75% { translate: calc(var(--dx) * .8) calc(var(--h) * .75); } 100% { translate: 0 var(--h); } }
@keyframes flutter { 0% { transform: rotate(-35deg) rotateX(0deg) rotateY(0deg); } 50% { transform: rotate(15deg) rotateX(55deg) rotateY(35deg); } 100% { transform: rotate(55deg) rotateX(10deg) rotateY(75deg); } }
.gust { position: absolute; inset: 0; z-index: 13; pointer-events: none; }
.gi { position: absolute; left: 0; top: 0; perspective: 220px; }

/* z-index 4 (atrás do palco, que é 5): os galhos crescem com a janela e o
   cartão cresce por conta própria, então em telas estreitas eles se cruzavam.
   Passando por trás, emolduram o convite em vez de cobri-lo, em qualquer tela. */
.branch { position: absolute; z-index: 4; pointer-events: none; }
.branch svg { display: block; width: 100%; height: 100%; }
.br-tl { left: 0; top: 0; transform-origin: 0 0; } .br-br { right: 0; bottom: 0; transform-origin: 100% 100%; }
.br-tr { right: 0; top: 0; transform-origin: 100% 0; } .br-bl { left: 0; bottom: 0; transform-origin: 0 100%; }
.phone .br-br { right: -40px; bottom: -50px; }
.br-tl svg, .br-bl svg { transform-origin: 0 0; animation: sway 7s ease-in-out infinite alternate; }
.br-br svg, .br-tr svg { transform-origin: 100% 100%; animation: sway 8s ease-in-out infinite alternate-reverse; }
@keyframes sway { from { rotate: -2.5deg; } to { rotate: 2.5deg; } }

/* ---------------- envelope ---------------- */
.ground { position: absolute; left: 35px; top: 462px; width: 210px; height: 30px; z-index: 0; border-radius: 50%;
          background: radial-gradient(ellipse at center, rgba(52,50,22,.38), rgba(52,50,22,0) 70%); animation: gfloat 4.6s ease-in-out infinite; }
@keyframes gfloat { 50% { scale: .9; opacity: .75; } }
.e-back, .e-pocket, .e-flap { position: absolute; left: 22px; top: 170px; width: 236px; }
.e-back { top: 171px; left: 23px; width: 234px; height: 281px; z-index: 1; box-shadow: 0 3px 8px rgba(30,28,10,.18);
          background: linear-gradient(180deg, rgba(40,36,10,.45), rgba(40,36,10,.1) 30%, transparent 60%), var(--liner); }
.e-pocket { height: 284px; z-index: 4; filter: drop-shadow(0 -1px 1.4px rgba(0,0,0,.3)); }
.pk { position: absolute; inset: 0; clip-path: path('M0 0 Q118 34 236 0 V284 H0 Z');
      background-image: var(--nap), var(--nuvem), var(--veludoluz), linear-gradient(172deg, #66662a 0%, #56561c 55%, #484814 100%);
      /* a nuvem em 100%: em ladrilho de 200px ela se repetia e desenhava uma grade de emendas no envelope */
      background-size: 22px 22px, 100% 100%, auto, auto, auto; }
.e-pocket > svg { position: absolute; inset: 0; width: 100%; height: 100%; }
/* a boca do bolso projeta sombra no cartão: um traço desfocado seguindo a
   curva; o .pk vem depois no DOM e cobre a metade que cairia no próprio bolso */
.mouth { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.mouth path { filter: blur(3px); }
/* e a aba projeta sombra no bolso; some quando a aba levanta (JS) */
.flap-shadow { position: absolute; inset: 0; opacity: .55; pointer-events: none;
               clip-path: path('M0 0 Q118 34 236 0 V284 H0 Z'); }
.flap-shadow i { position: absolute; left: 0; top: 0; width: 236px; height: 160px;
                 background: rgba(20,18,4,.6); filter: blur(5px); translate: 0 7px; }

.e-flap { height: 160px; z-index: 6; transform-origin: 50% 0; transform-style: preserve-3d; }
.seg { position: absolute; left: 0; width: 236px; transform-origin: 50% 0; transform-style: preserve-3d; }
.face { position: absolute; left: 0; width: 236px; height: 160px; backface-visibility: hidden; }
.fc { position: absolute; inset: 0;
      background-image: var(--nap), var(--nuvem), var(--veludoluz), linear-gradient(176deg, #6c6c2c, #55551b);
      background-size: 22px 22px, 100% 100%, auto, auto, auto; }
/* a beirada da aba: cópia escura desfocada por baixo, com a mesma silhueta.
   O desfoque mora num elemento só dele, então o selo continua nítido. Sem
   ela o close vira um verde chapado e não se lê como envelope. Some assim
   que a aba começa a curvar, que é quando a silhueta deixa de valer. */
.beirada { position: absolute; inset: 0; z-index: 0; filter: blur(1.3px); translate: 0 1.6px; }
.beirada i { position: absolute; inset: 0; background: rgba(26,23,6,.6); }
.go .beirada { display: none; }
.face.back .fc { background: linear-gradient(0deg, rgba(40,36,10,.35), rgba(40,36,10,0) 55%), var(--liner); }
.mono-env { position: absolute; left: 82px; top: 46px; width: 72px; height: 72px; }
.mono-env svg { position: absolute; inset: 0; width: 100%; height: 100%; }
/* a logo acende ao tocar: duas camadas (letras e moldura) na cor da luz, e a
   brasa no veludo em volta do selo */
.lit { opacity: 0; filter: drop-shadow(0 0 2.5px rgba(255,225,140,.95)); }
.ember { position: absolute; inset: -70%; opacity: 0; pointer-events: none; border-radius: 50%;
         background: radial-gradient(circle, rgba(255,236,186,.55), rgba(255,236,186,.18) 42%, rgba(255,236,186,0) 70%); }

.e-part, .card { animation: float 4.6s ease-in-out infinite; }
.go .e-part, .go .card, .go .ground { animation-play-state: paused; }
@keyframes float { 50% { translate: 0 -4px; } }

.spill { position: absolute; left: -10px; top: -10px; width: 300px; height: 185px; z-index: 2; opacity: 0; pointer-events: none; filter: blur(12px);
         background: conic-gradient(from 200deg at 50% 100%, transparent 12%, rgba(255,236,186,.5) 26%, rgba(255,248,224,.8) 50%, rgba(255,236,186,.5) 74%, transparent 88%); }
.pollen { position: absolute; left: 140px; top: 172px; z-index: 8; pointer-events: none; }
.pollen i { position: absolute; width: 2.6px; height: 2.6px; border-radius: 50%; background: #ffeeb8; box-shadow: 0 0 5px 1.5px rgba(255,226,150,.6); opacity: 0; }

/* ---------------- cartão ---------------- */
.bloom { position: absolute; left: -40px; top: 125px; width: 360px; height: 360px; z-index: 2; opacity: 0; pointer-events: none;
         background: radial-gradient(circle, rgba(255,249,228,.95), rgba(255,240,200,.35) 40%, rgba(255,240,200,0) 70%); }
.card { position: absolute; left: 8px; top: 135px; width: 264px; height: 340px; z-index: 3; perspective: 900px;
        transform: perspective(1000px) translateY(8px) scale(.82); }
.sheet { position: absolute; inset: 0; transform-style: preserve-3d; }
/* as sombras do cartão (contato + ambiente) e a espessura do papel. Ficam
   FORA do .sheet: dentro do preserve-3d o navegador ordena por profundidade e
   elas, coplanares com o papel, apareciam por cima dele em alguns quadros.
   Animadas por opacity/translate — nada de filter animado. */
.sh { position: absolute; inset: 0; pointer-events: none; background: #2a2608; }
.sh-near { opacity: .18; filter: blur(1.2px); translate: 0 1.5px; }
.sh-far  { opacity: 0;   filter: blur(14px);  translate: 0 8px; scale: .985 .99; }
.edge { position: absolute; inset: 0; pointer-events: none; translate: 0 1.1px;
        background: linear-gradient(180deg, #e9e5d3, #d8d4bf); }
.paper { position: absolute; inset: 0; overflow: hidden; color: #5b5930; text-align: center;
         background: var(--grain-soft), linear-gradient(158deg, #fefdf8 0%, #faf6ea 55%, #f6f2e4 100%);
         /* o grão dividido pelo zoom da cena: sempre do tamanho de um grão, e não ampliado 1,4–2,3x */
         background-size: calc(140px / var(--k, 1)) calc(140px / var(--k, 1)), auto; }
/* a luz do papel. Estava em 35% de branco: onde o clarão encostava, o
   contraste do texto morria — e ele encostava mesmo com o mouse longe.
   Em 15% o papel mantém o volume e o texto parado sobe de 592 para 725
   (variância do Laplaciano, captura em resolução real). */
.paper::after { content: ''; position: absolute; inset: 0; pointer-events: none;
                background: radial-gradient(circle at var(--gx, 28%) var(--gy, 16%), rgba(255,255,255,.15), rgba(60,55,20,.05) 78%); }
.frame1 { position: absolute; inset: 8px; border: .55px solid #cdc9b6; pointer-events: none; }
.frame2 { position: absolute; inset: 11px; border: .3px solid #ddd9c8; pointer-events: none; }
.corner { position: absolute; width: 22px; height: 22px; color: #b3b189; opacity: .75; }
.corner.tl { left: 12px; top: 12px; } .corner.tr { right: 12px; top: 12px; transform: scaleX(-1); }
.corner.bl { left: 12px; bottom: 12px; transform: scaleY(-1); } .corner.br { right: 12px; bottom: 12px; transform: scale(-1); }
.sheen { position: absolute; top: -20%; bottom: -20%; left: 0; width: 45%; pointer-events: none; transform: translateX(-130%) skewX(-12deg);
         background: linear-gradient(100deg, transparent, rgba(232,216,160,.28) 42%, rgba(255,249,226,.6) 50%, rgba(232,216,160,.28) 58%, transparent); }
.ci { position: absolute; inset: 0; padding: 14px 18px; display: flex; flex-direction: column; justify-content: center; align-items: center; }
.paper p { margin: 0; text-shadow: 0 .4px .3px rgba(255,255,255,.9), 0 -.15px .2px rgba(70,66,40,.22); }
.mono-card { width: 56px; height: 56px; margin-bottom: 11px; flex: none; }   /* flex:none: sem ele o layout espremia a logo */
.ring-reveal { stroke-dasharray: 1; stroke-dashoffset: 1; }
.mj { fill: #a6a393; fill-opacity: 0; stroke: #95927f; stroke-width: .4; stroke-dasharray: 1; stroke-dashoffset: 1; }
.mj.sh { fill: #96947f; stroke: #96947f; opacity: .6; }
.names { width: 218px; margin: 5px 0 6px; overflow: visible; flex: none; }
.g { fill: url(#ink); fill-opacity: 0; stroke: #4d4b25; stroke-width: 1.5; stroke-dasharray: 1; stroke-dashoffset: 1; }
.parents, .addr { display: flex; justify-content: space-between; width: 100%; }
.parents p, .addr p { width: 49%; }
.parents { font: 500 5.3px/1.65 Cinzel; letter-spacing: .06em; }   /* 5.3: cada nome de pai/mãe cabe em uma linha, como no impresso */
.conv { font: 500 5px/1.65 Cinzel; letter-spacing: .07em; margin-top: 16px !important; }
.det { font: 500 5px/2.15 Cinzel; letter-spacing: .05em; }   /* 5px: cada linha da cerimônia cabe inteira, como no impresso */
.det + .det { margin-top: 12px !important; }
.addr { font: 500 4.5px/1.65 Cinzel; margin-top: 13px; }   /* 4.5: cabe "…560, cs 34" em uma linha só, como no impresso */
.addr1 { font: 500 4.5px/1.65 Cinzel; margin-top: 9px !important; }
.rsvp { font: 500 5.4px/1.7 Cinzel; letter-spacing: .09em; margin-top: 12px !important; }
.ln { opacity: 0; }
.sprig { width: 34px; height: 12px; color: #a9a87e; opacity: .8; margin: 4px 0 2px; }

/* sem backdrop-filter: era recalculado a cada quadro enquanto o vegetal gira */
.vellum { position: absolute; inset: -3px; z-index: 4; transform-origin: 50% 0;
          background: var(--grain-soft), linear-gradient(150deg, rgba(255,254,250,.72), rgba(246,243,232,.58));
          background-size: calc(140px / var(--k, 1)) calc(140px / var(--k, 1)), auto;
          box-shadow: 0 2px 8px rgba(60,55,25,.14), inset 0 0 22px rgba(255,255,255,.5), inset 0 0 0 .7px rgba(255,255,255,.75);
          display: flex; align-items: center; justify-content: center; }
.vellum svg { width: 96px; height: 96px; color: #6f6d40; opacity: .55; }
/* fio de luz ao virar, e a sombra que ele deixa no papel */
.vsheen { position: absolute; inset: 0; opacity: 0; pointer-events: none;
          background: linear-gradient(180deg, rgba(255,255,255,.6), rgba(255,255,255,0) 48%); }
.vellum-shadow { position: absolute; inset: 0; z-index: 3; opacity: .12; pointer-events: none;
                 background: #3a3614; filter: blur(6px); translate: 0 3px; }

.hint { position: absolute; left: 0; right: 0; bottom: 42px; text-align: center; font: italic 16px 'Cormorant Garamond'; color: #f2ecd4; text-shadow: 0 1px 4px rgba(28,26,8,.55); letter-spacing: .04em; z-index: 15; animation: pulse 2.4s ease-in-out infinite; }
@keyframes pulse { 50% { opacity: .35; } }
/* o pulsar e o sumiço mexem os dois em `opacity`: duas animações disputando a
   mesma propriedade. O Chrome deixa o sumiço vencer, o celular não — e a
   frase continuava piscando com o convite já aberto. Ao tocar, o pulsar para;
   o JS ainda apaga o elemento depois da saída, para não sobrar disputa. */
.go .hint { animation: none; }
/* era 8px cinza: no celular ninguém lia e não se sabia que a página rolava.
   Agora 11px na cor do texto do convite, com um halo claro para ler sobre as
   folhas, e uma seta própria que balança em vez do texto inteiro. */
.more { position: absolute; bottom: 14px; left: 0; right: 0; text-align: center; font: 500 11px Cinzel; letter-spacing: .22em;
        color: #4F4C24; text-shadow: 0 0 6px rgba(245,242,231,.95), 0 0 2px rgba(245,242,231,.95); opacity: 0; z-index: 15; }
.desk .more { font-size: 10px; bottom: 16px; }
.more .seta { display: block; width: 16px; height: 9px; margin: 5px auto 0; overflow: visible;
              filter: drop-shadow(0 0 3px rgba(245,242,231,.95)); }
.done .more .seta { animation: bob 1.6s ease-in-out infinite; }
@keyframes bob { 50% { translate: 0 4px; } }


/* ---------------- o que rola depois do cartao ---------------- */
/* no mockup a .page era um rolador proprio dentro da moldura; aqui ela so
   segue a cena no fluxo normal e a pagina inteira rola */
/* flow-root segura a margem do primeiro divisor: sem isso ela escapava para
   fora e abria uma emenda de 30px entre a cena e a rolagem */
.page { display: flow-root;
        background: var(--grain-soft), linear-gradient(178deg, #DCE0C8 0%, #EDEBDD 14%, #F5F2E7 40%, #F2EFE2 100%);
        color: #4f4c33; text-align: center; }

.col { padding: 0 20px 28px; }
.desk .col { max-width: 520px; margin: 0 auto; padding: 0 20px 34px; }

/* a beirada falsa do cartao (.tail) saiu: o cartao de verdade fica logo acima,
   entao ela duplicava o "role para ver mais" e aparecia um retangulo solto */

/* divisória com raminho */
.rule { display: flex; align-items: center; justify-content: center; gap: 10px; margin: 30px 0 22px; color: #b3b189; }
.rule i { display: block; width: 46px; height: 1px; background: linear-gradient(90deg, transparent, #cdc9b6); }
.rule i + i { background: linear-gradient(90deg, #cdc9b6, transparent); }
.rule svg { width: 30px; height: 11px; opacity: .9; }

.kicker { font: 500 9px Cinzel; letter-spacing: .3em; color: #8a8660; margin: 0 0 12px; text-transform: uppercase; }
.desk .kicker { font-size: 10px; }
h2.date { font: 500 30px Cinzel; letter-spacing: .08em; color: #4F4C24; margin: 0; }
.desk h2.date { font-size: 38px; }
h3 { font: 500 17px Cinzel; letter-spacing: .1em; color: #4F4C24; margin: 0 0 8px; }
.desk h3 { font-size: 20px; }
.page p { margin: 0; font-size: 16px; line-height: 1.45; color: #5f5c40; }
.desk .page p { font-size: 17px; }
.page p.small { font-size: 14px; color: #7a7758; }
.count { font: italic 17px 'Cormorant Garamond'; color: #6f6c48; }
/* contagem regressiva: os números no Cinzel da data, rótulos no mesmo
   miúdo espaçado dos "kickers", e fios verticais como os da divisória */
/* Mais leve que a data (peso 400, menor): a data é o protagonista, a
   contagem acompanha. Células de largura fixa para nada andar quando um
   rótulo vira singular; a dos dias é mais larga porque tem 3 algarismos. */
.contagem { margin-top: 14px; }
.page .contagem .count { font-size: 15px; }
.desk .page .contagem .count { font-size: 16px; }
.contagem + .row2 { margin-top: 18px; }
.relogio { display: flex; justify-content: center; align-items: stretch; margin-top: 6px; }
.relogio > div { width: 66px; }
.relogio > div:first-child { width: 72px; }
.desk .relogio > div { width: 74px; }
.desk .relogio > div:first-child { width: 82px; }
.relogio b { display: block; font: 400 22px/1.15 Cinzel; letter-spacing: .03em; color: #4F4C24; }
.desk .relogio b { font-size: 26px; }
.relogio span { display: block; margin-top: 4px; font: 500 7.5px Cinzel; letter-spacing: .2em; text-transform: uppercase; color: #8a8660; white-space: nowrap; }
.desk .relogio span { font-size: 8px; }
/* o fio fica na altura dos algarismos, e não descendo até os rótulos */
.relogio i { flex: none; width: 1px; margin: 3px 0 17px; background: linear-gradient(180deg, transparent, #cdc9b6 35%, #cdc9b6 65%, transparent); }
@media (max-width: 340px) { .relogio > div, .relogio > div:first-child { width: 58px; } .relogio b { font-size: 19px; } .relogio span { letter-spacing: .12em; } }

.ghost { font: 500 13.5px 'Cormorant Garamond'; letter-spacing: .04em; padding: 7px 15px; border-radius: 22px; cursor: pointer;
         border: 1px solid #c3bfa2; background: rgba(255,255,255,.5); color: #56532f; transition: .18s; }
.ghost:hover { background: #4F4C24; border-color: #4F4C24; color: #fff; }
.ghost svg { width: 12px; height: 12px; vertical-align: -1.5px; margin-right: 5px; }
.row2 { display: flex; gap: 8px; justify-content: center; margin-top: 12px; flex-wrap: wrap; }

/* mapa — o do Google de verdade, no lugar do que era desenhado. Sai o pin e o
   rotulo feitos a mao: o proprio mapa ja marca o Espaco Le Jardin pelo nome. */
.map { position: relative; margin: 16px 0 0; border-radius: 10px; overflow: hidden; height: 200px;
       box-shadow: 0 4px 14px rgba(40,36,10,.14); }
.desk .map { height: 240px; }
.map iframe { display: block; width: 100%; height: 100%; border: 0; }

/* formulário */
.form { margin-top: 14px; text-align: left; }
.fld { margin-bottom: 11px; }
.fld label { display: block; font: 500 8.5px Cinzel; letter-spacing: .2em; color: #8a8660; margin-bottom: 5px; text-transform: uppercase; }
.fld input, .fld textarea { width: 100%; box-sizing: border-box; font: 400 16px 'Cormorant Garamond'; color: #3d3b24;
                        padding: 9px 11px; border: 1px solid #d3cfb8; border-radius: 7px; background: rgba(255,255,255,.72); transition: .18s; }
.fld textarea { height: 56px; resize: none; }
.fld input:focus, .fld textarea:focus { outline: none; border-color: #8f8b5c; background: #fffdf7; box-shadow: 0 0 0 3px rgba(143,139,92,.13); }
.fld input::placeholder { color: #a9a58a; }

.choice { display: flex; gap: 8px; margin: 14px 0 4px; justify-content: center; }
.opt { font: 500 13.5px 'Cormorant Garamond'; padding: 8px 16px; border-radius: 20px; cursor: pointer; transition: .18s; white-space: nowrap;
       border: 1px solid #c3bfa2; background: rgba(255,255,255,.6); color: #56532f; }
.opt:hover { border-color: #8f8b5c; }
.opt.on { background: #4F4C24; border-color: #4F4C24; color: #fff; box-shadow: 0 4px 10px rgba(79,76,36,.25); }
.opt.on.no { background: #7e6b4a; border-color: #7e6b4a; }

.fold { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .45s cubic-bezier(.4,0,.2,1), opacity .35s; opacity: 0; }
.fold > div { overflow: hidden; }
.fold.open { grid-template-rows: 1fr; opacity: 1; }

.who { margin-top: 12px; }
.pl { display: flex; align-items: center; gap: 6px; margin-bottom: 7px; }
.pl input { flex: 1; }
.pl .rm { flex: none; width: 26px; height: 26px; border: 0; background: none; color: #b0ac8e; font-size: 17px; cursor: pointer; line-height: 1; }
.pl .rm:hover { color: #7e6b4a; }
.add { font: 500 13px 'Cormorant Garamond'; color: #6f6c48; background: none; border: 0; cursor: pointer; padding: 2px 0; border-bottom: 1px dashed #b6b291; }
.step { display: flex; align-items: center; gap: 9px; }
.step button { width: 30px; height: 30px; border-radius: 50%; cursor: pointer; line-height: 1; transition: .18s;
               border: 1px solid #c3bfa2; background: rgba(255,255,255,.7); color: #56532f; font: 400 15px 'Cormorant Garamond'; }
.step button:hover { border-color: #8f8b5c; background: #fffdf7; }
.step .num { font: 500 17px Cinzel; color: #4F4C24; min-width: 16px; text-align: center; }
.step .steplbl { font: italic 14px 'Cormorant Garamond'; color: #9c9880; }
h3.conf { margin-top: 4px; }

.send { width: 100%; margin-top: 16px; font: 500 15px Cinzel; letter-spacing: .14em; padding: 13px; border-radius: 9px; cursor: pointer;
        border: 0; background: #4F4C24; color: #fff; box-shadow: 0 6px 16px rgba(79,76,36,.28); transition: .18s; }
.send:hover { background: #5f5c2e; }
.hintf { font-size: 13px; color: #8a8660; margin-top: 9px !important; }

.enviado { display: none; padding: 22px 6px 6px; }
.enviado.on { display: block; animation: up .6s cubic-bezier(.22,1,.36,1) both; }
@keyframes up { from { opacity: 0; transform: translateY(10px); } }
.enviado .seal { width: 54px; height: 54px; margin: 0 auto 10px; }
.enviado .seal svg { width: 100%; height: 100%; color: #8f8c63; }
.enviado h3 { margin-bottom: 6px; }
.enviado .resumo { margin-top: 10px; font-size: 15px; color: #6f6c48; background: rgba(255,255,255,.55); border: 1px solid #e0dcc6;
                border-radius: 9px; padding: 10px 12px; display: inline-block; }
.enviado .again { margin-top: 12px; }

/* ---------------- popup de "obrigado por confirmar" ---------------- */
body.travado { overflow: hidden; }
.pop { position: fixed; inset: 0; z-index: 60; display: none; align-items: center; justify-content: center; padding: 22px; }
.pop.on { display: flex; }
.pop-fundo { position: absolute; inset: 0; background: rgba(34,32,12,.58); backdrop-filter: blur(3px); animation: popfundo .4s ease both; }
@keyframes popfundo { from { opacity: 0; } }
.pop-cartao { position: relative; width: 100%; max-width: 330px; filter: drop-shadow(0 16px 32px rgba(28,26,8,.45));
              animation: popsobe .55s cubic-bezier(.22,1,.36,1) both; }
.desk .pop-cartao { max-width: 380px; }
@keyframes popsobe { from { opacity: 0; transform: translateY(16px) scale(.96); } }
/* mesmo papel do convite, e as mesmas quinas de raminho: é o cartão que
   acabou de ser lido, voltando para agradecer */
.pop-papel { position: relative; overflow: hidden; padding: 26px 24px 20px; text-align: center; color: #5b5930;
             background: var(--grain-soft), linear-gradient(158deg, #fefdf8 0%, #faf6ea 55%, #f6f2e4 100%); }
.pop-m1 { position: absolute; inset: 7px; border: 1px solid #dbd7c2; pointer-events: none; }
.pop-m2 { position: absolute; inset: 10px; border: 1px solid #ece8d7; pointer-events: none; }
.pop-selo { width: 52px; height: 52px; margin: 0 auto 12px; color: #8f8c63; }
.pop-selo svg { display: block; width: 100%; height: 100%; }
.pop-tit { font: 500 20px Cinzel !important; letter-spacing: .05em; color: #4F4C24; margin: 0 0 7px !important; }
.pop-msg { font-size: 15.5px !important; line-height: 1.5; color: #6f6c48 !important; margin: 0 !important; }
.pop-sprig { margin: 13px 0 11px; line-height: 0; }
.pop-data b { display: block; font: 500 23px Cinzel; letter-spacing: .09em; color: #4F4C24; }
.pop-data span { font: italic 15px 'Cormorant Garamond'; color: #7a7758; }
.pop-guarde { font: 500 8.5px Cinzel !important; letter-spacing: .22em; text-transform: uppercase;
              color: #8a8660 !important; margin: 13px 0 9px !important; }
.pop-bts { display: grid; gap: 8px; }
.pop-bts .ghost { width: 100%; padding: 10px 12px; font-size: 14.5px; }
.pop-fechar { display: block; margin: 17px auto 0; font: italic 14.5px 'Cormorant Garamond'; color: #8a8660;
              background: none; border: 0; cursor: pointer; border-bottom: 1px dashed #c6c2a4; padding: 1px 2px; }
.pop-fechar:hover { color: #4F4C24; }

.end { padding: 26px 0 30px; }
.end svg { width: 34px; height: 34px; color: #a9a68a; opacity: .85; }
.end p { font: 500 8px Cinzel !important; letter-spacing: .26em; color: #8a8660 !important; margin-top: 8px !important; }

/* quem já respondeu: o convite aparece aberto, chegando devagar em vez de
   surgir de estalo. `backwards` e não `both`: terminada, a animação não
   deixa nada aplicado na cena (ver "nitidez em repouso" abaixo) */
/* O fade é no que está DENTRO da cena, e não na cena: o degradê do fundo já
   vem pintado antes do JS, e apagar a cena inteira mostrava o creme liso do
   body por um instante — um clarão. */
.volta .screen > * { animation: surge .9s ease-out backwards; }
@keyframes surge { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .volta .screen > * { animation: none; } }

/* ---------------- nitidez em repouso ----------------
   filter, animação infinita e contexto 3D obrigam o navegador a achatar o
   elemento numa imagem antes de a cena ser ampliada — e a cena amplia o selo
   em 4,3x e o cartão em 2,3x. Medido em resolução real: sem o filter a aba
   vai de 27,3 para 34,6; sem a flutuação o cartão vai de 698 para 968.
   Então cada efeito só existe enquanto há movimento. */
.go .fs { filter: drop-shadow(0 2px 1.6px rgba(0,0,0,.3)); }
.done .card { animation: none; }
.done .sheet { transform-style: flat; }
/* A aba é feita de dois gomos para poder curvar, e o `backface-visibility` põe
   cada face numa camada à parte. Encostadas, as duas camadas deixavam um
   degrau de brilho atravessando o selo — 2,94 de 255, medido; a trama do linho
   escondia e o veludo denunciou. Parado não existe face de trás para esconder,
   então as duas voltam a ser uma superfície só e o degrau cai para 1,19, que é
   a variação do próprio veludo. */
.screen:not(.go) .face.back { display: none; }
.screen:not(.go) .face { backface-visibility: visible; }
