/* Effects. Everything here is decoration: it never catches clicks, and it is
   switched off by html[data-flash="0"], which reduced-motion users always get. */

.fx-canvas { position: fixed; inset: 0; z-index: 85; width: 100%; height: 100%; pointer-events: none; }
#fx-layer { position: absolute; inset: 0; z-index: 3; pointer-events: none; overflow: hidden; }
html[data-flash="0"] .fx-only { display: none; }

/* Shimmer and twinkling stars */
@keyframes fx-foil { to { background-position: -200% 0; } }
@keyframes fx-twinkle { 50% { opacity: .35; } }
html:not([data-flash="0"]) .title-in:not(:focus) {
  color: transparent; caret-color: #fff; -webkit-background-clip: text; background-clip: text;
  background-image: linear-gradient(100deg, #fff 20%, var(--accent) 35%, #fff 45%, #ffc8ea 55%, #fff 70%);
  background-size: 200% 100%; animation: fx-foil 7s linear infinite;
}
html:not([data-flash="0"]) .mast { position: relative; overflow: hidden; }
html:not([data-flash="0"]) .mast::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: var(--stars) 60px 20px / 260px 58px; animation: fx-twinkle 2.6s ease-in-out infinite;
}
html:not([data-flash="0"]) .mast > * { position: relative; }
html:not([data-flash="0"]) .hero h1 {
  color: transparent; -webkit-background-clip: text; background-clip: text;
  background-image: linear-gradient(100deg, #fff 22%, #ffe08a 36%, #fff 46%, #ffc8ea 56%, #fff 70%);
  background-size: 200% 100%; animation: fx-foil 8s linear infinite;
}
html[data-flash="3"] .title-in:not(:focus), html[data-flash="3"] .hero h1 {
  background-image: linear-gradient(100deg, #ff9ad5, #ffe08a, #a6f5d8, #a8d4ff, #dcb4ff, #ff9ad5); animation-duration: 3s;
}

/* A row earns a heart: a shimmer and a sticker */
.fx-sweep { position: absolute; height: var(--rh); background: linear-gradient(100deg, transparent 30%, rgba(255,160,215,.7) 46%, rgba(255,255,255,.95) 50%, rgba(255,226,150,.7) 54%, transparent 70%); background-size: 300% 100%; animation: fx-sweep .75s ease-out forwards; }
@keyframes fx-sweep { from { background-position: 120% 0; } to { background-position: -40% 0; } }
.fx-seal { position: absolute; width: 30px; height: 30px; background: linear-gradient(160deg, #ffc3e4, #ff4fa6 70%); clip-path: path("M15 28C5 20 1 15 1 9.500 1 5 4.500 2 8.500 2 11 2 13.500 3.500 15 6 16.500 3.500 19 2 21.500 2 25.500 2 29 5 29 9.500 29 15 25 20 15 28Z"); animation: fx-seal 1.15s cubic-bezier(.2,1.4,.4,1) forwards; }
@keyframes fx-seal { 0% { transform: scale(3) rotate(-70deg); opacity: 0; } 24% { transform: scale(.95) rotate(8deg); opacity: 1; } 34% { transform: scale(1.08) rotate(0); } 78% { opacity: 1; } 100% { transform: scale(1) rotate(0); opacity: 0; } }

/* Rows dissolve into sparkles */
.fx-burning, .fx-revive { -webkit-mask-image: linear-gradient(100deg, #000 44%, rgba(0,0,0,.6) 48%, transparent 54%); mask-image: linear-gradient(100deg, #000 44%, rgba(0,0,0,.6) 48%, transparent 54%); -webkit-mask-size: 240% 100%; mask-size: 240% 100%; animation: fx-burn .8s ease-in forwards; }
.fx-burning .cell, .fx-burning .rn { animation: fx-char .8s ease-in forwards; }
.fx-revive { position: absolute; height: var(--rh); background: var(--paper); box-shadow: inset 0 0 14px rgba(255,130,200,.9); }
@keyframes fx-burn { from { -webkit-mask-position: 0 0; mask-position: 0 0; } to { -webkit-mask-position: 100% 0; mask-position: 100% 0; } }
@keyframes fx-char { 50% { filter: brightness(1.15) saturate(1.8) hue-rotate(-30deg); } 100% { filter: brightness(1.5) saturate(.6); } }

/* Other people's edits, and picking a choice */
.fx-ripple { position: absolute; box-shadow: inset 0 0 0 2px var(--uc); background: color-mix(in srgb, var(--uc) 26%, transparent); animation: fx-ripple .7s ease-out forwards; }
@keyframes fx-ripple { to { transform: scale(1.1, 1.5); opacity: 0; } }


/* Announcement banners */
.fx-banner-wrap { position: fixed; top: 74px; left: 50%; z-index: 86; transform: translateX(-50%); display: grid; gap: 6px; justify-items: center; pointer-events: none; }
.fx-banner { padding: 7px 26px; font: italic 700 21px var(--script); color: #6b1f66; border-radius: 999px; background: linear-gradient(100deg, #ffb8e0, #ffe6f4 40%, #fff 50%, #ffe08a 60%, #ffb8e0); background-size: 220% 100%; box-shadow: 0 8px 24px rgba(0,0,0,.35); animation: fx-banner 2.6s ease-out forwards, fx-foil 2s linear infinite; }
@keyframes fx-banner { 0% { transform: translateY(-26px) scale(.9); opacity: 0; } 10% { transform: none; opacity: 1; } 84% { opacity: 1; } 100% { transform: translateY(-10px); opacity: 0; } }

/* Time rewinds */
.fx-vhs { position: fixed; inset: 0; z-index: 2147483000; pointer-events: none; display: grid; place-items: center; color: #fff; font: italic 700 clamp(30px, 6vw, 58px) "Lobster Two", cursive; text-shadow: 0 0 18px #ff6fbf, 0 0 4px #8a3fd1; background: radial-gradient(circle, rgba(255,160,220,.15), rgba(120,70,220,.5)); animation: fx-vhs .95s ease-in-out forwards; overflow: hidden; }
.fx-vhs::before { content: ""; position: absolute; left: 50%; top: 50%; width: min(70vmin, 520px); aspect-ratio: 1; margin: calc(min(70vmin, 520px) / -2) 0 0 calc(min(70vmin, 520px) / -2); background: url(/assets/flower-wreath.svg) center / contain no-repeat; opacity: .75; animation: fx-rewind-spin .95s cubic-bezier(.4,0,.3,1) forwards; }
@keyframes fx-vhs { 0% { opacity: 0; } 18% { opacity: 1; } 78% { opacity: 1; } 100% { opacity: 0; } }
@keyframes fx-rewind-spin { from { transform: rotate(360deg) scale(.7); } to { transform: rotate(-200deg) scale(1.08); } }

/* Curtain between sheet colours */
.fx-curtain { position: fixed; inset: 0; z-index: 84; pointer-events: none; background: repeating-linear-gradient(100deg, var(--cc) 0 90px, color-mix(in srgb, var(--cc) 72%, white) 90px 180px); box-shadow: 0 0 70px 20px var(--cc); animation: fx-curtain .62s cubic-bezier(.7,0,.3,1) forwards; }
@keyframes fx-curtain { from { transform: translateX(-112%); } 50% { transform: none; } to { transform: translateX(112%); } }

/* Share dialog */
html:not([data-flash="0"]) #share-dialog[open] #share-qr { animation: fx-unfurl .6s cubic-bezier(.2,.9,.3,1); }
@keyframes fx-unfurl { from { clip-path: inset(0 0 100% 0); transform: rotateX(50deg); } to { clip-path: inset(0); transform: none; } }

/* The sparkle gate */
.vault { position: fixed; inset: 0; z-index: 90; display: flex; overflow: hidden; }
.vault-door { flex: 1; background: radial-gradient(1.6px 1.6px at 30px 30px, #fff, transparent) 0 0 / 120px 110px, radial-gradient(1.2px 1.2px at 90px 80px, #ffe08a, transparent) 0 0 / 120px 110px, linear-gradient(160deg, #d0408f, #6b2aa8 75%); animation: vault-shut .24s ease-in; transition: transform .85s cubic-bezier(.75,0,.25,1); }
.vault-door.l { border-right: 2px solid #ffe08a; box-shadow: inset -30px 0 60px rgba(50,0,90,.4); --from: -100%; }
.vault-door.r { box-shadow: inset 30px 0 60px rgba(50,0,90,.4); --from: 100%; }
@keyframes vault-shut { from { transform: translateX(var(--from)); } }
.vault-wheel { position: absolute; left: 50%; top: 50%; width: min(62vmin, 420px); aspect-ratio: 1; margin: calc(min(62vmin, 420px) / -2) 0 0 calc(min(62vmin, 420px) / -2); background: url(/assets/flower-wreath.svg) center / contain no-repeat; filter: drop-shadow(0 0 16px #ffc8ea); animation: vault-spin 3.2s linear infinite; transition: transform .5s, opacity .4s; }
@keyframes vault-spin { to { transform: rotate(360deg); } }
.vault-light { position: absolute; left: 50%; top: 50%; width: 22px; height: 22px; margin: -11px 0 0 -11px; border-radius: 50%; background: #fff; box-shadow: 0 0 22px 8px #ffc8ea; transition: transform .4s, box-shadow .3s, background .2s; }
.vault.ok .vault-light { transform: scale(60); opacity: .9; box-shadow: 0 0 40px 20px #fff; }
.vault.no .vault-light { background: #ff5a7a; box-shadow: 0 0 26px 10px #ff5a7a; }
.vault.no .vault-wheel { filter: grayscale(.7) drop-shadow(0 0 10px #ff5a7a); animation: vault-rattle .09s linear 5 alternate; }
@keyframes vault-rattle { from { transform: translateX(-9px) rotate(-5deg); } to { transform: translateX(9px) rotate(5deg); } }
.vault.ok .vault-wheel { opacity: 0; transform: scale(1.5) rotate(240deg); animation: none; }
.vault.open .vault-door.l { transform: translateX(-102%); }
.vault.open .vault-door.r { transform: translateX(102%); }
.vault.open .vault-light { opacity: 0; }
.vault.gone { opacity: 0; transition: opacity .25s; }
.field-shake { animation: vault-field .36s; }
@keyframes vault-field { 25% { transform: translateX(-9px); } 50% { transform: translateX(8px); } 75% { transform: translateX(-5px); } }

/* Splash */
.splash { position: fixed; inset: 0; z-index: 2147483600; display: grid; place-items: center; overflow: hidden; background: #1a0a2e; cursor: pointer; transition: opacity .38s; }
.splash canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.splash.done { opacity: 0; pointer-events: none; }
.splash-title { position: relative; display: grid; justify-items: center; text-align: center; padding: 0 20px; font-family: "Lobster Two", cursive; font-style: italic; font-weight: 700; line-height: 1; color: transparent; -webkit-background-clip: text; background-clip: text; background-image: linear-gradient(100deg, #fff 20%, #ffe08a 36%, #fff 46%, #ffb8e6 56%, #fff 72%); background-size: 200% 100%; filter: drop-shadow(0 3px 14px rgba(70,0,90,.85)); opacity: 0; font-size: clamp(38px, 8.6vw, 116px); animation: fx-foil 2.2s linear infinite; }
.splash-title small { margin-top: .32em; font: 700 clamp(12px, 1.6vw, 18px) Comfortaa, sans-serif; letter-spacing: .24em; text-transform: uppercase; }
.splash-skip { position: absolute; bottom: 20px; font: 400 13px Inter, sans-serif; color: rgba(255,255,255,.5); }
