/* The wedding train film: title cards and wedding photos float over the valley while the train goes
   round, each line easing up after the one before; a quiet "Bỏ qua" while it plays; map pins once it is
   over (the invitation's own pin leads back to the card). The cards sit high, above the train the camera follows. */
.journey-hud { position: fixed; inset: 0; z-index: 20; pointer-events: none; transition: opacity 0.3s ease; }
body[data-mode='ticket'] .overlays, body[data-mode='quick'] .overlays, body[data-mode='quick'] .journey-hud { display: none; }
.film-captions {
  position: absolute; left: 0; right: 0; top: calc(var(--safe-top) + 1.1rem); display: grid; justify-items: center; pointer-events: none;
}
.film-caption {
  grid-area: 1 / 1; width: min(calc(100% - 1.6rem), 30rem); padding: 1.05rem 1.3rem 1.15rem; text-align: center;
  border-radius: 22px; background: rgba(var(--paper-rgb), 0.9); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  box-shadow: 0 14px 34px rgba(var(--shadow-rgb), 0.2); animation: caption-in 0.8s 0.25s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.film-caption.is-leaving { animation: caption-out 0.55s ease both; }
@keyframes caption-in { from { opacity: 0; transform: translateY(12px) scale(0.98); } }
@keyframes caption-out { to { opacity: 0; transform: translateY(-10px); } }
/* Line after line, so the card reads like a title sequence. */
.film-caption > *, .film-caption-names > * { animation: caption-line 0.9s cubic-bezier(0.2, 0.8, 0.2, 1) both; animation-delay: 0.35s; }
.film-caption > :nth-child(2), .film-caption-names > :nth-child(2) { animation-delay: 0.75s; }
.film-caption > :nth-child(3), .film-caption-names > :nth-child(3) { animation-delay: 1.15s; }
.film-caption > :nth-child(n + 4) { animation-delay: 1.5s; }
@keyframes caption-line { from { opacity: 0; transform: translateY(8px); } }
.film-caption p { margin: 0; }

/* Centred on every screen (the rule above would otherwise zero its auto margins), clear of the names'
   tall script capitals below. */
.film-caption .film-caption-lead {
  max-width: 22rem; margin: 0 auto 0.85rem; font-family: var(--font-serif); font-style: italic; font-weight: 500; font-size: var(--fs-lead);
  line-height: 1.3; color: var(--ink); text-wrap: balance;
}
.film-caption-kicker, .film-caption-label {
  font-family: var(--font-ui); font-size: var(--fs-caps); font-weight: 600; letter-spacing: var(--caps-track); text-transform: uppercase; color: var(--brand-soft);
}
.film-caption-kicker { margin-bottom: 0.3rem; }
.film-caption-label { margin-bottom: 0.15rem; }
/* The couple, signed in script, larger than anywhere else. */
.film-caption-name { font-family: var(--font-script); font-weight: 400; font-size: clamp(3rem, 13.5vw, 3.75rem); line-height: 1.02; color: var(--brand); }
.film-caption .couple-amp.film-caption-join { margin: 0.05rem 0 0.15rem; font-size: 2.2rem; }
.film-caption-main {
  font-family: var(--font-serif); font-weight: 600; font-size: clamp(2rem, 8.6vw, 2.4rem); line-height: 1.15; color: var(--brand); text-wrap: balance;
}
.film-caption-detail { margin-top: 0.25rem; font-size: var(--fs-body); font-weight: 600; color: var(--ink); }
.film-caption-sub { margin-top: 0.2rem; font-family: var(--font-serif); font-style: italic; font-weight: 500; font-size: 1.15rem; line-height: 1.35; color: var(--ink-soft); text-wrap: balance; }
/* Under the place, its address reads as plain text. */
.film-caption-row:has(.film-caption-label) .film-caption-sub { font-family: var(--font-ui); font-style: normal; font-weight: 400; font-size: 0.95rem; }
.film-caption-row + .film-caption-row { margin-top: 0.7rem; padding-top: 0.7rem; border-top: 1px solid var(--hairline); }
.film-caption-quote {
  font-family: var(--font-serif); font-style: italic; font-weight: 600; font-size: clamp(1.5rem, 6.6vw, 1.85rem); line-height: 1.3; color: var(--brand);
  text-wrap: balance;
}
.film-caption-quote::before { content: '❦'; display: block; margin-bottom: 0.3rem; font-style: normal; font-size: 1.1rem; color: var(--rule); }

/* A wedding photo per beat: a polaroid tilted left / right in turn, drifting slowly closer. */
.film-photo {
  position: absolute; top: calc(var(--safe-top) + 1.1rem); left: 50%; width: min(80vw, 380px); margin: 0;
  padding: 0.6rem 0.6rem 0.45rem; border-radius: 6px; background: var(--paper); box-shadow: 0 18px 40px rgba(var(--shadow-rgb), 0.32);
  transform: translateX(-50%) rotate(var(--tilt, -2.5deg)); pointer-events: none;
  animation: film-photo-in 0.8s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.film-photo[hidden] { display: none; }
.film-photo.is-leaving {
  opacity: 0; transform: translateX(-50%) rotate(var(--tilt, -2.5deg)) translateY(-10px) scale(0.96);
  transition: opacity 0.35s ease, transform 0.35s ease;
}
.film-photo-frame { aspect-ratio: 4 / 3; overflow: hidden; border-radius: 2px; background: var(--accent-soft, var(--accent-soft)); }
.film-photo.is-portrait { width: min(60vw, 280px); }
.film-photo.is-portrait .film-photo-frame { aspect-ratio: 3 / 4; }
.film-photo-img { display: block; width: 100%; height: 100%; object-fit: cover; animation: photo-drift 4.2s ease-out both; }
.film-photo-caption {
  margin: 0.4rem 0 0.05rem; text-align: center; font-family: var(--font-serif); font-style: italic; font-weight: 600; font-size: 1.15rem; color: var(--ink);
}
.film-photo-caption:empty { display: none; }
@keyframes film-photo-in { from { opacity: 0; transform: translateX(-46%) rotate(calc(var(--tilt, -2.5deg) * -2)) translateY(16px) scale(0.94); } }
@keyframes photo-drift { from { transform: scale(1.12); } }

/* "Bỏ qua": quiet, bottom right, only after the first seconds. */
.film-skip {
  position: absolute; right: 1rem; bottom: calc(1rem + var(--safe-bottom)); min-height: var(--tap); padding: 0 1rem;
  border: 0; border-radius: 999px; background: rgba(var(--paper-rgb), 0.72); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  font: 600 var(--fs-note) var(--font-ui); letter-spacing: 0.02em; color: var(--brand); cursor: pointer; pointer-events: auto;
  animation: skip-in 0.6s 3s both;
}
.film-skip::after { content: ' ›'; }
@keyframes skip-in { from { opacity: 0; visibility: hidden; } }
.film-skip[hidden] { display: none; }
/* After the film, where "Bỏ qua" was: day or night in the corner, the film again beside it, and beyond, once
   the guest has wandered off the whole island, the way back to it. */
.view-controls {
  position: absolute; right: 1rem; bottom: calc(1rem + var(--safe-bottom)); display: flex; gap: 0.6rem; pointer-events: none;
}
.recenter, .replay, .sky-toggle, .music-toggle {
  position: relative; width: 2.9rem; height: 2.9rem; padding: 0; border: 0; border-radius: 50%; background: var(--paper);
  box-shadow: 0 6px 16px rgba(var(--shadow-rgb), 0.35); cursor: pointer; pointer-events: auto; animation: pin-in 0.3s ease both;
}
.recenter::after, .replay::after, .sky-toggle::after, .music-toggle::after {
  content: ''; position: absolute; inset: 0; background: var(--brand);
  -webkit-mask: var(--icon) center / 1.35rem no-repeat; mask: var(--icon) center / 1.35rem no-repeat;
}
.recenter { --icon: var(--icon-recenter); }
.replay { --icon: var(--icon-replay); }
/* The icon is the sky a tap brings. */
.sky-toggle { --icon: var(--icon-moon); }
.sky-toggle[data-to='day'] { --icon: var(--icon-sun); }
/* The couple's song, bottom left on the envelope and the whole time the island shows; the icon is the sound now. */
.music-toggle {
  --icon-music: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 17.5V5.5l11-2v12'/%3E%3Ccircle cx='6.5' cy='17.5' r='2.5' fill='black'/%3E%3Ccircle cx='17.5' cy='15.5' r='2.5' fill='black'/%3E%3C/svg%3E");
  --icon-music-off: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 17.5V5.5l11-2v12' opacity='0.45'/%3E%3Ccircle cx='6.5' cy='17.5' r='2.5' fill='black' opacity='0.45'/%3E%3Ccircle cx='17.5' cy='15.5' r='2.5' fill='black' opacity='0.45'/%3E%3Cpath d='M3 3l18 18'/%3E%3C/svg%3E");
  position: absolute; left: 1rem; bottom: calc(1rem + var(--safe-bottom)); z-index: 2; --icon: var(--icon-music);
}
.music-toggle[data-on='false'] { --icon: var(--icon-music-off); }
/* The browser holds the song until a touch: the switch calls for one. */
/* Held by the browser, not silenced: the plain note, pulsing for a touch. */
.music-toggle[data-waiting='true'] { --icon: var(--icon-music); animation: pin-in 0.3s ease both, music-wait 1.8s 0.3s ease-in-out infinite; }
@keyframes music-wait { 50% { box-shadow: 0 6px 16px rgba(var(--shadow-rgb), 0.35), 0 0 0 8px rgba(var(--accent-rgb), 0.4); } }
.journey-hud {
  --icon-recenter: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='7'/%3E%3Ccircle cx='12' cy='12' r='2.6' fill='black' stroke='none'/%3E%3Cpath d='M12 1.5v3.5M12 19v3.5M1.5 12H5M19 12h3.5'/%3E%3C/svg%3E");
  --icon-replay: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 12a7.5 7.5 0 1 0 2.2-5.3'/%3E%3Cpath d='M4 3.5v4h4'/%3E%3Cpath d='M10.3 9.2v5.6l4.6-2.8z' fill='black'/%3E%3C/svg%3E");
  --icon-sun: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='4.2' fill='black'/%3E%3Cpath d='M12 2v2.4M12 19.6V22M2 12h2.4M19.6 12H22M4.9 4.9l1.7 1.7M17.4 17.4l1.7 1.7M4.9 19.1l1.7-1.7M17.4 6.6l1.7-1.7'/%3E%3C/svg%3E");
  --icon-moon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.5 14.1A8.6 8.6 0 1 1 9.9 3.5a6.9 6.9 0 0 0 10.6 10.6z' fill='black'/%3E%3C/svg%3E");
}
:is(.recenter, .replay, .sky-toggle, .music-toggle)[hidden] { display: none; }
.journey-hud.is-hidden :is(.film-captions, .film-photo, .film-skip, .recenter, .replay, .sky-toggle, .music-toggle) { opacity: 0; pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  .film-caption, .film-caption > *, .film-caption-names > *, .film-photo, .film-photo-img, .film-skip { animation: none; }
  .music-toggle[data-waiting='true'] { animation: none; box-shadow: 0 6px 16px rgba(var(--shadow-rgb), 0.35), 0 0 0 4px rgba(var(--accent-rgb), 0.5); }
}

/* The platform's hello: a speech bubble above the old traveler, its tail pointing down at him. */
.greeting-bubble {
  position: absolute; left: 0; top: 0; max-width: min(15rem, 72vw); margin: 0; padding: 0.6rem 0.85rem; border-radius: 14px;
  background: var(--paper); color: var(--ink); font: 600 0.9375rem/1.4 var(--font-ui); text-align: center; text-wrap: balance;
  box-shadow: 0 8px 22px rgba(var(--shadow-rgb), 0.3); pointer-events: none; will-change: transform;
  animation: bubble-in 0.45s cubic-bezier(0.3, 1.5, 0.5, 1) both;
}
.greeting-bubble::after {
  content: ''; position: absolute; left: 50%; bottom: -7px; width: 14px; height: 14px; transform: translateX(-50%) rotate(45deg); background: inherit;
}
.greeting-bubble[hidden] { display: none; }
.journey-hud.is-hidden .greeting-bubble { opacity: 0; }
@keyframes bubble-in { from { opacity: 0; scale: 0.6; } }
@media (prefers-reduced-motion: reduce) { .greeting-bubble { animation: none; } }

/* After the film: pins over the ceremonies' gates and the station; a gate's pin opens its card. */
.milestone-pins { position: absolute; inset: 0; pointer-events: none; }
.milestone-pins[hidden] { display: none; }
.milestone-pin { position: absolute; left: 0; top: 0; display: grid; justify-items: center; gap: 0.35rem; will-change: transform; }
.milestone-pin-label {
  position: relative; display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.3rem 0.75rem 0.3rem 0.3rem; border: 0; border-radius: 999px;
  background: var(--paper); color: var(--brand); font: 600 var(--fs-note) var(--font-ui); white-space: nowrap; cursor: pointer; pointer-events: auto;
  box-shadow: 0 6px 16px rgba(var(--shadow-rgb), 0.35); animation: pin-in 0.4s ease both;
}
.milestone-pin-label::after {
  content: ''; position: absolute; left: 50%; bottom: -5px; width: 10px; height: 10px; transform: translateX(-50%) rotate(45deg);
  background: var(--paper); z-index: -1;
}
.milestone-pin { padding-bottom: 6px; }
.milestone-pin-icon {
  display: inline-grid; place-items: center; width: 1.55rem; height: 1.55rem; border-radius: 50%; font-size: 0.8rem; color: var(--seal-mark);
  background: radial-gradient(circle at 35% 30%, var(--seal-light), var(--seal));
}
/* A pin without an icon (the ceremonies'): even padding round its words. */
.milestone-pin-label.is-plain { padding: 0.35rem 0.85rem; }
.milestone-pin.is-open { z-index: 2; }
/* The invitation's pin, the way back to the card: in the card's rose, a size up, always on screen. */
.milestone-pin.is-primary { z-index: 1; }
.milestone-pin.is-primary .milestone-pin-label {
  gap: 0.5rem; padding: 0.35rem 1.1rem 0.35rem 0.35rem; font-size: var(--fs-body); color: var(--on-accent); background: var(--accent);
  box-shadow: 0 8px 22px rgba(var(--shadow-rgb), 0.45);
}
.milestone-pin.is-primary .milestone-pin-label::after { background: var(--accent); }
.milestone-pin.is-primary .milestone-pin-icon { width: 1.9rem; height: 1.9rem; font-size: 0.95rem; color: var(--seal-mark); background: var(--seal); }
.milestone-pin.is-away .milestone-pin-label::after { display: none; }
.pin-card {
  order: -1; width: 15rem; padding: 0.75rem 0.9rem 0.8rem; border-radius: 14px; text-align: center; pointer-events: auto;
  background: var(--paper) var(--paper-grain); box-shadow: inset 0 0 0 1px rgba(var(--rule-rgb), 0.7), 0 12px 28px rgba(var(--shadow-rgb), 0.4);
  animation: pin-in 0.3s ease both;
}
.pin-card :where(p) { margin: 0; }
.pin-card-day { font-family: var(--font-serif); font-weight: 600; font-size: 1.35rem; line-height: 1.2; color: var(--brand); }
.pin-card-time { font-weight: 600; font-size: var(--fs-note); color: var(--ink); }
.pin-card-lunar { margin-top: 0.1rem; font-family: var(--font-serif); font-style: italic; font-weight: 500; font-size: 1.05rem; line-height: 1.3; color: var(--ink-soft); text-wrap: balance; }
.pin-card-venue { margin-top: 0.5rem; font-family: var(--font-serif); font-weight: 700; font-size: 1.3rem; line-height: 1.2; color: var(--brand); }
.pin-card-address { margin-top: 0.1rem; font-size: var(--fs-note); color: var(--ink); }
.pin-card-link {
  display: inline-flex; align-items: center; min-height: 2.2rem; margin-top: 0.55rem; padding: 0 1rem; border-radius: 999px;
  font: 600 var(--fs-note) var(--font-ui); color: var(--paper); background: var(--brand); text-decoration: none;
}
@keyframes pin-in { from { opacity: 0; transform: translateY(6px); } }
@media (prefers-reduced-motion: reduce) { .milestone-pin-label, .pin-card { animation: none; } }
