/* ═══════════════════════════════════════════════════════════════════════════
   THE OBSERVATORY — a birthday card
   Aesthetic: antique celestial atlas, brass ink on deep sky, paper scraps.
   You shouldn't need to edit this file; colours live in assets/js/config.js
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── tokens ──────────────────────────────────────────────────────────────── */
:root {
  --void:      #070b1a;
  --deep:      #0d1330;
  --nebula-a:  #241a4a;
  --nebula-b:  #3d1f45;
  --brass:     #e6c485;
  --rose:      #e8a0ab;
  --cyan:      #9fd4ef;
  --cream:     #f5ecd8;

  --ink:       #f0e6d2;
  --ink-soft:  rgba(240, 230, 210, 0.62);
  --ink-faint: rgba(240, 230, 210, 0.34);

  --brass-glow: color-mix(in srgb, var(--brass) 40%, transparent);
  --hairline:   color-mix(in srgb, var(--brass) 26%, transparent);

  --serif:  'Cormorant Garamond', 'Iowan Old Style', Georgia, serif;
  --hand:   'Caveat', 'Segoe Script', cursive;
  --mono:   'Cutive Mono', 'Courier New', monospace;

  --measure: 62ch;
  --gutter:  clamp(1.25rem, 5vw, 3.5rem);
  --ease:    cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  min-height: 100svh;
  background: var(--void);
  color: var(--ink);
  font-family: var(--serif);
  font-size: clamp(1.02rem, 0.95rem + 0.35vw, 1.22rem);
  font-weight: 300;
  line-height: 1.72;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { background: var(--brass); color: var(--void); }

:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 4px;
  border-radius: 2px;
}

/* ── atmosphere ──────────────────────────────────────────────────────────── */
#sky, .nebula, .vignette, .grain {
  position: fixed;
  inset: 0;
  pointer-events: none;
}
#sky    { z-index: 0; }
.nebula { z-index: 1; }
.vignette { z-index: 2; }
.grain  { z-index: 3; }

.nebula {
  background:
    radial-gradient(58% 44% at 18% 12%, color-mix(in srgb, var(--nebula-a) 62%, transparent) 0%, transparent 64%),
    radial-gradient(50% 40% at 84% 78%, color-mix(in srgb, var(--nebula-b) 50%, transparent) 0%, transparent 66%),
    radial-gradient(70% 50% at 50% 108%, color-mix(in srgb, var(--rose) 12%, transparent) 0%, transparent 70%);
  filter: blur(18px);
  opacity: 0.85;
  animation: drift 42s var(--ease-in-out) infinite alternate;
}
@keyframes drift {
  from { transform: translate3d(-1.5%, -1%, 0) scale(1.04); }
  to   { transform: translate3d(1.5%, 1.5%, 0) scale(1.11); }
}

.vignette {
  background: radial-gradient(120% 88% at 50% 42%, transparent 42%, rgba(3, 5, 14, 0.72) 100%);
}

.grain {
  opacity: 0.16;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
}

#burst {
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
}

/* ── stage & scenes ──────────────────────────────────────────────────────── */
#stage { position: relative; z-index: 10; }

.scene {
  display: none;
  min-height: 100svh;
  padding: clamp(3rem, 9vh, 6rem) var(--gutter);
}
.scene.is-active { display: block; }
.scene.is-centred,
#scene-envelope.is-active,
#scene-finale.is-active {
  display: grid;
  place-items: center;
}
.scene.is-entering { animation: sceneIn 1.15s var(--ease) both; }
@keyframes sceneIn {
  from { opacity: 0; transform: translateY(26px) scale(0.985); filter: blur(6px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}

/* ── shared type ─────────────────────────────────────────────────────────── */
.section-title {
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(1.9rem, 1.4rem + 2.2vw, 3.1rem);
  letter-spacing: 0.01em;
  margin: 0 0 0.35rem;
  color: var(--cream);
}
.section-title span { position: relative; }

.section-note {
  font-family: var(--hand);
  font-size: clamp(1.25rem, 1.05rem + 0.7vw, 1.65rem);
  color: var(--brass);
  opacity: 0.86;
  margin: 0 0 2.75rem;
  line-height: 1.4;
}

.kicker,
.hero-kicker,
.env-kicker,
.counter-label {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--brass);
  opacity: 0.72;
  margin: 0;
}

.hand { font-family: var(--hand); color: var(--brass); font-size: 1.24em; line-height: 1; }

.rule {
  display: flex;
  align-items: center;
  gap: 1rem;
  color: var(--brass);
  margin: 2.4rem auto 0;
  max-width: 22rem;
  opacity: 0.7;
}
.rule span {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--hairline), transparent);
}

/* ── buttons ─────────────────────────────────────────────────────────────── */
.btn {
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  padding: 0.95em 2.1em;
  border-radius: 2px;
  cursor: pointer;
  transition: all 0.45s var(--ease);
  background: transparent;
  position: relative;
}
.btn-primary {
  border: 1px solid var(--brass);
  color: var(--brass);
}
.btn-primary:not(:disabled):hover {
  background: var(--brass);
  color: var(--void);
  box-shadow: 0 0 34px -6px var(--brass-glow);
}
.btn-primary:disabled {
  border-color: color-mix(in srgb, var(--ink) 16%, transparent);
  color: var(--ink-faint);
  cursor: not-allowed;
}
.btn-primary.is-live {
  animation: pulseBrass 2.6s ease-in-out infinite;
}
@keyframes pulseBrass {
  0%, 100% { box-shadow: 0 0 0 0 var(--brass-glow); }
  50%      { box-shadow: 0 0 30px 2px var(--brass-glow); }
}
.btn-ghost {
  border: none;
  color: var(--ink-faint);
  text-decoration: underline;
  text-underline-offset: 5px;
  text-decoration-thickness: 1px;
  padding: 0.8em 0.4em;
}
.btn-ghost:hover { color: var(--ink-soft); }

/* ── music toggle ────────────────────────────────────────────────────────── */
.music-toggle {
  position: fixed;
  z-index: 50;
  top: max(1.1rem, env(safe-area-inset-top));
  right: max(1.1rem, env(safe-area-inset-right));
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.95rem;
  background: color-mix(in srgb, var(--void) 72%, transparent);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  color: var(--brass);
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  cursor: pointer;
  backdrop-filter: blur(10px);
  transition: opacity 0.4s var(--ease), border-color 0.4s var(--ease);
  opacity: 0.5;
}
.music-toggle:hover { opacity: 1; border-color: var(--brass); }
.music-ico {
  width: 13px; height: 13px;
  display: flex; align-items: flex-end; gap: 2px;
}
.music-ico::before, .music-ico::after {
  content: ''; flex: 1; background: currentColor; border-radius: 1px; height: 40%;
}
.music-toggle[aria-pressed="true"] { opacity: 1; }
.music-toggle[aria-pressed="true"] .music-ico::before { animation: eq 0.9s ease-in-out infinite alternate; }
.music-toggle[aria-pressed="true"] .music-ico::after  { animation: eq 0.9s ease-in-out 0.35s infinite alternate; }
@keyframes eq { from { height: 25%; } to { height: 100%; } }

/* ═══ SCENE 1 · ENVELOPE ═════════════════════════════════════════════════ */
.env-wrap { text-align: center; display: grid; gap: 2.6rem; justify-items: center; }
.env-kicker { animation: fadeUp 1.4s var(--ease) 0.2s both; }

.envelope {
  --w: min(clamp(20rem, 68vw, 30rem), 88vw);
  --h: calc(var(--w) * 0.64);
  position: relative;
  width: var(--w);
  height: var(--h);
  cursor: pointer;
  perspective: 1400px;
  animation: fadeUp 1.5s var(--ease) 0.45s both, hover 7s ease-in-out 2s infinite;
  transition: transform 0.6s var(--ease);
}
@keyframes hover {
  0%, 100% { transform: translateY(0) rotate(-0.4deg); }
  50%      { transform: translateY(-11px) rotate(0.4deg); }
}
.envelope:hover { filter: brightness(1.06); }
.envelope.is-open { animation: none; cursor: default; }

.env-shadow {
  position: absolute;
  inset: auto 8% -9% 8%;
  height: 22px;
  background: radial-gradient(ellipse at center, rgba(0,0,0,0.62), transparent 70%);
  filter: blur(9px);
}

.env-body, .env-flap, .env-letter {
  position: absolute;
  border-radius: 3px;
}

/* the paper body */
.env-body {
  inset: 0;
  background:
    linear-gradient(163deg, #1a2145 0%, #131a38 46%, #0f1530 100%);
  border: 1px solid var(--hairline);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.06),
    0 34px 70px -24px rgba(0,0,0,0.9);
  z-index: 3;
}
/* the two lower folds, drawn as thin brass creases */
.env-body::before, .env-body::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom right, transparent calc(50% - 0.5px), var(--hairline) 50%, transparent calc(50% + 0.5px));
}
.env-body::after { transform: scaleX(-1); }

/* the letter that rises out */
.env-letter {
  inset: 8% 7% auto 7%;
  height: 86%;
  background: linear-gradient(170deg, #f7efdd, #e6d9bd);
  z-index: 2;
  padding: 14% 12% 0;
  display: grid;
  align-content: start;
  gap: 9%;
  box-shadow: 0 -8px 26px -8px rgba(0,0,0,0.6);
  transition: transform 1.1s var(--ease) 0.42s;
}
.env-letter-line {
  height: 2px;
  background: color-mix(in srgb, #4a3a24 34%, transparent);
  border-radius: 2px;
}
.env-letter-line.short { width: 55%; }

/* the flap */
.env-flap {
  inset: 0 0 auto 0;
  height: 62%;
  background: linear-gradient(178deg, #202a55 0%, #18204a 100%);
  border: 1px solid var(--hairline);
  border-bottom: none;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  transform-origin: top center;
  transform: rotateX(0deg);
  transition: transform 0.85s var(--ease-in-out), z-index 0s 0.42s;
  z-index: 5;
  backface-visibility: hidden;
}

.env-seal {
  position: absolute;
  top: 52%;
  left: 50%;
  translate: -50% -50%;
  width: clamp(3.1rem, 11vw, 4.1rem);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, #d4707f, #a83e51 58%, #7d2739 100%);
  display: grid;
  place-items: center;
  font-family: var(--serif);
  font-size: clamp(1.5rem, 5vw, 2rem);
  color: rgba(255, 235, 235, 0.9);
  box-shadow: 0 6px 18px -4px rgba(0,0,0,0.75), inset 0 -3px 8px rgba(0,0,0,0.35);
  z-index: 6;
  transition: opacity 0.35s var(--ease), transform 0.6s var(--ease);
}
.env-seal::after {
  content: '';
  position: absolute;
  inset: 5px;
  border-radius: 50%;
  border: 1px dashed rgba(255,225,225,0.34);
}

.env-addressed {
  position: absolute;
  left: 8%;
  bottom: 11%;
  margin: 0;
  font-family: var(--hand);
  font-size: clamp(1.35rem, 4.5vw, 1.9rem);
  color: var(--cream);
  opacity: 0.82;
  z-index: 4;
  transform: rotate(-2deg);
  text-shadow: 0 1px 8px rgba(0,0,0,0.5);
}

/* open state */
.envelope.is-open .env-flap  { transform: rotateX(180deg); z-index: 1; }
.envelope.is-open .env-seal  { opacity: 0; transform: translate(-50%, -50%) scale(1.5) rotate(14deg); }
.envelope.is-open .env-letter { transform: translateY(-46%) scale(1.03); }
.envelope.is-open .env-addressed { opacity: 0; transition: opacity 0.4s; }

.env-prompt {
  font-family: var(--hand);
  font-size: clamp(1.3rem, 1.1rem + 0.8vw, 1.7rem);
  color: var(--brass);
  margin: 0;
  opacity: 0.75;
  animation: fadeUp 1.4s var(--ease) 1s both, breathe 3.4s ease-in-out 2.4s infinite;
}
@keyframes breathe { 0%, 100% { opacity: 0.45; } 50% { opacity: 0.95; } }
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}

/* ═══ SCENE 2 · THE CARD ═════════════════════════════════════════════════ */
#scene-card { max-width: 74rem; margin-inline: auto; }

.reveal {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 1.1s var(--ease), transform 1.1s var(--ease);
}
.reveal.is-in { opacity: 1; transform: none; }

.hero { text-align: center; margin-bottom: clamp(4rem, 12vh, 7rem); }
.hero-kicker { margin-bottom: 1.1rem; }

.hero-name {
  font-family: var(--serif);
  font-weight: 300;
  font-style: italic;
  font-size: clamp(3.6rem, 1.5rem + 13vw, 9.5rem);
  line-height: 0.94;
  margin: 0;
  color: var(--cream);
  letter-spacing: -0.015em;
  text-shadow:
    0 0 60px color-mix(in srgb, var(--cyan) 22%, transparent),
    0 0 140px color-mix(in srgb, var(--rose) 16%, transparent);
}
.hero-sub {
  font-family: var(--hand);
  font-size: clamp(1.35rem, 1.1rem + 1.1vw, 2rem);
  color: var(--brass);
  max-width: 34ch;
  margin: 1.4rem auto 0;
  line-height: 1.35;
  opacity: 0.9;
}

/* the letter */
.letter {
  max-width: var(--measure);
  margin: 0 auto clamp(4.5rem, 13vh, 8rem);
}
.letter p {
  margin: 0 0 1.6em;
  color: var(--ink-soft);
}
.letter p:first-child::first-letter {
  font-size: 3.4em;
  line-height: 0.82;
  float: left;
  padding: 0.1em 0.14em 0 0;
  color: var(--brass);
  font-style: italic;
}

/* counter */
.counter { text-align: center; margin-bottom: clamp(4rem, 11vh, 7rem); }
.counter-grid {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: clamp(1.1rem, 4vw, 2.6rem);
  margin-top: 1.6rem;
}
.counter-cell { min-width: 4.2rem; }
.counter-num {
  display: block;
  font-family: var(--serif);
  font-size: clamp(2rem, 1.4rem + 2.6vw, 3.4rem);
  color: var(--cream);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.counter-unit {
  display: block;
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--brass);
  opacity: 0.6;
  margin-top: 0.55rem;
}

/* ── memory flip cards ───────────────────────────────────────────────────── */
.reasons { margin-bottom: clamp(5rem, 15vh, 9rem); }

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(15.5rem, 100%), 1fr));
  gap: clamp(1.1rem, 3vw, 2rem);
}

.flip {
  perspective: 1300px;
  aspect-ratio: 3 / 4;
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: inherit;
  text-align: left;
}
.flip-inner {
  position: relative;
  width: 100%;
  height: 100%;
  transition: transform 0.95s var(--ease);
  transform-style: preserve-3d;
}
.flip.is-flipped .flip-inner { transform: rotateY(180deg); }

.flip-face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  border-radius: 3px;
  overflow: hidden;
  border: 1px solid var(--hairline);
  box-shadow: 0 22px 48px -22px rgba(0,0,0,0.9);
}

/* front — the photo */
.flip-front {
  background: linear-gradient(165deg, #151c3c, #0e1430);
  display: grid;
  grid-template-rows: 1fr auto;
}
.flip-photo {
  position: relative;
  overflow: hidden;
  background: radial-gradient(circle at 50% 45%, #1c2450, #0b1128);
}
.flip-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  filter: saturate(0.86) contrast(1.04) brightness(0.92);
  transition: transform 1.2s var(--ease), filter 0.6s var(--ease);
}
.flip:hover .flip-photo img { transform: scale(1.05); filter: saturate(1) brightness(1); }
.flip-photo svg { width: 100%; height: 100%; display: block; }

/* warm duotone wash so photos sit in the palette */
.flip-photo::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 45%, rgba(7,11,26,0.86) 100%),
              radial-gradient(circle at 50% 0%, color-mix(in srgb, var(--rose) 14%, transparent), transparent 70%);
  pointer-events: none;
}
.flip-index {
  position: absolute;
  top: 0.85rem;
  left: 0.9rem;
  z-index: 2;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.2em;
  color: var(--brass);
  opacity: 0.85;
  text-shadow: 0 1px 6px rgba(0,0,0,0.8);
}
.flip-caption {
  padding: 0.95rem 1.05rem 1.1rem;
  font-family: var(--hand);
  font-size: 1.28rem;
  color: var(--cream);
  line-height: 1.2;
  border-top: 1px solid var(--hairline);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
}
.flip-turn {
  font-family: var(--mono);
  font-size: 0.55rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--brass);
  opacity: 0.55;
  white-space: nowrap;
}

/* back — the reason, on paper */
.flip-back {
  transform: rotateY(180deg);
  background:
    linear-gradient(168deg, #f7efdd 0%, #ece0c4 100%);
  color: #2c2416;
  padding: clamp(1.2rem, 3.5vw, 1.7rem);
  display: grid;
  align-content: center;
  gap: 0.9rem;
}
.flip-back::before {
  content: '';
  position: absolute;
  inset: 0;
  opacity: 0.35;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23p)' opacity='0.35'/%3E%3C/svg%3E");
  pointer-events: none;
}
.flip-reason {
  font-family: var(--hand);
  font-size: clamp(1.22rem, 1.05rem + 0.5vw, 1.5rem);
  line-height: 1.34;
  margin: 0;
  position: relative;
  z-index: 1;
}
/* the hidden puzzle digit */
.flip-digit {
  position: absolute;
  right: 0.9rem;
  bottom: 0.75rem;
  font-family: var(--serif);
  font-size: 1.9rem;
  font-style: italic;
  color: #b08333;
  opacity: 0.92;
  z-index: 1;
  text-shadow: 0 1px 0 rgba(255,255,255,0.5);
}
.flip-digit::after {
  content: '';
  position: absolute;
  inset: -6px -8px;
  border: 1px solid rgba(176, 131, 51, 0.4);
  border-radius: 50%;
}

/* ── the vault ───────────────────────────────────────────────────────────── */
.vault { margin-bottom: clamp(3rem, 8vh, 5rem); }

.locks {
  display: grid;
  gap: clamp(1rem, 2.5vw, 1.5rem);
  margin-bottom: 3rem;
}

.lock {
  border: 1px solid var(--hairline);
  border-radius: 3px;
  background: color-mix(in srgb, var(--deep) 55%, transparent);
  backdrop-filter: blur(6px);
  overflow: hidden;
  transition: border-color 0.7s var(--ease), background 0.7s var(--ease);
}
.lock.is-solved {
  border-color: color-mix(in srgb, var(--brass) 55%, transparent);
  background: color-mix(in srgb, var(--brass) 7%, transparent);
}
.lock.is-wrong { animation: shake 0.5s var(--ease-in-out); }
@keyframes shake {
  10%, 90% { transform: translateX(-3px); }
  20%, 80% { transform: translateX(6px); }
  30%, 50%, 70% { transform: translateX(-9px); }
  40%, 60% { transform: translateX(9px); }
}

.lock-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  padding: clamp(1.1rem, 3vw, 1.5rem) clamp(1.2rem, 3.5vw, 1.9rem);
  background: none;
  border: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  text-align: left;
}
.lock-title {
  font-family: var(--serif);
  font-size: clamp(1.25rem, 1.1rem + 0.7vw, 1.7rem);
  color: var(--cream);
  margin: 0;
  font-weight: 400;
}
.lock-status {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink-faint);
  display: flex;
  align-items: center;
  gap: 0.6rem;
  white-space: nowrap;
}
.lock.is-solved .lock-status { color: var(--brass); }
.lock-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  border: 1px solid currentColor;
}
.lock.is-solved .lock-dot { background: var(--brass); box-shadow: 0 0 12px var(--brass); }

.lock-body {
  padding: 0 clamp(1.2rem, 3.5vw, 1.9rem) clamp(1.4rem, 3.5vw, 2rem);
  display: grid;
  gap: 1.3rem;
}
.lock[hidden] { display: none; }
.lock-body[hidden] { display: none; }

.lock-prompt {
  font-family: var(--hand);
  font-size: clamp(1.2rem, 1.05rem + 0.5vw, 1.45rem);
  color: var(--brass);
  margin: 0;
  opacity: 0.85;
  line-height: 1.35;
}

.lock-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.9rem;
}

.lock-hint {
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  background: none;
  border: none;
  color: var(--ink-faint);
  cursor: pointer;
  padding: 0.5em 0;
  text-decoration: underline;
  text-underline-offset: 4px;
}
.lock-hint:hover { color: var(--brass); }

.hint-text {
  font-family: var(--hand);
  font-size: 1.2rem;
  color: var(--rose);
  margin: 0;
  opacity: 0;
  max-height: 0;
  transition: opacity 0.5s var(--ease), max-height 0.5s var(--ease);
  overflow: hidden;
}
.hint-text.is-shown { opacity: 0.9; max-height: 8rem; }

/* text inputs */
.lock-input {
  font-family: var(--mono);
  font-size: 1rem;
  letter-spacing: 0.35em;
  text-transform: uppercase;
  background: rgba(0,0,0,0.3);
  border: 1px solid var(--hairline);
  border-radius: 2px;
  color: var(--cream);
  padding: 0.85em 1em;
  width: min(18rem, 100%);
  transition: border-color 0.4s var(--ease), box-shadow 0.4s var(--ease);
}
.lock-input:focus {
  outline: none;
  border-color: var(--brass);
  box-shadow: 0 0 22px -6px var(--brass-glow);
}
.lock-input::placeholder { color: var(--ink-faint); letter-spacing: 0.2em; }

/* cipher glyphs */
.cipher-strip {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(0.5rem, 2vw, 1rem);
  font-size: clamp(1.7rem, 1.2rem + 2.4vw, 2.8rem);
  color: var(--brass);
  line-height: 1;
}
.cipher-strip span {
  animation: glyphIn 0.6s var(--ease) both;
  text-shadow: 0 0 20px var(--brass-glow);
}
@keyframes glyphIn { from { opacity: 0; transform: translateY(-8px) rotate(-20deg); } to { opacity: 1; transform: none; } }

.legend {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(3.6rem, 1fr));
  gap: 0.7rem;
  padding: 1.1rem;
  border: 1px dashed var(--hairline);
  border-radius: 3px;
  background: rgba(0,0,0,0.22);
}
.legend-item {
  display: grid;
  justify-items: center;
  gap: 0.3rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--ink-soft);
}
.legend-glyph { font-size: 1.25rem; color: var(--brass); font-family: var(--serif); }

/* the dial */
.dial-row { display: flex; gap: clamp(0.5rem, 2.5vw, 0.9rem); }
.dial-cell {
  width: clamp(3rem, 13vw, 4.2rem);
  aspect-ratio: 3 / 4;
  background: linear-gradient(170deg, rgba(255,255,255,0.05), rgba(0,0,0,0.4));
  border: 1px solid var(--hairline);
  border-radius: 3px;
  color: var(--cream);
  font-family: var(--serif);
  font-size: clamp(1.6rem, 1.1rem + 2vw, 2.3rem);
  text-align: center;
  transition: border-color 0.35s var(--ease), box-shadow 0.35s var(--ease);
  -moz-appearance: textfield;
}
.dial-cell::-webkit-outer-spin-button,
.dial-cell::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.dial-cell:focus {
  outline: none;
  border-color: var(--brass);
  box-shadow: 0 0 24px -6px var(--brass-glow);
}

/* the constellation */
.constel-wrap {
  position: relative;
  border: 1px dashed var(--hairline);
  border-radius: 3px;
  background:
    radial-gradient(circle at 30% 20%, rgba(159,212,239,0.07), transparent 60%),
    rgba(0,0,0,0.28);
  aspect-ratio: 16 / 10;
  overflow: hidden;
  touch-action: manipulation;
}
.constel-wrap svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.constel-line {
  stroke: var(--brass);
  stroke-width: 1;
  stroke-linecap: round;
  opacity: 0.75;
  filter: drop-shadow(0 0 4px var(--brass-glow));
}
.cstar {
  position: absolute;
  translate: -50% -50%;
  width: clamp(2rem, 7vw, 2.7rem);
  aspect-ratio: 1;
  border-radius: 50%;
  border: 1px solid transparent;
  background: none;
  color: var(--ink-soft);
  font-family: var(--serif);
  font-size: clamp(0.85rem, 0.7rem + 0.6vw, 1.1rem);
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: all 0.4s var(--ease);
}
.cstar::before {
  content: '';
  position: absolute;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: var(--cyan);
  box-shadow: 0 0 10px 2px color-mix(in srgb, var(--cyan) 55%, transparent);
  translate: 0 -1.05em;
  transition: all 0.4s var(--ease);
}
.cstar:hover { color: var(--cream); border-color: var(--hairline); }
.cstar.is-picked {
  color: var(--void);
  background: var(--brass);
  border-color: var(--brass);
  box-shadow: 0 0 26px -2px var(--brass-glow);
}
.cstar.is-picked::before { background: var(--brass); box-shadow: 0 0 14px 3px var(--brass-glow); }

.constel-readout {
  font-family: var(--mono);
  font-size: 0.95rem;
  letter-spacing: 0.5em;
  color: var(--brass);
  min-height: 1.4em;
  text-transform: uppercase;
}

/* vault door */
.vault-door { text-align: center; display: grid; gap: 1rem; justify-items: center; }
.vault-progress {
  font-family: var(--mono);
  font-size: 0.65rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 0.5rem;
}
.vault-progress b { color: var(--brass); font-weight: normal; }

/* ═══ SCENE 3 · FINALE ═══════════════════════════════════════════════════ */
.finale {
  max-width: var(--measure);
  text-align: center;
  animation: sceneIn 1.4s var(--ease) both;
}
.finale-mark {
  font-size: 2rem;
  color: var(--brass);
  animation: spin 22s linear infinite;
  margin-bottom: 1.6rem;
}
@keyframes spin { to { transform: rotate(360deg); } }

.finale-title {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(2.1rem, 1.5rem + 3.2vw, 4rem);
  line-height: 1.06;
  margin: 0 0 2.4rem;
  color: var(--cream);
  text-shadow: 0 0 70px color-mix(in srgb, var(--rose) 26%, transparent);
}
.finale-body { text-align: left; }
.finale-body p { margin: 0 0 1.6em; color: var(--ink-soft); }

.finale-signoff {
  font-family: var(--hand);
  font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2.2rem);
  color: var(--brass);
  white-space: pre-line;
  line-height: 1.25;
  margin: 3rem 0 2.5rem;
  transform: rotate(-1.5deg);
}

/* ── motion & print courtesies ───────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { opacity: 1; transform: none; }
}

@media (max-width: 30rem) {
  .legend { grid-template-columns: repeat(auto-fit, minmax(3rem, 1fr)); }
  .letter p:first-child::first-letter { font-size: 2.8em; }
}
