/*
  Emily & Nick — interactive intro
  ---------------------------------
  This is the click-through sequence between the Save the Date and the
  homepage: ticket -> stamp -> route -> real Abruzzo footage -> homepage.
  In Squarespace this sequence isn't a "page" in the normal sense — it's
  the code-injected content on the homepage itself that runs once, then
  reveals the real homepage markup underneath. See intro.js for the logic.
*/

html,body{margin:0;padding:0;height:100%;background:#12161C;overflow:hidden;}

#intro-root{
  position:fixed; inset:0; z-index:100;
  background:#12161C; color:#F4F1EA;
  font-family:var(--font-sans);
}

.intro-screen{
  position:absolute; inset:0;
  display:flex; align-items:center; justify-content:center;
  flex-direction:column; text-align:center; padding:24px;
  opacity:0; pointer-events:none;
  transition:opacity 0.5s ease;
}
.intro-screen.active{opacity:1; pointer-events:auto;}

/* skip control, always available */
#skip-intro{
  position:fixed; top:20px; right:20px; z-index:200;
  background:rgba(0,0,0,0.25); border:1px solid rgba(244,241,234,0.4);
  color:#F4F1EA; font-family:var(--font-label); font-size:11px;
  letter-spacing:1.5px; text-transform:uppercase;
  padding:10px 16px; border-radius:20px; cursor:pointer;
}
#skip-intro:hover{background:rgba(244,241,234,0.15);}

/* progress dots */
#intro-progress{
  position:fixed; bottom:22px; left:50%; transform:translateX(-50%); z-index:200;
  display:flex; gap:8px;
}
#intro-progress span{
  width:6px; height:6px; border-radius:50%; background:rgba(244,241,234,0.3);
}
#intro-progress span.done{background:#B08D57;}

/* ---------- Screen: invitation (only for non-STD arrivals) ---------- */
#screen-invite{ display:block; padding:0; overflow:hidden; }
#screen-invite .invite-bg{ position:absolute; inset:0; }
#screen-invite .invite-bg img{
  width:100%; height:100%; object-fit:cover; object-position:58% 42%;
}
#screen-invite .invite-scrim{
  position:absolute; inset:0;
  background:
    linear-gradient(180deg, rgba(8,10,14,0.30) 0%, rgba(8,10,14,0.04) 26%, rgba(8,10,14,0.18) 62%, rgba(8,10,14,0.72) 100%),
    linear-gradient(90deg, rgba(8,10,14,0.42) 0%, rgba(8,10,14,0) 34%);
}
#screen-invite .invite-content{
  position:relative; z-index:1; width:100%; height:100%;
  display:flex; align-items:center; justify-content:center;
  padding:24px;
}
#screen-invite .invite-btn{
  font-size:clamp(12px,1.4vw,14px); letter-spacing:3px; padding:22px 50px; border-radius:2px;
}
#screen-invite .invite-footer{
  position:absolute; z-index:1; left:36px; bottom:32px; text-align:left; pointer-events:none;
}
#screen-invite .invite-names{
  font-family:var(--font-label); font-weight:500; font-size:clamp(16px,2.4vw,20px);
  letter-spacing:5px; text-transform:uppercase; color:#F5F1E8;
}
#screen-invite .invite-meta{
  font-family:var(--font-mono); font-size:11px; letter-spacing:2px; text-transform:uppercase;
  color:#C9C4B8; margin-top:8px;
}
@media (max-width:640px){
  #screen-invite .invite-bg img{ object-position:22% 30%; }
  /* bottom:22px used to sit at the exact same height as the fixed
     progress dots, so the date line overlapped them — lifted well clear. */
  #screen-invite .invite-footer{ left:20px; bottom:58px; }
  #screen-invite .invite-btn{ padding:18px 34px; }
}

/* ---------- Screen: ticket ---------- */
#screen-ticket{background:#12161C;}
.ticket{
  width:100%; max-width:640px;
  position:relative;
}
.ticket .ticket-art{
  display:block; width:100%; height:auto;
  filter:drop-shadow(0 26px 54px rgba(0,0,0,0.45));
}
.ticket .stamp-mark{
  position:absolute; left:61.5%; top:34%; width:21%; height:auto;
  pointer-events:none;
  filter:drop-shadow(0 3px 7px rgba(120,40,10,0.45));
  will-change:transform, opacity;
  transform:translate(-50%,-50%) scale(0) rotate(-16deg); opacity:0;
  transition:transform 0.45s cubic-bezier(.2,1.6,.4,1), opacity 0.45s ease;
}
.ticket.stamped .stamp-mark{transform:translate(-50%,-50%) scale(1) rotate(-8deg); opacity:1;}

/* Ticket is the click target itself once the stamp cursor is active */
.ticket.stampable{cursor:pointer;}
.stamp-active .ticket.stampable{cursor:none;}

#screen-ticket .cta-row{margin-top:30px;}

/* Real button still exists for keyboard/screen-reader users, but visually
   recedes once the stamp-cursor takes over the pointer interaction. */
#stamp-btn.visually-recede{
  background:transparent; border-color:rgba(244,241,234,0.35); color:rgba(244,241,234,0.7);
}
#stamp-btn:focus-visible{outline:2px solid #B08D57; outline-offset:3px;}

#screen-ticket .hint{
  margin-top:14px; font-family:var(--font-mono); font-size:11.5px; color:#8A8988;
}

/* ---------- custom stamp cursor ---------- */
#stamp-cursor{
  position:fixed; top:0; left:0; z-index:300;
  width:126px; height:auto;
  pointer-events:none;
  transform:translate(-50%,-47%) rotate(-14deg) scale(0);
  opacity:0;
  transition:opacity 0.15s ease, transform 0.12s cubic-bezier(.3,1.5,.4,1);
}
#stamp-cursor.show{opacity:1; transform:translate(-50%,-47%) rotate(-14deg) scale(1);}
#stamp-cursor.press{transform:translate(-50%,-29%) rotate(-14deg) scale(0.88);}
#stamp-cursor img{
  display:block; width:100%; height:auto;
}

/* ---------- Screen: route ---------- */
#screen-route svg{
  width:min(92vw, 1300px); height:auto; max-height:76vh;
  aspect-ratio:1672/941;
}
#screen-route .route-caption{
  font-family:var(--font-mono); font-size:13px; letter-spacing:2px; text-transform:uppercase;
  color:#C9C4B8; height:20px; margin-top:22px;
}
#screen-route .route-stats{
  font-family:var(--font-mono); font-size:11.5px; letter-spacing:1.5px;
  color:#8A8988; margin-top:8px; height:16px;
}
.route-line{
  /* dasharray is set to match the actual path length closely (~981 units)
     so the line-draw reveal and the plane's offset-path position finish
     at the same time — too generous a buffer here made the line finish
     drawing before the plane arrived. */
  stroke-dasharray:988; stroke-dashoffset:988;
}
.route-line.draw{animation:draw-route 2.6s ease forwards;}
@keyframes draw-route{ to { stroke-dashoffset:0; } }

/* the plane travels the path at a calm, steady pace — no extra bobbing */
.route-plane{ offset-path: path('M330,430 Q799,200 1269,463'); offset-distance:0%; }
.route-plane.fly{animation:fly-route 2.6s ease forwards;}
@keyframes fly-route{ to { offset-distance:100%; } }

/* ---------- ambient life on the map ----------
   Everything below is deliberately subtle — meant to read as a beautiful
   still illustration first, with motion you only notice on a second look.
   All of it is scoped to #screen-route.active so it only plays while this
   screen is on screen, and the global prefers-reduced-motion rule at the
   top of styles.css already neutralizes every animation here for anyone
   who has that preference set. */

/* a slow, cinematic push toward Europe while the plane crosses — the whole
   scene (map, ocean, clouds, route, pins, plane) scales together as one
   unit so nothing drifts off the artwork it's keyed to */
.map-scene{ transform-origin:1050px 420px; }
#screen-route.active .map-scene{ animation:map-push-in 2.6s cubic-bezier(.2,.65,.2,1) forwards; }
@keyframes map-push-in{ from{ transform:scale(1); } to{ transform:scale(1.045); } }

/* watercolor ocean, breathing very slowly like pigment settling on paper */
.ocean-bloom.bloom-a{ transform-origin:760px 470px; }
.ocean-bloom.bloom-b{ transform-origin:940px 360px; }
#screen-route.active .ocean-bloom.bloom-a{ animation:ocean-breathe 22s ease-in-out infinite; }
#screen-route.active .ocean-bloom.bloom-b{ animation:ocean-breathe 27s ease-in-out infinite 5s; }
@keyframes ocean-breathe{
  0%, 100% { transform:scale(1); opacity:0.05; }
  50%      { transform:scale(1.08); opacity:0.09; }
}

/* painted clouds drifting almost imperceptibly west to east */
#screen-route.active .cloud-drift-a{ animation:cloud-drift 55s linear infinite; }
#screen-route.active .cloud-drift-b{ animation:cloud-drift 70s linear infinite 4s; }
#screen-route.active .cloud-drift-c{ animation:cloud-drift 46s linear infinite 9s; }
@keyframes cloud-drift{ from{ transform:translateX(0); } to{ transform:translateX(60px); } }

/* the faintest suggestion of light moving across the paper's surface */
#screen-route.active .paper-sheen{ animation:sheen-sweep 34s ease-in-out infinite; }
@keyframes sheen-sweep{
  0%   { transform:translateX(-200px); }
  50%  { transform:translateX(1900px); }
  100% { transform:translateX(4000px); }
}

/* a happy little bounce + warm glow when the plane touches down in Abruzzo */
#abruzzo-marker .glow{ transition:opacity 0.7s ease; }
#abruzzo-marker.landed .glow{ opacity:0.55; }
#abruzzo-marker.landed{
  animation:marker-pop 0.6s cubic-bezier(.34,1.56,.64,1) forwards;
  transform-origin:1269px 463px;
}
@keyframes marker-pop{
  0%   { transform:scale(1); }
  45%  { transform:scale(1.7); }
  65%  { transform:scale(0.9); }
  100% { transform:scale(1); }
}

/* ---------- Screen: reveal ---------- */
#screen-reveal{ display:block; padding:0; overflow:hidden; }
#screen-reveal .reveal-bg{ position:absolute; inset:0; }
#screen-reveal .reveal-bg img{
  width:100%; height:100%; object-fit:cover; object-position:50% 32%;
  transform:scale(1.06); transition:transform 8s ease;
}
#screen-reveal.active .reveal-bg img{ transform:scale(1.14); }
/* This photo has both of you spread fairly wide across the frame. On a
   tall phone screen, cropping it edge-to-edge (cover) zooms in so far
   that one of you gets cut out of view. Showing the whole frame instead
   (contain) means you always see the full photo, same as on desktop.
   Rather than overlay the names/date on top of the letterboxed photo,
   the photo sits flush at the top, undimmed, and the text moves into
   the space right below it — cleaner than competing with the image. */
@media (max-width:640px){
  #screen-reveal .reveal-bg img{
    object-fit:contain; object-position:50% 0%;
    transform:none; transition:none;
  }
  #screen-reveal .reveal-scrim{
    background:linear-gradient(180deg, rgba(8,10,14,0.05) 0%, rgba(8,10,14,0.15) 100%);
  }
  #screen-reveal .reveal-content{
    justify-content:flex-start;
    padding-top:calc(66.7vw + 40px);
  }
}
#screen-reveal .reveal-scrim{
  position:absolute; inset:0;
  background:linear-gradient(180deg, rgba(8,10,14,0.55) 0%, rgba(8,10,14,0.35) 40%, rgba(8,10,14,0.65) 100%);
}
#screen-reveal .reveal-content{
  position:relative; z-index:1; width:100%; height:100%;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  text-align:center; padding:24px;
}
#screen-reveal h1{font-family:var(--font-display); font-weight:400; font-size:clamp(34px,6vw,56px); margin-bottom:4px; color:#F5F1E8;}
#screen-reveal .line2{font-family:var(--font-label); font-size:13px; letter-spacing:3px; text-transform:uppercase; color:#E8E2D4; margin-bottom:22px;}
#screen-reveal .date{font-family:var(--font-mono); font-size:15px; letter-spacing:1px; color:#D9BE8F; margin-bottom:36px;}

/* ---------- Screen: video trailer ---------- */
#screen-video{ display:block; padding:0; overflow:hidden; background:#000; }
#screen-video .video-wrap{ position:absolute; inset:0; }
#screen-video video{ width:100%; height:100%; object-fit:cover; display:block; background:#000; }
/* The trailer was shot landscape. Holding a phone upright (portrait) and
   filling the screen edge-to-edge (cover) would crop out a lot of the
   actual footage — so in portrait we show the whole frame letterboxed
   instead, like a cinema trailer. Turn the phone sideways (landscape) and
   it naturally becomes true full-screen, since the shape now matches the
   video — guests effectively get the choice just by how they hold it. */
@media (max-width:900px) and (orientation:portrait){
  #screen-video video{ object-fit:contain; }
}

/* Fallback "tap for sound" pill — only shown by JS if the browser blocked
   unmuted autoplay and we had to fall back to a muted start. */
#video-sound-btn{
  position:absolute; left:24px; bottom:24px; z-index:6;
  display:none;
  background:rgba(0,0,0,0.45); border:1px solid rgba(244,241,234,0.5); color:#F4F1EA;
  font-family:var(--font-label); font-size:11px; letter-spacing:1.5px; text-transform:uppercase;
  padding:10px 16px; border-radius:20px; cursor:pointer;
}
#video-sound-btn.show{ display:block; }

/* the 30-second "keep watching or move on" prompt */
.video-choice{
  position:absolute; left:50%; bottom:40px; z-index:5;
  transform:translate(-50%,16px);
  text-align:center; max-width:92vw;
  background:rgba(10,12,14,0.74);
  border:1px solid rgba(244,241,234,0.18);
  border-radius:10px; padding:22px 30px;
  opacity:0; pointer-events:none;
  transition:opacity 0.4s ease, transform 0.4s ease;
}
.video-choice.show{ opacity:1; transform:translate(-50%,0); pointer-events:auto; }
.video-choice-text{
  font-family:var(--font-mono); font-size:13px; letter-spacing:0.5px; color:#F5F1E8; margin-bottom:16px;
}
.video-choice-actions{ display:flex; gap:14px; justify-content:center; flex-wrap:wrap; }
.btn-plain{
  background:none; border:none; cursor:pointer;
  font-family:var(--font-label); font-size:12px; letter-spacing:1.5px; text-transform:uppercase;
  color:#C9C4B8; text-decoration:underline; text-underline-offset:3px;
  padding:14px 4px;
}
.btn-plain:hover{ color:#F5F1E8; }
@media (max-width:640px){
  .video-choice{ bottom:24px; padding:18px 20px; }
  .video-choice-actions{ flex-direction:column; gap:10px; }
}

.final-stamp{
  position:fixed; inset:0; z-index:150; background:#F5F1E8;
  clip-path:circle(0% at 50% 50%);
  display:flex; align-items:center; justify-content:center;
}
.final-stamp.expand{ animation:stamp-wipe 0.9s cubic-bezier(.4,0,.2,1) forwards; }
@keyframes stamp-wipe{ to { clip-path:circle(150% at 50% 50%); } }

