/* ---------- foundation ---------- */
:root {
  --bg: #05040a;
  --ink: #f1ecf8;
  --dim: #9b93b0;
  --accent: #c9b6ff;
  --warm: #ffc9dc;
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --ease: cubic-bezier(.2, .7, .2, 1);
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background:
    radial-gradient(120% 90% at 50% -10%, #0a0818 0%, #040310 46%, #010106 100%);
  color: var(--ink);
  font-family: var(--serif);
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

button { font: inherit; color: inherit; }

::selection { background: rgba(201, 182, 255, .28); }

/* ---------- sky ---------- */
#sky {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  opacity: 0;
  transition: opacity 1.8s ease;
}
body.is-lit #sky { opacity: 1; }

/* while she is opening the lights the sky steps back, so the only
   bright things on the page are the ones she has touched */
body[data-stage="reasons"]:not(.sky-up) #sky { opacity: .28; }

.vignette {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(72% 62% at 50% 44%, transparent 0%, rgba(2, 1, 6, .55) 66%, rgba(1, 1, 4, .94) 100%);
}

/* film grain, drawn by the browser — no image files */
.grain {
  position: fixed;
  inset: -60%;
  z-index: 45;
  pointer-events: none;
  opacity: .055;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 200px 200px;
  animation: grainShift 1.1s steps(4) infinite;
}

/* ---------- chrome ---------- */
.chrome {
  position: fixed;
  z-index: 40;
  top: 0;
  right: 0;
  padding: calc(env(safe-area-inset-top) + .9rem) 1.1rem 0 0;
}

.sound {
  font-family: var(--sans);
  font-size: .58rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--dim);
  background: rgba(255, 255, 255, .02);
  border: 1px solid rgba(241, 236, 248, .13);
  border-radius: 999px;
  padding: .5rem .85rem;
  cursor: pointer;
  backdrop-filter: blur(6px);
  transition: color .4s ease, border-color .4s ease;
}
.sound:hover { color: var(--ink); border-color: rgba(241, 236, 248, .32); }
.sound[aria-pressed="true"] { color: var(--accent); border-color: rgba(201, 182, 255, .4); }

/* ---------- stages ---------- */
.stage {
  position: fixed;
  inset: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: calc(env(safe-area-inset-top) + 2.2rem) 1.25rem calc(env(safe-area-inset-bottom) + 3.4rem);
  opacity: 0;
  visibility: hidden;
  transform: translateY(16px);
  filter: blur(7px);
  transition:
    opacity 1.2s ease,
    transform 1.35s var(--ease),
    filter 1.2s ease,
    visibility 1.2s;
}
.stage.is-active {
  opacity: 1;
  visibility: visible;
  transform: none;
  filter: none;
}

.stage--scroll {
  display: block;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: rgba(241, 236, 248, .18) transparent;
}
.stage--scroll::-webkit-scrollbar { width: 6px; }
.stage--scroll::-webkit-scrollbar-thumb {
  background: rgba(241, 236, 248, .16);
  border-radius: 99px;
}

.stage-inner {
  width: 100%;
  max-width: 40rem;
  margin: 0 auto;
  padding: clamp(1.5rem, 6vh, 4rem) 0 4.5rem;
}

/* ---------- shared bits ---------- */
.kicker {
  font-family: var(--sans);
  font-size: .58rem;
  letter-spacing: .34em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0 0 1rem;
}

.eyebrow { text-align: center; margin-bottom: clamp(1.6rem, 5vh, 2.8rem); }
.eyebrow h2 {
  font-size: clamp(1.7rem, 6.4vw, 2.6rem);
  font-weight: 400;
  line-height: 1.3;
  margin: 0 0 .7rem;
  letter-spacing: .01em;
}
.eyebrow .sub {
  font-family: var(--sans);
  font-size: .7rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0;
}
.eyebrow .count { color: var(--accent); }

.ghost {
  font-family: var(--sans);
  font-size: .64rem;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--ink);
  background: transparent;
  border: 1px solid rgba(241, 236, 248, .22);
  border-radius: 999px;
  padding: .85rem 1.6rem;
  cursor: pointer;
  transition: border-color .45s ease, background .45s ease, letter-spacing .45s ease, opacity .4s ease;
}
.ghost:hover { border-color: rgba(201, 182, 255, .6); background: rgba(201, 182, 255, .06); letter-spacing: .3em; }
.ghost--small { font-size: .56rem; padding: .6rem 1.1rem; letter-spacing: .2em; }
.ghost[hidden] { display: none; }

/* ---------- arrival ---------- */
.arrival {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2.2rem;
  text-align: center;
}

.first-star {
  position: relative;
  width: 96px;
  height: 96px;
  border: 0;
  background: none;
  cursor: pointer;
  display: grid;
  place-items: center;
  -webkit-tap-highlight-color: transparent;
}
.star-core {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #fff;
  box-shadow:
    0 0 16px 5px rgba(255, 228, 240, .7),
    0 0 54px 18px rgba(180, 160, 255, .3);
  animation: pulse 3.6s ease-in-out infinite;
  transition: transform 1.1s var(--ease), opacity 1.1s ease;
}
.star-ring {
  position: absolute;
  inset: 12px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .16);
  animation: ring 4.2s ease-out infinite;
}
.star-ring--slow { animation-duration: 6.4s; animation-delay: 1.6s; }

.first-star.is-gone .star-core { transform: scale(22); opacity: 0; }
.first-star.is-gone .star-ring { opacity: 0; transition: opacity .5s ease; }

.name {
  font-size: clamp(2.6rem, 11vw, 4.4rem);
  font-weight: 400;
  letter-spacing: .16em;
  margin: 0;
  color: #f6f1fd;
  text-shadow: 0 0 46px rgba(200, 180, 255, .45);
}

.hint {
  font-family: var(--sans);
  font-size: .58rem;
  letter-spacing: .38em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0;
  animation: hintPulse 5s ease-in-out infinite;
}

/* ---------- opening lines ---------- */
.col {
  max-width: 33rem;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.35rem;
}
.line {
  font-size: clamp(1.3rem, 4.7vw, 1.85rem);
  line-height: 1.6;
  margin: 0;
  opacity: 0;
  font-style: italic;
  color: #ece6f7;
}
.line--lead { font-style: normal; letter-spacing: .01em; color: #fff; }
[data-stage="open"].is-active .line { animation: rise 1.8s var(--ease) forwards; }
[data-stage="open"].is-active .line:nth-child(1) { animation-delay: .6s; }
[data-stage="open"].is-active .line:nth-child(2) { animation-delay: 2.4s; }
[data-stage="open"].is-active .ghost { animation: rise 1.8s var(--ease) 4s forwards; opacity: 0; }

/* leaving "look up": the words drift off the top of the frame */
.stage[data-stage="open"]:not(.is-active) { transform: translateY(-46px); }

/* ---------- reasons ---------- */
.reasons { display: flex; flex-direction: column; align-items: center; }

.orbs {
  position: relative;
  width: min(32rem, 100%);
  height: min(50vh, 25rem);
  margin-bottom: clamp(1.5rem, 4vh, 2.4rem);
}

.orb {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 54px;
  height: 54px;
  border: 0;
  background: none;
  display: grid;
  place-items: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  animation: float 9s ease-in-out infinite;
}
/* unopened: a dark pinprick that is barely there */
.orb-core {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(206, 200, 240, .16);
  box-shadow: 0 0 6px 1px rgba(150, 140, 210, .1);
  transition: background 1s ease, box-shadow 1.2s ease, transform .8s var(--ease), width .8s var(--ease), height .8s var(--ease);
}
.orb-halo {
  position: absolute;
  inset: 9px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .055);
  animation: halo 6s ease-out infinite;
  transition: border-color .8s ease, opacity .8s ease, transform .8s var(--ease);
}
.orb:hover .orb-core,
.orb:focus-visible .orb-core {
  background: rgba(255, 242, 250, .7);
  box-shadow:
    0 0 14px 5px rgba(255, 225, 240, .5),
    0 0 40px 14px rgba(180, 158, 255, .25);
  transform: scale(1.3);
}
.orb:focus-visible { outline: none; }
.orb:focus-visible .orb-halo { border-color: rgba(255, 255, 255, .45); }

/* opened: it keeps beating, like something with a pulse */
.orb.is-collected { cursor: default; animation-play-state: paused; }
.orb.is-collected .orb-core {
  width: 8px;
  height: 8px;
  background: #fff3fa;
  animation: beat 3.1s ease-in-out infinite;
}
.orb.is-collected .orb-halo {
  border-color: rgba(255, 214, 238, .3);
  opacity: 1;
  transform: scale(1.45);
  animation: heldHalo 3.1s ease-in-out infinite;
}

/* ---------- letter ---------- */
.letter-wrap { max-width: 31rem; }

.letter {
  font-size: clamp(1.06rem, 3vw, 1.22rem);
  line-height: 2.05;
  color: #e7e1f3;
  letter-spacing: .004em;
}
.letter p { margin: 0 0 1.45em; }
.letter p:last-child { margin-bottom: 0; }
.letter p.is-typing::after {
  content: "";
  display: inline-block;
  width: 1px;
  height: 1.05em;
  margin-left: 3px;
  vertical-align: -.16em;
  background: var(--accent);
  animation: caret 1.1s steps(1) infinite;
}
.letter p:first-child {
  font-size: 1.32em;
  letter-spacing: .06em;
  color: #fff;
  margin-bottom: 1.6em;
}
.letter p:last-child { font-style: italic; color: #fff; }

.letter-tools {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  padding-top: 2.6rem;
}

/* ---------- finale ---------- */
.finale {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 2.2rem;
  z-index: 6;
}
#finaleKicker { transition: opacity 1s ease; }

.hold-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
  opacity: 0;
  transform: scale(.9);
  pointer-events: none;
  transition: opacity 1.4s ease, transform 1.4s var(--ease);
}
.finale.is-ready .hold-wrap { opacity: 1; transform: none; pointer-events: auto; }
.finale.is-done .hold-wrap { display: none; }

.hold {
  position: relative;
  width: 112px;
  height: 112px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .16);
  background: radial-gradient(circle at 50% 45%, rgba(255, 226, 240, .2), rgba(160, 140, 255, .07) 58%, transparent 72%);
  color: #fff;
  cursor: pointer;
  display: grid;
  place-items: center;
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
  box-shadow: 0 0 60px rgba(190, 165, 255, .16);
  transition: transform .25s var(--ease), box-shadow .4s ease;
}
.hold::before {
  content: "";
  position: absolute;
  inset: -7px;
  border-radius: 50%;
  background: conic-gradient(var(--accent) calc(var(--p, 0) * 1%), rgba(255, 255, 255, .05) 0);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
}
.hold:active { transform: scale(.96); }
.hold-heart {
  font-size: 2rem;
  color: #ffd9e8;
  text-shadow: 0 0 26px rgba(255, 190, 220, .7);
  transition: transform .3s var(--ease);
}
.hold.is-holding .hold-heart { transform: scale(1.12); }
.hint--hold { transition: opacity .5s ease; }
.hold.is-holding + .hint--hold { opacity: 0; }

.finale-message {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .9rem;
  max-width: 30rem;
}
.finale-message[hidden] { display: none; }
.finale-message > * { opacity: 0; animation: rise 1.6s var(--ease) forwards; }
.finale-message .big {
  font-size: clamp(1.6rem, 6vw, 2.5rem);
  line-height: 1.4;
  margin: 0;
}
.finale-message .big--warm {
  color: #ffe0ec;
  text-shadow: 0 0 44px rgba(255, 190, 220, .35);
  animation-delay: 1.1s;
}
.finale-message .big:first-child { animation-delay: .1s; }
.finale-message .tiny {
  font-family: var(--sans);
  font-size: .58rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #6f6885;
  margin: 1.8rem 0 0;
  animation-delay: 3.4s;
}
.replay {
  font-family: var(--sans);
  font-size: .58rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--dim);
  background: none;
  border: 0;
  border-bottom: 1px solid rgba(241, 236, 248, .2);
  padding: 0 0 2px;
  cursor: pointer;
}
.replay:hover { color: var(--ink); }

/* ---------- photographs ---------- */
.photos { max-width: 44rem; }
.photo-list { display: flex; flex-direction: column; gap: clamp(1.8rem, 5vh, 3rem); }
.photo { margin: 0; }
.photo img,
.photo video {
  display: block;
  width: 100%;
  height: auto;
  max-height: 82vh;
  object-fit: cover;
  border-radius: 20px;
  border: 1px solid rgba(241, 236, 248, .1);
  filter: saturate(.92) contrast(1.04) brightness(.96);
  background: #07060d;
  box-shadow: 0 34px 90px rgba(0, 0, 0, .5);
}
.photo video { cursor: pointer; }
.photo figcaption {
  margin-top: 1.05rem;
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(.94rem, 2.7vw, 1.04rem);
  letter-spacing: .012em;
  text-transform: none;
  line-height: 1.62;
  color: #cdc4e0;
}

/* ---------- veils & panels ---------- */
.veil {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: 1.4rem;
  background: rgba(4, 3, 9, .74);
  backdrop-filter: blur(14px);
  opacity: 0;
  transition: opacity .5s ease;
}
.veil[hidden] { display: none; }
.veil.is-open { opacity: 1; }

.reason-card {
  width: min(30rem, 100%);
  padding: clamp(1.7rem, 5vw, 2.6rem);
  border: 1px solid rgba(241, 236, 248, .12);
  border-radius: 24px;
  background:
    radial-gradient(120% 90% at 20% 0%, rgba(201, 182, 255, .1), transparent 60%),
    linear-gradient(160deg, rgba(255, 255, 255, .055), rgba(255, 255, 255, .012));
  box-shadow: 0 40px 120px rgba(0, 0, 0, .55);
  transform: translateY(14px) scale(.98);
  opacity: 0;
  transition: transform .7s var(--ease), opacity .7s ease;
}
.veil.is-open .reason-card { transform: none; opacity: 1; }

.reason-card h3 {
  font-size: clamp(1.35rem, 5vw, 1.75rem);
  font-weight: 400;
  line-height: 1.35;
  margin: 0 0 1rem;
  color: #fff;
}
.reason-text {
  font-size: clamp(1rem, 3.1vw, 1.08rem);
  line-height: 1.95;
  color: #ded7ec;
  margin: 0 0 1.9rem;
}

/* ---------- dots ---------- */
.dots {
  position: fixed;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom) + 1.2rem);
  transform: translateX(-50%);
  z-index: 30;
  display: flex;
  gap: .55rem;
  transition: opacity .9s ease;
}
body[data-stage="arrival"] .dots { opacity: 0; pointer-events: none; }
.dots span {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: rgba(241, 236, 248, .2);
  transition: background .6s ease, box-shadow .6s ease, transform .6s var(--ease);
}
.dots span.on {
  background: var(--accent);
  box-shadow: 0 0 12px rgba(201, 182, 255, .9);
  transform: scale(1.7);
}

/* ---------- confetti ---------- */
.confetti { position: fixed; inset: 0; z-index: 55; pointer-events: none; overflow: hidden; }
.confetti i {
  position: absolute;
  top: -10vh;
  font-style: normal;
  font-size: 14px;
  color: rgba(255, 205, 225, .9);
  text-shadow: 0 0 12px rgba(255, 180, 210, .5);
  animation: fall linear forwards;
  will-change: transform, opacity;
}

/* ---------- animation ---------- */
@keyframes pulse {
  0%, 100% { transform: scale(1); opacity: .95; }
  50% { transform: scale(1.45); opacity: 1; }
}
@keyframes ring {
  0% { transform: scale(.45); opacity: 0; }
  30% { opacity: .8; }
  100% { transform: scale(1.55); opacity: 0; }
}
@keyframes hintPulse {
  0%, 100% { opacity: .42; }
  50% { opacity: .95; }
}
@keyframes rise {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: none; }
}
@keyframes float {
  0%, 100% { transform: translate(-50%, -50%); }
  50% { transform: translate(-50%, calc(-50% - 10px)); }
}
@keyframes beat {
  0%, 100% {
    transform: scale(.9);
    opacity: .7;
    box-shadow: 0 0 10px 3px rgba(255, 214, 238, .32), 0 0 26px 8px rgba(190, 160, 255, .16);
  }
  50% {
    transform: scale(1.35);
    opacity: 1;
    box-shadow: 0 0 20px 8px rgba(255, 224, 242, .7), 0 0 58px 22px rgba(190, 160, 255, .38);
  }
}
@keyframes heldHalo {
  0%, 100% { opacity: .18; transform: scale(1.35); }
  50% { opacity: .5; transform: scale(1.6); }
}
@keyframes halo {
  0% { transform: scale(.5); opacity: 0; }
  35% { opacity: .55; }
  100% { transform: scale(1.3); opacity: 0; }
}
@keyframes caret {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}
@keyframes fall {
  from { transform: translate3d(0, 0, 0) rotate(0deg); opacity: 0; }
  10% { opacity: 1; }
  to { transform: translate3d(var(--drift, 0px), 118vh, 0) rotate(340deg); opacity: 0; }
}
@keyframes grainShift {
  0% { transform: translate(0, 0); }
  25% { transform: translate(-2%, 1%); }
  50% { transform: translate(1%, -2%); }
  75% { transform: translate(-1%, -1%); }
  100% { transform: translate(0, 0); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  [data-stage="open"].is-active .line,
  [data-stage="open"].is-active .ghost { opacity: 1; }
}
