/* The love page: what every template shares. Colours come from themes.css; each template adds its
   own public/assets/templates/<key>.css (body[data-layout]). Here: the page and its lock screen, the floating hearts,
   the music controls, the slideshow kit used by classic/cinematic/polaroid (.show, .slide, .hud, .letter) and the
   building blocks of the interactive templates (lightbox, photo prints, the letter sheet, celebration hearts). */

:root {
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --soft: cubic-bezier(0.45, 0, 0.2, 1);
  --slide-ms: 8000ms;
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  color: var(--text);
  background: var(--bg);
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}
[hidden] { display: none !important; }
button { font: inherit; }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ---------- floating hearts ---------- */
.hearts { position: fixed; inset: 0; pointer-events: none; overflow: hidden; z-index: 12; }
.heart {
  position: absolute; bottom: -8vh; left: var(--x);
  font-size: var(--s); line-height: 1; color: var(--accent);
  opacity: 0; filter: drop-shadow(0 0 8px var(--heart-glow));
  animation: rise var(--d) var(--soft) var(--delay) infinite;
  will-change: transform, opacity;
}
@keyframes rise {
  0%   { transform: translate3d(0, 0, 0) scale(.7); opacity: 0; }
  12%  { opacity: var(--o); }
  35%  { transform: translate3d(calc(var(--sway) * 1), -38vh, 0) scale(.95); }
  65%  { transform: translate3d(calc(var(--sway) * -1), -78vh, 0) scale(1.05); }
  100% { transform: translate3d(calc(var(--sway) * .4), -118vh, 0) scale(1.1); opacity: 0; }
}

/* ---------- the stage (shared by every layout) ---------- */
.show {
  position: fixed; inset: 0; z-index: 5; overflow: hidden; display: flex; flex-direction: column;
  background: radial-gradient(120% 90% at 30% 20%, var(--bg-2), var(--bg) 70%);
  opacity: 0; transition: opacity 1.4s ease, filter 2.6s var(--soft), transform 2.8s var(--ease);
}
.show.on { opacity: 1; }
/* the blur belongs to the lock screen only: once open, photos are shown as they are */
.show.locked { will-change: filter, transform; filter: blur(70px) brightness(.5) saturate(1.3); transform: scale(1.25); }
body[data-scheme="light"] .show.locked { filter: blur(70px) brightness(1.02) saturate(1.2); }
.viewer { position: relative; flex: 1; min-height: 0; }
.frame { position: absolute; inset: 0; overflow: hidden; }
.stage, .slide { position: absolute; inset: 0; margin: 0; }
/* only the photo on screen and the one fading out are rendered */
.slide { opacity: 0; visibility: hidden; transition: opacity 2.4s var(--soft); overflow: hidden; }
.slide.active { opacity: 1; visibility: visible; z-index: 2; }
.slide.out { visibility: visible; z-index: 1; }
.slide .fg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; transform-origin: 50% 45%; }
.slide.play .fg { will-change: transform; }
.ph { position: absolute; inset: 0; }
.ph0 { background: linear-gradient(135deg, var(--ph-1), var(--ph-2)); }
.ph1 { background: linear-gradient(160deg, var(--ph-3), var(--ph-4)); }
.ph2 { background: linear-gradient(120deg, var(--ph-2), var(--ph-3)); }

/* slow drifting zoom; stays on while the slide fades out, so nothing snaps */
.slide.play.fx0 .fg, .slide.play.fx0 .ph { animation: kb0 14s var(--soft) both; }
.slide.play.fx1 .fg, .slide.play.fx1 .ph { animation: kb1 14s var(--soft) both; }
.slide.play.fx2 .fg, .slide.play.fx2 .ph { animation: kb2 14s var(--soft) both; }
.slide.play.fx3 .fg, .slide.play.fx3 .ph { animation: kb3 14s var(--soft) both; }
@keyframes kb0 { from { transform: scale(1.1); } to { transform: scale(1.01); } }
@keyframes kb1 { from { transform: scale(1.02) translate3d(2.5%, 0, 0); } to { transform: scale(1.09) translate3d(-1.5%, 0, 0); } }
@keyframes kb2 { from { transform: scale(1.02); } to { transform: scale(1.1); } }
@keyframes kb3 { from { transform: scale(1.02) translate3d(-2.5%, 0, 0); } to { transform: scale(1.09) translate3d(1.5%, 0, 0); } }

.vignette { position: absolute; inset: 0; z-index: 3; pointer-events: none; background: radial-gradient(ellipse at 50% 45%, transparent 50%, var(--vignette) 100%), linear-gradient(to top, var(--vignette), transparent 28%); }
.glow {
  position: absolute; inset: -20%; z-index: 3; pointer-events: none; opacity: .5; /* plain alpha, not a blend mode */
  background: radial-gradient(40% 35% at 20% 15%, var(--glow-a), transparent 70%), radial-gradient(45% 40% at 85% 90%, var(--glow-b), transparent 70%);
  animation: glow 12s ease-in-out infinite alternate;
}
@keyframes glow { from { transform: translate3d(-3%, -2%, 0) scale(1); opacity: .3; } to { transform: translate3d(3%, 2%, 0) scale(1.08); opacity: .55; } }

.nav { position: absolute; top: 0; bottom: 0; z-index: 6; width: 28%; border: 0; background: transparent; cursor: pointer; }
.nav.prev { left: 0; } .nav.next { right: 0; }
.nav:focus-visible { outline: 2px solid var(--accent); outline-offset: -6px; }

.hud { position: absolute; z-index: 7; left: 24px; right: 24px; bottom: max(22px, env(safe-area-inset-bottom)); display: flex; align-items: center; gap: 14px; pointer-events: none; }
.count { font-size: .72rem; letter-spacing: .22em; color: rgba(255, 255, 255, .72); font-variant-numeric: tabular-nums; text-shadow: 0 1px 6px rgba(0, 0, 0, .35); }
.bar { flex: 1; height: 2px; border-radius: 2px; background: rgba(255, 255, 255, .25); overflow: hidden; }
.bar i { display: block; height: 100%; width: 100%; transform-origin: left; transform: scaleX(0); background: linear-gradient(90deg, var(--accent), var(--gold)); }
.bar i.run { animation: fill var(--slide-ms) linear forwards; }
@keyframes fill { to { transform: scaleX(1); } }

.mute {
  position: absolute; z-index: 8; top: max(16px, env(safe-area-inset-top)); right: 16px; width: 44px; height: 44px; display: grid; place-items: center;
  border-radius: 50%; border: 1px solid rgba(255, 255, 255, .24); background: rgba(20, 10, 18, .28); color: #fff; cursor: pointer;
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); transition: transform .3s var(--ease), background .3s, opacity .3s;
  animation: pop .9s var(--ease) both;
}
.mute:hover { background: rgba(20, 10, 18, .4); }
.mute:active { transform: scale(.94); }
.mute.off { opacity: .5; }
.mute:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
@keyframes pop { from { opacity: 0; transform: scale(.7); } }

/* ---------- now playing ---------- */
.nowplaying {
  position: absolute; z-index: 8; top: max(16px, env(safe-area-inset-top)); left: 16px; max-width: calc(100% - 92px);
  display: flex; align-items: center; gap: 12px; padding: 9px 16px 9px 13px; border-radius: 999px;
  background: rgba(20, 10, 18, .5); border: 1px solid rgba(255, 255, 255, .2); color: #fff;
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  animation: npIn 1.4s var(--ease) both; transition: opacity .5s var(--soft);
}
.nowplaying.paused { opacity: .6; }
@keyframes npIn { from { opacity: 0; transform: translate3d(-14px, 0, 0); } }
.np-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.np-label { font-size: .58rem; letter-spacing: .26em; text-transform: uppercase; color: var(--gold); }
body[data-scheme="light"] .np-label { color: #f4d9b0; }
.np-title { font-family: 'Cormorant Garamond', Georgia, serif; font-style: italic; font-size: 1.1rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.np-by { font-family: 'Inter', system-ui, sans-serif; font-style: normal; font-size: .72rem; letter-spacing: .04em; color: rgba(255, 255, 255, .7); }
.eq { display: inline-flex; align-items: flex-end; gap: 3px; height: 16px; }
.eq i { display: block; width: 3px; height: 100%; border-radius: 2px; background: linear-gradient(to top, var(--accent), var(--gold)); transform-origin: bottom; animation: eq 1.1s ease-in-out infinite; }
.eq i:nth-child(2) { animation-duration: .85s; animation-delay: -.3s; }
.eq i:nth-child(3) { animation-duration: 1.3s; animation-delay: -.6s; }
.eq i:nth-child(4) { animation-duration: .95s; animation-delay: -.15s; }
.nowplaying.paused .eq i { animation-play-state: paused; }
@keyframes eq { 0%, 100% { transform: scaleY(.25); } 50% { transform: scaleY(1); } }

/* ---------- the letter (classic: beside the photos, below them on phones) ---------- */
.letter {
  position: relative; z-index: 6; flex: 0 0 40dvh; display: flex; flex-direction: column; min-height: 0;
  padding: 1.1rem 1.4rem .4rem; background: linear-gradient(180deg, var(--panel-a), var(--panel-b));
  border-top: 1px solid var(--panel-line, rgba(255, 255, 255, .1));
  opacity: 0; transform: translate3d(0, 28px, 0); transition: opacity 1.8s var(--soft), transform 1.8s var(--ease);
}
.show.reading .letter { opacity: 1; transform: none; }
.letter-head { text-align: center; }
.eyebrow { margin: 0 0 .5rem; font-size: .68rem; letter-spacing: .38em; text-transform: uppercase; color: var(--gold); }
.letter-head .eyebrow { margin: 0; }
.letter-head h2 { margin: .1rem 0 .4rem; font-family: 'Cormorant Garamond', Georgia, serif; font-style: italic; font-weight: 400; font-size: 1.9rem; color: var(--text); }
.letter-view {
  position: relative; flex: 1; min-height: 0; overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 12%, #000 86%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 12%, #000 86%, transparent 100%);
}
.letter-text { padding: 1.4rem .2rem 0; will-change: transform; font-family: 'Cormorant Garamond', Georgia, serif; font-style: italic; font-size: 1.2rem; line-height: 1.75; color: var(--text); opacity: .92; text-align: center; }
.letter-text p { margin: 0 0 1.4em; text-wrap: pretty; }
.letter-text { transform: translate3d(0, 110%, 0); } /* parked below the panel until the scroll starts */
.letter-text.run { animation: readIn var(--d1) linear forwards; }
.letter-text.loop { animation: readLoop var(--d2) linear infinite; }
.letter-view:hover .letter-text, .letter-view:active .letter-text { animation-play-state: paused; }
@keyframes readIn { from { transform: translate3d(0, calc(var(--vh) * .72), 0); } to { transform: translate3d(0, calc(var(--th) * -1), 0); } }
@keyframes readLoop { from { transform: translate3d(0, var(--vh), 0); } to { transform: translate3d(0, calc(var(--th) * -1), 0); } }
.letter-view.manual { overflow-y: auto; -webkit-mask-image: none; mask-image: none; }

/* ---------- lock screen ---------- */
.gate {
  position: fixed; inset: 0; z-index: 10; display: grid; place-items: center;
  padding: max(20px, env(safe-area-inset-top)) 20px max(20px, env(safe-area-inset-bottom));
  background: linear-gradient(160deg, var(--gate-a), var(--gate-b));
  transition: opacity 1.8s var(--soft), background 1.8s var(--soft);
}
.gate::after { /* soft bloom of light at the moment of unlocking */
  content: ''; position: absolute; inset: 0; pointer-events: none; opacity: 0;
  background: radial-gradient(circle at 50% 50%, rgba(255, 226, 214, .85), color-mix(in srgb, var(--accent) 35%, transparent) 38%, transparent 68%);
}
.card {
  position: relative; width: min(92vw, 380px); padding: 2.2rem 1.7rem 1.7rem; text-align: center; color: var(--card-text);
  background: linear-gradient(160deg, rgba(255, 255, 255, .16), rgba(255, 255, 255, .06));
  border: 1px solid rgba(255, 255, 255, .22); border-radius: 30px;
  backdrop-filter: blur(22px) saturate(1.3); -webkit-backdrop-filter: blur(22px) saturate(1.3);
  box-shadow: 0 30px 80px rgba(10, 2, 10, .5), inset 0 1px 0 rgba(255, 255, 255, .25);
  animation: cardIn 1.5s var(--ease) both;
  transition: transform 1.5s var(--ease), opacity 1.2s var(--soft), filter 1.4s var(--soft), box-shadow 1.2s var(--soft);
}
body[data-scheme="light"] .card { background: linear-gradient(160deg, rgba(255, 255, 255, .78), rgba(255, 255, 255, .52)); border-color: rgba(255, 255, 255, .9); box-shadow: 0 30px 80px rgba(120, 50, 80, .22), inset 0 1px 0 #fff; }
@keyframes cardIn { from { opacity: 0; transform: translate3d(0, 28px, 0) scale(.96); filter: blur(8px); } }
.card > * { animation: fadeUp 1.2s var(--ease) both; }
.card > .lock { animation-delay: .25s; } .card > .eyebrow { animation-delay: .4s; }
.card > .question { animation-delay: .55s; } .card > .field, .card > .open-btn { animation-delay: .7s; } .card > .err { animation-delay: .8s; }
@keyframes fadeUp { from { opacity: 0; transform: translate3d(0, 12px, 0); } }

.lock { display: inline-grid; place-items: center; width: 62px; height: 62px; border-radius: 50%; color: var(--accent); margin-bottom: 1rem;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent) 22%, transparent), color-mix(in srgb, var(--accent) 4%, transparent) 70%); border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  animation: fadeUp 1.2s var(--ease) .25s both, breathe 4s ease-in-out 1.5s infinite; }
.lock-heart { fill: var(--bg-2); opacity: .85; }
.shackle { transform-origin: 44px 32px; transition: transform 1s var(--ease); }
@keyframes breathe { 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 35%, transparent); } 50% { box-shadow: 0 0 0 14px transparent; } }

.question {
  display: block; margin: 0 0 1.6rem; font-family: 'Cormorant Garamond', Georgia, serif; font-style: italic; font-weight: 400;
  font-size: clamp(1.9rem, 8.5vw, 2.4rem); line-height: 1.12; color: var(--card-text); overflow-wrap: anywhere;
}
.field { position: relative; }
#pw {
  width: 100%; height: 56px; padding: 0 64px 0 22px; font: inherit; font-size: 1rem; letter-spacing: .12em; color: var(--card-text);
  background: var(--field-bg); border: 1px solid var(--field-line); border-radius: 999px; outline: none;
  transition: border-color .4s var(--soft), box-shadow .4s var(--soft), background .4s var(--soft);
}
#pw::placeholder { color: var(--card-text); opacity: .45; letter-spacing: .04em; }
#pw:focus { border-color: var(--accent); box-shadow: 0 0 0 5px color-mix(in srgb, var(--accent) 16%, transparent), 0 0 30px color-mix(in srgb, var(--accent) 25%, transparent); }
.field button, .open-btn {
  display: grid; place-items: center; border: 0; cursor: pointer; color: var(--on-accent);
  background: linear-gradient(135deg, var(--gold), var(--accent)); box-shadow: 0 6px 18px color-mix(in srgb, var(--accent-deep) 45%, transparent);
  transition: transform .35s var(--ease), box-shadow .35s;
}
.field button { position: absolute; top: 6px; right: 6px; width: 44px; height: 44px; border-radius: 50%; }
.field button:hover, .open-btn:hover { transform: scale(1.06); }
.field button:active, .open-btn:active { transform: scale(.94); }
.field button:focus-visible, .open-btn:focus-visible { outline: 2px solid var(--card-text); outline-offset: 3px; }
.field button svg { grid-area: 1 / 1; transition: opacity .5s var(--soft), transform .6s var(--ease); }
.field .i-heart { opacity: 0; transform: scale(.4); }
.open-btn { display: inline-flex; align-items: center; gap: .55rem; height: 52px; padding: 0 28px; border-radius: 999px; font-size: 1rem; font-weight: 500; letter-spacing: .06em; }
.err { min-height: 1.3em; margin: .9rem 0 0; font-size: .85rem; color: var(--accent); letter-spacing: .02em; }
body[data-scheme="light"] .err { color: var(--accent-deep); }
.preview-note { margin: .4rem 0 0; font-size: .76rem; color: var(--card-text); opacity: .7; }
.card.shake { animation: shake .55s var(--soft); }
@keyframes shake { 15%, 55% { transform: translateX(-8px); } 35%, 75% { transform: translateX(8px); } }

/* ---------- unlock sequence ---------- */
.gate.unlocking .shackle { transform: translateY(-9px) rotate(30deg); }
.gate.unlocking .i-arrow { opacity: 0; transform: scale(.4); }
.gate.unlocking .field .i-heart { opacity: 1; transform: scale(1); animation: beat .9s var(--ease) both; }
.gate.unlocking .card { transform: scale(1.03); box-shadow: 0 0 80px 10px color-mix(in srgb, var(--accent) 45%, transparent), 0 30px 80px rgba(10, 2, 10, .5); }
@keyframes beat { 0% { transform: scale(.4); } 55% { transform: scale(1.35); } 100% { transform: scale(1); } }
.gate.leaving { opacity: 0; background: transparent; pointer-events: none; }
.gate.leaving::after { animation: bloom 2.2s var(--soft) both; }
.gate.leaving .card { opacity: 0; transform: translate3d(0, -26px, 0) scale(1.07); filter: blur(10px); }
@keyframes bloom { 0% { opacity: 0; } 30% { opacity: 1; } 100% { opacity: 0; } }

.made-with {
  position: fixed; z-index: 20; left: 50%; transform: translateX(-50%); bottom: max(14px, env(safe-area-inset-bottom));
  padding: 9px 16px; border-radius: 999px; font-size: .8rem; text-decoration: none; color: var(--on-accent);
  background: linear-gradient(135deg, var(--gold), var(--accent)); box-shadow: 0 10px 30px rgba(0, 0, 0, .3); white-space: nowrap;
}

/* ---------- kit: building blocks of the interactive templates ---------- */
/* the music controls float above templates that have no photo frame for them */
.chrome .nowplaying, .chrome .mute { position: fixed; z-index: 14; }
/* a full-screen area that scrolls (the page itself never does) */
.scroller { position: absolute; inset: 0; overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.scroller:focus { outline: none; }

/* the letter on a sheet of paper */
.sheet { position: relative; color: var(--ink); background: var(--paper); border-radius: 14px; padding: 1.6rem 1.5rem 1.1rem; box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 24px 60px rgba(0, 0, 0, .28); }
.sheet:focus { outline: none; }
.sheet:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.sheet-head { text-align: center; margin-bottom: 1rem; }
.sheet-head .eyebrow { margin: 0; color: color-mix(in srgb, var(--ink) 55%, transparent); }
.sheet-head h2 { margin: .15rem 0 0; font-family: 'Cormorant Garamond', Georgia, serif; font-style: italic; font-weight: 400; font-size: 2.1rem; line-height: 1.15; color: var(--ink); overflow-wrap: anywhere; }
.sheet-body { font-family: 'Cormorant Garamond', Georgia, serif; font-size: 1.22rem; line-height: 1.7; }
.sheet-body p { margin: 0 0 1em; text-wrap: pretty; }

/* small framed prints of the photos; each opens the lightbox */
.prints { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(40vw, 150px), 1fr)); gap: 18px; }
.print-btn { display: block; width: 100%; padding: 8px 8px 24px; border: 0; border-radius: 3px; background: #fff; cursor: zoom-in; transform: rotate(var(--tilt, 0deg)); box-shadow: 0 2px 4px rgba(0, 0, 0, .16), 0 12px 26px rgba(0, 0, 0, .24); transition: transform .35s var(--ease); }
.print-btn:hover { transform: rotate(0deg) scale(1.04); }
.print-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.print-btn img { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; background: #ece7e2; }

/* the full-screen photo viewer */
.lightbox { width: 100vw; height: 100dvh; max-width: none; max-height: none; margin: 0; padding: 0; border: 0; color: var(--text); background: color-mix(in srgb, var(--bg) 94%, transparent); }
.lightbox::backdrop { background: rgba(0, 0, 0, .45); }
.lightbox[open] { display: grid; place-items: center; animation: lbIn .35s var(--ease); }
.lb-figure { margin: 0; display: grid; justify-items: center; gap: 12px; max-width: 92vw; touch-action: pan-y; }
.lb-img { display: block; max-width: 92vw; max-height: 80dvh; object-fit: contain; border-radius: 6px; box-shadow: 0 30px 80px rgba(0, 0, 0, .45); user-select: none; }
.lb-count { font-size: .75rem; letter-spacing: .22em; color: var(--muted); font-variant-numeric: tabular-nums; }
.lb-btn { position: fixed; width: 48px; height: 48px; display: grid; place-items: center; padding: 0; border-radius: 50%; border: 1px solid var(--panel-line, rgba(255, 255, 255, .2)); color: var(--text); background: color-mix(in srgb, var(--bg-2) 75%, transparent); font-size: 1.7rem; line-height: 1; cursor: pointer; }
.lb-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.lb-prev, .lb-next { top: 50%; transform: translateY(-50%); }
.lb-prev { left: 12px; } .lb-next { right: 12px; }
.lb-close { right: 12px; top: max(12px, env(safe-area-inset-top)); }
.lightbox.single .lb-prev, .lightbox.single .lb-next, .lightbox.single .lb-count { display: none; }
@keyframes lbIn { from { opacity: 0; } }

/* buttons and hints in the theme's colours */
.pill {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem; min-height: 44px; padding: 0 22px; border: 0; border-radius: 999px;
  font: inherit; font-size: .95rem; font-weight: 500; letter-spacing: .04em; color: var(--on-accent); cursor: pointer;
  background: linear-gradient(135deg, var(--gold), var(--accent)); box-shadow: 0 6px 18px color-mix(in srgb, var(--accent-deep) 40%, transparent);
  transition: transform .3s var(--ease), opacity .3s;
}
.pill:hover { transform: scale(1.04); }
.pill:active { transform: scale(.96); }
.pill:focus-visible { outline: 2px solid var(--text); outline-offset: 3px; }
.pill:disabled { opacity: .45; cursor: default; transform: none; }
.pill.ghost { color: var(--text); background: color-mix(in srgb, var(--bg-2) 65%, transparent); border: 1px solid var(--panel-line, rgba(255, 255, 255, .18)); box-shadow: none; }
.hint { margin: 0; font-size: .74rem; letter-spacing: .26em; text-transform: uppercase; text-align: center; color: var(--gold); animation: hint 2.4s ease-in-out infinite; }
body[data-scheme="light"] .hint { color: var(--accent-deep); }
@keyframes hint { 50% { opacity: .45; } }

/* celebration hearts */
.burst { position: fixed; z-index: 40; width: 0; height: 0; pointer-events: none; }
.burst i { position: absolute; left: 0; top: 0; font-style: normal; font-size: var(--s); line-height: 1; color: var(--accent); filter: drop-shadow(0 0 6px var(--heart-glow)); animation: burst 1.5s var(--ease) forwards; }
@keyframes burst {
  from { transform: translate(-50%, -50%) scale(.3); opacity: 1; }
  to { transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) rotate(var(--r)) scale(1); opacity: 0; }
}

/* when a template is missing or fails: the letter and the photos, plainly */
.plain { position: absolute; inset: 0; overflow-y: auto; padding: 76px 18px 40px; display: grid; gap: 28px; justify-items: center; align-content: start; }
.plain .sheet { width: min(100%, 640px); }
.plain .prints { width: min(100%, 760px); }

@media (prefers-reduced-motion: reduce) {
  .hint, .lightbox[open] { animation: none; }
  .eq i { animation: none; transform: scaleY(.6); }
  .heart, .glow, .lock { animation: none; }
  .slide.play .fg, .slide.play .ph { animation: none !important; }
  .slide { transition-duration: 1s; }
  /* the page is usable as soon as the lock screen is gone, not after a long zoom out of the blur */
  .show { transition-duration: .4s; }
}

/* ---------- seasonal lock screen (Halloween, Christmas, Valentine): the season's emoji instead of the heart, and a card in 3D ---------- */
.lock { position: relative; }
.lock::after { content: var(--glyph, none); position: absolute; left: 50%; top: 61%; transform: translate(-50%, -50%); font-size: 17px; line-height: 1; }
body[data-season] .lock-heart,
body[data-season] .i-heart { display: none; }
.field button::after { content: var(--glyph, none); grid-area: 1 / 1; font-size: 20px; line-height: 1; opacity: 0; transform: scale(.4); transition: opacity .5s var(--soft), transform .6s var(--ease); }
.gate.unlocking .field button::after { opacity: 1; transform: scale(1); animation: beat .9s var(--ease) both; }
.open-btn::after { content: var(--glyph, none); }

body[data-season] .gate { perspective: 900px; }
body[data-season] .card {
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); transition: transform .25s ease-out, opacity 1.2s var(--soft), filter 1.4s var(--soft), box-shadow 1.2s var(--soft);
  overflow: hidden;
}
body[data-season] .card::before {
  content: ''; position: absolute; inset: 0; pointer-events: none; border-radius: inherit; opacity: .55;
  background: radial-gradient(circle at var(--mx, 50%) var(--my, 0%), color-mix(in srgb, var(--accent) 38%, transparent), transparent 55%);
}
body[data-season] .gate.unlocking .card { transform: rotateX(0) rotateY(0) scale(1.03); }
body[data-season] .gate.leaving .card { transform: translate3d(0, -26px, 0) scale(1.07); }
