:root {
  --sky: #b9e4f5;
  --rain: #eefbff;
  --ink: #193446;
  --muted: #587b8c;
  --warm: #ff9cb4;
  --warm-bright: #ffdae4;
  --glass: rgba(241, 252, 255, 0.32);
}

* { box-sizing: border-box; }

html, body { min-height: 100%; }

body {
  margin: 0;
  overflow: hidden;
  background: var(--sky);
  color: var(--ink);
  font-family: "Microsoft YaHei", "PingFang SC", system-ui, sans-serif;
}

button { font: inherit; }

.scene {
  isolation: isolate;
  position: relative;
  min-height: 100svh;
  overflow: hidden;
  background:
    linear-gradient(165deg, #c7edf9 0%, #a9dcf0 48%, #8bc7df 100%);
}

.access-gate { position: absolute; z-index: 20; inset: 0; display: grid; place-items: center; padding: 1.5rem; background: rgba(185, 228, 245, .36); backdrop-filter: blur(9px); transition: opacity .7s ease, visibility .7s ease; }
.access-gate.unlocked { opacity: 0; visibility: hidden; pointer-events: none; }
.access-card { width: min(25rem, 100%); text-align: center; }
.access-card .eyebrow { color: #4a7588; }
.access-card h1 { margin: 1rem 0 2.1rem; font-size: clamp(2.7rem, 5vw, 4.2rem); line-height: 1.15; }
.access-label { display: block; margin-bottom: .55rem; color: var(--muted); font-size: .76rem; letter-spacing: .08em; }
.access-card input { width: 100%; min-height: 3.1rem; border: 1px solid rgba(255,255,255,.8); border-radius: 4px; padding: .7rem .85rem; background: rgba(246,253,255,.6); color: var(--ink); font: inherit; font-size: 1rem; outline: none; box-shadow: 0 .8rem 2.4rem rgba(47, 111, 135, .1); }
.access-card input:focus { border-color: rgba(70, 126, 148, .68); box-shadow: 0 0 0 3px rgba(255,255,255,.38); }
.access-submit { width: 100%; min-height: 3.1rem; margin-top: .75rem; border: 1px solid rgba(255,255,255,.82); border-radius: 4px; background: rgba(255,255,255,.64); color: #214354; cursor: pointer; font: inherit; transition: transform .2s ease, background .2s ease; }
.access-submit:hover, .access-submit:focus-visible { transform: translateY(-2px); background: rgba(255,255,255,.84); outline: none; }
.access-submit:disabled { cursor: wait; opacity: .65; transform: none; }
.access-message { min-height: 1.3rem; margin: .85rem 0 0; color: #4f7283; font-size: .8rem; }

#rain-canvas { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; }

.mist {
  position: absolute;
  z-index: -1;
  width: 56vw;
  height: 16rem;
  border-radius: 50%;
  background: rgba(244, 253, 255, 0.33);
  filter: blur(28px);
  pointer-events: none;
}
.mist-one { top: -7rem; left: -10rem; transform: rotate(-12deg); }
.mist-two { right: -16rem; bottom: -6rem; opacity: .58; }

.topbar {
  position: absolute;
  z-index: 4;
  top: 0;
  left: 0;
  display: flex;
  justify-content: space-between;
  width: 100%;
  padding: 1.6rem clamp(1.2rem, 4vw, 4rem);
}

.eyebrow, .date, .weather {
  margin: 0;
  font-size: .67rem;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
}
.weather { color: var(--muted); letter-spacing: .04em; }

.panel, .memory-stage, .heart-stage {
  position: absolute;
  inset: 0;
  display: grid;
  align-content: center;
  justify-items: center;
  padding: 6rem 1.25rem 7rem;
  text-align: center;
  transition: opacity .45s ease, transform .45s cubic-bezier(.2,.8,.2,1), visibility .45s;
}

.opening { z-index: 1; }
.date { color: var(--muted); }
h1, h2 { margin: .8rem 0 1rem; font-family: Georgia, "Songti SC", serif; font-weight: 500; letter-spacing: 0; }
h1 { font-size: clamp(2.4rem, 6vw, 5.4rem); line-height: 1.19; }
h2 { font-size: clamp(2rem, 4vw, 3.4rem); line-height: 1.2; }
.intro, .memory-copy > p:last-child, .heart-copy > p:last-child {
  max-width: 26rem;
  margin: 0;
  color: var(--muted);
  font-size: .93rem;
  line-height: 1.9;
}

.memory-stage, .heart-stage { visibility: hidden; opacity: 0; transform: translateY(2rem) scale(.985); pointer-events: none; }
.memory-stage { z-index: 2; grid-template-columns: minmax(13rem, 22rem) minmax(16rem, 28rem); grid-template-rows: auto auto; gap: 1.8rem 3rem; text-align: left; }
.memory-copy { align-self: center; }
.memory-copy .eyebrow, .heart-copy .eyebrow { color: #4a7588; }
.memory-copy h2 { white-space: nowrap; font-size: clamp(1.9rem, 3.2vw, 3rem); line-height: 1.24; }
.memory-copy > p:last-child { margin-top: 0; }

.photo-window {
  position: relative;
  width: min(32vw, 18rem);
  min-width: 14rem;
  aspect-ratio: 4 / 5;
  margin: 0;
  overflow: hidden;
  border: 1px solid rgba(255,255,255,.7);
  border-radius: 4px;
  background: rgba(220, 241, 248, .8);
  box-shadow: 0 1.6rem 4rem rgba(47, 111, 135, .24), 0 0 0 1px rgba(255,255,255,.24);
  transform: rotate(2deg);
  will-change: transform, opacity, filter;
}
.photo-window::after { content: ""; position: absolute; inset: 0; border: 9px solid rgba(255,255,255,.2); pointer-events: none; }
.photo-window img { width: 100%; height: 100%; object-fit: contain; display: block; animation: photoIn 1.05s cubic-bezier(.2,.8,.2,1); }
@keyframes photoIn { from { opacity: 0; transform: scale(1.09); filter: blur(8px); } to { opacity: 1; transform: scale(1); filter: blur(0); } }
.photo-window figcaption { position: absolute; right: .8rem; bottom: .65rem; z-index: 1; color: white; font-size: .66rem; letter-spacing: .14em; text-shadow: 0 1px 5px rgba(0,0,0,.25); }

.photo-strip { grid-column: 1 / -1; display: flex; justify-content: center; gap: .45rem; max-width: min(90vw, 39rem); }
.thumb { width: 3.2rem; height: 3.2rem; padding: 0; overflow: hidden; border: 1px solid rgba(255,255,255,.45); border-radius: 2px; background: transparent; cursor: pointer; opacity: .52; transition: transform .25s ease, opacity .25s ease; }
.thumb:hover, .thumb:focus-visible, .thumb.active { opacity: 1; transform: translateY(-.25rem); outline: none; }
.thumb:focus-visible { outline: 2px solid var(--warm); outline-offset: 3px; }
.thumb img { width: 100%; height: 100%; object-fit: cover; }

.vortex-portal {
  position: absolute;
  z-index: 1;
  top: 50%;
  left: 50%;
  width: min(25vw, 16rem);
  aspect-ratio: 1.55 / 1;
  border-radius: 50%;
  background: transparent;
  box-shadow: none;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(.15);
  will-change: transform, opacity, filter;
}
.vortex-portal::before, .vortex-portal::after { content: none; }

.heart-stage { z-index: 3; }
.heart-copy { z-index: 2; text-align: center; transform: translateY(11rem); }
.heart-copy > p:last-child { color: #5d586a; }
.heart-copy h2 { white-space: nowrap; font-size: clamp(2rem, 3.4vw, 3.2rem); line-height: 1.22; }
.heart-stage h2 { color: #532c42; text-shadow: 0 1px 0 rgba(255,255,255,.7); }
.heart-glow { position: absolute; top: 3%; left: 50%; width: min(56vmin, 31rem); aspect-ratio: 1; border-radius: 50%; background: rgba(255, 205, 220, .48); filter: blur(38px); transform: translateX(-50%); }
.particle-heart { position: absolute; top: 8%; left: 50%; width: min(46vmin, 24rem); aspect-ratio: 1; transform: translateX(-50%); }
.heart-particle { position: absolute; left: calc(50% + var(--to-x)); top: calc(50% + var(--to-y)); width: var(--size); height: var(--size); border-radius: 50%; background: var(--color); box-shadow: 0 0 calc(var(--size) * 3) var(--color); transform: translate(-50%, -50%); animation: particleArrive 1.15s cubic-bezier(.14,.82,.2,1) both, particlePulse 2.7s ease-in-out 1.2s infinite; }
@keyframes particleArrive { from { transform: translate(var(--from-x), var(--from-y)); opacity: 0; } to { transform: translate(-50%, -50%); opacity: 1; } }
@keyframes particlePulse { 50% { opacity: .5; filter: brightness(1.2); } }

.camera-window { position: absolute; z-index: 5; top: 4.2rem; right: clamp(1.2rem, 4vw, 4rem); width: 9.5rem; overflow: hidden; border: 1px solid rgba(255,255,255,.56); border-radius: 4px; background: rgba(221, 243, 249, .38); box-shadow: 0 .8rem 1.8rem rgba(52, 104, 122, .12); opacity: 0; transform: translateY(-.5rem); pointer-events: none; transition: opacity .35s ease, transform .35s ease; backdrop-filter: blur(12px); }
.camera-window.active { opacity: 1; transform: none; }
.camera-window video { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; transform: scaleX(-1); }
.camera-window p { margin: 0; padding: .38rem .5rem; color: #365c6d; font-size: .64rem; text-align: center; }
.controls { position: absolute; z-index: 5; bottom: 2.15rem; left: 50%; display: flex; align-items: center; gap: .5rem; transform: translateX(-50%); }
.control, .quiet-control { min-height: 2.55rem; border-radius: 4px; cursor: pointer; transition: transform .2s ease, background .2s ease, color .2s ease; }
.control { border: 1px solid rgba(255,255,255,.68); padding: 0 1rem; background: var(--glass); color: #214354; backdrop-filter: blur(12px); }
.camera-control.active { background: rgba(255, 255, 255, .7); color: #5b2d42; }
.control:hover, .control:focus-visible { transform: translateY(-2px); background: rgba(255,255,255,.62); outline: none; }
.quiet-control { border: 0; padding: 0 .5rem; background: transparent; color: rgba(27,65,81,.7); font-size: .76rem; }
.quiet-control:hover, .quiet-control:focus-visible { color: var(--ink); outline: none; }
.hint { position: absolute; z-index: 4; bottom: .75rem; left: 50%; margin: 0; transform: translateX(-50%); color: rgba(30,70,86,.62); font-size: .7rem; white-space: nowrap; }
kbd { padding: .05rem .25rem; border: 1px solid rgba(47,92,110,.28); border-radius: 2px; font-family: inherit; }

.show-vortex .opening, .show-memory .opening, .show-heart .opening, .show-heart .memory-stage { visibility: hidden; opacity: 0; transform: translateY(-1.5rem) scale(.98); }
.show-memory .memory-stage, .show-heart .heart-stage { visibility: visible; opacity: 1; transform: none; pointer-events: auto; }
.show-vortex .vortex-portal, .show-memory .vortex-portal { opacity: 0; transform: translate(-50%, -50%) scale(1); }
.show-memory .vortex-portal { opacity: 0; transform: translate(-50%, -50%) scale(1.1); }
.show-heart { background: linear-gradient(165deg, #d8f3f7 0%, #ffdce5 58%, #eec4d0 100%); }

@media (max-width: 700px) {
  .topbar { padding-top: 1.15rem; }
  .memory-stage { grid-template-columns: 1fr; grid-template-rows: auto auto auto; gap: 1rem; padding-top: 4.4rem; text-align: center; }
  .memory-copy { align-self: end; }
  .memory-copy h2 { margin: .35rem 0; white-space: normal; font-size: clamp(1.65rem, 7vw, 2.3rem); }
  .memory-copy > p:last-child { margin-inline: auto; }
  .photo-window { width: min(64vw, 18rem); min-width: 0; transform: rotate(1deg); }
  .vortex-portal { left: 50%; top: 45%; width: min(72vw, 19rem); }
  .photo-strip { gap: .35rem; }
  .thumb { width: 2.65rem; height: 2.65rem; }
  .heart-copy { transform: translateY(9rem); padding-inline: 1.5rem; }
  .heart-copy h2 { white-space: normal; font-size: clamp(1.75rem, 8vw, 2.65rem); }
  .controls { bottom: 2.15rem; width: calc(100% - 2rem); justify-content: center; }
  .camera-window { top: 3.65rem; width: 7.5rem; }
  .control { padding-inline: .65rem; font-size: .78rem; }
  .hint { font-size: .62rem; }
}

@media (prefers-reduced-motion: reduce) { *, *::before, *::after { scroll-behavior: auto !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; } }
