/* Invitation card for every design. Colours, fonts and sizes come from the per-invitation
   <style> block (src/builder/render.js): --bg --paper --ink --accent --orn --muted, .f-<field>. */
* { box-sizing: border-box; }
html { min-width: 280px; background: var(--bg); }
body {
  margin: 0; min-height: 100svh; background: var(--bg); color: var(--ink);
  font-family: var(--font-body); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
body.is-sealed, body.is-opening { overflow: hidden; }
p, h1 { margin: 0; font-weight: inherit; }
:root { --ease: cubic-bezier(.22, .61, .36, 1); }

/* ---------- page backgrounds ---------- */
.page-velvet { background: radial-gradient(ellipse at 50% 25%, color-mix(in srgb, var(--bg), #fff 16%), var(--bg) 60%, color-mix(in srgb, var(--bg), #000 35%)) fixed; }
.page-spotlight { background: radial-gradient(ellipse at 50% 0%, #f7dfc8 0%, color-mix(in srgb, var(--bg), #fff 40%) 28%, var(--bg) 70%) fixed; }
.page-linen { background: repeating-linear-gradient(0deg, #ffffff22 0 1px, transparent 1px 4px), repeating-linear-gradient(90deg, #0000000a 0 1px, transparent 1px 4px), var(--bg) fixed; }
.page-tiles { background: linear-gradient(color-mix(in srgb, var(--bg) 90%, transparent), color-mix(in srgb, var(--bg) 90%, transparent)), url('/b/tile.svg') 0 0 / 120px 120px; }
.page-stars, .page-bokeh { background: radial-gradient(ellipse at 50% -10%, color-mix(in srgb, var(--bg), #fff 18%), var(--bg) 70%) fixed; }
.page-extras { position: fixed; inset: 0; pointer-events: none; overflow: hidden; }
.page-extras i { position: absolute; border-radius: 50%; }
.page-extras--stars i { background: #fff; opacity: .7; animation: twinkle 5s ease-in-out infinite; }
.page-extras--bokeh i { background: radial-gradient(circle, color-mix(in srgb, var(--orn) 40%, transparent), transparent 70%); filter: blur(1px); animation: drift 16s linear infinite; }

/* ---------- the card ---------- */
.card { position: relative; padding: clamp(28px, 7vw, 64px) clamp(14px, 4vw, 40px); outline: none; }
.paper {
  position: relative; width: min(100%, 520px); margin: 0 auto; container-type: inline-size;
  background: var(--paper); box-shadow: 0 1px 2px #0000000f, 0 30px 70px -30px #00000066;
}
.content { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; padding: 12cqw 10cqw; overflow-wrap: anywhere; }
.content > * { max-width: 100%; }
.caps { text-transform: uppercase; letter-spacing: .3em; padding-left: .3em; }
.f-title, .f-date, .f-venue, .f-times { font-weight: 500; }
.f-intro { margin-top: 4cqw; line-height: 1.45; }
.names { display: flex; flex-direction: column; align-items: center; margin: 5cqw 0 3cqw; font-weight: 400; line-height: 1.05; }
.names .amp { margin: .6cqw 0; font-family: var(--font-title); font-style: italic; font-size: 6.4cqw; line-height: 1.2; color: var(--orn); }
.f-date { letter-spacing: .08em; font-variant-numeric: lining-nums; }
.f-receptionLabel { line-height: 1.5; }
.f-times { margin-top: 1.4cqw; font-variant-numeric: lining-nums; letter-spacing: .06em; }
.f-venue { margin-top: 2cqw; line-height: 1.3; }
.map {
  margin-top: 3.6cqw; padding: 2cqw 5.4cqw; border-radius: 999px; border: 1px solid var(--accent); color: var(--accent);
  font-family: var(--font-body); font-size: 2.9cqw; letter-spacing: .2em; text-transform: uppercase; text-decoration: none;
  transition: background-color .2s var(--ease), color .2s var(--ease);
}
.map:hover, .map:focus-visible { background: var(--accent); color: var(--paper); outline: none; }
.f-closing { margin-top: 7cqw; line-height: 1.7; }
.f-welcome { margin-top: 3cqw; line-height: 1.15; }

/* Dividers */
.divider { width: 16cqw; height: 1px; margin: 6cqw 0 5cqw; background: var(--orn); opacity: .6; }
.divider--deco { width: 40cqw; height: auto; background: none; opacity: 1; color: var(--orn); }
.divider--deco svg { display: block; width: 100%; }
.divider--star { display: flex; align-items: center; gap: 3cqw; width: auto; height: auto; background: none; opacity: 1; color: var(--orn); }
.divider--star::before, .divider--star::after { content: ''; width: 14cqw; height: 1px; background: currentColor; opacity: .6; }
.divider--star svg { width: 3.4cqw; height: 3.4cqw; fill: currentColor; }
.divider--leaf { width: 30cqw; height: 4cqw; opacity: .75; background:
  radial-gradient(ellipse 22% 38% at 50% 50%, var(--orn) 96%, transparent) center / 8cqw 4cqw no-repeat,
  linear-gradient(var(--orn), var(--orn)) center / 100% 1px no-repeat; }

/* ---------- frames ---------- */
/* Florals down both sides, the printed proportions of the original Ftesa card. */
.frame-florals .paper { display: flex; flex-direction: column; aspect-ratio: 813 / 1204; box-shadow: 0 0 90px #3d2c2212; }
.frame-florals .content { flex: 1; justify-content: center; padding: 12cqw 19cqw; }
.fl {
  position: absolute; top: 0; bottom: 0; width: 20cqw; background: var(--orn); pointer-events: none;
  -webkit-mask-image: url('/b/florals.webp'), linear-gradient(transparent, #000 4%, #000 94%, transparent), linear-gradient(90deg, transparent, #000 35%);
  mask-image: url('/b/florals.webp'), linear-gradient(transparent, #000 4%, #000 94%, transparent), linear-gradient(90deg, transparent, #000 35%);
  -webkit-mask-size: auto 100%, 100% 100%, 100% 100%; mask-size: auto 100%, 100% 100%, 100% 100%;
  -webkit-mask-position: right center, 0 0, 0 0; mask-position: right center, 0 0, 0 0;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-composite: source-in; mask-composite: intersect;
}
.fl--r { right: 0; }
.fl--l { left: 0; transform: scaleX(-1); }

/* Double gold rule, with corner flourishes or stars. */
.frame-double .paper::before, .frame-double .paper::after, .frame-stars .paper::before, .frame-stars .paper::after { content: ''; position: absolute; pointer-events: none; }
.frame-double .paper::before, .frame-stars .paper::before { inset: 3.4cqw; border: 1px solid color-mix(in srgb, var(--orn) 65%, transparent); }
.frame-double .paper::after, .frame-stars .paper::after { inset: 4.6cqw; border: 1px solid color-mix(in srgb, var(--orn) 30%, transparent); }
.frame-double .content, .frame-stars .content { padding: 14cqw 12cqw 13cqw; }
.corners .corner { position: absolute; width: 17cqw; height: 17cqw; color: var(--orn); top: 2cqw; left: 2cqw; }
.corners .corner:nth-child(2) { left: auto; right: 2cqw; transform: scaleX(-1); }
.corners .corner:nth-child(3) { top: auto; bottom: 2cqw; transform: scaleY(-1); }
.corners .corner:nth-child(4) { top: auto; left: auto; bottom: 2cqw; right: 2cqw; transform: scale(-1); }
.corner-stars .star { position: absolute; width: 5cqw; height: 5cqw; fill: var(--orn); }
.corner-stars .star:nth-child(1) { top: 1.4cqw; left: 1.4cqw; } .corner-stars .star:nth-child(2) { top: 1.4cqw; right: 1.4cqw; }
.corner-stars .star:nth-child(3) { bottom: 1.4cqw; left: 1.4cqw; } .corner-stars .star:nth-child(4) { bottom: 1.4cqw; right: 1.4cqw; }

/* Arch: a rounded-top panel with a double gold edge. */
.frame-arch .paper {
  border: 1px solid color-mix(in srgb, var(--orn) 55%, transparent); border-radius: 50cqw 50cqw 2cqw 2cqw;
  box-shadow: inset 0 0 0 2.4cqw var(--paper), inset 0 0 0 calc(2.4cqw + 1px) color-mix(in srgb, var(--orn) 35%, transparent), 0 0 80px color-mix(in srgb, var(--orn) 18%, transparent), 0 40px 80px -30px #000;
}
.frame-arch .content { padding: 12cqw 11cqw 12cqw; }

/* Tile bands top and bottom. */
.band { height: 20cqw; background: url('/b/tile.svg') 0 0 / 20cqw 20cqw repeat-x; border-bottom: 3px solid var(--orn); }
.band--bottom { border-bottom: 0; border-top: 3px solid var(--orn); }
.frame-band .content { padding: 7cqw 10cqw 9cqw; }

/* Olive branches above and below, drawing themselves once the card is shown. */
.olive { fill: none; stroke: var(--orn); stroke-width: 1.2; stroke-linecap: round; }
.olive-wrap { width: 54cqw; }
.olive-wrap svg { display: block; width: 100%; }
.olive-wrap--top { margin-bottom: 5cqw; }
.olive-wrap--bottom { margin-top: 7cqw; transform: scale(-1, -1); }
.olive-wrap path, .olive-wrap ellipse { stroke-dasharray: 1; }
body:not(.is-sealed):not(.is-opening) .olive-wrap path, body:not(.is-sealed):not(.is-opening) .olive-wrap ellipse { animation: draw 2200ms 300ms cubic-bezier(.45, 0, .2, 1) both; }
body:not(.is-sealed):not(.is-opening) .olive-wrap--bottom path, body:not(.is-sealed):not(.is-opening) .olive-wrap--bottom ellipse { animation-delay: 1200ms; }

/* Minimal: no paper, just generous space and two hairlines. */
.frame-minimal .paper { background: transparent; box-shadow: none; }
.frame-minimal .content { padding: 10cqw 4cqw; border-top: 1px solid color-mix(in srgb, var(--ink) 20%, transparent); border-bottom: 1px solid color-mix(in srgb, var(--ink) 20%, transparent); }

/* ---------- emblems ---------- */
.emblem { margin-bottom: 5cqw; color: var(--orn); }
.emblem--sunburst svg { display: block; width: 44cqw; }
.emblem--lemon svg { display: block; width: 19cqw; filter: drop-shadow(0 4px 6px #c8961a40); }
.emblem--monogram {
  display: flex; align-items: center; justify-content: center; gap: 2.4cqw; width: 17cqw; height: 17cqw; border-radius: 50%;
  border: 1px solid var(--orn); box-shadow: 0 0 0 1.2cqw var(--paper), 0 0 0 calc(1.2cqw + 1px) color-mix(in srgb, var(--orn) 40%, transparent);
  font-family: var(--font-title); font-size: 5.6cqw; line-height: 1; color: var(--accent);
}
.emblem--monogram i { width: 1px; height: 6.5cqw; background: var(--orn); rotate: 20deg; }
.emblem--seal .seal { display: block; width: 24cqw; aspect-ratio: 1; margin-top: -2cqw; }
.seal { background: var(--seal) center / contain no-repeat; filter: drop-shadow(0 1px 1px #4a32187a) drop-shadow(1px 5px 6px #4a321847); }

/* ---------- rendered artwork (designs with `art`, images from tools/art) ---------- */
/* The page backdrop sits on a fixed layer: background-attachment: fixed is ignored on iOS. */
body.page-art { background: transparent; }
.page-art::before { content: ''; position: fixed; inset: 0; z-index: -1; background: var(--art-page); }
.paper-art .paper { background: var(--art-paper); }
/* A minimal design over a scene still needs a card to read on. */
.paper-art .frame-minimal .paper { background: var(--art-paper); border-radius: 3cqw; box-shadow: 0 30px 70px -30px #0000004d; }
.paper-art .frame-minimal .content { border: 0; padding: 12cqw 9cqw; }
/* 9-slice frame: corners keep their shape, edges stretch or repeat. Drawn on its own layer
   so the frame width can be in cqw of the paper. */
.frame-art .paper { box-shadow: 0 2px 4px #0000001a, 0 30px 70px -30px #00000073; }
.frame-art .content { padding: calc(var(--frame-pad) + 6cqw) calc(var(--frame-pad) + 4cqw); }
.art-frame { position: absolute; inset: 0; pointer-events: none; border-style: solid; border-width: var(--frame-w); border-image: var(--frame-src) var(--frame-slice) / var(--frame-w) var(--frame-repeat); }
.emblem--art { width: var(--emblem-w); aspect-ratio: var(--emblem-ratio); background: var(--emblem-src) center / contain no-repeat; }
.emblem--butterfly svg, .emblem--heart svg { display: block; width: 16cqw; fill: var(--orn); }
.emblem--heart svg { width: 9cqw; }
.divider--star .heart { width: 3.6cqw; fill: currentColor; }
.divider--butterfly svg { width: 7cqw; height: auto; fill: currentColor; }

/* Age (birthdays): a large numeral with a small unit under it. */
.age { display: flex; flex-direction: column; align-items: center; margin-top: 3cqw; line-height: .9; }
.f-age { font-variant-numeric: lining-nums; }
.age-unit { margin-top: 1cqw; font-family: var(--font-title); font-size: 3.2cqw; letter-spacing: .4em; padding-left: .4em; text-transform: uppercase; color: var(--muted); }
.names--one { margin-top: 3cqw; }

/* Floating butterflies, confetti, petals, balloons or hearts, drifting over the page. */
.floaters { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
/* They drift behind the card, so the text stays clean. */
.card { z-index: 1; }
.floaters i { position: absolute; top: 100%; display: block; scale: var(--s); animation: float-up 14s linear infinite; }
.floaters--confetti i, .floaters--petals i { top: -6%; animation-name: fall; }
.floaters svg { display: block; width: 34px; fill: var(--orn); }
.floaters--hearts svg { width: 18px; opacity: .7; }
.floaters--butterflies i { animation-name: flutter-by; }
.floaters--butterflies .wing { transform-box: fill-box; animation: flap .32s ease-in-out infinite alternate; }
.floaters--butterflies .wing--l { transform-origin: 100% 50%; }
.floaters--butterflies .wing--r { transform-origin: 0 50%; }
.floaters--confetti b { display: block; width: 7px; height: 12px; border-radius: 1px; background: var(--c); rotate: var(--r); animation: tumble 1.8s linear infinite; }
.floaters--petals b { display: block; width: 16px; height: 12px; border-radius: 80% 0 80% 0; background: radial-gradient(ellipse at 30% 30%, #fff8f6, var(--orn)); opacity: .85; animation: tumble 4s ease-in-out infinite; }
.floaters--balloons b { position: relative; display: block; width: 38px; height: 46px; border-radius: 50% 50% 48% 48% / 56% 56% 44% 44%; opacity: .92;
  background: radial-gradient(circle at 34% 28%, #ffffffcc 0 6%, transparent 22%), radial-gradient(circle at 50% 45%, var(--c), color-mix(in srgb, var(--c), #000 22%)); }
.floaters--balloons b::after { content: ''; position: absolute; left: 50%; top: 100%; width: 1px; height: 46px; background: color-mix(in srgb, var(--ink) 35%, transparent); }
/* Only once the card is showing, and never in the generator's still thumbnails. */
.is-sealed .floaters, .is-opening .floaters, [data-preview="sealed"] .floaters { display: none; }

/* ---------- hero: the full-screen opening scene (designs with a rendered backdrop) ---------- */
/* It cancels the card's padding so the scene fills the screen edge to edge. */
.hero {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 100svh; margin: calc(-1 * clamp(28px, 7vw, 64px)) calc(-1 * clamp(14px, 4vw, 40px)) clamp(28px, 7vw, 64px);
  padding: 72px 20px 96px; text-align: center;
}
.hero-inner { position: relative; width: min(100%, 520px); container-type: inline-size; display: flex; flex-direction: column; align-items: center; gap: 2.4cqw; }
/* Hero text uses the design's colour for text on its backdrop (light on velvet or night sky, dark on
   plaster or sky), over a soft halo of the backdrop's own tone, so it reads on any scene. */
.hero { --hero-ink: var(--cv-on-dark); }
.hero-inner::before {
  content: ''; position: absolute; inset: -18% -16%; z-index: -1; pointer-events: none;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--cv-dark) 70%, transparent), color-mix(in srgb, var(--cv-dark) 30%, transparent) 62%, transparent);
  filter: blur(10px);
}
.hero .f-name1, .hero .f-name2 { color: var(--hero-ink); }
.hero-emblem { margin-bottom: 2cqw; }
.hero-title { font-family: var(--font-title); font-size: 3.4cqw; letter-spacing: .36em; padding-left: .36em; text-transform: uppercase; color: var(--hero-ink); opacity: .82; }
.hero-names { display: flex; flex-direction: column; align-items: center; line-height: 1.02; zoom: 1.35; }
.hero-names .amp { font-family: var(--font-title); font-style: italic; font-size: 6cqw; color: var(--hero-ink); opacity: .75; margin: .4cqw 0; }
.hero-date { font-family: var(--font-title); font-size: 4.2cqw; letter-spacing: .24em; padding-left: .24em; text-transform: uppercase; color: var(--hero-ink); }
.hero-scroll {
  position: absolute; left: 50%; bottom: max(28px, env(safe-area-inset-bottom)); translate: -50% 0;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  font-family: var(--font-title); font-size: 12px; letter-spacing: .3em; padding-left: .3em; text-transform: uppercase; color: var(--hero-ink);
  text-shadow: 0 0 12px var(--cv-dark), 0 0 2px var(--cv-dark);
}
.hero-scroll svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.4; animation: nudge 2.2s ease-in-out infinite; }

/* ---------- sections under the card: photos, the place, dress code ---------- */
/* Torn-paper sheets: the paper colour with ragged top and bottom edges. */
.sec { position: relative; width: min(100%, 520px); margin: clamp(28px, 7vw, 56px) auto 0; text-align: center; color: var(--ink); }
.sec--sheet {
  display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 46px 28px 50px;
  background: var(--paper); filter: drop-shadow(0 18px 30px #00000026);
  -webkit-mask: url('/b/torn.svg') top / 100% 16px no-repeat, linear-gradient(#000, #000) 0 15px / 100% calc(100% - 30px) no-repeat, url('/b/torn-b.svg') bottom / 100% 16px no-repeat;
  mask: url('/b/torn.svg') top / 100% 16px no-repeat, linear-gradient(#000, #000) 0 15px / 100% calc(100% - 30px) no-repeat, url('/b/torn-b.svg') bottom / 100% 16px no-repeat;
}
.paper-art .sec--sheet { background: var(--art-paper); }
.sec-icon { width: 30px; height: 30px; fill: none; stroke: var(--orn); stroke-width: 1.3; stroke-linejoin: round; }
.sec-title { margin: 0; font-family: var(--font-names); font-weight: 400; font-size: 40px; line-height: 1.1; color: var(--accent); }
.sec-lead { font-family: var(--font-title); font-size: 21px; line-height: 1.3; }
.sec-text { font-family: var(--font-body); font-size: 17px; line-height: 1.55; color: var(--muted); max-width: 34ch; }
.sec-meta { font-family: var(--font-title); font-size: 15px; letter-spacing: .14em; color: var(--accent); font-variant-numeric: lining-nums; }
.sec .map { margin-top: 14px; padding: 12px 26px; font-size: 12px; }

/* Photos as prints, slightly askew, overlapping when there are several. */
.sec--photos { display: flex; justify-content: center; align-items: center; padding: 10px 0; }
.photo { margin: 0; padding: 10px 10px 34px; background: #fffdf8; box-shadow: 0 2px 4px #0000001f, 0 22px 40px -14px #00000066; rotate: var(--r, -2deg); }
.photo img { display: block; width: 100%; aspect-ratio: 4 / 5; object-fit: cover; background: color-mix(in srgb, var(--paper), var(--ink) 8%); }
.sec--n1 .photo { width: min(78%, 360px); --r: -1.5deg; }
.sec--n2 .photo, .sec--n3 .photo { width: 52%; }
.sec--n2 .photo:nth-child(1) { --r: -5deg; margin-right: -8%; translate: 0 12px; }
.sec--n2 .photo:nth-child(2) { --r: 4deg; z-index: 1; }
.sec--n3 .photo { width: 42%; }
.sec--n3 .photo:nth-child(1) { --r: -7deg; margin-right: -10%; translate: 0 18px; }
.sec--n3 .photo:nth-child(2) { --r: 1deg; z-index: 1; }
.sec--n3 .photo:nth-child(3) { --r: 6deg; margin-left: -10%; translate: 0 22px; }

/* Signed off at the very end. */
.sign-off { margin: clamp(36px, 9vw, 64px) auto 8px; text-align: center; }
.so-names { font-family: var(--font-names); font-size: 36px; line-height: 1.15; color: var(--accent); }
.so-date { margin-top: 6px; font-family: var(--font-title); font-size: 13px; letter-spacing: .3em; padding-left: .3em; text-transform: uppercase; color: var(--muted); }
.report { display: inline-block; margin-top: 28px; padding: 8px; font-family: var(--font-body); font-size: 11px; letter-spacing: .04em; color: var(--muted); opacity: .7; }
.page-art .report { color: var(--cv-on-dark); }
.page-art .so-names, .page-art .so-date { color: var(--cv-on-dark); text-shadow: 0 0 14px var(--cv-dark), 0 0 3px var(--cv-dark); }

/* ---------- scroll reveals (invite.js marks what scrolled into view) ---------- */
/* Only once the script is running, so the page never stays hidden without it. */
.js-reveal [data-reveal] { opacity: 0; translate: 0 26px; transition: opacity 900ms var(--ease), translate 900ms var(--ease); transition-delay: calc(var(--i, 0) * 140ms); }
.js-reveal .photo[data-reveal] { translate: 0 40px; rotate: calc(var(--r, 0deg) * 3); transition-property: opacity, translate, rotate; }
.js-reveal [data-reveal].is-in { opacity: 1; translate: 0 0; rotate: var(--r, 0deg); }

/* ---------- music toggle (cards without a cover) ---------- */
.music {
  position: fixed; z-index: 3; right: max(16px, env(safe-area-inset-right)); bottom: max(16px, env(safe-area-inset-bottom));
  width: 48px; height: 48px; display: grid; place-items: center; padding: 0; cursor: pointer;
  border: 1px solid var(--orn); border-radius: 50%; background: color-mix(in srgb, var(--paper) 88%, transparent); color: var(--accent);
  box-shadow: 0 6px 18px #0000004d; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.music svg { width: 20px; height: 20px; }
.music[aria-pressed="true"] { background: var(--accent); color: var(--paper); }
.music:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* The card rises in once there is no cover in front of it. */
.is-open .card { animation: rise 900ms var(--ease) both; }
.is-sealed .card, .is-opening .card { visibility: visible; }

.no-motion *, .no-motion *::before, .no-motion *::after { animation: none !important; transition: none !important; }

@keyframes rise { from { opacity: 0; translate: 0 18px; } }
@keyframes draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes twinkle { 50% { opacity: .2; } }
@keyframes nudge { 50% { translate: 0 6px; } }
@keyframes float-up { to { transform: translateY(calc(-100vh - 120%)) translateX(6vw); } }
@keyframes fall { to { transform: translateY(calc(100vh + 120%)) translateX(-8vw); } }
@keyframes flutter-by { 0% { transform: translate(0, 0) rotate(-8deg); } 25% { transform: translate(8vw, -30vh) rotate(10deg); } 50% { transform: translate(-4vw, -60vh) rotate(-6deg); } 75% { transform: translate(10vw, -85vh) rotate(8deg); } 100% { transform: translate(0, calc(-100vh - 120%)) rotate(0); } }
@keyframes flap { to { transform: scaleX(.25); } }
@keyframes tumble { 50% { transform: rotateX(70deg) rotateY(40deg); } 100% { transform: rotateX(0) rotateY(360deg); } }
@keyframes drift { 0% { transform: translateY(0); opacity: 0; } 15%, 85% { opacity: 1; } 100% { transform: translateY(-40vh); opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .olive-wrap path, .olive-wrap ellipse { stroke-dashoffset: 0; }
}

/* ---------- per-design touches ---------- */
/* Disko: neon script names and a night-club card. */
.design-disko .f-name1, .design-disko .f-name2, .design-disko .f-welcome {
  text-shadow: 0 0 2px #fff, 0 0 8px currentColor, 0 0 18px currentColor, 0 0 36px color-mix(in srgb, currentColor 60%, transparent);
}
.design-disko .paper { box-shadow: 0 0 0 1px #9b7bff55, 0 0 60px #ff5fc133, 0 30px 70px -30px #000; }
.design-disko .frame-minimal .content { border-color: #9b7bff55; }
