/* ===========================================================================
   Convite de Noivado

   Escala tipográfica e de espaçamento fluidas: tudo deriva das variáveis
   --step-* e --s-*, para que o ritmo se mantenha coerente do telemóvel ao
   ecrã grande sem saltos abruptos.
   =========================================================================== */

:root {
  /* --- paleta: Noite Esmeralda ------------------------------------------------
     Festa à noite, num salão: verde-esmeralda profundo como cor de fundo das
     secções escuras (envelope, abertura, contagem, fecho), marfim nas secções
     claras, e dourado champanhe nos detalhes. As secções escuras redefinem as
     mesmas variáveis mais abaixo (TEMA), por isso o resto do CSS não muda. */
  --white: #ffffff;
  --paper: #fffdf8;        /* marfim — cartões e superfícies */
  --sand-50: #f7f1e5;
  --sand-100: #efe5d1;
  --sand-200: #e8dcc2;
  --sand-300: #dcc79a;
  --sand-400: #c9ad74;
  --sand-500: #a8843f;     /* dourado sobre marfim: números grandes, filetes */
  --clay: #1b4a3c;         /* esmeralda: estados activos, coração do dia */

  --emerald-950: #08201a;
  --emerald-900: #0e2a22;
  --emerald-800: #143a2f;
  --emerald-700: #1b4a3c;
  --emerald-600: #24604d;
  --champagne: #ecdcb6;
  --gold-bright: #d8b970;  /* dourado sobre esmeralda */

  --ink: #17332a;          /* verde quase preto — texto principal */
  --ink-mid: #2f4c41;      /* números do calendário */
  --ink-soft: #5d736a;     /* etiquetas e texto secundário */

  --line: rgba(23, 51, 42, 0.11);
  --line-strong: rgba(23, 51, 42, 0.2);

  --cream: #f8f3ea;       /* secções claras */
  --cream-2: #fdfaf4;     /* secções claras alternadas, um tom acima */
  --gold: var(--sand-500);
  --gold-soft: var(--sand-300);

  /* --- papel do envelope: marfim, a brilhar contra o esmeralda ------------- */
  --env-1: #f8f2e6;
  --env-2: #efe6d3;
  --env-3: #e3d6bb;
  --env-4: #d3c19f;
  --liner-1: #24604d;      /* forro em esmeralda, visível ao abrir */
  --liner-2: #0e2a22;

  /* --- famílias -------------------------------------------------------------
     Pinyon Script — caligrafia copperplate, mais formal que a da main,
     reservada aos nomes e ao monograma.
     Marcellus — capitulares de inscrição, para as etiquetas espacejadas.
     Cormorant Garamond — garalda para o texto corrido, datas e números.
     ------------------------------------------------------------------------ */
  --font-script: 'Pinyon Script', 'Segoe Script', cursive;
  /* Só para o & comercial. A Parisienne desenha-o com o laço aberto, o que o
     torna legível a corpo pequeno — ao contrário da garalda em itálico, cujo
     & é a antiga ligadura "Et" e poucos reconhecem como tal. */
  --font-amp: 'Parisienne', 'Pinyon Script', cursive;
  /* Manuscrito de leitura corrida: só para a mensagem do convite. Tem de
     aguentar cinquenta palavras, por isso é uma cursiva de corpo generoso e
     não uma caligrafia de exibição. */
  --font-hand: 'Dancing Script', 'Segoe Script', cursive;
  --font-caps: 'Marcellus', Georgia, serif;
  --font-serif: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
  --font-sans: var(--font-serif);

  /* --- escala tipográfica fluida ------------------------------------------- */
  --step--2: clamp(10px, 0.24vw + 9.2px, 11.5px);  /* micro-etiquetas */
  --step--1: clamp(12px, 0.4vw + 10.8px, 14px);
  --step-0: clamp(14.5px, 0.5vw + 13px, 17px);
  --step-1: clamp(17px, 1.5vw + 12.5px, 23px);
  --step-2: clamp(21px, 3vw + 13px, 32px);
  --step-3: clamp(28px, 5vw + 13px, 48px);
  --step-4: clamp(38px, 10vw + 6px, 84px);

  /* --- escala de espaçamento ----------------------------------------------- */
  --s-1: clamp(6px, 1.2vw, 10px);
  --s-2: clamp(11px, 2.4vw, 18px);
  --s-3: clamp(18px, 4vw, 30px);
  --s-4: clamp(28px, 6vw, 46px);
  --s-5: clamp(42px, 9vw, 72px);
  --s-6: clamp(60px, 13vw, 112px);

  /* --- envelope ------------------------------------------------------------ */
  --env-w: min(80vw, 400px);
  --env-h: calc(var(--env-w) / 1.45);
  --flap-h: 54%;
  --env-tilt: 17deg;

  /* --- movimento ------------------------------------------------------------ */
  --t-flap: 1050ms;
  --t-card: 1150ms;
  --ease-paper: cubic-bezier(0.22, 0.9, 0.24, 1);

  /* --- grão de papel -------------------------------------------------------- */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");

  /* --- coração que marca o dia no calendário (usado como máscara) ---------- */
  --heart: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 20.7C12 20.7 2.6 15.2 2.6 8.9 2.6 5.9 4.9 3.8 7.5 3.8 9.4 3.8 11.1 4.9 12 6.5 12.9 4.9 14.6 3.8 16.5 3.8 19.1 3.8 21.4 5.9 21.4 8.9 21.4 15.2 12 20.7 12 20.7Z' fill='%23000'/%3E%3C/svg%3E");
}

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

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

body {
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: var(--step-0);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  overscroll-behavior-y: none;
}

body.is-sealed {
  overflow: hidden;
  height: 100svh;
}

.defs {
  position: absolute;
  width: 0;
  height: 0;
}

/* ===========================================================================
   CENA DO ENVELOPE
   =========================================================================== */

.scene {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  grid-template-rows: auto 1fr auto;
  place-items: center;
  gap: var(--s-3);
  padding: calc(var(--s-4) + env(safe-area-inset-top)) var(--s-3)
    calc(var(--s-4) + env(safe-area-inset-bottom));
  background: radial-gradient(circle at 50% 38%, #fffdf8 0%, #f4ead9 46%, #dec7a8 100%);
}

/* clarão que pulsa quando a cera parte */
.scene.is-opening .scene__glow {
  animation: bloom 1700ms ease-out;
}

@keyframes bloom {
  0%   { transform: scale(1);    opacity: 0.9; }
  16%  { transform: scale(1.14); opacity: 1; }
  100% { transform: scale(1);    opacity: 0.9; }
}

.scene__glow {
  position: absolute;
  top: 46%;
  left: 50%;
  width: min(128vw, 760px);
  aspect-ratio: 1;
  translate: -50% -50%;
  background: radial-gradient(
    circle,
    rgba(255, 248, 236, 0.9) 0%,
    rgba(242, 229, 209, 0.42) 40%,
    transparent 70%
  );
  pointer-events: none;
}

.scene__kicker,
.scene__hint {
  font-family: var(--font-caps);
  position: relative;
  z-index: 2;
  font-size: var(--step--2);
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: center;
  text-indent: 0.34em; /* compensa o letter-spacing da última letra */
  transition: opacity 520ms ease;
}

.scene__hint {
  letter-spacing: 0.22em;
  text-indent: 0.22em;
  animation: breathe 3.4s ease-in-out infinite;
}

@keyframes breathe {
  0%, 100% { opacity: 0.5; transform: translateY(0); }
  50%      { opacity: 1;   transform: translateY(-5px); }
}

/* Três responsabilidades, três elementos: o palco faz a entrada, a moldura
   faz a flutuação em repouso, o envelope faz a inclinação e a abertura.
   Empilhá-las no mesmo `transform` faria umas anular as outras. */
.scene__stage {
  position: relative;
  z-index: 2;
  display: grid;
  place-items: center;
  animation: stageIn 1300ms var(--ease-paper) 180ms backwards;
  transition: transform 1600ms var(--ease-paper);
}

/* Enquanto o cartão sai, o palco aproxima-se — o equivalente a dar um passo
   em frente para ler melhor. */
.scene.is-zoom .scene__stage {
  transform: scale(1.09);
}

@keyframes stageIn {
  from { opacity: 0; transform: translateY(36px) scale(0.92); }
  to   { opacity: 1; transform: none; }
}

.envelope-float {
  perspective: 1500px;
  perspective-origin: 50% 42%;
  animation: envFloat 7.5s ease-in-out 1.6s infinite;
}

@keyframes envFloat {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-10px); }
}

/* assim que se abre o movimento passa a ser outro — a flutuação sai de cena */
.scene.is-opening .envelope-float {
  animation: none;
}

/* --- corpo do envelope ---------------------------------------------------- */

/* O `transform` é montado a partir de variáveis para que a inclinação vinda
   do ponteiro, o estado de abertura e o recuo possam mudar de forma
   independente sem se sobrescreverem. */
.envelope {
  --tilt-base: var(--env-tilt);
  --tilt-x: 0deg;   /* ponteiro, eixo vertical */
  --tilt-y: 0deg;   /* ponteiro, eixo horizontal */
  --tilt-z: -1.2deg;
  --env-z: 0px;
  --press: 1;

  position: relative;
  width: var(--env-w);
  height: var(--env-h);
  transform-style: preserve-3d;
  transform: translateZ(var(--env-z)) scale(var(--press))
    rotateX(calc(var(--tilt-base) + var(--tilt-x)))
    rotateY(var(--tilt-y))
    rotateZ(var(--tilt-z));
  transition: transform 560ms var(--ease-paper);
  cursor: pointer;
}

/* resposta ao toque: o papel cede um pouco */
.envelope:active {
  --press: 0.972;
  transition: transform 140ms ease-out;
}

.envelope.is-open {
  --tilt-base: calc(var(--env-tilt) * 0.42);
  --tilt-z: 0deg;
  transition: transform 1150ms var(--ease-paper);
}

/* o envelope recua enquanto o cartão avança: a atenção transfere-se sozinha */
.envelope.is-out {
  --env-z: -38px;
}

/* Desfoque de profundidade de campo: com o cartão à frente, o envelope sai de
   foco como sairia numa fotografia. É o que torna a transferência de atenção
   inequívoca — o recuo sozinho não chega.
   O desfoque é aplicado a cada superfície e não ao envelope inteiro: um filtro
   no contentor achataria o espaço 3D e partiria a aba. */
.envelope__back,
.fold,
.flap__face {
  transition: filter 1100ms ease;
}

.envelope.is-out .envelope__back,
.envelope.is-out .fold,
.envelope.is-out .flap__face {
  filter: blur(3px);
}

.envelope__shadow {
  position: absolute;
  left: 50%;
  bottom: -9%;
  width: 90%;
  height: 24%;
  translate: -50% 0;
  transform: translateZ(-8px);
  background: radial-gradient(ellipse at center, rgba(104, 80, 54, 0.3), transparent 70%);
  filter: blur(18px);
  transition: opacity 900ms ease, width 900ms ease;
}

.envelope.is-open .envelope__shadow {
  width: 102%;
  opacity: 0.7;
}

.envelope__back {
  position: absolute;
  inset: 0;
  transform: translateZ(0);
  border-radius: 4px;
  background: linear-gradient(168deg, var(--env-1), var(--env-3));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7), 0 14px 28px rgba(104, 80, 54, 0.12);
}

/* sombra interna na boca: dá profundidade ao interior */
.envelope__back::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 42%;
  border-radius: 4px 4px 0 0;
  background: linear-gradient(180deg, rgba(80, 60, 40, 0.34), rgba(80, 60, 40, 0) 78%);
}

.envelope__back::after,
.fold::after,
.flap__face::after,
.card::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: var(--grain);
  opacity: 0.075;
  mix-blend-mode: multiply;
  pointer-events: none;
  border-radius: inherit;
  clip-path: inherit;
}

/* --- bolsa: quatro dobras que preenchem o rectângulo ---------------------- */

.envelope__pocket {
  position: absolute;
  inset: 0;
  transform: translateZ(18px);
  pointer-events: none;
}

.fold {
  position: absolute;
  inset: 0;
  display: block;
}

/* a luz vem de cima-à-esquerda: esquerda mais escura, direita mais clara */
.fold--left {
  clip-path: polygon(0 0, 50.4% 50%, 0 100%);
  background: linear-gradient(104deg, var(--env-2) 0%, var(--env-4) 100%);
  filter: drop-shadow(1px 0 0 rgba(255, 253, 249, 0.5));
}

.fold--right {
  clip-path: polygon(100% 0, 49.6% 50%, 100% 100%);
  background: linear-gradient(256deg, var(--env-1) 0%, var(--env-3) 100%);
  filter: drop-shadow(-1px 0 0 rgba(255, 253, 249, 0.5));
}

/* a de baixo dobra por cima das laterais, logo é a mais clara */
.fold--bottom {
  clip-path: polygon(0 100%, 50% 29%, 100% 100%);
  background: linear-gradient(183deg, var(--env-1) 0%, var(--env-2) 58%, var(--env-3) 100%);
  filter: drop-shadow(0 -1px 0 rgba(255, 254, 250, 0.7))
    drop-shadow(0 -5px 9px rgba(104, 80, 54, 0.13));
}

/* Sombra que a aba lança sobre a bolsa enquanto sobe: aparece, desce um pouco
   e desvanece. É um detalhe pequeno, mas é o que convence de que a aba passou
   mesmo por cima e não apenas mudou de desenho. */
.flap-shadow {
  position: absolute;
  inset: 0 0 auto 0;
  height: 78%;
  transform: translateZ(17.6px);
  background: linear-gradient(
    180deg,
    rgba(74, 55, 34, 0.4) 0%,
    rgba(74, 55, 34, 0.16) 44%,
    rgba(74, 55, 34, 0) 76%
  );
  opacity: 0;
  pointer-events: none;
}

.envelope.is-open .flap-shadow {
  animation: flapSweep 1320ms var(--ease-paper) forwards;
}

@keyframes flapSweep {
  0%   { opacity: 0;    transform: translateZ(17.6px) translateY(-6%); }
  24%  { opacity: 0.95; transform: translateZ(17.6px) translateY(4%); }
  100% { opacity: 0;    transform: translateZ(17.6px) translateY(26%); }
}

/* --- aba superior: duas faces --------------------------------------------- */

.envelope__flap {
  position: absolute;
  inset: 0 0 auto 0;
  height: var(--flap-h);
  transform-origin: 50% 0;
  transform: translateZ(19px) rotateX(0deg);
  transform-style: preserve-3d;
  transition: transform var(--t-flap) var(--ease-paper);
  pointer-events: none;
}

/* A aba não roda de uma vez: descola devagar, ganha balanço, passa um pouco
   além do fim e assenta. É esse terceiro tempo que faz parecer papel e não
   uma peça rígida a rodar sobre um eixo. */
.envelope.is-open .envelope__flap {
  animation: flapOpen 1320ms cubic-bezier(0.34, 0.86, 0.26, 1) forwards;
}

@keyframes flapOpen {
  0%   { transform: translateZ(19px) rotateX(0deg); }
  10%  { transform: translateZ(19px) rotateX(-9deg); }
  62%  { transform: translateZ(19px) rotateX(-184deg); }
  82%  { transform: translateZ(19px) rotateX(-169deg); }
  100% { transform: translateZ(19px) rotateX(-176deg); }
}

.flap__face {
  position: absolute;
  inset: 0;
  display: block;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  backface-visibility: hidden;
}

.flap__face--outer {
  background: linear-gradient(177deg, var(--env-1) 0%, var(--env-2) 72%, var(--env-3) 100%);
  filter: drop-shadow(0 3px 7px rgba(104, 80, 54, 0.2));
}

/* forro interior: só visível depois de abrir */
.flap__face--liner {
  transform: rotateX(180deg);
  background: linear-gradient(183deg, var(--liner-2) 0%, var(--liner-1) 55%, var(--sand-300) 100%);
  filter: drop-shadow(0 -3px 7px rgba(90, 66, 42, 0.26));
}

.flap__face--liner::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 47%, rgba(255, 255, 255, 0.26) 50%, transparent 53%);
}

/* --- lacre de cera --------------------------------------------------------- */

.seal {
  position: absolute;
  left: 50%;
  top: calc(var(--flap-h) - 11%);
  width: clamp(58px, 16vw, 80px);
  aspect-ratio: 1;
  translate: -50% 0;
  transform: translateZ(22px);
  border: 0;
  background: none;
  padding: 0;
  cursor: pointer;
  transform-style: preserve-3d;
  transition: filter 420ms ease;
  filter: drop-shadow(0 4px 8px rgba(96, 70, 26, 0.38));
  animation: sealPulse 3.6s ease-in-out infinite;
}

@keyframes sealPulse {
  0%, 100% { scale: 1; }
  50%      { scale: 1.04; }
}

.seal:hover,
.seal:focus-visible {
  filter: drop-shadow(0 7px 13px rgba(96, 70, 26, 0.48)) brightness(1.05);
  outline: none;
}

/* área de toque confortável no telemóvel sem aumentar o lacre visualmente */
.seal::before {
  content: '';
  position: absolute;
  inset: -12px;
}

.seal__half {
  position: absolute;
  inset: 0;
  display: block;
  transition: transform 720ms cubic-bezier(0.3, 0.7, 0.3, 1), opacity 720ms ease;
}

.seal__half svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.seal__half--left  { clip-path: polygon(0 0, 51% 0, 49% 100%, 0 100%); }
.seal__half--right { clip-path: polygon(51% 0, 100% 0, 100% 100%, 49% 100%); }

.envelope.is-cracking .seal { animation: none; }

.envelope.is-cracking .seal__half--left {
  transform: translate3d(-58%, 46%, 12px) rotate(-38deg);
  opacity: 0;
}

.envelope.is-cracking .seal__half--right {
  transform: translate3d(58%, 52%, 12px) rotate(41deg);
  opacity: 0;
}

.seal__crack {
  position: absolute;
  left: 50%;
  top: 8%;
  width: 2px;
  height: 84%;
  translate: -50% 0;
  background: linear-gradient(180deg, transparent, rgba(255, 238, 218, 0.95), transparent);
  opacity: 0;
}

.envelope.is-cracking .seal__crack {
  animation: crackFlash 420ms ease-out;
}

@keyframes crackFlash {
  0%   { opacity: 0; scale: 1 0.2; }
  35%  { opacity: 1; scale: 1 1; }
  100% { opacity: 0; scale: 2.6 1; }
}

/* --- o cartão -------------------------------------------------------------- */

.card {
  position: absolute;
  left: 50%;
  bottom: 7px;
  width: calc(100% - 26px);
  height: calc(100% - 16px);
  translate: -50% 0;
  transform: translateZ(3px) translateY(0) rotateX(0deg) scale(1);
  transform-origin: 50% 100%;
  border-radius: 3px;
  background: linear-gradient(170deg, var(--paper) 0%, var(--sand-50) 100%);
  box-shadow: 0 2px 5px rgba(104, 80, 54, 0.18);
  transition: box-shadow var(--t-card) ease;
  display: grid;
  place-items: center;
  overflow: hidden;
}

/* O cartão hesita, solta-se e sobe a endireitar-se para o leitor: acaba com
   uma inclinação que anula a do envelope, ficando de frente. */
.envelope.is-out .card {
  animation: cardOut 1450ms cubic-bezier(0.3, 0.82, 0.24, 1) forwards;
  box-shadow: 0 22px 40px rgba(94, 70, 46, 0.26);
}

@keyframes cardOut {
  0% {
    transform: translateZ(3px) translateY(0) rotateX(0deg) scale(1);
  }
  16% {
    transform: translateZ(8px) translateY(-4%) rotateX(1.5deg) scale(1.004);
  }
  100% {
    transform: translateZ(84px) translateY(-80%) rotateX(-9deg) scale(1.12);
  }
}

/* Reflexo que percorre o papel no momento em que apanha a luz ao sair. */
.card__sheen {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(
    104deg,
    transparent 34%,
    rgba(255, 255, 255, 0.62) 49%,
    transparent 64%
  );
  transform: translateX(-130%);
}

.envelope.is-out .card__sheen {
  animation: sheen 1500ms ease-out 320ms;
}

@keyframes sheen {
  to { transform: translateX(130%); }
}

.card__edge {
  position: absolute;
  inset: 7px;
  border: 1px solid var(--line-strong);
  border-radius: 2px;
  pointer-events: none;
}

.card__edge::before {
  content: '';
  position: absolute;
  inset: 4px;
  border: 1px solid var(--line);
}

.card__body {
  position: relative;
  z-index: 1;
  text-align: center;
  padding: 10px 22px;
  opacity: 0;
  transition: opacity 700ms ease 280ms;
}

.envelope.is-out .card__body {
  opacity: 1;
}

.card__eyebrow {
  font-family: var(--font-caps);
  font-size: var(--step--2);
  letter-spacing: 0.32em;
  text-indent: 0.32em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: var(--s-2);
  line-height: 1.4;
}

.card__names {
  font-family: var(--font-script);
  font-size: clamp(28px, 8.8vw, 42px);
  font-weight: 400;
  line-height: 1.18;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
}

.card__names em {
  display: block;
  font-size: 0.68em;
  margin: 2px 0;
}

/* Sem filete: só o espaço separa os nomes da data. */
.card__rule {
  height: var(--s-2);
}

.card__line {
  font-family: var(--font-caps);
  font-size: var(--step--2);
  letter-spacing: 0.26em;
  text-indent: 0.26em;
  color: var(--ink-soft);
}

/* --- poeira dourada -------------------------------------------------------- */

.dust {
  position: absolute;
  inset: -40% -20%;
  transform: translateZ(30px);
  pointer-events: none;
}

.dust i {
  position: absolute;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--sand-200), rgba(206, 173, 120, 0));
  opacity: 0;
}

/* lascas de cera: opacas, angulares, e caem em vez de subirem */
.dust i.crumb {
  width: 5px;
  height: 4px;
  border-radius: 1px;
  background: linear-gradient(140deg, #d1ae68, #8a6630);
  box-shadow: 0 1px 2px rgba(70, 50, 18, 0.4);
}

@keyframes motes {
  0%   { opacity: 0;    transform: translate3d(0, 0, 0) scale(0.3); }
  18%  { opacity: 0.92; }
  100% {
    opacity: 0;
    transform: translate3d(var(--dx), var(--dy), 0) scale(1.1)
      rotate(var(--spin, 0deg));
  }
}

@keyframes crumbs {
  0%   { opacity: 0; transform: translate3d(0, 0, 0) rotate(0deg); }
  12%  { opacity: 1; }
  72%  { opacity: 1; }
  100% {
    opacity: 0;
    transform: translate3d(var(--dx), var(--dy), 0) rotate(var(--spin, 0deg));
  }
}

/* Saída da cena: sobe e afasta-se devagar, em vez de encolher de repente. */
.scene {
  transition: opacity 1100ms ease, transform 1400ms var(--ease-paper);
}

.scene.is-leaving {
  opacity: 0;
  transform: scale(1.045) translateY(-22px);
  pointer-events: none;
}

.scene.is-leaving .scene__kicker,
.scene.is-leaving .scene__hint {
  opacity: 0;
}

/* ===========================================================================
   VÉU DE LUZ
   Cobre a passagem entre o envelope e o convite com um clarão quente, para
   que não haja um corte visível entre as duas cenas.
   =========================================================================== */

.veil {
  position: fixed;
  inset: 0;
  z-index: 120;
  opacity: 0;
  pointer-events: none;
  background: radial-gradient(120% 100% at 50% 45%, var(--white) 0%, var(--cream-2) 55%, var(--cream) 100%);
  transition: opacity 900ms ease;
}

.veil.is-on {
  opacity: 1;
}

/* ===========================================================================
   DIVISORES

   Dois filetes horizontais que se esbatem para fora, partidos ao meio por um
   coração em contorno. Fecham cada secção, à excepção da última — ali não há
   nada a seguir para separar.
   =========================================================================== */

.divider {
  position: absolute;
  left: 50%;
  bottom: clamp(22px, 5vh, 56px);
  translate: -50% 0;
  z-index: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(14px, 3.2vw, 22px);
  width: min(84%, 480px);
  color: var(--clay);
  opacity: 0;
  pointer-events: none;
  transition: opacity 1000ms ease;
}

.divider.is-in {
  opacity: 0.42;
}

/* Os filetes desvanecem-se para as pontas em vez de terminarem a direito:
   é o que os faz parecer suspensos em vez de cortados. */
.divider span {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, currentColor);
}

.divider span:last-child {
  background: linear-gradient(90deg, currentColor, transparent);
}

.divider svg {
  flex: none;
  width: clamp(14px, 3.4vw, 17px);
  height: clamp(14px, 3.4vw, 17px);
  scale: 0.7;
  transition: scale 900ms var(--ease-paper) 220ms;
}

.divider.is-in svg {
  scale: 1;
}

/* ---------------------------------------------------------------------------
   Variante que vive dentro do texto, por baixo dos nomes no fecho.

   Aqui a opacidade é do bloco `.reveal` que a envolve, por isso a leveza tem
   de vir da cor: mexer em `opacity` seria anulado pela revelação.
--------------------------------------------------------------------------- */

.divider--inline {
  position: static;
  translate: none;
  margin: var(--s-4) auto 0;
  width: min(64%, 320px);
  color: rgba(143, 117, 80, 0.42);
}

@media (max-width: 560px) {
  .divider {
    width: 88%;
    bottom: clamp(16px, 3.5vh, 34px);
  }

  .divider--inline {
    width: 74%;
  }
}

/* ===========================================================================
   LINHA DO TEMPO DA LEITURA

   Encostada à margem direita: a esquerda é onde o olho pousa a cada linha de
   texto, e o ramo botânico do hero ocupa o canto inferior esquerdo.
   Fica escondida enquanto o hero está no ecrã — ali o protagonista são os
   nomes, e a régua só faz sentido depois de haver percurso para medir.
   =========================================================================== */

.timeline {
  position: fixed;
  right: max(clamp(16px, 3.2vw, 46px), env(safe-area-inset-right));
  top: 50%;
  translate: 0 -50%;
  z-index: 20;
  height: min(46vh, 320px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 900ms ease, translate 900ms var(--ease-paper);
}

/* entra a subir: aparecer de repente no meio do ecrã seria brusco */
.timeline.is-on {
  opacity: 1;
}

.timeline.is-hidden {
  opacity: 0;
  translate: 0 calc(-50% + 12px);
}

/* O traço esbate-se nas duas pontas em vez de terminar a direito: é o que
   o faz parecer um detalhe de impressão e não um elemento de interface. */
.timeline__track {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--line-strong);
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 14%, #000 86%, transparent);
  mask-image: linear-gradient(180deg, transparent, #000 14%, #000 86%, transparent);
}

.timeline__fill {
  position: absolute;
  right: 0;
  top: 0;
  width: 1px;
  height: 0;
  background: linear-gradient(180deg, transparent, var(--gold) 22%, var(--gold));
  transition: height 260ms linear;
}

.timeline__marks {
  position: relative;
  height: 100%;
  list-style: none;
}

/* Cada marca alinha a partir da régua para dentro: o nome cresce para a
   esquerda, para nunca sair do ecrã. */
.timeline__mark {
  position: absolute;
  right: 0;
  translate: 50% -50%;
  display: flex;
  flex-direction: row-reverse;
  align-items: center;
  gap: 14px;
}

/* losango vazado; enche-se quando o passo fica para trás */
.timeline__dot {
  width: 4px;
  height: 4px;
  flex: none;
  rotate: 45deg;
  border: 1px solid var(--sand-400);
  background: transparent;
  transition: background 460ms ease, border-color 460ms ease, scale 460ms var(--ease-paper);
}

.timeline__mark.is-past .timeline__dot {
  background: var(--gold-soft);
  border-color: var(--gold-soft);
}

.timeline__mark.is-active .timeline__dot {
  background: var(--gold);
  border-color: var(--gold);
  scale: 1.6;
}

.timeline__label {
  font-family: var(--font-caps);
  font-size: 9px;
  letter-spacing: 0.26em;
  text-indent: 0.26em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink-soft);
  opacity: 0;
  translate: 8px 0;
  transition: opacity 560ms ease, translate 560ms var(--ease-paper);
}

/* só o passo activo se identifica: mostrar os seis nomes seria uma lista de
   navegação, não um ornamento */
.timeline__mark.is-active .timeline__label {
  opacity: 1;
  translate: 0 0;
}

/* Ecrãs estreitos: não há margem para os nomes, fica só a régua. */
@media (max-width: 760px) {
  .timeline {
    right: max(12px, env(safe-area-inset-right));
    height: min(34vh, 220px);
  }

  .timeline__label {
    display: none;
  }
}

/* ===========================================================================
   PÁGINA DO CONVITE
   =========================================================================== */

.page {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 1300ms ease, transform 1500ms var(--ease-paper);
}

body:not(.is-sealed) .page {
  opacity: 1;
  transform: none;
}

.section {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 100svh;
  padding: var(--s-6) var(--s-3);
  overflow: hidden;
}

/* Ecrãs baixos (telemóvel na horizontal, janelas curtas): prender cada secção
   a um ecrã inteiro esmaga o conteúdo — deixa-o respirar e fluir. */
@media (max-height: 640px) {
  .section {
    min-height: auto;
    padding-block: var(--s-5);
  }
}

/* Gradiente contínuo entre secções: lê-se como uma peça só, não como caixas. */
/* Fundo do hero reproduzido a partir do convite de referência: clarão central
   que escurece para os cantos, iniciais gigantes em marca de água e dois ramos
   botânicos em cantos opostos. */
.section--hero {
  background: radial-gradient(circle at center, #fffdf9 0%, var(--cream) 70%, #e9dccb 100%);
}

/* --- iniciais em marca de água -------------------------------------------- */

.watermark {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  font-family: var(--font-script);
  font-weight: 400;
  font-size: clamp(360px, 50vw, 720px);
  line-height: 1;
  color: rgba(120, 94, 72, 0.045);
}

.watermark span {
  position: absolute;
  translate: -50% -50%;
}

/* desencontradas na diagonal, como um monograma sobreposto */
.watermark span:first-child { left: 33%; top: 40%; }
.watermark span:last-child  { left: 68%; top: 61%; }

/* --- ramos botânicos nos cantos ------------------------------------------- */

.sprig {
  position: absolute;
  z-index: 0;
  width: clamp(88px, 17vw, 190px);
  height: auto;
  color: rgba(163, 135, 100, 0.34);
  pointer-events: none;
}

.sprig--tr {
  top: clamp(-30px, -3vh, -10px);
  right: clamp(-22px, -2vw, -6px);
}

/* o de baixo é o mesmo desenho virado, para os dois se lerem como um par */
.sprig--bl {
  bottom: clamp(-30px, -3vh, -10px);
  left: clamp(-22px, -2vw, -6px);
  transform: scale(-1);
}

/* --- estrela de quatro pontas --------------------------------------------- */

.spark {
  margin: calc(var(--s-3) * -1) auto var(--s-3);
  color: var(--gold);
  line-height: 0;
}

.spark svg {
  width: 13px;
  height: 13px;
}

/* o conteúdo fica acima da decoração em qualquer secção */
.section .wrap,
.section .scroll-hint {
  position: relative;
  z-index: 1;
}

.section--date,
.section--closing {
  background: var(--cream-2);
}

.section--venue {
  background: var(--cream);
}

.wrap {
  width: 100%;
  max-width: 680px;
  text-align: center;
}

/* --- revelação ao scroll, com escalonamento dos filhos -------------------- */

.reveal > * {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 820ms ease, transform 820ms var(--ease-paper);
}

.reveal.is-in > * {
  opacity: 1;
  transform: none;
}

.reveal.is-in > :nth-child(1) { transition-delay: 0ms; }
.reveal.is-in > :nth-child(2) { transition-delay: 90ms; }
.reveal.is-in > :nth-child(3) { transition-delay: 180ms; }
.reveal.is-in > :nth-child(4) { transition-delay: 270ms; }
.reveal.is-in > :nth-child(5) { transition-delay: 360ms; }
.reveal.is-in > :nth-child(6) { transition-delay: 450ms; }
.reveal.is-in > :nth-child(7) { transition-delay: 540ms; }

/* --- tipografia comum ------------------------------------------------------ */

.eyebrow,
.kicker {
  font-family: var(--font-caps);
  font-size: var(--step--2);
  letter-spacing: 0.34em;
  text-indent: 0.34em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: var(--s-4);
  line-height: 1.5;
}


/* Entrelinha curta e espacejamento ligeiramente negativo: é o aperto que
   faz um título serifado ler como contemporâneo em vez de cerimonioso. */
/* Numa caligrafia as letras ligam-se umas às outras: qualquer espacejamento
   positivo parte essas ligações. Daí letter-spacing zero — e o corpo maior,
   porque a altura-de-x de um traço manuscrito é muito menor que a de um serif. */
.names {
  font-family: var(--font-script);
  font-size: clamp(50px, 13.5vw + 4px, 114px);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: 0;
  /* Caixa alta e baixa: só a inicial de cada nome é maiúscula. Numa
     caligrafia as maiúsculas seguidas ficariam ilegíveis. */
  text-transform: none;
  padding-bottom: 0.08em;  /* folga para as hastes descendentes */
}

/* O & é sempre o mesmo, esteja onde estiver: garalda em itálico, em corpo
   bem menor que os nomes e em dourado. No corpo da caligrafia domina os nomes
   em vez de os ligar — e era isso que acontecia no fecho, onde estava em
   texto solto a herdar a fonte e o tamanho à volta. */
/* O & é sempre o mesmo, esteja onde estiver: caligrafia da mesma família dos
   nomes, em corpo menor e em dourado. Uma letra manuscrita tem altura-de-x
   pequena, por isso o corpo sobe em relação ao que uma serifada pediria. */
.amp,
.card__names em,
.foot em {
  font-family: var(--font-amp);
  font-style: normal;
  color: var(--gold);
  letter-spacing: 0;
  text-indent: 0;
  line-height: 1;
}

.amp {
  display: block;
  font-size: 0.66em;
  margin: calc(var(--s-1) * 0.6) 0;
}

.foot em {
  font-size: 0.6em;
  padding: 0 0.22em;
}

.ornament {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  margin: var(--s-4) auto;
  color: var(--gold-soft);
}


.ornament svg {
  width: 16px;
  height: 16px;
  flex: none;
}

.hero__date {
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1.4;
  letter-spacing: 0.05em;
}

.hero__place {
  font-family: var(--font-caps);
  margin-top: var(--s-1);
  font-size: var(--step--2);
  letter-spacing: 0.28em;
  text-indent: 0.28em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* ---------------------------------------------------------------------------
   Convite a descer

   Fica logo por baixo do local, e não colado ao fundo da secção: ali seria
   mais um elemento de interface; aqui lê-se como o remate do bloco de texto.

   Três peças que já existem noutros pontos da página — etiqueta em capitulares
   espacejadas, filete fino e losango dourado — para não introduzir vocabulário
   visual novo só para isto.
--------------------------------------------------------------------------- */

.scroll-hint {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-2);
  margin: var(--s-5) auto 0;
  padding: 10px 18px 6px;
  border: 0;
  background: none;
  cursor: pointer;
  color: var(--ink-soft);
  animation: hintFloat 3.6s ease-in-out infinite;
  transition: opacity 700ms ease;
}

/* Cumprido o seu papel, sai de cena: um convite a descer que continua visível
   depois de já se ter descido passa a ruído. */
.scroll-hint.is-gone {
  opacity: 0;
  pointer-events: none;
}

@keyframes hintFloat {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-7px); }
}

.scroll-hint__label {
  font-family: var(--font-caps);
  font-size: 9px;
  letter-spacing: 0.34em;
  text-indent: 0.34em;
  text-transform: uppercase;
  transition: color 420ms ease;
}

.scroll-hint:hover .scroll-hint__label,
.scroll-hint:focus-visible .scroll-hint__label {
  color: var(--gold);
}

/* filete com um segmento dourado que o percorre em ciclo */
.scroll-hint__line {
  position: relative;
  width: 1px;
  height: 46px;
  background: var(--line-strong);
  overflow: hidden;
}

.scroll-hint__line i {
  position: absolute;
  left: 0;
  width: 1px;
  height: 18px;
  background: linear-gradient(180deg, transparent, var(--gold));
  animation: hintTrail 2.8s cubic-bezier(0.5, 0, 0.5, 1) infinite;
}

@keyframes hintTrail {
  0%   { transform: translateY(-100%); opacity: 0; }
  22%  { opacity: 1; }
  76%  { opacity: 1; }
  100% { transform: translateY(260%); opacity: 0; }
}

/* o mesmo losango dos marcadores da linha do tempo */
.scroll-hint__dot {
  width: 4px;
  height: 4px;
  rotate: 45deg;
  background: var(--gold-soft);
  transition: background 420ms ease, scale 420ms var(--ease-paper);
}

.scroll-hint:hover .scroll-hint__dot,
.scroll-hint:focus-visible .scroll-hint__dot {
  background: var(--gold);
  scale: 1.4;
}

.scroll-hint:focus-visible {
  outline: 1px solid var(--gold-soft);
  outline-offset: 6px;
}

.prose {
  font-family: var(--font-serif);
  font-size: var(--step-1);
  font-weight: 400;
  line-height: 1.62;
  color: var(--ink);
  max-width: 32ch;
  margin: 0 auto;
}

.prose--quote {
  font-style: italic;
  color: var(--ink-soft);
}

/* A mensagem em letra de mão. Um manuscrito precisa de mais corpo e de muito
   mais entrelinha que uma serifada: as hastes sobem e descem bastante e, sem
   ar entre as linhas, elas tocam-se e a leitura trava. */
.prose--hand {
  font-family: var(--font-hand);
  font-size: clamp(20px, 1.6vw + 15px, 26px);
  font-weight: 500;
  line-height: 1.95;
  max-width: 30ch;
}

.signature {
  font-family: var(--font-caps);
  margin-top: var(--s-4);
  font-size: var(--step--2);
  letter-spacing: 0.26em;
  text-indent: 0.26em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* --- versículo -------------------------------------------------------------
   Em itálico e num corpo abaixo da mensagem: a Escritura enquadra o convite,
   não compete com ele. A referência fica em maiúsculas espacejadas.
   -------------------------------------------------------------------------- */

.verse {
  max-width: 28ch;
  margin: 0 auto var(--s-5);
}

.verse p {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--step-1);
  line-height: 1.7;
  color: var(--ink-soft);
}

.verse cite {
  display: block;
  margin-top: var(--s-2);
  font-family: var(--font-caps);
  font-style: normal;
  font-size: var(--step--2);
  letter-spacing: 0.26em;
  text-indent: 0.26em;
  text-transform: uppercase;
  color: var(--gold);
}

/* --- cartão da data + calendário ------------------------------------------ */

/* moldura só para dar perspectiva — o tilt acontece no cartão lá dentro */
.datecard-frame {
  max-width: 420px;
  margin: 0 auto;
}

.has-tilt {
  perspective: 1100px;
}

[data-tilt] {
  --tilt-x: 0deg;
  --tilt-y: 0deg;
  --tilt-lift: 0;
  transform: rotateX(var(--tilt-x)) rotateY(var(--tilt-y))
    translateZ(calc(var(--tilt-lift) * 16px));
  transform-style: preserve-3d;
  transition: transform 460ms var(--ease-paper), box-shadow 460ms ease;
}

.datecard {
  max-width: 420px;
  margin: 0 auto;
  padding: var(--s-4) clamp(14px, 3.4vw, 26px);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 3px;
  box-shadow: 0 12px 34px rgba(104, 80, 54, 0.06);
}

.datecard__top {
  padding-bottom: var(--s-1);
}

.datecard__month,
.datecard__weekday {
  font-family: var(--font-caps);
  font-size: var(--step--2);
  letter-spacing: 0.32em;
  text-indent: 0.32em;
  text-transform: uppercase;
  color: var(--ink-soft);
  line-height: 1.5;
}

.datecard__day {
  font-family: var(--font-serif);
  font-size: var(--step-4);
  font-weight: 300;
  line-height: 1;
  margin: var(--s-1) 0;
  color: var(--gold);
}

.calendar {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  /* linhas com mais folga que colunas: é o que dá ar sem alargar o cartão */
  gap: 7px 2px;
  margin: var(--s-3) 0;
  padding: var(--s-3) 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

/* cabeçalho dos dias da semana */
.calendar b {
  font-family: var(--font-caps);
  position: relative;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding-bottom: 10px;
  margin-bottom: 3px;
}

/* um único filete por baixo de toda a linha de cabeçalho */
.calendar b::after {
  content: '';
  position: absolute;
  left: -1px;
  right: -1px;
  bottom: 0;
  height: 1px;
  background: var(--line);
}

.calendar i {
  font-style: normal;
  font-size: clamp(13px, 3.4vw, 15px);
  font-weight: 400;
  color: var(--ink-mid);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border-radius: 50%;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* Sábado e Domingo mais leves — dá ritmo à grelha e ajuda a localizar o dia.
   Os sete <b> do cabeçalho ocupam as posições 1-7, por isso a mesma contagem
   serve para o cabeçalho e para os dias. */
.calendar > :nth-child(7n + 6),
.calendar > :nth-child(7n) {
  color: var(--gold);
}

.calendar > i:nth-child(7n + 6),
.calendar > i:nth-child(7n) {
  color: var(--ink-soft);
}

/* O dia do noivado fica dentro de um coração em vez do círculo.
   O coração é uma máscara, não uma imagem: herda a cor de --gold e mantém-se
   nítido em qualquer densidade de ecrã. */
/* O dia do noivado fica dentro de um coração.
   O coração é `::before` posicionado e o número vive num <span> também
   posicionado: é a ordenação entre os dois que decide quem fica à frente.
   (A versão anterior punha o coração em z-index:-1, o que o empurrava para
   trás do fundo opaco do cartão — o coração desaparecia e o número, sendo
   branco, desaparecia com ele.) */
.calendar i.is-day {
  position: relative;
  font-weight: 500;
  background: none;
  box-shadow: none;
}

.calendar i.is-day::before {
  content: '';
  position: absolute;
  inset: -12%;
  z-index: 0;
  background: var(--clay);
  -webkit-mask: var(--heart) center / contain no-repeat;
  mask: var(--heart) center / contain no-repeat;
  filter: drop-shadow(0 3px 8px rgba(143, 117, 80, 0.32));
  animation: heartbeat 4.6s ease-in-out infinite;
}

.calendar i.is-day > span {
  position: relative;
  z-index: 1;
  color: var(--white);
  /* a massa visual de um coração está acima do centro geométrico: sem este
     acerto o número parece estar a escorregar para o bico */
  transform: translateY(-5%);
}

@keyframes heartbeat {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.035); }
}

.datecard__time {
  font-family: var(--font-serif);
  font-size: var(--step-1);
  letter-spacing: 0.06em;
}

/* --- countdown: sem caixas, só finos separadores ------------------------- */

.countdown {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  max-width: 440px;
  margin: 0 auto;
}

.cd {
  position: relative;
  padding: var(--s-2) 2px;
}

/* separadores verticais em vez de quatro caixas — muito mais leve */
.cd + .cd::before {
  content: '';
  position: absolute;
  left: 0;
  top: 18%;
  bottom: 18%;
  width: 1px;
  background: var(--line);
}

.cd b {
  display: block;
  font-family: var(--font-serif);
  font-size: var(--step-3);
  font-weight: 300;
  line-height: 1;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}

.cd small {
  font-family: var(--font-caps);
  display: block;
  margin-top: var(--s-1);
  font-size: 9px;
  letter-spacing: 0.2em;
  text-indent: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.cd__note {
  margin-top: var(--s-4);
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--step-1);
  color: var(--ink-soft);
}

/* --- local + mapa ---------------------------------------------------------- */

.venue__name {
  font-family: var(--font-serif);
  font-size: var(--step-2);
  font-weight: 400;
  line-height: 1.25;
}

.venue__addr {
  margin-top: var(--s-1);
  font-size: var(--step--1);
  line-height: 1.7;
  color: var(--ink-soft);
}

.map {
  margin: var(--s-4) 0 0;
  border: 1px solid var(--line);
  border-radius: 3px;
  overflow: hidden;
  box-shadow: 0 12px 30px rgba(104, 80, 54, 0.07);
}

.map iframe {
  display: block;
  width: 100%;
  height: clamp(200px, 38svh, 320px);
  border: 0;
  filter: sepia(0.24) saturate(0.88) contrast(0.96);
}

/* --- botões ---------------------------------------------------------------- */

.btn {
  font-family: var(--font-caps);
  display: inline-block;
  margin-top: var(--s-4);
  padding: 15px 32px;
  min-height: 46px; /* alvo de toque confortável */
  border: 1px solid var(--gold);
  border-radius: 2px;
  color: var(--gold);
  font-size: var(--step--2);
  letter-spacing: 0.28em;
  text-indent: 0.28em;
  text-transform: uppercase;
  text-decoration: none;
  background: transparent;
  transition: background 380ms ease, color 380ms ease, transform 380ms ease;
}

.btn:hover,
.btn:focus-visible {
  background: var(--gold);
  color: var(--paper);
  transform: translateY(-2px);
}

/* ---------------------------------------------------------------------------
   Botão de confirmação

   É a única acção do convite, e fica no fim de tudo: flutua devagar para se
   ler como algo que espera ser tocado.

   A sombra faz parte do mesmo ciclo — alarga e suaviza quando o botão sobe.
   Sem ela o movimento leria como um deslize; com ela lê como altura.

   O atraso de 900 ms deixa a entrada da secção acontecer primeiro: sem ele a
   animação assumiria o `transform` logo à partida e o botão apareceria já no
   sítio, sem participar na revelação.
--------------------------------------------------------------------------- */

.btn--solid {
  position: relative;
  background: var(--gold);
  color: var(--paper);
  box-shadow: 0 5px 12px rgba(143, 117, 80, 0.26);
  animation: rsvpFloat 3.6s ease-in-out 900ms infinite;
}

@keyframes rsvpFloat {
  0%, 100% {
    transform: translateY(0);
    box-shadow: 0 5px 12px rgba(143, 117, 80, 0.26);
  }
  50% {
    transform: translateY(-6px);
    box-shadow: 0 14px 22px rgba(143, 117, 80, 0.15);
  }
}

/* halo que se abre e desvanece, como uma gota a tocar na água */
.btn--solid::after {
  content: '';
  position: absolute;
  inset: -1px;
  border: 1px solid var(--gold);
  border-radius: inherit;
  opacity: 0;
  pointer-events: none;
  animation: rsvpHalo 3.6s ease-out 900ms infinite;
}

@keyframes rsvpHalo {
  0%   { opacity: 0.45; scale: 1; }
  65%  { opacity: 0;    scale: 1.16; }
  100% { opacity: 0;    scale: 1.16; }
}

/* Ao ser alcançado, o botão pára: o convite já foi aceite pelo ponteiro e
   continuar a acenar passaria a distracção. */
.btn--solid:hover,
.btn--solid:focus-visible {
  background: var(--clay);
  border-color: var(--clay);
  animation-play-state: paused;
}

.btn--solid:hover::after,
.btn--solid:focus-visible::after {
  animation-play-state: paused;
  opacity: 0;
}

.foot {
  margin-top: var(--s-5);
  font-family: var(--font-script);
  font-size: var(--step-3);
  line-height: 1.35;
  letter-spacing: 0;
  text-transform: none;
  color: var(--gold);
}

/* ===========================================================================
   TEMA: NOITE ESMERALDA

   As secções escuras redefinem as variáveis da paleta: tudo o que lá dentro
   usa --ink, --gold, --line, etc. passa a ler-se em marfim e dourado sobre
   verde sem tocar nas regras de cada componente.
   =========================================================================== */

.section--dark {
  --ink: #f6eedd;
  --ink-mid: #e8dab9;
  --ink-soft: #bfb08a;
  --gold: var(--gold-bright);
  --gold-soft: #9c844f;
  --clay: var(--champagne);
  --paper: var(--emerald-900);
  --line: rgba(236, 220, 182, 0.15);
  --line-strong: rgba(236, 220, 182, 0.26);
  color: var(--ink);
  background: radial-gradient(circle at 50% 42%, var(--emerald-600) 0%, var(--emerald-800) 52%, var(--emerald-950) 100%);
}

/* Filete fino dourado a rematar cada secção escura em cima e em baixo:
   lê-se como o debrum de um cartão impresso. */
.section--dark::before,
.section--dark::after {
  content: '';
  position: absolute;
  left: 50%;
  translate: -50% 0;
  width: min(72%, 560px);
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(216, 185, 112, 0.5), transparent);
  pointer-events: none;
}

.section--dark::before { top: clamp(14px, 3vh, 28px); }
.section--dark::after  { bottom: clamp(8px, 1.6vh, 16px); }

.section--dark .watermark { color: rgba(216, 185, 112, 0.06); }
.section--dark .sprig     { color: rgba(216, 185, 112, 0.34); }
.section--dark .divider--inline { color: rgba(216, 185, 112, 0.5); }

/* nomes do hero em champanhe, com um brilho quente de vela */
.section--dark .names {
  color: var(--champagne);
  text-shadow: 0 0 28px rgba(216, 185, 112, 0.22);
}

.section--dark .btn--solid {
  color: var(--emerald-900);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
}

.section--dark .btn--solid:hover,
.section--dark .btn--solid:focus-visible {
  background: var(--champagne);
  border-color: var(--champagne);
}

/* --- cena do envelope: veludo esmeralda --------------------------------- */

.scene {
  background: radial-gradient(circle at 50% 38%, var(--emerald-600) 0%, var(--emerald-800) 48%, var(--emerald-950) 100%);
}

.scene__glow {
  background: radial-gradient(
    circle,
    rgba(216, 185, 112, 0.2) 0%,
    rgba(216, 185, 112, 0.07) 40%,
    transparent 70%
  );
}

.scene__kicker,
.scene__hint {
  color: var(--champagne);
}

.envelope__shadow {
  background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.55), transparent 70%);
}

/* o forro esmeralda leva um filete dourado na borda, como papel de cerimónia */
.flap__face--liner {
  background: linear-gradient(183deg, var(--liner-2) 0%, var(--liner-1) 70%, var(--gold-bright) 100%);
}

.veil {
  background: radial-gradient(120% 100% at 50% 45%, #2f6e59 0%, var(--emerald-800) 55%, var(--emerald-950) 100%);
}

/* --- secções claras ----------------------------------------------------- */

.calendar i.is-day::before {
  filter: drop-shadow(0 3px 8px rgba(27, 74, 60, 0.3));
}

.btn--solid:hover,
.btn--solid:focus-visible {
  color: var(--champagne);
}

/* o mapa perde o tom sépia da main */
.map iframe {
  filter: saturate(0.75) contrast(0.97);
}

/* a linha do tempo atravessa secções claras e escuras: dourado lê-se nas duas */
.timeline__label {
  color: var(--gold);
}

/* ===========================================================================
   AJUSTES POR ECRÃ
   ===========================================================================

/* Telemóveis estreitos: menos inclinação no envelope (uma perspectiva forte
   num ecrã pequeno lê-se como distorção), e mais ar à volta. */
@media (max-width: 420px) {
  :root {
    --env-w: min(78vw, 320px);
    --env-tilt: 13deg;
  }

  .calendar b {
    font-size: 8.5px;
    letter-spacing: 0;
  }

  .btn {
    padding: 15px 26px;
    letter-spacing: 0.22em;
    text-indent: 0.22em;
  }
}

/* Ecrãs largos: mais respiração lateral no texto corrido. */
@media (min-width: 900px) {
  .prose {
    max-width: 34ch;
  }
}

/* ===========================================================================
   MOVIMENTO REDUZIDO
   =========================================================================== */

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

  .reveal > * {
    opacity: 1;
    transform: none;
  }
}
