/* Fonts are subset to the characters this page uses — run tools/build-fonts.py after editing text. */
@font-face { font-family: 'NSC'; src: url(../assets/fonts/nsc-700.woff2) format('woff2'); font-weight: 700; font-display: block; }
@font-face { font-family: 'NSC'; src: url(../assets/fonts/nsc-900.woff2) format('woff2'); font-weight: 900; font-display: block; }
@font-face { font-family: 'Bodoni'; src: url(../assets/fonts/bodoni.woff2) format('woff2'); font-weight: 400 900; font-display: block; }
@font-face { font-family: 'Plex'; src: url(../assets/fonts/plex-400.woff2) format('woff2'); font-weight: 400; font-display: block; }
@font-face { font-family: 'Plex'; src: url(../assets/fonts/plex-500.woff2) format('woff2'); font-weight: 500; font-display: block; }

:root {
  --paper: #ded4c7;
  --ink: #221913;
  --ink-soft: rgba(34, 25, 19, .62);
  --grid: rgba(70, 52, 34, .055);
  --ease: cubic-bezier(.2, .7, .1, 1);
  --u: min(1vw, .46vh, 5px);  /* layout unit: ~3.9px on a 390x844 phone, smaller on short screens */
  --pad: clamp(22px, 7vw, 34px);
  --top: env(safe-area-inset-top, 0px);
  --bottom: env(safe-area-inset-bottom, 0px);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { height: 100%; overflow: hidden; overscroll-behavior: none; -webkit-text-size-adjust: 100%; }
body {
  background: var(--paper);
  color: var(--ink);
  font-family: 'NSC', 'Songti SC', 'STSong', serif;
  font-weight: 700;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}
.mono { font-family: 'Plex', 'NSC', ui-monospace, Menlo, monospace; font-weight: 500; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
a { color: inherit; }

/* ---------- paper: grid + vignette + grain, fixed under everything ---------- */
.paper {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(130% 95% at 50% 32%, transparent 52%, rgba(92, 68, 44, .17) 100%),
    linear-gradient(var(--grid) 1px, transparent 1px) 0 0 / 10px 10px,
    linear-gradient(90deg, var(--grid) 1px, transparent 1px) 0 0 / 10px 10px,
    var(--paper);
}
.paper::after {
  content: ''; position: absolute; inset: 0; opacity: .5;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .22 0 0 0 0 .16 0 0 0 0 .1 .55 0 0 0 -.2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- gate: loading, then "tap to open" (also unlocks audio) ---------- */
.gate {
  position: fixed; inset: 0; z-index: 20;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; outline: none;
  transition: opacity 1s var(--ease), visibility 0s 1s;
}
.kicker { font-size: 10px; letter-spacing: .5em; margin-right: -.5em; }
.gate-staff, .gate-staff i {
  display: block; height: 21px;
  background:
    linear-gradient(currentColor 0 0) 0 0 / 100% 1px no-repeat,
    linear-gradient(currentColor 0 0) 0 5px / 100% 1px no-repeat,
    linear-gradient(currentColor 0 0) 0 10px / 100% 1px no-repeat,
    linear-gradient(currentColor 0 0) 0 15px / 100% 1px no-repeat,
    linear-gradient(currentColor 0 0) 0 20px / 100% 1px no-repeat;
}
.gate-staff { position: relative; width: 132px; margin: 24px 0 22px; color: rgba(34, 25, 19, .18); }
.gate-staff i { position: absolute; inset: 0; color: var(--ink); transform: scaleX(0); transform-origin: 0 50%; transition: transform .5s var(--ease); }
.gate-names { font-weight: 900; font-size: 30px; letter-spacing: .1em; margin-right: -.1em; }
.gate-names span { margin: 0 .35em; }
.gate-date { font-size: 11px; letter-spacing: .32em; margin: 12px -.32em 0 0; }
.gate-hint { margin-top: 10vh; font-size: 11px; letter-spacing: .24em; min-height: 1.5em; }
.gate-hint b { font-weight: 500; display: inline-block; min-width: 2ch; text-align: right; }
.gate-hint .tap { display: none; }
.ready .gate-hint .loading { display: none; }
.ready .gate-hint .tap { display: inline; animation: breathe 2.6s ease-in-out infinite; }
.opened .gate { opacity: 0; visibility: hidden; pointer-events: none; }
@keyframes breathe { 50% { opacity: .35; } }

/* ---------- music toggle ---------- */
.music {
  position: fixed; z-index: 15; top: calc(var(--top) + 12px); right: 12px;
  width: 40px; height: 40px; display: grid; place-items: center;
  opacity: 0; visibility: hidden; transition: opacity .8s var(--ease) .6s;
}
.opened .music { opacity: 1; visibility: visible; }
.music[hidden] { display: none; }
.music svg { width: 24px; height: 24px; fill: none; stroke: var(--ink); stroke-width: 1.1; }
.music .dot { fill: var(--ink); stroke: none; }
.music .slash { stroke-width: 1.3; }
.music.playing svg { animation: spin 7s linear infinite; }
.music.playing .slash { display: none; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- pages: full-screen, snap ---------- */
.pages {
  position: relative; z-index: 1;
  height: 100vh; height: 100dvh;
  overflow-y: auto; overscroll-behavior: contain;
  scroll-snap-type: y mandatory; -webkit-overflow-scrolling: touch;
  visibility: hidden; opacity: 0;
}
.opened .pages { visibility: visible; opacity: 1; transition: opacity 1.2s var(--ease) .15s; }
.page {
  position: relative; overflow: hidden;
  height: 100vh; height: 100dvh;
  max-width: 520px; margin: 0 auto;
  padding: calc(var(--top) + var(--u) * 17) var(--pad) 0;
  scroll-snap-align: start; scroll-snap-stop: always;
}

/* ---------- entrance animations: a section gets .in when it's on screen ---------- */
[data-anim] {
  opacity: 0;
  transition: opacity 1s var(--ease) var(--d, 0s), transform 1.3s var(--ease) var(--d, 0s), filter 1.3s var(--ease) var(--d, 0s);
}
[data-anim='up'] { transform: translateY(12px); }
[data-anim='streak'] { transform: translateX(-14%) scaleX(1.7); transform-origin: 0 50%; filter: blur(5px); }
.in [data-anim] { opacity: 1; transform: none; filter: none; }

.staff, .photo-staff i, .deco i { transform: scaleX(0); transform-origin: 0 50%; transition: transform 1.4s var(--ease) var(--d, 0s); }
.bar { transform: scaleY(0); transform-origin: 50% 0; transition: transform .9s var(--ease) var(--d, 0s); }
.in .staff, .in .photo-staff i, .in .deco i, .in .bar { transform: none; }

/* Safety net (see index.html): the script didn't run, so show everything as a still page. */
.no-js .gate, .no-js .music { display: none; }
.no-js .pages { visibility: visible; opacity: 1; }
.no-js [data-anim], .no-js .staff, .no-js .bar, .no-js .photo-staff i, .no-js .deco i { opacity: 1; transform: none; filter: none; transition: opacity .6s; }

@media (prefers-reduced-motion: reduce) {
  [data-anim], .staff, .bar, .photo-staff i, .deco i { transform: none !important; filter: none !important; transition-duration: .4s !important; }
}

/* ---------- cover ---------- */
.cover { display: flex; flex-direction: column; }
.title { position: relative; z-index: 2; }
.row { display: flex; align-items: center; font-weight: 900; font-size: calc(var(--u) * 15); line-height: 1.08; }
.row.half { width: 60%; }
.staff { flex: 1; align-self: center; margin: 0 .12em; color: var(--ink-soft); }
.staff.five {
  height: .5em;
  background:
    linear-gradient(currentColor 0 0) 0 0 / 100% 1px no-repeat,
    linear-gradient(currentColor 0 0) 0 25% / 100% 1px no-repeat,
    linear-gradient(currentColor 0 0) 0 50% / 100% 1px no-repeat,
    linear-gradient(currentColor 0 0) 0 75% / 100% 1px no-repeat,
    linear-gradient(currentColor 0 0) 0 100% / 100% 1px no-repeat;
}
.staff.three {
  height: .42em; margin-left: 0;
  background:
    linear-gradient(currentColor 0 0) 0 0 / 100% 1px no-repeat,
    linear-gradient(currentColor 0 0) 0 50% / 100% 1px no-repeat,
    linear-gradient(currentColor 0 0) 0 100% / 100% 1px no-repeat;
}
.bar { width: 3px; height: .78em; background: var(--ink); }
.en { font-size: calc(var(--u) * 4.4); letter-spacing: .5em; margin: .45em 0 .3em; }
.cover .names { position: relative; z-index: 2; margin-top: calc(var(--u) * 7.5); font-size: calc(var(--u) * 4.4); letter-spacing: .08em; }
.date { position: relative; z-index: 2; margin-top: .45em; font-size: calc(var(--u) * 4.2); letter-spacing: .05em; }
.note { position: relative; z-index: 2; margin-top: 1.1em; font-size: clamp(8px, calc(var(--u) * 2.45), 11px); line-height: 1.5; font-weight: 400; color: var(--ink-soft); }
.spiral {
  flex: 1 1 0; min-height: 0; display: block;
  width: calc(100% + 2 * var(--pad) + 24%);
  margin: calc(var(--u) * 2) calc(-1 * var(--pad) - 12%) 0;
  pointer-events: none;
}
.hint {
  position: absolute; left: 0; right: 0; bottom: calc(var(--bottom) + 16px); z-index: 2;
  text-align: center; font-size: 10px; letter-spacing: .3em; margin-right: -.3em;
}

/* ---------- photo ---------- */
.photo { --photo-w: min(100%, 45vh); display: flex; flex-direction: column; justify-content: center; align-items: center; padding-top: var(--top); }
.photo-staff { position: absolute; left: 0; right: 0; top: 50%; height: 64px; margin-top: -32px; }
.photo-staff i { position: absolute; left: 0; right: 0; height: 1px; background: rgba(34, 25, 19, .4); }
.photo-staff i:nth-child(2) { top: 25%; }
.photo-staff i:nth-child(3) { top: 50%; }
.photo-staff i:nth-child(4) { top: 75%; }
.photo-staff i:nth-child(5) { top: 100%; }
.photo figure {
  position: relative; z-index: 1;
  width: var(--photo-w); aspect-ratio: 2 / 3;
  background: #cdc3b6;
  box-shadow: 0 1px 2px rgba(40, 28, 18, .2), 0 22px 44px -16px rgba(60, 40, 22, .45);
}
.photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.photo figure::after { content: ''; position: absolute; inset: 0; opacity: .45; mix-blend-mode: multiply; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .22 0 0 0 0 .16 0 0 0 0 .1 .55 0 0 0 -.2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
.caption {
  display: flex; justify-content: space-between;
  width: var(--photo-w); margin-top: 14px;
  font-size: 10px; letter-spacing: .2em;
}

/* ---------- info ---------- */
.info { padding-top: calc(var(--top) + max(58px, var(--u) * 15)); }
.deco { width: calc(76% + var(--pad)); margin: 0 calc(-1 * var(--pad)) calc(var(--u) * 7) auto; }
.deco i { display: block; height: 1px; width: var(--w); margin: 0 0 calc(var(--u) * 2.5) auto; background: var(--ink); transform-origin: 100% 50%; }
.deco i.thick { height: 2.5px; }
.wi { font-family: 'Bodoni'; font-weight: 400; font-size: calc(var(--u) * 11.6); line-height: .98; letter-spacing: -.01em; }
.info .names { margin-top: calc(var(--u) * 5.5); font-size: calc(var(--u) * 4.9); letter-spacing: .1em; }
.when { margin-top: calc(var(--u) * 8); font-family: 'Bodoni'; }
.year { font-weight: 800; font-size: calc(var(--u) * 5.6); letter-spacing: .03em; line-height: 1; }
.md { display: flex; align-items: flex-end; line-height: .86; }
.md .m { font-weight: 800; font-size: calc(var(--u) * 9); align-self: flex-start; margin-top: .12em; }
.md .slash { width: 1.5px; height: calc(var(--u) * 10); background: var(--ink); transform: rotate(30deg); margin: 0 .5em .12em .2em; align-self: center; }
.md .d { font-weight: 900; font-size: calc(var(--u) * 19.5); letter-spacing: -.02em; }
.md .dow { font-size: max(10px, calc(var(--u) * 3)); letter-spacing: .12em; margin: 0 0 .5em .45em; }
.schedule { margin-top: calc(var(--u) * 5.5); }
.schedule div { display: flex; align-items: center; gap: calc(var(--u) * 4); margin-top: calc(var(--u) * 1.3); }
.schedule dt { display: flex; flex-direction: column; font-size: calc(var(--u) * 4.6); letter-spacing: .14em; line-height: 1.15; }
.schedule dt small { font-size: clamp(6px, calc(var(--u) * 1.8), 8px); letter-spacing: .3em; margin-top: 3px; }
.schedule dd { font-family: 'Bodoni'; font-weight: 900; font-size: calc(var(--u) * 8.6); line-height: 1; letter-spacing: .01em; }
address { font-style: normal; margin-top: calc(var(--u) * 8); }
.venue { font-size: calc(var(--u) * 4.4); letter-spacing: .06em; }
.addr { margin-top: 5px; font-size: max(11px, calc(var(--u) * 3.1)); letter-spacing: .03em; }
.addr-en { margin-top: 8px; font-size: max(8.5px, calc(var(--u) * 2.45)); line-height: 1.5; font-weight: 400; color: var(--ink-soft); }
.actions { display: flex; gap: 24px; margin-top: calc(var(--u) * 5); font-size: max(10px, calc(var(--u) * 2.8)); letter-spacing: .12em; }
.actions a, .actions button { display: inline-block; padding: 8px 0 5px; border-bottom: 1px solid var(--ink); text-decoration: none; line-height: 1.2; }
.info footer {
  position: absolute; left: var(--pad); right: var(--pad); bottom: calc(var(--bottom) + var(--u) * 5.5);
  display: flex; justify-content: space-between; align-items: baseline; font-size: 14px; letter-spacing: .2em;
}
.info footer .mono { font-size: 10px; letter-spacing: .22em; }
