/* ══════════════════════════════════════════════════════════════════════════
   A birthday gift, disguised as a broken server.
   ══════════════════════════════════════════════════════════════════════════ */

:root{
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
          "Liberation Mono", "Courier New", monospace;
  --ui:   "Quicksand", "Segoe UI", system-ui, -apple-system, sans-serif;
  --hand: "Dancing Script", "Segoe Script", "Bradley Hand", cursive;

  --ink:      #d7e3ea;
  --ink-dim:  #6d7f8b;
  --term-bg:  #07131f;
  --err:      #ff5f56;
  --warn:     #ffbd2e;
  --ok:       #7ee787;
  --sea:      #7fe3ff;
}

*{ box-sizing: border-box; }

html{ scroll-behavior: auto; }

body{
  margin: 0;
  background: #04121c;
  color: var(--ink);
  font-family: var(--ui);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}

/* while the "server is down", nothing scrolls */
body.is-crashed{ overflow: hidden; }

::selection{ background: #1d7f92; color: #fff; }

/* One visible focus ring for every control. Keyboard users get a real
   indicator on the dark scene; controls on the parchment get a dark one. */
:focus-visible{
  outline: 3px solid #ffd08a;
  outline-offset: 3px;
  border-radius: 4px;
}
.letter-paper :focus-visible{ outline-color: #8a5426; }
#awsnap :focus-visible{ outline-color: #1a73e8; }


/* ══════════════════════════════════════════════════════════════════════════
   SCENE 1 — the fake 404
   ══════════════════════════════════════════════════════════════════════════ */

#crash-screen{
  position: fixed; inset: 0; z-index: 900;
  background: var(--term-bg);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 13px;
  line-height: 1.55;
  overflow-y: auto;
  overflow-x: hidden;
  padding: clamp(16px, 3.4vh, 40px) clamp(14px, 5vw, 56px) 34px;
  animation: crtFlicker 7s infinite steps(1);
}
@keyframes crtFlicker{
  0%,96%,100%{ opacity: 1; }
  97%{ opacity: .93; }
  98.5%{ opacity: .98; }
}

.crash-inner{ max-width: 900px; margin: 0 auto; }

.crash-status{
  display: flex; align-items: baseline; gap: 12px;
  font-size: clamp(28px, 7vw, 46px);
  font-weight: 400;
  letter-spacing: -.02em;
  margin-bottom: 2px;
}
.crash-code{ color: var(--err); }
.crash-sep { color: #24384a; }
.crash-msg { color: #9fb2be; }

.crash-rule{
  border: 0; border-top: 1px solid #17293a;
  margin: 10px 0 14px;
}

.crash-head{
  margin: 0 0 16px;
  color: #7d95a4;
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 12.5px;
}
.crash-head span{ color: #a9c0ce; }

.crash-box{
  border: 1px solid #1d3346;
  border-left: 3px solid var(--err);
  background: #0a1a29;
  margin-bottom: 14px;
}
.crash-box-title{
  padding: 8px 14px;
  border-bottom: 1px solid #16283a;
  color: #ff8a80;
  font-size: 12px;
  letter-spacing: .02em;
}
.crash-trace{
  margin: 0;
  padding: 14px;
  overflow-x: auto;
  color: #8fa6b4;
  font-size: 12.5px;
  white-space: pre;
}

/* the hidden way in — looks like just another frame in the stack trace */
.secret{
  color: #8fa6b4;
  cursor: pointer;
  text-decoration: underline dotted transparent;
  text-underline-offset: 3px;
  transition: color .25s, text-decoration-color .25s;
}
.secret:hover, .secret:focus-visible{
  color: var(--sea);
  text-decoration-color: var(--sea);
}

.crash-logs{
  height: clamp(64px, 12vh, 108px);
  overflow: hidden;
  border: 1px solid #16283a;
  background: #050f19;
  padding: 8px 12px;
  margin-bottom: 14px;
  position: relative;
  mask-image: linear-gradient(#000 60%, transparent);
  -webkit-mask-image: linear-gradient(#000 60%, transparent);
}
#log-stream div{
  color: #6b8496;
  font-size: 11.5px;
  white-space: nowrap;
  animation: logIn .28s ease-out;
}
#log-stream .s404{ color: #e08a80; }
#log-stream .s502{ color: #d8a869; }
#log-stream .s200{ color: #7fb98c; }
@keyframes logIn{ from{ opacity:0; transform: translateY(6px); } to{ opacity:1; } }

.crash-foot{
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 10px 22px;
  font-size: 12.5px;
  color: #58707f;
}
#retry-line{ color: #7c96a5; }
.dots{ display: inline-block; width: 14px; text-align: left; }

.crash-details{
  color: #6f8b9b;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 1px;
  transition: color .3s, border-color .3s, text-shadow .5s;
  cursor: pointer;
}
.crash-details:hover, .crash-details:focus-visible{
  color: var(--sea);
  border-color: var(--sea);
}
/* after a while, it starts breathing so she can't miss it */
.crash-details.beckon{
  color: #9fd6e8;
  animation: beckon 2.6s ease-in-out infinite;
}
@keyframes beckon{
  0%,100%{ text-shadow: none; border-color: transparent; }
  50%    { text-shadow: 0 0 14px rgba(127,227,255,.75); border-color: rgba(127,227,255,.5); }
}

.cursor{
  color: var(--sea);
  animation: blink 1.05s steps(1) infinite;
  font-size: 11px;
  transform: translateY(-1px);
}
@keyframes blink{ 0%,50%{opacity:1} 51%,100%{opacity:0} }

.crash-sig{
  margin-top: 16px;
  padding-top: 10px;
  border-top: 1px solid #12222f;
  color: #3b4d5a;
  font-size: 11.5px;
}

/* faint CRT scanlines over the whole thing */
.crt-lines{
  position: fixed; inset: 0; pointer-events: none; z-index: 2;
  background: repeating-linear-gradient(
    to bottom, rgba(0,0,0,0) 0 2px, rgba(0,0,0,.16) 2px 3px);
  opacity: .5;
}


/* ══════════════════════════════════════════════════════════════════════════
   THE 3D JOURNEY
   ══════════════════════════════════════════════════════════════════════════ */

#gl{
  position: fixed; inset: 0;
  width: 100%; height: 100%;
  display: block;
  z-index: 0;
  opacity: 0;
  transition: opacity 1.1s ease;
  touch-action: pan-y;
}
body.is-live #gl{ opacity: 1; }
body.in-finale #gl{ opacity: 0; transition: opacity .8s ease; }

#vignette{
  position: fixed; inset: 0; z-index: 1; pointer-events: none;
  opacity: 0; transition: opacity 1.4s ease;
  background:
    radial-gradient(125% 95% at 50% 40%, transparent 52%, rgba(2,44,66,.42) 100%);
}
body.is-live #vignette{ opacity: 1; }

/* the white flash when she punches through the water surface */
#surface-flash{
  position: fixed; inset: 0; z-index: 2; pointer-events: none;
  background: radial-gradient(70% 60% at 50% 45%, #ffffff, rgba(190,240,255,0) 70%);
  opacity: 0;
}

#scroll-spacer{ height: 900vh; position: relative; z-index: -1; }


/* ─── the opening line ─────────────────────────────────────────────────── */
#intro-text{
  position: fixed; z-index: 6; pointer-events: none;
  left: 50%; top: 40%;
  transform: translate(-50%, -50%) translateY(18px);
  width: min(880px, 92vw);
  text-align: center;
  font-family: var(--hand);
  font-weight: 600;
  font-size: clamp(30px, 5.6vw, 56px);
  line-height: 1.25;
  color: #ffffff;
  text-shadow:
    0 1px 3px rgba(2,40,60,.9),
    0 2px 22px rgba(2,40,60,.75),
    0 0 54px rgba(2,30,48,.55);
  opacity: 0;
  transition: opacity 1.5s ease, transform 1.5s ease;
}
#intro-text.on{ opacity: 1; transform: translate(-50%, -50%); }

/* ─── captions ─────────────────────────────────────────────────────────── */
#captions{
  position: fixed; z-index: 6; pointer-events: none;
  left: 50%; bottom: clamp(90px, 16vh, 160px);
  transform: translateX(-50%);
  width: min(720px, 86vw);
  text-align: center;
}
/* Every caption occupies the SAME slot. In normal flow they stacked, so
   each line appeared at a different height as she scrolled. */
#captions p{
  position: absolute;
  left: 0; right: 0; bottom: 0;
  margin: 0;
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .7s ease, transform .7s ease;
}
#captions p.on{ opacity: 1; transform: none; }

/* The scene behind swings from night navy to bright peach to pale sand, so
   no fixed text colour can hold 4.5:1. The scrim travels with the text.  */
#captions span{
  display: inline-block;
  padding: 9px 20px;
  border-radius: 999px;
  background: rgba(4,32,46,.62);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  font-size: clamp(15px, 2.4vw, 21px);
  font-weight: 500;
  letter-spacing: .01em;
  line-height: 1.45;
  color: #ffffff;
  text-shadow: 0 1px 3px rgba(2,26,40,.6);
}


/* ─── scroll hint ──────────────────────────────────────────────────────── */
#scroll-hint{
  position: fixed; z-index: 6; left: 50%; bottom: 26px;
  transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 9px;
  opacity: 0; transition: opacity .6s ease; pointer-events: none;
}
#scroll-hint.on{ opacity: 1; }
/* it's an instruction, so it gets the same scrim as the captions */
.sh-text{
  padding: 7px 16px;
  border-radius: 999px;
  background: rgba(4,32,46,.62);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: #ffffff;
  font-size: 11px; font-weight: 600;
  letter-spacing: .22em; text-transform: uppercase;
}
.sh-arrow{
  width: 2px; height: 34px;
  border-radius: 2px;
  background: linear-gradient(#ffffff, rgba(255,255,255,0));
  box-shadow: 0 0 6px rgba(2,30,48,.7);
  animation: shDrop 1.9s ease-in-out infinite;
}
@keyframes shDrop{
  0%   { transform: scaleY(.2); transform-origin: top; opacity: 0; }
  35%  { transform: scaleY(1);  transform-origin: top; opacity: 1; }
  100% { transform: scaleY(1);  transform-origin: bottom; opacity: 0; }
}


/* ─── bottle hint ──────────────────────────────────────────────────────── */
#bottle-hint{
  position: fixed; z-index: 7; left: 50%; bottom: 34px;
  transform: translateX(-50%);
  display: flex; align-items: center; gap: 9px;
  min-height: 44px;                     /* touch target minimum */
  padding: 12px 22px;
  border-radius: 999px;
  border: 1px solid rgba(150,235,255,.35);
  background: rgba(6,32,46,.5);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: #d6f4ff;
  font-family: var(--ui); font-size: 13.5px; font-weight: 600;
  letter-spacing: .02em;
  cursor: pointer;
  opacity: 0; pointer-events: none;
  transition: opacity .6s ease, transform .3s ease;
}
#bottle-hint.on{ opacity: 1; pointer-events: auto; }
#bottle-hint:hover{ transform: translateX(-50%) translateY(-2px); }
.bh-dot{
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--sea);
  box-shadow: 0 0 0 0 rgba(127,227,255,.7);
  animation: ping 1.8s ease-out infinite;
}
@keyframes ping{
  0%  { box-shadow: 0 0 0 0 rgba(127,227,255,.6); }
  70% { box-shadow: 0 0 0 12px rgba(127,227,255,0); }
  100%{ box-shadow: 0 0 0 0 rgba(127,227,255,0); }
}


/* ─── audio button ─────────────────────────────────────────────────────── */
#audio-toggle{
  position: fixed; z-index: 8; right: 18px; top: 18px;
  width: 44px; height: 44px;            /* touch target minimum */
  display: none; place-items: center;
  border-radius: 50%;
  border: 1px solid rgba(160,220,240,.25);
  background: rgba(6,26,38,.45);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  cursor: pointer;
  padding: 0;
}
body.is-live #audio-toggle{ display: grid; }
#audio-toggle svg{
  width: 20px; height: 20px;
  fill: none; stroke: #b6e4f5; stroke-width: 1.7;
  stroke-linejoin: round;
}
#audio-toggle .ico-on{ display: none; }
#audio-toggle[aria-pressed="true"] .ico-on { display: block; }
#audio-toggle[aria-pressed="true"] .ico-off{ display: none; }
#audio-toggle:hover{ border-color: rgba(160,220,240,.55); }

/* she reached the finale still muted — the song is the point, so say so */
#audio-toggle.nudge{
  border-color: rgba(255,214,150,.9);
  background: rgba(70,40,10,.45);
  animation: audioNudge 1.9s ease-in-out infinite;
}
#audio-toggle.nudge svg{ stroke: #ffe0ad; }
@keyframes audioNudge{
  0%,100%{ box-shadow: 0 0 0 0 rgba(255,205,140,.55); transform: scale(1); }
  50%    { box-shadow: 0 0 0 15px rgba(255,205,140,0); transform: scale(1.09); }
}
#audio-nudge{
  position: fixed; z-index: 8; right: 68px; top: 27px;
  padding: 7px 15px; border-radius: 999px;
  background: rgba(255,240,212,.95); color: #7a4d24;
  font-family: var(--ui); font-size: 12.5px; font-weight: 700;
  white-space: nowrap; pointer-events: none;
  box-shadow: 0 6px 20px rgba(0,0,0,.3);
  opacity: 0; transform: translateX(10px);
  transition: opacity .5s ease, transform .5s ease;
}
#audio-nudge.on{ opacity: 1; transform: none; }
@media (max-width: 620px){ #audio-nudge{ right: 58px; top: 22px; font-size: 11.5px; } }


/* ══════════════════════════════════════════════════════════════════════════
   SCENE 5 — the letter
   ══════════════════════════════════════════════════════════════════════════ */

#letter-overlay{
  position: fixed; inset: 0; z-index: 60;
}
#letter-overlay[hidden]{ display: none; }

.letter-backdrop{
  position: absolute; inset: 0;
  background: radial-gradient(90% 70% at 50% 45%, rgba(4,32,46,.72), rgba(1,12,20,.94));
  backdrop-filter: blur(7px); -webkit-backdrop-filter: blur(7px);
  opacity: 0;
}
.letter-scroll{
  position: absolute; inset: 0;
  overflow-y: auto;
  overscroll-behavior: contain;   /* don't let the page scroll behind the letter */
  display: flex; align-items: center; justify-content: center;
  padding: clamp(16px, 5vh, 56px) 16px;
}
.letter-paper{
  position: relative;
  width: min(620px, 100%);
  padding: clamp(30px, 5vw, 54px) clamp(24px, 5vw, 52px) clamp(34px, 5vw, 48px);
  border-radius: 4px;
  background:
    linear-gradient(#fdf5e2, #f6e9cd);
  box-shadow:
    0 40px 90px rgba(0,0,0,.55),
    0 0 0 1px rgba(120,90,50,.18),
    inset 0 0 70px rgba(180,140,80,.16);
  transform-origin: top center;
  /* torn-ish top and bottom edges */
  -webkit-mask-image:
    radial-gradient(6px 6px at 6px 0, transparent 98%, #000 100%),
    linear-gradient(#000, #000);
  mask-image: linear-gradient(#000, #000);
}
.paper-grain{
  position: absolute; inset: 0; pointer-events: none; border-radius: 4px;
  opacity: .5; mix-blend-mode: multiply;
  background-image:
    repeating-linear-gradient(0deg, rgba(150,115,60,.05) 0 1px, transparent 1px 3px),
    radial-gradient(70% 50% at 15% 10%, rgba(160,120,60,.12), transparent 60%),
    radial-gradient(60% 60% at 90% 90%, rgba(140,100,50,.14), transparent 60%);
}
.letter-body{ position: relative; z-index: 1; }

.letter-close{
  position: absolute; top: 8px; right: 10px; z-index: 2;
  width: 44px; height: 44px; border: 0; border-radius: 50%;  /* touch target */
  background: transparent; color: #a98b58;
  font-size: 26px; line-height: 1; cursor: pointer;
  transition: background .2s, color .2s;
}
.letter-close:hover{ background: rgba(169,139,88,.14); color: #6b5330; }

.letter-title{
  margin: 0 0 22px;
  font-family: var(--hand);
  font-weight: 700;
  font-size: clamp(34px, 6.5vw, 50px);
  color: #7a4a24;
  text-align: center;
  letter-spacing: .01em;
}
.letter-text p{
  margin: 0 0 18px;
  font-family: var(--hand);
  font-size: clamp(20px, 3.1vw, 25px);
  line-height: 1.62;
  color: #3f2e1c;
}
.letter-sign{
  margin: 26px 0 0;
  text-align: right;
  font-family: var(--hand);
  font-size: clamp(21px, 3.2vw, 27px);
  color: #7a4a24;
}
.letter-cta{
  display: block;
  margin: 30px auto 0;
  padding: 12px 30px;
  border: 0; border-radius: 999px;
  background: linear-gradient(135deg, #ff8fab, #ffb26b);
  color: #46200e;
  font-family: var(--ui); font-weight: 700; font-size: 15px;
  letter-spacing: .015em;
  cursor: pointer;
  box-shadow: 0 8px 24px rgba(190,90,70,.32);
  transition: transform .2s ease, box-shadow .2s ease;
}
.letter-cta:hover{ transform: translateY(-2px); box-shadow: 0 12px 30px rgba(190,90,70,.42); }
.letter-cta:active{ transform: translateY(0); }


/* ══════════════════════════════════════════════════════════════════════════
   THE TWIST — glitch, fake browser crash, joke popup
   ══════════════════════════════════════════════════════════════════════════ */

#glitch{
  position: fixed; inset: 0; z-index: 998;
  width: 100%; height: 100%;
  pointer-events: none;
  opacity: 0;
  display: block;
}

/* applied to <body> for the "the whole page is dying" moment */
body.glitching{
  animation: pageShake .19s steps(2) infinite;
}
@keyframes pageShake{
  0%  { transform: translate(0,0); }
  25% { transform: translate(-4px, 2px) skewX(.6deg); }
  50% { transform: translate(3px, -3px); }
  75% { transform: translate(-2px, -1px) skewX(-.4deg); }
  100%{ transform: translate(0,0); }
}
body.invert{ filter: invert(1) hue-rotate(120deg) saturate(1.6); }

#awsnap{
  position: fixed; inset: 0; z-index: 999;
  background: #ffffff;
  display: grid; place-items: center;
  padding: 24px;
  font-family: "Segoe UI", system-ui, -apple-system, Roboto, Arial, sans-serif;
  color: #202124;
}
#awsnap[hidden]{ display: none; }
.snap-inner{ max-width: 480px; text-align: left; }
.snap-face svg{ fill: #ced0d3; stroke: none; margin-bottom: 24px; }
.snap-face .eye{ fill: #9aa0a6; }
.snap-face .mouth{ fill: none; stroke: #9aa0a6; stroke-width: 4.5; stroke-linecap: round; }
#awsnap h1{
  margin: 0 0 12px;
  font-size: 24px; font-weight: 400; color: #202124;
}
#awsnap p{ margin: 0 0 10px; font-size: 15px; color: #5f6368; line-height: 1.5; }
.snap-code{ font-size: 13px !important; color: #80868b !important; margin-top: 20px !important; }
.snap-code span{ font-family: var(--mono); }
.snap-actions{ margin-top: 26px; display: flex; align-items: center; gap: 22px; }
.snap-btn{
  background: #1a73e8; color: #fff; border: 0; border-radius: 4px;
  padding: 9px 22px; font-size: 14px; font-family: inherit; cursor: default;
}
.snap-link{ color: #1a73e8; font-size: 14px; }

#joke-popup{
  position: fixed; inset: 0; z-index: 1000;
  display: grid; place-items: center;
  padding: 22px;
  background: rgba(3,14,22,.62);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
#joke-popup[hidden]{ display: none; }
.joke-card{
  position: relative; overflow: hidden;
  width: min(430px, 100%);
  padding: 38px 30px 30px;
  text-align: center;
  border-radius: 26px;
  background: linear-gradient(160deg, #fff6f8, #ffeede);
  box-shadow: 0 30px 80px rgba(0,0,0,.5), inset 0 0 0 1px rgba(255,255,255,.7);
}
.joke-confetti{
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none;
}
.joke-emoji{ font-size: 58px; line-height: 1; margin-bottom: 14px; position: relative; }
#joke-popup h2{
  position: relative;
  margin: 0 0 10px;
  font-size: clamp(21px, 4.4vw, 27px);
  font-weight: 700;
  color: #d2456f;
  letter-spacing: -.01em;
}
#joke-popup p{
  position: relative;
  margin: 0 0 26px; font-size: 15px; color: #7d5f52; line-height: 1.55;
}
#joke-ok{
  position: relative;
  padding: 13px 30px; border: 0; border-radius: 999px;
  background: linear-gradient(135deg, #ff7aa2, #ffb36b);
  color: #fff; font-family: var(--ui); font-weight: 700; font-size: 15.5px;
  cursor: pointer;
  box-shadow: 0 10px 26px rgba(255,110,150,.4);
  animation: okPulse 2.2s ease-in-out infinite;
}
@keyframes okPulse{
  0%,100%{ transform: scale(1); }
  50%    { transform: scale(1.045); }
}


/* ══════════════════════════════════════════════════════════════════════════
   SCENE 7 — the celebration
   ══════════════════════════════════════════════════════════════════════════ */

#finale{
  position: relative; z-index: 20;
  min-height: 100vh; min-height: 100dvh;
  overflow: hidden;
  display: grid; place-items: center;
  padding: clamp(48px, 9vh, 96px) 20px clamp(150px, 22vh, 230px);
  background:
    radial-gradient(120% 80% at 50% 8%,  #2a1a4d 0%, transparent 55%),
    radial-gradient(90% 70% at 15% 95%,  #4a2140 0%, transparent 60%),
    radial-gradient(90% 70% at 88% 88%,  #12385c 0%, transparent 60%),
    linear-gradient(#0a0a1c, #06121f 60%, #081826);
}
#finale[hidden]{ display: none; }

#fx{ position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }

.finale-glow{
  position: absolute; left: 50%; top: 34%;
  width: min(900px, 130vw); aspect-ratio: 1;
  transform: translate(-50%,-50%);
  background: radial-gradient(circle, rgba(255,226,170,.30), rgba(255,180,120,.10) 40%, transparent 66%);
  pointer-events: none;
  opacity: 0;
  animation: glowBreathe 6s ease-in-out infinite;
}
@keyframes glowBreathe{
  0%,100%{ transform: translate(-50%,-50%) scale(1);    }
  50%    { transform: translate(-50%,-50%) scale(1.08); }
}

.finale-content{
  position: relative; z-index: 3;
  width: min(760px, 100%);
  text-align: center;
}

.finale-kicker{
  margin: 0 0 22px;
  font-size: 12px; letter-spacing: .34em; text-transform: uppercase;
  color: rgba(255,222,180,.6);
}

/* ─── photo ───────────────────────────────────────────────────────────── */
/* the 46vh term keeps the photo, the name and the buttons on one screen */
.photo-wrap{ margin: 0 auto 30px; width: min(440px, 80vw, 46vh); }
.photo-frame{
  position: relative;
  border-radius: 18px;
  overflow: hidden;
  padding: 10px;
  background: linear-gradient(150deg, rgba(255,236,200,.95), rgba(255,205,160,.75));
  box-shadow:
    0 30px 70px rgba(0,0,0,.6),
    0 0 90px rgba(255,200,140,.28);
  animation: photoFloat 7s ease-in-out infinite;
}
@keyframes photoFloat{
  0%,100%{ transform: translateY(0) rotate(-.6deg); }
  50%    { transform: translateY(-11px) rotate(.6deg); }
}
.photo-frame img{
  display: block; width: 100%; height: auto; border-radius: 10px;
  aspect-ratio: 4 / 3; object-fit: cover;
  clip-path: inset(0 0 100% 0);
}
.photo-sweep{
  position: absolute; left: 0; right: 0; top: 0; height: 40%;
  background: linear-gradient(rgba(255,255,255,0), rgba(255,255,255,.92), rgba(255,255,255,0));
  opacity: 0; pointer-events: none;
  filter: blur(2px);
}
.photo-caption{
  margin: 16px 0 0;
  font-size: 13.5px; color: rgba(255,228,196,.66); letter-spacing: .04em;
}

/* ─── title ───────────────────────────────────────────────────────────── */
.finale-title{
  margin: 8px 0 18px;
  font-family: var(--hand);
  font-weight: 700;
  font-size: clamp(40px, 10.5vw, 92px);
  line-height: 1.06;
  /* every letter is its own inline-block, so the browser would happily break
     mid-word. One line, always — Finale.fitTitle() shrinks it to fit. */
  white-space: nowrap;
  color: #fff4e0;
  text-shadow: 0 0 30px rgba(255,196,130,.55), 0 0 90px rgba(255,150,110,.35);
}
.finale-title .ch{
  display: inline-block;
  opacity: 0;
  transform: translateY(38px) rotate(8deg) scale(.7);
  will-change: transform, opacity;
}
.finale-title.lit{ animation: titleGlow 3.6s ease-in-out infinite; }
@keyframes titleGlow{
  0%,100%{ text-shadow: 0 0 30px rgba(255,196,130,.5),  0 0 90px rgba(255,150,110,.3); }
  50%    { text-shadow: 0 0 44px rgba(255,214,160,.85), 0 0 130px rgba(255,160,120,.5); }
}

.finale-sub{
  margin: 0 auto 34px; max-width: 30em;
  font-size: clamp(14.5px, 2.3vw, 17.5px);
  line-height: 1.7;
  color: rgba(255,236,214,.8);
  opacity: 0;
}

/* ─── buttons ─────────────────────────────────────────────────────────── */
.finale-actions{ display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; opacity: 0; }
.fbtn{
  padding: 12px 26px;
  border-radius: 999px;
  border: 1px solid rgba(255,214,170,.35);
  background: rgba(255,236,206,.07);
  color: #ffe9cd;
  font-family: var(--ui); font-weight: 600; font-size: 14.5px;
  cursor: pointer;
  transition: transform .2s ease, background .2s ease, border-color .2s ease;
}
.fbtn:hover{ transform: translateY(-2px); background: rgba(255,236,206,.15); border-color: rgba(255,214,170,.7); }
.fbtn-primary{
  border-color: transparent;
  background: linear-gradient(135deg, #ff8fab, #ffc06b);
  color: #4a2210;
  box-shadow: 0 10px 28px rgba(255,140,150,.3);
}

/* ─── flowers ─────────────────────────────────────────────────────────── */
.garden{
  position: absolute; left: 0; right: 0; bottom: 0; height: clamp(150px, 24vh, 250px);
  z-index: 2; pointer-events: none;
  display: flex; align-items: flex-end; justify-content: space-around;
}
.garden svg{ display: block; overflow: visible; }
/* stem dashes and bloom scale are both driven from JS — do NOT set
   transform / transform-box here, it would also retarget the SVG transform
   attributes on the petals. */


/* ══════════════════════════════════════════════════════════════════════════
   Small screens & accessibility
   ══════════════════════════════════════════════════════════════════════════ */

/* short screens: tighten the finale so it still reads as one shot */
@media (max-height: 860px){
  #finale{ padding: clamp(28px, 5vh, 60px) 20px clamp(110px, 18vh, 170px); }
  .finale-kicker{ margin-bottom: 14px; }
  .finale-title{ margin: 4px 0 12px; font-size: clamp(34px, 8vw, 68px); }
  .finale-sub{ margin-bottom: 24px; font-size: clamp(13.5px, 1.9vw, 15.5px); }
  .photo-wrap{ margin-bottom: 22px; }
  .garden{ height: clamp(110px, 17vh, 180px); }
}

@media (max-width: 620px){
  #crash-screen{ font-size: 11.5px; line-height: 1.6; }
  .crash-trace, .crash-head{ font-size: 11px; }
  .crash-logs{ height: 104px; }
  #captions{ bottom: clamp(110px, 20vh, 170px); }
  #audio-toggle{ right: 12px; top: 12px; }
}

@media (prefers-reduced-motion: reduce){
  /* every looping animation in the file, not just the obvious ones */
  .photo-frame, .finale-glow, .finale-title.lit, #joke-ok, .bh-dot, .sh-arrow,
  .crash-details.beckon, #audio-toggle.nudge, .cursor, #log-stream div,
  #crash-screen, body.glitching{
    animation: none !important;
  }
  /* keep the blinking cursor and the beckoning link legible without motion */
  .cursor{ opacity: 1; }
  .crash-details.beckon{
    color: #bfe9ff;
    border-color: rgba(127,227,255,.7);
    text-shadow: 0 0 14px rgba(127,227,255,.75);
  }
  #audio-toggle.nudge{ box-shadow: 0 0 0 4px rgba(255,205,140,.45); }
  *, *::before, *::after{ scroll-behavior: auto !important; }
}
