/* Layout owns the artwork: canvas effects follow these same DOM anchors. */
:root {
  --scene-top: max(88px, calc(74px + env(safe-area-inset-top, 0px)));
  --scene-bottom: calc(124px + var(--safe-bottom));
  --ease-out: cubic-bezier(.22, 1, .36, 1);
}

html { font-size: 16px; }
body { color: var(--ink); }
#story { height: 100dvh; touch-action: pan-y; }
.scene {
  padding: var(--scene-top) 7vw var(--scene-bottom);
  gap: clamp(18px, 3vh, 32px);
  transform: translate3d(0, 22px, 0);
  transition: opacity .55s ease, transform .75s var(--ease-out), visibility .75s;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.scene.active { transform: none; }
.scene h1, .scene h2 { line-height: 1.1; letter-spacing: -.025em; }
.scene.active h1, .scene.active h2 { animation: phrase-in .9s var(--ease-out) both; }
.scene-details { opacity: .7; }
.detail-arc { opacity: .6; }
.scene-details > span:nth-child(3n) { opacity: calc(var(--twinkle) * .7); }

/* The title, number, rings and moon form a single centered composition. */
.birthday {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr) auto;
  justify-items: center;
  gap: 20px;
  padding-top: max(96px, var(--scene-top));
}
.birthday h1 {
  width: min(100%, 1000px);
  max-width: 1000px;
  margin: 0;
  font-size: clamp(52px, 6.1vw, 104px);
  line-height: 1.04;
}
.birthday h1 em { color: #ecd5df; }
.birthday-orbit {
  position: relative;
  grid-row: 2;
  align-self: center;
  left: auto;
  top: auto;
  transform: none;
  width: min(460px, 72vw);
  height: min(340px, 34dvh);
  max-width: none;
  padding: 0;
  flex: none;
  background: radial-gradient(ellipse, #e9b5dc06, transparent 68%);
}
.birthday-orbit:before {
  inset: 3% -14%;
  transform: rotate(-18deg) scaleY(.55);
  border-color: #ddbddb36;
  box-shadow: 0 0 24px #d9b9df08;
  animation: birthday-ring 14s ease-in-out infinite;
}
.birthday-orbit:after {
  inset: 9% -8%;
  transform: rotate(24deg) scaleY(.68);
  border-color: #bdd6ef22;
  animation: birthday-ring-secondary 17s ease-in-out infinite;
}
.date-moon {
  right: -7%;
  top: 9%;
  width: clamp(70px, 7vw, 98px);
  height: clamp(70px, 7vw, 98px);
  border: 1px solid #ebf7ff70;
  box-shadow: 0 0 45px #bbddff20, inset -9px -8px 20px #182f4766;
  animation: moon-float 9s ease-in-out infinite;
}
.date-moon b { font-size: clamp(34px, 3.2vw, 44px); }
.date-moon > span { font-size: 12px; }
.age-fallback {
  display: grid;
  place-items: center;
  height: 100%;
  font-size: clamp(130px, 19vw, 260px);
  color: #ecd0de;
}
.replay-film {
  position: relative;
  grid-row: 3;
  left: auto;
  bottom: auto;
  font-size: 14px;
  letter-spacing: 0;
  padding: 8px 14px;
  opacity: .72;
}

/* Keep the next ticket on the viewport center, even with no back button. */
.story-controls {
  width: min(440px, calc(100vw - 32px));
  height: 62px;
  bottom: calc(22px + var(--safe-bottom));
  justify-content: center;
  gap: 0;
}
.back {
  position: absolute;
  left: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  transform: none;
  border-color: color-mix(in srgb, var(--accent) 28%, transparent);
  background: color-mix(in srgb, var(--bg) 76%, transparent);
  backdrop-filter: blur(12px);
  transition: opacity .3s, background .3s, scale .25s;
}
.back:hover { scale: 1.06; }
.back:disabled { visibility: hidden; }
.next-arena {
  flex: 0 1 clamp(200px, 64vw, 280px);
  width: clamp(200px, 64vw, 280px);
  justify-content: center;
}
.next { width: 100%; height: 62px; min-height: 62px; padding: 0 23px; }
.next:before {
  background: linear-gradient(110deg,
    color-mix(in srgb, var(--bg) 86%, var(--accent)),
    color-mix(in srgb, var(--bg) 78%, var(--accent)));
  opacity: .88;
  transition: opacity .3s;
}
.next:hover:before { opacity: 1; }
.next-copy { font-size: 14px; line-height: 1.5; letter-spacing: 0; }
.next.needs-discovery { opacity: .8; }
.next-frame path { opacity: .5; }
.next-frame .next-edge { opacity: 1; }
.next:focus-visible { outline: none; filter: drop-shadow(0 0 5px var(--accent)); }
.next:focus-visible .next-frame path { stroke-width: 1.8; opacity: 1; }
.keepsakes .dock-label { display: inline; font-size: 14px; }
.keepsakes button { min-height: 44px; transition: background .3s, translate .3s; }
.keepsakes button:hover { translate: 0 -2px; }
.quiet-button, .accelerate, .draft-panel label, .draft-bottom p,
.editor-bar, .emote-caption, .race-heading, .light-slider,
.warm-hint, .kindness-note, .heart-score { font-size: 14px; }
.draft-bottom p { line-height: 1.65; }
.draft-bottom { min-height: 56px; }
.elements button, .emote-view .round { width: 44px; height: 44px; }
.emote-thumbs button { width: 44px; height: 44px; flex-basis: 44px; }
.emote-stage {
  background: linear-gradient(150deg,
    color-mix(in srgb, var(--bg) 86%, var(--accent)),
    color-mix(in srgb, var(--bg) 97%, transparent));
  box-shadow: 0 24px 80px #0003, inset 0 1px #ffffff08;
}
.emote-caption { min-height: 38px; }
.accelerate { min-height: 46px; }

/* Photo targets and lens glints move with the photograph. */
.scene.has-photo-game {
  padding: var(--scene-top) 8vw var(--scene-bottom);
  overflow-x: hidden;
  overflow-y: auto;
}
.photo-status { font-size: 16px; line-height: 1.7; min-height: 54px; }
.photo-instructions { gap: 16px; }
.photo-targets, .glasses-glint {
  transform: translate(var(--look-x, 0px), var(--look-y, 0px));
}
.interactive-photo img {
  mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent),
    linear-gradient(transparent, #000 8%, #000 92%, transparent);
}
.scene.active .photo-instructions { animation: supporting-in .85s .12s var(--ease-out) both; }
.scene.active .emote-stage { animation: supporting-in .9s .08s var(--ease-out) both; }
.shutter-button { bottom: 8%; }
.light-slider { width: min(290px, 100%); }

/* One visible progress meter; the entire light is also clickable. */
.kindness-meter { font-size: 14px; width: min(430px, 88vw); margin-top: 0; gap: 14px; }
.kindness-meter b { font-size: 14px; }
.kindness-note { font-size: 18px; }
.kindness-spark { min-height: 140px; }
.warm-hint { opacity: .9; }

/* The spark actually travels around its target, with a readable top zone. */
.finale h2 { margin: 0; font-size: clamp(48px, 5.3vw, 88px); }
.heart-console {
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  grid-template-rows: 1fr 1fr;
  align-items: center;
  gap: 24px 36px;
  width: min(860px, 90vw);
  min-height: 260px;
}
.heart-console > p {
  position: relative;
  grid-column: 1;
  grid-row: 1;
  left: auto;
  top: auto;
  align-self: end;
  max-width: 320px;
  font-size: 16px;
  line-height: 1.7;
  opacity: 1;
  color: var(--accent);
}
.heart-track {
  --pulse-radius: 46px;
  position: relative;
  grid-column: 1;
  grid-row: 2;
  justify-self: center;
  align-self: start;
  left: auto;
  top: auto;
  width: 112px;
  height: 112px;
  background: transparent;
}
.heart-track:before {
  content: '';
  position: absolute;
  width: 36px;
  height: 22px;
  left: calc(50% - 18px);
  top: -1px;
  background: #f9c8e024;
  border: 1px solid #f9c8e052;
  border-radius: 50% 50% 35% 35%;
  box-shadow: 0 0 22px #f9c8e010;
}
.heart-track b { width: 92px; height: 92px; border-color: #f3c7dd40; }
.heart-track i {
  width: 18px;
  height: 18px;
  left: calc(50% - 9px);
  top: calc(50% - 9px);
  display: grid;
  place-items: center;
  font-size: 18px;
  transform-origin: center;
}
.galaxy-heart {
  position: relative;
  grid-column: 2;
  grid-row: 1 / 3;
  justify-self: center;
  left: auto;
  top: auto;
  transform: none;
  width: min(340px, 36vw, 38dvh);
  height: auto;
  aspect-ratio: 1;
}
.heart-core-mark { font-size: clamp(70px, 8vw, 100px); }
.heart-score { bottom: 16%; }
.galaxy-heart.complete { animation: none; box-shadow: 0 0 0 18px #f9d6e518, 0 0 100px #f0a8d957, inset 0 0 90px #f3b7d53d; }
.finale-awake:after { background: radial-gradient(ellipse at 65% 55%, #ffc7e217, transparent 55%); }

/* Dialogs remain readable in every scene palette. */
#badges-dialog { color: #f4ece7; background: #18141d; }
#badges-dialog > p, .badge p { font-size: 14px; line-height: 1.7; color: #c8bbc6; }
.badge b { font-size: 16px; }
.badge { color: #c3b7c0; }
.badge.earned { color: #f1c4d9; }
.dialog-close { width: 44px; height: 44px; }
.letter-paper p { font-size: 16px; line-height: 1.85; }
.letter-date { font-size: 12px; letter-spacing: 1.4px; }
.achievement-toast small { font-size: 12px; }
.achievement-toast b { font-size: 14px; white-space: normal; }
.entry-note { font-size: 12px; }
.entry p { font-size: 14px; max-width: 380px; }
.cinema #skip-intro { font-size: 14px; min-height: 46px; }

@keyframes supporting-in {
  from { opacity: 0; translate: 0 12px; }
  to { opacity: 1; translate: 0 0; }
}
@keyframes birthday-ring {
  50% { transform: rotate(-12deg) scaleY(.58); opacity: .7; }
}
@keyframes birthday-ring-secondary {
  50% { transform: rotate(17deg) scaleY(.62); }
}

@media (max-width: 900px) {
  :root { --scene-top: max(82px, calc(72px + env(safe-area-inset-top, 0px))); }
  .scene.has-photo-game {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(150px, 1fr) auto;
    padding: var(--scene-top) 6vw var(--scene-bottom);
    gap: 16px;
  }
  .has-photo-game > h2 { font-size: clamp(32px, 7.6vw, 50px); line-height: 1.08; }
  .photo-status { font-size: 14px; min-height: 24px; line-height: 1.6; }
  .photo-instructions { gap: 8px; }
  .light-slider { width: min(270px, 75vw); font-size: 14px; }
}

@media (max-width: 600px) {
  :root { --scene-bottom: calc(110px + var(--safe-bottom)); }
  .scene { padding: var(--scene-top) 6vw var(--scene-bottom); gap: 18px; }
  .scene h2 { font-size: clamp(31px, 8.5vw, 43px); }
  .birthday { padding-top: var(--scene-top); gap: 16px; }
  .birthday h1 { font-size: clamp(46px, 12.7vw, 68px); }
  .birthday-orbit { width: 68vw; height: min(290px, 33dvh); }
  .date-moon { right: -8%; top: 7%; width: 70px; height: 70px; }
  .date-moon > span { font-size: 12px; }
  .story-controls { height: 58px; bottom: calc(18px + var(--safe-bottom)); }
  .next { height: 58px; min-height: 58px; padding: 0 18px; gap: 12px; }
  .next-copy { font-size: 14px; }
  .back { width: 40px; height: 40px; }
  .keepsakes button { padding: 8px 12px; }
  .keepsakes .dock-label { font-size: 12px; }
  .dota { gap: 10px; }
  .dota h2, .emote h2 { font-size: clamp(27px, 7.2vw, 35px); }
  .draft-panel label { font-size: 14px; margin-bottom: 8px; }
  .draft-bottom { flex-wrap: wrap; gap: 4px 10px; padding-top: 5px; }
  .draft-bottom p { font-size: 14px; flex: 1 1 200px; }
  #hint { font-size: 14px; }
  #hero-form .primary { font-size: 14px; padding: 10px 16px; }
  .summon { min-height: 120px; }
  .elements button { width: 44px; height: 44px; }
  .emote-stage { padding: 12px 10px 8px; min-height: 250px; }
  .emote-caption, .editor-bar { font-size: 12px; }
  .emote-view .round { width: 40px; height: 40px; }
  .ferrari h2 { font-size: clamp(33px, 8.7vw, 44px); }
  .race-stage { width: 100%; gap: 15px; }
  .circuit { width: min(100%, 76dvh); }
  .accelerate { font-size: 14px; padding: 0 16px; }
  .kindness h2 { font-size: clamp(30px, 8vw, 40px); }
  .kindness-meter { width: 100%; font-size: 12px; padding: 12px; gap: 10px; }
  .kindness-meter b { font-size: 14px; }
  .kindness-note { font-size: 16px; right: 0; }
  .kindness-spark { width: 86vw; }
  .finale h2 { font-size: clamp(45px, 12vw, 62px); }
  .heart-console {
    width: 100%;
    grid-template-columns: 112px minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    gap: 20px 14px;
    min-height: 280px;
  }
  .heart-console > p { grid-column: 1 / 3; grid-row: 1; font-size: 14px; text-align: center; max-width: 100%; }
  .heart-track { grid-column: 1; grid-row: 2; align-self: center; }
  .galaxy-heart { grid-column: 2; grid-row: 2; width: min(220px, 51vw); }
  .heart-core-mark { font-size: 68px; }
  .heart-score { font-size: 14px; }
  .letter-paper p { font-size: 16px; }
  .entry { gap: 20px; }
  .entry h1 { font-size: clamp(48px, 14vw, 62px); }
}

@media (max-height: 700px) {
  :root { --scene-top: 74px; --scene-bottom: calc(100px + var(--safe-bottom)); }
  .birthday { padding-top: var(--scene-top); gap: 12px; }
  .birthday h1 { font-size: clamp(42px, 8vw, 70px); }
  .birthday-orbit { height: min(260px, 30dvh); }
  .replay-film { font-size: 14px; padding: 5px 10px; }
  .story-controls { height: 54px; bottom: calc(14px + var(--safe-bottom)); }
  .next { height: 54px; min-height: 54px; }
  .entry { gap: 12px; }
  .entry p { font-size: 14px; }
  .emote-stage { min-height: 230px; }
  .draft-panel { flex-shrink: 0; }
  .kindness { gap: 18px; }
  .heart-console { min-height: 220px; }
}

@media (max-height: 500px) and (orientation: landscape) {
  :root { --scene-top: 62px; --scene-bottom: calc(78px + var(--safe-bottom)); }
  .scene { padding: var(--scene-top) 6vw var(--scene-bottom); gap: 24px; }
  .scene h1, .scene h2 { font-size: 32px; line-height: 1.08; }
  .birthday { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr auto; gap: 8px 32px; }
  .birthday h1 { width: 100%; max-width: 100%; grid-column: 1; grid-row: 1; text-align: left; align-self: center; font-size: 42px; }
  .birthday-orbit { grid-column: 2; grid-row: 1 / 3; width: min(32vw, 360px); height: 48dvh; }
  .date-moon { width: 60px; height: 60px; top: 0; }
  .date-moon b { font-size: 30px; }
  .date-moon > span { font-size: 12px; }
  .replay-film { grid-column: 1; grid-row: 2; justify-self: start; }
  .story-controls { height: 48px; bottom: calc(12px + var(--safe-bottom)); }
  .next { height: 48px; min-height: 48px; }
  .next-copy { font-size: 14px; }
  .scene.has-photo-game { grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); grid-template-rows: 1fr 1fr; gap: 14px 28px; padding: var(--scene-top) 7vw var(--scene-bottom); }
  .has-photo-game > h2 { grid-column: 1; grid-row: 1; text-align: left; align-self: end; font-size: 29px; }
  .interactive-photo { grid-column: 2; grid-row: 1 / 3; }
  .photo-instructions { grid-column: 1; grid-row: 2; align-self: start; text-align: left; align-items: flex-start; }
  .photo-status, .light-slider { font-size: 14px; }
  .scene.dota { grid-template-rows: auto auto; }
  .dota h2 { font-size: 25px; }
  .draft-panel label { font-size: 12px; }
  .draft-bottom p, #hint { font-size: 12px; }
  .draft-bottom { min-height: 38px; }
  .emote-stage { min-height: 180px; height: 100%; max-height: 100%; }
  .emote-thumbs { display: flex; padding-bottom: 0; }
  .emote-thumbs button { width: 32px; height: 32px; flex-basis: 32px; }
  .emote-caption { min-height: 28px; padding: 4px; }
  .editor-bar { padding-bottom: 5px; }
  .emote-view .round { width: 36px; height: 36px; }
  .race-stage { height: 100%; max-width: 50%; gap: 6px; }
  .circuit { width: min(100%, 65dvh); }
  .race-heading { font-size: 12px; }
  .accelerate { min-height: 40px; height: 40px; font-size: 12px; }
  .kindness { display: grid; grid-template-columns: 1.2fr 1fr; grid-template-rows: 1fr auto; gap: 12px 24px; }
  .kindness h2 { grid-column: 1; grid-row: 1; width: 100%; max-width: 100%; font-size: 29px; }
  .kindness-meter { grid-column: 1; grid-row: 2; width: 100%; max-width: 100%; }
  .kindness-spark { grid-column: 2; grid-row: 1 / 3; width: 100%; max-width: 100%; height: 100%; max-height: 100%; }
  .kindness-note { font-size: 14px; }
  .finale { display: grid; grid-template-columns: .9fr 1.4fr; align-items: center; }
  .finale h2 { width: 100%; max-width: 100%; font-size: 39px; }
  .heart-console { width: 100%; max-width: 100%; min-height: 0; height: 100%; gap: 12px; grid-template-columns: 1fr 1fr; grid-template-rows: auto 1fr; }
  .heart-console > p { grid-column: 1; grid-row: 1; font-size: 14px; text-align: left; }
  .heart-track { grid-column: 1; grid-row: 2; align-self: center; }
  .galaxy-heart { grid-column: 2; grid-row: 1 / 3; width: min(100%, 48dvh); }
  .heart-core-mark { font-size: 65px; }
}

@media (prefers-reduced-motion: reduce) {
  .scene, .scene.active { transform: none; }
  .scene *, .scene *:before, .scene *:after { animation: none !important; transition: none !important; }
  .photo-targets, .glasses-glint, .interactive-photo img { transform: none; }
}

/* The finale is a quiet closing card after the interactive scenes. */
.finale {
  display: flex !important;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 22px;
  text-align: center;
}
.finale h2 {
  width: min(100%, 780px);
  max-width: 780px;
  margin: 0;
  text-align: center;
}
.finale-note {
  max-width: 520px;
  margin: 0;
  color: var(--accent);
  font: 500 16px/1.6 var(--sans);
  opacity: .78;
  animation: finale-note-in 1.1s ease both;
}
@keyframes finale-note-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: .78; transform: translateY(0); }
}

.credits-screen { position: fixed; inset: 0; z-index: 40; display: grid; place-items: center; overflow: hidden; isolation: isolate; color: #f3edf4; background: #02030a; }
.credits-screen[hidden] { display: none; }
.credits-screen:before, .credits-screen:after, .credits-stars { content: ''; position: absolute; inset: -35%; pointer-events: none; background-image: radial-gradient(circle at 8% 17%,#fff 0 1px,transparent 1.8px),radial-gradient(circle at 74% 28%,#d4c6ff 0 1px,transparent 1.6px),radial-gradient(circle at 42% 72%,#fff 0 1px,transparent 1.8px),radial-gradient(circle at 88% 84%,#b7d9ff 0 1px,transparent 1.6px),radial-gradient(circle at 24% 55%,#e6bfd6 0 1px,transparent 1.7px); background-size: 290px 250px,390px 330px,260px 310px,420px 360px,340px 290px; opacity: .38; }
.credits-screen:before { animation: credits-stars-drift 24s linear infinite; }
.credits-screen:after { opacity: .2; transform: scale(1.35); animation: credits-stars-drift 38s linear reverse infinite; }
.credits-stars { opacity: .24; transform: scale(1.7); animation: credits-stars-twinkle 4s ease-in-out infinite alternate; }
.credits-content { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: center; gap: 22px; text-align: center; }
.credits-kicker { margin: 0; color: #a9a6bb; font: 11px/1 var(--sans); letter-spacing: .24em; text-transform: uppercase; opacity: 0; }
.credits-content h1 { margin: 0; color: #f6f0f7; font: 500 clamp(60px,10vw,150px)/.9 var(--serif); letter-spacing: -.045em; text-shadow: 0 0 42px #b8a7d655; opacity: 0; }
.credits-content h1 span { color: #c8a8d1; }
.credits-by { margin: 14vh 0 0; color: #8d8a9e; font: 13px/1 var(--sans); letter-spacing: .18em; opacity: 0; }
.credits-screen.is-visible .credits-kicker { animation: credits-rise .8s .35s ease-out forwards; }
.credits-screen.is-visible .credits-content h1 { animation: credits-title-in 1.4s .8s cubic-bezier(.2,.8,.2,1) forwards; }
.credits-screen.is-visible .credits-by { animation: credits-rise .9s 2s ease-out forwards; }
@keyframes credits-stars-drift { from { transform: translate3d(0,0,0) rotate(0); } to { transform: translate3d(4%,2%,0) rotate(3deg); } }
@keyframes credits-stars-twinkle { from { opacity: .16; } to { opacity: .42; } }
@keyframes credits-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: .82; transform: translateY(0); } }
@keyframes credits-title-in { from { opacity: 0; transform: translateY(28px) scale(.96); filter: blur(10px); } to { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); } }
