/* Passport Journey (2026-10-27): Kling film opening + passport pages on the owner's blank guilloche page art.
   Motion rules (VIDEO-CHECKLIST #34/#35): only opacity / transform animate; nothing loops on background-position. */
:root {
  --linen: #efe8dc; --ink: #2b2430; --soft: #6b5d58; --wine: #6b1f2e; --wine-2: #8c2b40; --gold: #b8954f; --gold-deep: #8a6a3c;
  --navy: #2c3e5c; --page: #f6efe2;
}
* { box-sizing: border-box; }
html, body { margin: 0; background: var(--linen); color: var(--ink); -webkit-text-size-adjust: 100%; }
body { font-family: 'Cormorant Garamond', Georgia, serif; overflow-x: hidden; }
body.locked { overflow: hidden; height: 100dvh; }
.app { position: relative; max-width: 560px; margin: 0 auto; }

/* ───── stage: the film frame covers the first screen ───── */
.stage { position: relative; height: 100svh; min-height: 520px; overflow: hidden; background: var(--linen); }
.stage-bg { position: absolute; inset: -40px; background: url(../../art/passport-journey/still.webp) center / cover; filter: blur(22px) saturate(.9); opacity: .55; }
.frame { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); --fw: 560px; }
.frame > img, .frame > video, .frame > canvas { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.f-film { opacity: 0; transition: opacity .28s linear; }
.stage.rolling .f-film { opacity: 1; }
.f-still { transition: opacity .28s linear .05s; }
.stage.rolling .f-still, .stage.ended .f-still { opacity: 0; }
.f-last { opacity: 0; }
.stage.ended .f-last { opacity: 1; }
.stage.ended .f-film { opacity: 0; transition: opacity .2s linear .05s; }
.stage.instant * { transition: none !important; }

/* the couple's initials in gold foil inside the empty laurel crest (frame px: crest centre ≈ 591 × 888 of 1176 × 1764).
   2026-10-27 owner: a clear, legible face (the script initial was hard to read) and it stays ON the cover as it swings open —
   .mono-trk is a full-frame layer driven by the crest's tracked homography (cover-track.json → matrix3d), faded only in the
   last frames before the cover turns edge-on. */
.mono-trk { position: absolute; inset: 0; transform-origin: 0 0; pointer-events: none; will-change: transform, opacity; }
/* the wreath's empty centre (measured on frame 0, 1176 wide): x 479–698, y ≈ 800–960, visual centre (589, 885). The initials stay
   inside ≤ 60 % of that width and ≈ 75 px tall (app.js fitMono scales --mf down for wide initials such as "M & W") */
.mono { position: absolute; left: 50.09%; top: 50.17%; transform: translate(-50%, -50%); pointer-events: none; --mono-w: calc(var(--fw) * .13); --mono-h: calc(var(--fw) * .075); }
.mono span { display: block; font-family: 'Parisienne', cursive; font-weight: 400; font-size: calc(var(--fw) * .086 * var(--mf, 1)); line-height: 1.15; white-space: nowrap;
  padding: 0 .06em; /* script swashes overhang their box: keep them inside the gradient clip */
  background: linear-gradient(160deg, #f6e2a6 0%, #d9b86c 38%, #a87e36 62%, #f0d68f 100%); -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 1px 0 rgba(60, 10, 20, .55)); }
/* owner's pick 2026-10-27: Parisienne; the "&" smaller, on the capitals' midline */
.mono span i { font-style: normal; font-size: .6em; margin: 0 .36em; vertical-align: .08em; } /* ≈ .22em of the capitals each side: reads "N & J" */
.stage.ended .mono-trk { opacity: 0; }

/* printed on the first page; the layer spans the whole frame so its transform (tracked to the page) is in frame px */
.print { position: absolute; inset: 0; transform-origin: 0 0; opacity: 0; pointer-events: none; will-change: transform, opacity; }
.pr-box { position: absolute; left: 21%; width: 58%; top: 31%; text-align: center; color: #3a2a26; mix-blend-mode: multiply; }
.pr-k { font-family: 'Cinzel', serif; font-size: calc(var(--fw) * .021); letter-spacing: .32em; text-transform: uppercase; color: #7a2333; }
/* names: a flowing wedding script (owner 2026-10-27: "the font more cursive"); long names shrink to fit (app.js fitNames) */
.pr-n { margin-top: calc(var(--fw) * .026); font-family: 'Great Vibes', 'Pinyon Script', cursive; font-size: calc(var(--fw) * .112 * var(--nf, 1)); line-height: 1.04; color: #3b2724; }
.pr-n span { display: block; white-space: nowrap; }
.pr-n i { display: block; font-style: normal; font-size: .46em; line-height: 1.1; color: #8a6a3c; }
.pr-rule { width: 34%; height: 1px; margin: calc(var(--fw) * .035) auto calc(var(--fw) * .03); background: linear-gradient(90deg, transparent, #b8954f, transparent); }
.pr-d { font-family: 'Cinzel', serif; font-size: calc(var(--fw) * .024); letter-spacing: .14em; text-transform: uppercase; }
.pr-p { margin-top: calc(var(--fw) * .014); font-family: 'IBM Plex Mono', monospace; font-size: calc(var(--fw) * .017); letter-spacing: .18em; text-transform: uppercase; color: #6b5d58; }

.pr-box { position: absolute; }
/* ── the magic print (owner 2026-10-27): kicker/date/place machine-typed, names written by an invisible pen,
   the arrivals stamp pressed last (the holographic sweep was removed 2026-10-28). Only opacity / transform / a one-off clip-path animate. ── */
.print .ch { opacity: 0; }
.print.go .ch { animation: pjType .09s linear both; }
@keyframes pjType { from { opacity: 0; } to { opacity: 1; } }
/* 2026-10-27: with steps(1,end) some finished characters stayed at opacity 0 (Chrome + WebKit) — linear + an explicit
   end state after the sequence, so a typed character can never stay invisible */
.print.typed .ch { animation: none; opacity: 1; }
.print .ink { position: relative; display: block; width: max-content; margin: 0 auto; }
.print.go .ink { clip-path: inset(-20% 105% -30% -5%); animation: pjInk .78s cubic-bezier(.45, .05, .35, 1) var(--d) both; }
@keyframes pjInk { to { clip-path: inset(-20% -5% -30% -5%); } }
.print .pen { position: absolute; inset: 0; pointer-events: none; opacity: 0; transform: translateX(-100%); }
.print .pen::after { content: ''; position: absolute; right: -.12em; top: 18%; bottom: 8%; width: .26em; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 230, 170, .95), rgba(214, 170, 90, .45) 55%, transparent); filter: blur(1px); }
.print.go .pen { animation: pjPen .78s cubic-bezier(.45, .05, .35, 1) var(--d) both; }
@keyframes pjPen { 0% { opacity: 0; transform: translateX(-100%); } 12% { opacity: 1; } 88% { opacity: 1; } 100% { opacity: 0; transform: translateX(0); } }
.print .amp, .print .pr-rule { opacity: 0; }
.print.go .amp { animation: pjFade .5s ease 1.0s both; }
.print.go .pr-rule { transform-origin: 50% 50%; animation: pjRule .6s ease 1.5s both; }
@keyframes pjFade { to { opacity: 1; } }
@keyframes pjRule { from { opacity: 0; transform: scaleX(0); } to { opacity: 1; transform: scaleX(1); } }
.pr-stamp { position: absolute; right: -6%; top: calc(100% + var(--fw) * .03); width: calc(var(--fw) * .17); aspect-ratio: 1; opacity: 0; transform: rotate(-11deg) scale(1.25); }
.pr-stamp img, .pr-stamp svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.pr-stamp text.ring { font-family: 'Cinzel', serif; font-weight: 600; font-size: 7.4px; letter-spacing: 1.2px; fill: #8c1d33; }
.print.go .pr-stamp { animation: pjStamp .55s cubic-bezier(.3, .7, .35, 1.12) 2.15s both; }
@keyframes pjStamp { 0% { opacity: 0; transform: rotate(-17deg) scale(1.35); } 60% { opacity: .92; transform: rotate(-11deg) scale(.96); } 100% { opacity: .86; transform: rotate(-11deg) scale(1); } }
/* ?open, a missed film, reduced motion: everything in its final place, no sequence */
.print.still .ch, .print.still .amp, .print.still .pr-rule { opacity: 1; }
.print.still .pr-stamp { opacity: .86; transform: rotate(-11deg); }
@media (prefers-reduced-motion: reduce) { .print .ink, .print .pen { animation: none !important; clip-path: none !important; } }

.tap { position: absolute; inset: 0; z-index: 3; background: none; border: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.stage.open .tap { display: none; }
.hint { position: absolute; left: 50%; bottom: calc(26px + env(safe-area-inset-bottom)); transform: translateX(-50%); z-index: 4; margin: 0; padding: 9px 18px;
  font-family: 'Cinzel', serif; font-size: 11px; letter-spacing: .26em; text-transform: uppercase; white-space: nowrap; color: var(--wine);
  background: rgba(250, 246, 238, .82); border-radius: 99px; box-shadow: 0 4px 14px rgba(60, 40, 30, .12); transition: opacity .4s; pointer-events: none; }
.stage.open .hint { opacity: 0; }
.cue { position: absolute; left: 50%; bottom: calc(20px + env(safe-area-inset-bottom)); transform: translateX(-50%); z-index: 4; font-family: 'Cinzel', serif; font-size: 10px;
  letter-spacing: .34em; text-transform: uppercase; color: #6b5d58; opacity: 0; transition: opacity .6s; }
.cue.show { opacity: .85; }
.pj-draft .hint, .pj-draft .cue { bottom: calc(62px + env(safe-area-inset-bottom)); }
.cue.gone { opacity: 0 !important; translate: 0 16px; transition: opacity .6s cubic-bezier(.4,0,.2,1), translate .6s cubic-bezier(.4,0,.2,1); } /* soft exit on the first scroll (owner 2026-10-27) */

/* ───── passport pages ───── */
.pages { padding: 18px 16px calc(40px + env(safe-area-inset-bottom)); display: grid; gap: 22px; }
.sheet { position: relative; padding: 30px 24px 44px; text-align: center; border-radius: 10px 10px 10px 10px;
  background: url(../../art/passport-journey/page.webp) center / cover, var(--page);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .7) inset, 0 18px 34px -18px rgba(70, 40, 30, .35), 0 2px 6px rgba(70, 40, 30, .12); overflow: hidden; }
.sheet::before { content: ''; position: absolute; inset: 9px; border: 1px solid rgba(184, 149, 79, .38); border-radius: 6px; pointer-events: none; }
.v-head { display: flex; justify-content: space-between; gap: 10px; font-family: 'IBM Plex Mono', monospace; font-size: 10.5px; letter-spacing: .2em; text-transform: uppercase; color: #7a2333; opacity: .85; margin: 0 0 18px; }
.pno { position: absolute; right: 22px; bottom: 16px; font-family: 'IBM Plex Mono', monospace; font-size: 10px; letter-spacing: .2em; color: #8a7a70; }
.kicker { font-family: 'Cinzel', serif; font-size: 11.5px; letter-spacing: .28em; text-transform: uppercase; color: #8a6a3c; margin-top: 4px; }
.title { margin: 8px 0 12px; font-family: 'Pinyon Script', cursive; font-weight: 400; font-size: clamp(38px, 11vw, 50px); line-height: 1.1; color: var(--wine); text-wrap: balance; }
.lead { max-width: 340px; margin: 0 auto; font-size: 19px; line-height: 1.55; font-weight: 500; text-wrap: pretty; }
.lead.center { text-align: center; }
.pj-ico { color: #8a6a3c; margin-bottom: 8px; }
.pj-ico svg { width: 62px; height: 62px; }

/* photos: the passport photo (gold-edged, slightly lifted) / without photos an engraved monogram */
.pass-photo { width: min(46%, 170px); aspect-ratio: 3 / 4; margin: 2px auto 16px; padding: 6px; background: #fbf7ee; border-radius: 4px;
  box-shadow: 0 0 0 1px rgba(184, 149, 79, .55), 0 10px 22px -10px rgba(60, 30, 20, .45); transform: rotate(-1.5deg); }
.pass-photo img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 2px; filter: saturate(.92) contrast(1.02); }
.engraved { width: 128px; height: 128px; margin: 0 auto 14px; border-radius: 50%; display: grid; place-items: center;
  box-shadow: 0 0 0 1px rgba(184, 149, 79, .55), 0 0 0 7px rgba(184, 149, 79, .08), inset 0 0 0 4px rgba(250, 246, 238, .6); }
.engraved span { font-family: 'Pinyon Script', cursive; font-size: 40px; color: #8a6a3c; text-shadow: 0 1px 0 rgba(255, 255, 255, .8); white-space: nowrap; }
.sign { margin: 18px auto 0; display: flex; align-items: baseline; justify-content: center; gap: 12px; flex-wrap: wrap; }
.sign small { font-family: 'IBM Plex Mono', monospace; font-size: 9.5px; letter-spacing: .18em; text-transform: uppercase; color: #8a7a70; }
.sign span { font-family: 'Pinyon Script', cursive; font-size: 30px; color: #3b2724; }

/* stamps: the owner's ink stamps + our printed text; they ink in with a soft press when their page is reached */
.stamp { position: relative; margin: 18px auto 4px; width: 150px; aspect-ratio: 1; opacity: 0; transform: scale(1.18) rotate(var(--rot, -8deg)); transition: opacity .5s ease, transform .55s cubic-bezier(.3, .7, .35, 1.12); }
.stamp.small { width: 118px; }
.stamp.tilt-l { --rot: -9deg; } .stamp.tilt-r { --rot: 8deg; }
.sheet.in .stamp { opacity: .9; transform: scale(1) rotate(var(--rot, -8deg)); transition-delay: .35s; }
.stamp img { width: 100%; height: 100%; display: block; mix-blend-mode: multiply; }
.stamp svg { position: absolute; inset: 0; width: 100%; height: 100%; mix-blend-mode: multiply; }
.stamp.circ text.ring { font-family: 'Cinzel', serif; font-weight: 600; font-size: 7.4px; letter-spacing: 1.2px; fill: #8c1d33; }
.stamp.rect { width: 200px; }
.stamp.rect text { font-family: 'Cinzel', serif; font-weight: 600; fill: #2c3e5c; }
.stamp.rect text.top { font-size: 7px; letter-spacing: 2.4px; }
.stamp.rect text.big { font-size: 10.5px; letter-spacing: 1.6px; font-family: 'IBM Plex Mono', monospace; font-weight: 500; }

/* countdown with a boarding-pass perforation */
.cd { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; max-width: 320px; margin: 4px auto 0; }
.cd b { display: block; font-family: 'IBM Plex Mono', monospace; font-weight: 500; font-size: clamp(26px, 8vw, 34px); color: var(--wine); line-height: 1.1; }
.cd small { font-family: 'Cinzel', serif; font-size: 10px; letter-spacing: .22em; text-transform: uppercase; color: #8a7a70; }
.perf { height: 1px; margin: 22px -24px 18px; background: repeating-linear-gradient(90deg, rgba(122, 35, 51, .5) 0 6px, transparent 6px 12px); position: relative; }
.perf::before, .perf::after { content: ''; position: absolute; top: -9px; width: 18px; height: 18px; border-radius: 50%; background: var(--linen); }
.perf::before { left: -9px; } .perf::after { right: -9px; }

/* itinerary: each event a line of the travel plan, sliding in one after another */
.itin { list-style: none; margin: 6px auto 0; padding: 0; max-width: 340px; text-align: left; }
.itin li { display: grid; grid-template-columns: 84px 1fr; gap: 12px; padding: 12px 0; border-bottom: 1px dashed rgba(122, 35, 51, .25);
  opacity: 0; transform: translateY(8px); transition: opacity .6s ease, transform .6s ease; transition-delay: calc(var(--i) * .12s + .2s); }
.itin li.in, .sheet.in .itin li { opacity: 1; transform: none; }
.itin li:last-child { border-bottom: 0; }
.itin .t { font-family: 'IBM Plex Mono', monospace; font-size: 14px; color: var(--wine); padding-top: 3px; white-space: nowrap; }
.itin b { display: block; font-family: 'Cinzel', serif; font-weight: 500; font-size: 14px; letter-spacing: .08em; text-transform: uppercase; }
.itin span:not(.t) { display: block; font-size: 17px; line-height: 1.35; color: var(--soft); }

/* destination: the ribbon with its little plane, the address, the buyer's snapshots */
.ribbon { margin: -4px -24px 14px; overflow: hidden; }
.ribbon img { width: 100%; height: auto; display: block; transform: translateX(-14%); opacity: 0; transition: transform 1.6s cubic-bezier(.25, .7, .2, 1), opacity .6s ease; }
.sheet.in .ribbon img { transform: none; opacity: 1; }
.addr { margin: 0 auto 4px; font-size: 18px; line-height: 1.5; color: var(--soft); }
.snaps { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin: 20px auto 0; max-width: 340px; }
.snaps.one { grid-template-columns: minmax(0, 220px); justify-content: center; }
.snaps figure { margin: 0; padding: 6px 6px 18px; background: #fbf7ee; box-shadow: 0 8px 18px -10px rgba(60, 30, 20, .45), 0 0 0 1px rgba(184, 149, 79, .25); transform: rotate(var(--r, 0deg)); }
.snaps img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; }

.palette { display: flex; justify-content: center; gap: 10px; margin: 16px 0 4px; }
.palette span { width: 30px; height: 30px; border-radius: 50%; box-shadow: 0 0 0 2px #fbf7ee, 0 0 0 3px rgba(184, 149, 79, .5); }

/* buttons with a slow light pass (transform only) */
.btns { display: flex; justify-content: center; gap: 10px; flex-wrap: wrap; margin-top: 18px; }
.btn { position: relative; overflow: hidden; display: inline-block; padding: 12px 22px; border-radius: 99px; text-decoration: none; cursor: pointer;
  font-family: 'Cinzel', serif; font-size: 12px; letter-spacing: .2em; text-transform: uppercase; color: #fbf6ec; background: var(--wine); border: 1px solid var(--wine); }
.btn.ghost { color: var(--wine); background: rgba(251, 247, 238, .7); }
.btn::after { content: ''; position: absolute; top: 0; bottom: 0; left: 0; width: 60%; background: linear-gradient(105deg, transparent, rgba(255, 255, 255, .35), transparent);
  transform: translateX(-120%); animation: pjSheen 7s ease-in-out 2s infinite; pointer-events: none; }
@keyframes pjSheen { 0%, 70% { transform: translateX(-120%); } 100% { transform: translateX(260%); } }
.sigline { margin-top: 22px; font-family: 'Pinyon Script', cursive; font-size: 28px; color: #3b2724; }

.music-btn { position: fixed; right: 14px; bottom: calc(14px + env(safe-area-inset-bottom)); z-index: 20; width: 42px; height: 42px; border-radius: 50%; border: 0;
  background: rgba(250, 246, 238, .9); color: var(--wine); font-size: 18px; box-shadow: 0 4px 14px rgba(60, 40, 30, .18); }
.music-btn.playing { color: var(--gold-deep); }

@media (max-width: 360px) {
  .sheet { padding: 26px 18px 42px; }
  .itin li { grid-template-columns: 72px 1fr; gap: 8px; }
  .perf { margin-left: -18px; margin-right: -18px; }
  .ribbon { margin-left: -18px; margin-right: -18px; }
  .stamp.rect { width: 180px; }
}
@media (prefers-reduced-motion: reduce) {
  .stamp, .itin li, .ribbon img { transition: none !important; }
  .btn::after { animation: none; display: none; }
}
