/* THEME: Adat Lampung — Siger & Kain Tapis — emas di atas maroon. Maroon dan emas kain tapis dengan mahkota siger, motif kapal, gajah, pucuk rebung, serta rumah lamban pesagi. */
:root{
  --color-bg: #fdf7ef;
  --color-surface: #fffcf6;
  --color-text: #352a26;
  --color-text-soft: #6b5a52;
  --color-primary: #c9a33c;
  --color-secondary: #8c2438;
  --color-accent: #5c1b28;
  --color-line: rgba(92,27,40,0.22);
  --font-heading: 'Gilda Display', serif;
  --font-script: 'Great Vibes', cursive;
  --font-body: 'Cormorant Garamond', serif;

  /* Text-only companions: the palette above keeps its values everywhere it
     fills, borders or backs something — only the type moves onto these, which
     are tuned for contrast against the paper as it actually renders (frame
     tint + section wash + motif stacked). */
  --ink-primary: #856713;
  --ink-accent: #6b1d29;
  --on-accent: #fdf7ef;

  --deco-shadow: rgba(107,29,41,0.28);
  --halo-color: rgba(201,163,60,0.16);
  --arrow-bg: rgba(255,255,255,.9);
  --reveal-from: scale(.92) translateY(26px);
  --reveal-dur: 1.4s;
}

body{ background: #dcc5a4; }

.frame{
  overflow-x: hidden;
  background:
    radial-gradient(circle at 8% 6%, rgba(201,163,60,0.10), transparent 38%),
    radial-gradient(circle at 95% 16%, rgba(140,36,56,0.12), transparent 36%),
    radial-gradient(circle at 4% 34%, rgba(140,36,56,0.12), transparent 34%),
    radial-gradient(circle at 96% 48%, rgba(201,163,60,0.10), transparent 36%),
    radial-gradient(circle at 6% 64%, rgba(201,163,60,0.10), transparent 34%),
    radial-gradient(circle at 94% 78%, rgba(140,36,56,0.12), transparent 36%),
    radial-gradient(circle at 10% 92%, rgba(140,36,56,0.12), transparent 34%),
    radial-gradient(circle at 92% 96%, rgba(201,163,60,0.10), transparent 36%),
    var(--color-bg);
}

/* The woven motif this adat is known for, repeated as the paper's own
   texture — two layers so the weave never lines up into a visible grid. */
.frame::before{
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.24;
  background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%22120%22 height=%22120%22%3E %3Cg fill=%22none%22 stroke=%22%23c9a33c%22 stroke-width=%221.1%22 opacity=%22.7%22%3E%3Cpath d=%22M16 36 L26 14 L36 36 Z%22/%3E%3Cpath d=%22M84 96 L94 74 L104 96 Z%22/%3E%3C/g%3E %3Cg fill=%22%238c2438%22 opacity=%22.3%22%3E%3Cpath d=%22M60 46 L70 52 L60 58 L50 52 Z%22/%3E%3C/g%3E %3Cg fill=%22none%22 stroke=%22%238c2438%22 stroke-width=%22.9%22 opacity=%22.4%22%3E%3Cpath d=%22M0 62 H120 M0 66 H120%22/%3E%3C/g%3E %3Cg fill=%22%23c9a33c%22 opacity=%22.4%22%3E%3Ccircle cx=%2296%22 cy=%2226%22 r=%222.4%22/%3E%3Ccircle cx=%2224%22 cy=%2292%22 r=%222.4%22/%3E%3C/g%3E%3C/svg%3E"), url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2276%22 height=%2276%22%3E %3Cg fill=%22%23c9a33c%22 opacity=%22.45%22%3E%3Cpath d=%22M38 12 L47 30 H29 Z%22/%3E%3C/g%3E %3Ccircle cx=%2210%22 cy=%2258%22 r=%221.8%22 fill=%22%238c2438%22 opacity=%22.5%22/%3E%3C/svg%3E");
  background-repeat: repeat, repeat;
  background-size: 120px 120px, 76px 76px;
  background-position: 0 0, 45px 20px;
}

.cover{
  overflow-x: hidden;
  background:
    radial-gradient(circle at 15% 15%, rgba(201,163,60,0.10), transparent 42%),
    radial-gradient(circle at 85% 88%, rgba(140,36,56,0.12), transparent 45%),
    var(--color-bg);
}
.cover::before{
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.24;
  background-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%22120%22 height=%22120%22%3E %3Cg fill=%22none%22 stroke=%22%23c9a33c%22 stroke-width=%221.1%22 opacity=%22.7%22%3E%3Cpath d=%22M16 36 L26 14 L36 36 Z%22/%3E%3Cpath d=%22M84 96 L94 74 L104 96 Z%22/%3E%3C/g%3E %3Cg fill=%22%238c2438%22 opacity=%22.3%22%3E%3Cpath d=%22M60 46 L70 52 L60 58 L50 52 Z%22/%3E%3C/g%3E %3Cg fill=%22none%22 stroke=%22%238c2438%22 stroke-width=%22.9%22 opacity=%22.4%22%3E%3Cpath d=%22M0 62 H120 M0 66 H120%22/%3E%3C/g%3E %3Cg fill=%22%23c9a33c%22 opacity=%22.4%22%3E%3Ccircle cx=%2296%22 cy=%2226%22 r=%222.4%22/%3E%3Ccircle cx=%2224%22 cy=%2292%22 r=%222.4%22/%3E%3C/g%3E%3C/svg%3E");
  background-repeat: repeat;
  background-size: 120px 120px;
}

/* The cover names are a centred flex child, so on a narrow phone they take
   their max-content width and spill past the paper's edge. Holding the box
   to the cover's own width makes a long pair wrap at its "&" instead. */
.cover__names{ max-width: 100%; }

.section{ border-bottom: none; }

.section__title::after{
  content: '✷';
  display: inline-block;
  font-size: 17px;
  color: var(--color-primary);
  margin-top: 10px;
}

/* Soft corner blooms of colour behind each section, drifting slowly. */
.section::before, .section::after{
  content: '';
  position: absolute;
  width: 70px;
  height: 70px;
  pointer-events: none;
  z-index: -1;
  background: radial-gradient(circle, rgba(201,163,60,0.22), transparent 70%);
  border-radius: 50%;
}
.section::before{ top: 10px; left: -10px; }
.section::after{ bottom: 10px; right: -10px; background: radial-gradient(circle, rgba(140,36,56,0.26), transparent 70%); }
.section:nth-of-type(even)::before{ background: radial-gradient(circle, rgba(140,36,56,0.26), transparent 70%); }
.section:nth-of-type(even)::after{ background: radial-gradient(circle, rgba(201,163,60,0.22), transparent 70%); }

@keyframes decoDrift{
  0%, 100%{ transform: translate(0,0) rotate(0deg); }
  50%{ transform: translate(6px, -10px) rotate(6deg); }
}
.section::before, .section::after,
.footer::before, .footer::after{ animation: decoDrift 13s ease-in-out infinite; }
.section::after, .footer::after{ animation-delay: -6s; }

@keyframes ornamentSpin{
  0%, 100%{ transform: rotate(-8deg) scale(1); }
  50%{ transform: rotate(8deg) scale(1.15); }
}
.section__title::after{ animation: ornamentSpin 6.5s ease-in-out infinite; }

.countdown__item{ box-shadow: 0 12px 30px -18px rgba(107,29,41,0.34); }

/* Several of these themes hang a woven border or a carved band off a card's
   own edge. The panel above them carries `perspective`, which otherwise
   becomes the containing block for those layers and throws them to the top
   of the section — so each card is made its own positioning context. */
.event-card, .gift-card, .wish-card, .countdown__item{ position: relative; }

/* Stacked-paper depth: two extra shadow layers read as sheets sitting behind
   the card, with no extra elements and no clipping of corner ornaments. */
.event-card, .gift-card, .wish-card{
  box-shadow:
    0 12px 30px -18px rgba(107,29,41,0.34),
    5px 7px 0 -3px rgba(255,252,246,0.80),
    9px 12px 0 -3px rgba(140,36,56,0.26);
}

.couple__photo{ border-color: #fff; box-shadow: 0 14px 34px -14px rgba(107,29,41,0.34); }
.gallery__item{ border-radius: 14px; box-shadow: 0 8px 20px -12px rgba(107,29,41,0.34); }
.video-box{ border-radius: 14px; }
.btn-open{ border-color: var(--color-accent); }

.footer{
  background: linear-gradient(180deg, transparent, rgba(201,163,60,0.10));
  position: relative;
}
.footer::before, .footer::after{
  content: '';
  position: absolute;
  width: 90px;
  height: 90px;
  pointer-events: none;
  z-index: -1;
  border-radius: 50%;
}
.footer::before{ top: -10px; left: 6%; background: radial-gradient(circle, rgba(140,36,56,0.26), transparent 70%); }
.footer::after{ top: 10%; right: 6%; background: radial-gradient(circle, rgba(201,163,60,0.22), transparent 70%); }

/* ==========================================================================
   SECTION-TO-SECTION COLOUR GRADATION — each section's gradient starts where
   the previous one ended, so the wash flows continuously down the whole page.
   nth-of-type(5) is the rundown and nth-of-type(7) the video; main.js hides
   either one when its content is empty, so both stay flat continuations and
   the wash survives whichever way they render.
   ========================================================================== */
.section:nth-of-type(1){ background: linear-gradient(180deg, transparent, rgba(201,163,60,0.10)); }
.section:nth-of-type(2){ background: linear-gradient(180deg, rgba(201,163,60,0.10), rgba(140,36,56,0.12)); }
.section:nth-of-type(3){ background: linear-gradient(180deg, rgba(140,36,56,0.12), rgba(201,163,60,0.10)); }
.section:nth-of-type(4){ background: linear-gradient(180deg, rgba(201,163,60,0.10), rgba(140,36,56,0.12)); }
.section:nth-of-type(5){ background: rgba(140,36,56,0.12); }
.section:nth-of-type(6){ background: linear-gradient(180deg, rgba(140,36,56,0.12), rgba(201,163,60,0.10)); }
.section:nth-of-type(7){ background: rgba(201,163,60,0.10); }
.section:nth-of-type(8){ background: linear-gradient(180deg, rgba(201,163,60,0.10), rgba(140,36,56,0.12)); }
.section:nth-of-type(9){ background: linear-gradient(180deg, rgba(140,36,56,0.12), transparent); }

/* ==========================================================================
   READABILITY — every text role moves onto the --ink-* companions so no line
   of copy is left sitting on the decoration at a low contrast ratio.
   ========================================================================== */
.section__eyebrow,
.hero__quote-src,
.hero__amp,
.couple__ig,
.couple__divider,
.story__date,
.rundown__time,
.gift-card__bank,
.wish-card__status,
.footer__hashtag{ color: var(--ink-primary); }

.section__title,
.hero__names,
.cover__names,
.couple__name,
.event-card__name,
.story__title,
.rundown__title,
.countdown__num,
.gift-card__num,
.wish-card__name,
.footer__names{ color: var(--ink-accent); }

/* Hero names shimmer — the sweep stays inside the theme family and never
   rises above the paper, so the letters are readable at every frame. */
.hero__names span{
  background-image: linear-gradient(100deg,
    #3e1017 30%,
    #5c1823 42%,
    var(--ink-accent) 50%,
    #5c1823 58%,
    #3e1017 70%);
  background-size: 250% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: shimmerText 7.5s linear infinite;
}
@keyframes shimmerText{
  0%{ background-position: 200% 0; }
  100%{ background-position: -50% 0; }
}

/* ==========================================================================
   SIGNATURE — what makes this one read as Lampung and not as any other
   template in the set: its own watermark, card treatment and lettering.
   ========================================================================== */
.hero::after{
  content: '';
  position: absolute;
  top: 44%; left: 50%;
  width: 240px; height: 240px;
  margin: -120px 0 0 -120px;
  z-index: -1;
  opacity: .07;
  pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 96 64%22 fill=%22%238c2438%22%3E %3Cpath d=%22M48 58 C28 58 14 50 8 38 C16 42 26 44 34 42 C30 34 30 24 34 16 C38 24 44 30 48 30 C52 30 58 24 62 16 C66 24 66 34 62 42 C70 44 80 42 88 38 C82 50 68 58 48 58 Z%22/%3E%3C/svg%3E") center / contain no-repeat;
}
/* Lampung signature: gold couching lines run across every card the way tapis
   thread is laid over the cloth, with the siger tumpal along the top. */
.event-card, .gift-card, .wish-card{
  border: 1px solid rgba(140,36,56,.4);
  background-image: repeating-linear-gradient(0deg, rgba(201,163,60,.09) 0 1px, transparent 1px 9px);
}
.event-card::before, .gift-card::before, .wish-card::before{
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 11px;
  pointer-events: none;
  background: linear-gradient(135deg, var(--color-primary) 50%, transparent 51%) 0 0 / 15px 11px repeat-x;
  opacity: .75;
}
.countdown__item{ border: 1px solid rgba(201,163,60,.6); border-radius: 3px; }
.section__title{ letter-spacing: .03em; }
.cover__eyebrow{ color: var(--ink-accent); letter-spacing: .3em; }
.greeting{ color: var(--ink-accent); letter-spacing: .05em; }
/* ==========================================================================
   SHARED MECHANICS — reveal choreography, floating sprites, falling particles,
   the photo carousel and the small depth/interaction touches. Everything here
   is driven by the palette + tuning variables declared at the top of this
   file's theme block above, so the same machinery reads differently per theme.
   ========================================================================== */

/* 3D viewing context — lets transformed descendants render with real
   foreshortening instead of a flat 2D pop. */
.section, .footer{ perspective: 1200px; }
.couple__person{ perspective: 800px; }
.gallery{ perspective: 900px; }

/* ---------- Greeting line above the hero quote ---------- */
.greeting{
  font-family: var(--font-heading);
  font-size: clamp(14px, 3.8vw, 17px);
  letter-spacing: .04em;
  color: var(--ink-primary, var(--color-primary));
  margin: 0 0 14px;
}
.greeting:empty{ display: none; }
.gift__intro{ font-size: 14px; color: var(--color-text-soft); margin: -10px 0 22px; }
.footer__closing{
  font-family: var(--font-heading);
  font-size: clamp(13px, 3.6vw, 16px);
  color: var(--ink-primary, var(--color-primary));
  margin: 14px 0 0;
}
.footer__closing:empty{ display: none; }

/* ==========================================================================
   THEMED REVEAL — the base entrance every .reveal element shares. Themes
   override --reveal-from / --reveal-dur to change its character.
   ========================================================================== */
.reveal{
  opacity: 0;
  transform: var(--reveal-from, scale(.92) translateY(24px));
  transition: opacity var(--reveal-dur, 1.4s) cubic-bezier(.22,1,.36,1),
              transform var(--reveal-dur, 1.4s) cubic-bezier(.22,1,.36,1);
}
.reveal.in{ opacity: 1; transform: none; }

.countdown__item.reveal{ transition-delay: calc(var(--i, 0) * 110ms); }

.gallery__item.reveal{ transition-delay: calc(var(--i, 0) * 70ms); }
.gallery__item:nth-child(1){ --i: 0; } .gallery__item:nth-child(2){ --i: 1; } .gallery__item:nth-child(3){ --i: 2; }
.gallery__item:nth-child(4){ --i: 3; } .gallery__item:nth-child(5){ --i: 4; } .gallery__item:nth-child(6){ --i: 5; }
.gallery__item:nth-child(7){ --i: 6; } .gallery__item:nth-child(8){ --i: 7; } .gallery__item:nth-child(9){ --i: 8; }

.story__item.reveal{ transition-delay: calc(var(--i, 0) * 120ms); }
.story__item:nth-child(1){ --i: 0; } .story__item:nth-child(2){ --i: 1; }
.story__item:nth-child(3){ --i: 2; } .story__item:nth-child(4){ --i: 3; }

/* ---------- Variative directions, so sections never all arrive alike ---------- */
.reveal--left{ transform: scale(.93) translateX(-42px) rotateY(-30deg); }
.reveal--left.in{ transform: none; }
.reveal--right{ transform: scale(.93) translateX(42px) rotateY(30deg); }
.reveal--right.in{ transform: none; }
.reveal--zoom{ transform: scale(.58) rotateY(-20deg) rotateX(10deg); }
.reveal--zoom.in{ transform: none; }
.reveal--flip{ transform: rotateX(56deg) translateY(24px) scale(.92); }
.reveal--flip.in{ transform: none; }

.hero__names span.reveal{ display: inline-block; }

.event-card.reveal{ transition-delay: calc(var(--i,0) * 90ms); }
.event-card:nth-of-type(odd).reveal{ transform: scale(.95) translateX(-30px) rotateY(-24deg); }
.event-card:nth-of-type(odd).reveal.in{ transform: none; }
.event-card:nth-of-type(even).reveal{ transform: scale(.95) translateX(30px) rotateY(24deg); }
.event-card:nth-of-type(even).reveal.in{ transform: none; }

.story__item:nth-child(odd).reveal{ transform: scale(.94) translateX(-26px) rotateY(-20deg); }
.story__item:nth-child(odd).reveal.in{ transform: none; }
.story__item:nth-child(even).reveal{ transform: scale(.94) translateX(26px) rotateY(20deg); }
.story__item:nth-child(even).reveal.in{ transform: none; }

/* ==========================================================================
   SECTION TITLE — a curtain lift: the words rise through a mask, independent
   of the generic fade used everywhere else.
   ========================================================================== */
.section__title__mask{ display: block; overflow: hidden; perspective: 400px; }
.section__title__inner{
  display: block;
  transform: translateY(112%) rotateX(-70deg);
  transform-origin: center bottom;
  transition: transform 1.35s cubic-bezier(.22,1,.36,1);
}
.section__title.reveal{ transform: none; transition: opacity .7s ease; }
.section__title.reveal.in{ transform: none; }
.section__title.reveal.in .section__title__inner{ transform: translateY(0) rotateX(0); }

/* ==========================================================================
   FLOATING SPRITES — themed artwork drifting inside each section. Purely
   decorative and never interactive.
   ========================================================================== */
.deco-float{
  position: absolute;
  z-index: 1;
  pointer-events: none;
  filter: drop-shadow(0 4px 8px var(--deco-shadow, rgba(0,0,0,.18)));
  will-change: transform;
  opacity: 0;
  translate: 0 0;
  transition: opacity 1.9s cubic-bezier(.22,1,.36,1), translate 1.9s cubic-bezier(.22,1,.36,1);
}
.deco-float svg{ width: 100%; height: 100%; display: block; }

/* Entrance — direction is chosen in JS from the sprite's real position, then
   applied through `translate` so it composes with the sway `animation` below
   instead of fighting it over the same `transform` property. */
.deco-float.enter-left{ translate: -60px 10px; }
.deco-float.enter-right{ translate: 60px 10px; }
.deco-float.enter-top{ translate: 0 -50px; }
.deco-float.enter-bottom{ translate: 0 50px; }
.deco-float.is-entered{ opacity: 1; translate: 0 0; }
.deco-float.is-far.is-entered{ opacity: .6; }
.deco-float.is-ghost.is-entered{ opacity: .22; }
.deco-float.is-soft.is-entered{ opacity: .5; }
.deco-float.is-back.is-entered{ opacity: .16; }

.cover__names{
  opacity: 0;
  translate: 0 -46px;
  transition: opacity 2.1s cubic-bezier(.22,1,.36,1), translate 2.1s cubic-bezier(.22,1,.36,1);
}
.cover__names.is-entered{ opacity: 1; translate: 0 0; }

@keyframes floatSwayA{
  0%, 100%{ transform: translateY(0) rotate(-6deg); }
  50%{ transform: translateY(-16px) rotate(8deg); }
}
@keyframes floatSwayB{
  0%, 100%{ transform: translateY(0) rotate(5deg); }
  50%{ transform: translateY(-11px) rotate(-8deg); }
}
@keyframes floatSwayC{
  0%, 100%{ transform: translate(0,0) rotate(0deg); }
  33%{ transform: translate(5px,-9px) rotate(5deg); }
  66%{ transform: translate(-5px,-4px) rotate(-5deg); }
}
@keyframes floatDriftD{
  0%, 100%{ transform: translate(0,0) rotate(-4deg) scale(1); }
  50%{ transform: translate(-8px,-18px) rotate(10deg) scale(1.08); }
}
@keyframes flutterE{
  0%, 100%{ transform: translate(0,0) rotate(-10deg); }
  25%{ transform: translate(10px,-8px) rotate(6deg); }
  50%{ transform: translate(4px,-20px) rotate(-14deg); }
  75%{ transform: translate(-10px,-9px) rotate(8deg); }
}
@keyframes twinkleF{
  0%, 100%{ transform: scale(.7) rotate(0deg); opacity:.4; }
  50%{ transform: scale(1.25) rotate(90deg); opacity:1; }
}
@keyframes floatWaveG{
  0%, 100%{ transform: translateX(0) rotate(0deg); }
  50%{ transform: translateX(10px) rotate(-3deg); }
}
@keyframes flutterH{
  0%, 100%{ transform: translateY(0) rotate(-6deg) scale(1); }
  50%{ transform: translateY(-9px) rotate(9deg) scale(1.06); }
}
.deco-float.anim-a{ animation: floatSwayA 9.5s ease-in-out infinite; }
.deco-float.anim-b{ animation: floatSwayB 11s ease-in-out infinite; }
.deco-float.anim-c{ animation: floatSwayC 12.5s ease-in-out infinite; }
.deco-float.anim-d{ animation: floatDriftD 14s ease-in-out infinite; }
.deco-float.anim-e{ animation: flutterE 8.5s ease-in-out infinite; }
.deco-float.anim-f{ animation: twinkleF 4s ease-in-out infinite; }
.deco-float.anim-g{ animation: floatWaveG 10s ease-in-out infinite; }
.deco-float.anim-h{ animation: flutterH 7s ease-in-out infinite; }

/* Depth layers: blurred + dimmer sprites sit behind the copy so corners and
   empty mid-section space read as full without ever competing with text. */
.deco-float.is-far{ filter: blur(1.4px) drop-shadow(0 4px 8px var(--deco-shadow, rgba(0,0,0,.14))); }
@keyframes bloomDriftBack{
  0%, 100%{ transform: translate(0,0) rotate(-5deg) scale(1); }
  50%{ transform: translate(-10px,-14px) rotate(5deg) scale(1.06); }
}
.deco-float.is-back{
  z-index: -1;
  filter: blur(6px);
  animation: bloomDriftBack 16s ease-in-out infinite;
}
/* Big architectural sprites (arches, panels, horizons) sit flat behind
   everything and never sway — they read as scenery, not as confetti. */
.deco-float.is-scene{ z-index: 0; animation: none; }
.deco-float.is-ghost{ z-index: -1; animation: none; }
.deco-float.is-soft{ z-index: 0; }

/* ==========================================================================
   FALLING PARTICLES — a continuous, varied-speed shower drifting down the
   whole viewport. Above the background, never in the way of a tap.
   ========================================================================== */
.petals-overlay{
  position: fixed;
  inset: 0;
  max-width: var(--max-w);
  margin: 0 auto;
  overflow: hidden;
  pointer-events: none;
  z-index: 350;
}
.petal{
  position: absolute;
  top: -8%;
  will-change: transform;
  animation-name: petalFall;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}
.petal svg{ width:100%; height:100%; display:block; }
@keyframes petalFall{
  0%{ transform: translate(0,0) rotate(0deg); }
  100%{ transform: translate(var(--drift, 20px), 118vh) rotate(var(--spin, 320deg)); }
}

/* ---------- Scroll progress bar ---------- */
.scroll-progress{
  position: fixed;
  top: 0; left: 0;
  height: 3px;
  width: 0%;
  background: linear-gradient(90deg, var(--color-secondary), var(--color-primary), var(--color-accent));
  z-index: 600;
  transition: width .1s linear;
}

/* ---------- Countdown tick — a flip-clock digit change ---------- */
.countdown__num{ transform-style: preserve-3d; backface-visibility: hidden; }
@keyframes countTick{
  0%{ transform: rotateX(0deg); }
  45%, 55%{ transform: rotateX(-100deg); color: var(--color-accent); }
  100%{ transform: rotateX(0deg); }
}
.countdown__num.is-ticking{ animation: countTick .5s ease-out; transform-origin: center; }

@keyframes softPulse{
  0%, 100%{ transform: rotateY(0deg) scale(1); }
  50%{ transform: rotateY(8deg) scale(1.04); }
}
.countdown__item{ perspective: 300px; animation: softPulse 4.2s ease-in-out infinite; }
.countdown__item:nth-child(2){ animation-delay: .15s; }
.countdown__item:nth-child(3){ animation-delay: .3s; }
.countdown__item:nth-child(4){ animation-delay: .45s; }

/* ---------- Orbiting ring around each portrait ---------- */
.couple__photo-wrap{ position: relative; width: 160px; height: 160px; margin: 0 auto 18px; }
.couple__photo-wrap .couple__photo{ margin: 0; }
.couple__photo{ transition: transform .18s ease-out; }
.couple__photo-orbit{
  position: absolute;
  inset: -18px;
  animation: orbitSpin 17s linear infinite;
  pointer-events: none;
}
.couple__photo-orbit span{
  position: absolute;
  top: 50%; left: 50%;
  width: 8px; height: 8px;
  margin: -4px 0 0 -4px;
  border-radius: 50%;
  box-shadow: 0 0 6px var(--deco-shadow, rgba(0,0,0,.3));
}
.couple__photo-orbit span:nth-child(1){ transform: rotate(0deg) translateY(-98px); background: var(--color-primary); }
.couple__photo-orbit span:nth-child(2){ transform: rotate(60deg) translateY(-98px); background: var(--color-secondary); width:6px; height:6px; margin:-3px 0 0 -3px; }
.couple__photo-orbit span:nth-child(3){ transform: rotate(120deg) translateY(-98px); background: var(--color-accent); width:5px; height:5px; margin:-2.5px 0 0 -2.5px; }
.couple__photo-orbit span:nth-child(4){ transform: rotate(180deg) translateY(-98px); background: var(--color-primary); }
.couple__photo-orbit span:nth-child(5){ transform: rotate(240deg) translateY(-98px); background: var(--color-secondary); width:6px; height:6px; margin:-3px 0 0 -3px; }
.couple__photo-orbit span:nth-child(6){ transform: rotate(300deg) translateY(-98px); background: var(--color-accent); width:5px; height:5px; margin:-2.5px 0 0 -2.5px; }
@keyframes orbitSpin{ from{ transform: rotate(0deg); } to{ transform: rotate(360deg); } }

/* ==========================================================================
   PHOTO GRID — every photo is on screen at once; the mosaic layout itself
   lives in base.css. This only adds the template's own depth and hover so
   the tiles still belong to this design. Prev/next moved into the lightbox,
   which opens when a tile is tapped.
   ========================================================================== */
.gallery__item{ transition: transform .45s cubic-bezier(.22,1,.36,1), box-shadow .45s ease; }
.gallery__item:hover{ transform: translateY(-3px); }

/* ---------- Cursor-tracked 3D tilt (set inline by the page script) ---------- */
.event-card, .gift-card, .wish-card, .couple__photo{
  transform-style: preserve-3d;
  will-change: transform;
}

/* ---------- Soft rotating halo behind the hero ---------- */
.hero{ position: relative; }
.hero::before{
  content: '';
  position: absolute;
  top: 50%; left: 50%;
  width: 440px; height: 440px;
  margin: -220px 0 0 -220px;
  background: radial-gradient(circle, var(--halo-color, rgba(0,0,0,.08)), transparent 62%);
  filter: blur(6px);
  z-index: -1;
  pointer-events: none;
  animation: heroHaloSpin 42s linear infinite;
}
@keyframes heroHaloSpin{
  0%{ transform: rotate(0deg) scale(1); }
  50%{ transform: rotate(180deg) scale(1.18); }
  100%{ transform: rotate(360deg) scale(1); }
}

/* ---------- Buttons — lift/press depth instead of a flat colour swap ---------- */
.btn-solid{ transition: transform .25s ease, box-shadow .25s ease, opacity .25s ease; }
.btn-solid:hover{ transform: translateY(-3px) scale(1.03); box-shadow: 0 14px 26px -12px var(--deco-shadow, rgba(0,0,0,.45)); }
.btn-solid:active{ transform: translateY(0) scale(.97); }
.btn-outline{ transition: background .3s, color .3s, transform .25s ease; }
.btn-outline:hover{ transform: translateY(-2px); }
.btn-open{ transition: background .35s ease, color .35s ease, transform .25s ease; }
.btn-open:hover{ transform: translateY(-2px) scale(1.04); }

.event-card, .gift-card, .wish-card{ transition: transform .18s ease-out, box-shadow .3s ease; }

@media (max-width: 420px){
  .deco-float:not(.is-scene):not(.is-ghost){ transform: scale(.8); }
}

@media (prefers-reduced-motion: reduce){
  .section::before, .section::after, .footer::before, .footer::after,
  .section__title::after, .countdown__item, .deco-float,
  .petal, .hero__names span, .countdown__num.is-ticking,
  .hero::before, .couple__photo-orbit{ animation: none !important; }
  .reveal, .reveal--left, .reveal--right, .reveal--zoom, .reveal--flip,
  .section__title__inner, .gallery__item,
  .event-card, .gift-card, .wish-card, .couple__photo,
  .deco-float, .cover__names{ transition-duration: .01ms !important; }
  .petals-overlay{ display: none; }
}
