/* ==========================================================================
   THE LAGOON LOUNGE — Pool day party · CARD (invitation)
   A lazy, splashy beach-club invitation: an ivory card floating on soft
   lagoon water, coral + teal accents, a sun-soaked timeline.
   --------------------------------------------------------------------------
   Tokens · Shell · Cards · Cover · Details · Media (photos/video/flyer) ·
   RSVP · Guestbook · Nav · Footer · A11y (reduced motion · print · no-JS)
   ========================================================================== */

/* ---------- 1. Tokens ---------- */
:root {
  /* palette */
  --ink:       #0c3f49;
  --ink-soft:  #39707b;
  --lagoon:    #17b3a3;
  --lagoon-soft: #9cdcd2;
  --aqua-bg:   #bfe9e1;
  --aqua-bg-2: #d9f2ec;
  --sand:      #fdf6ec;
  --sand-2:    #f3e7d3;
  --coral:     #ff6f61;
  --coral-soft:#ffb3a9;
  --gold:      #e9b44c;
  --white:     #ffffff;

  /* type */
  --font-head: "Arial Rounded MT Bold", "Avenir Next", "Helvetica Neue", "Segoe UI", sans-serif;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-script: "Snell Roundhand", "Brush Script MT", "Segoe Script", "Apple Chancery", cursive;

  /* layout */
  --nav-h: 72px;
  --safe-b: env(safe-area-inset-bottom, 0px);

  /* motion */
  --move-fast: 220ms ease;
  --move-slow: 650ms ease;

  /* elevation */
  --shadow-card: 0 20px 45px rgba(12, 63, 73, 0.16);
  --shadow-lift: 0 12px 26px rgba(12, 63, 73, 0.2);
}

/* ---------- 2. Reset & base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--aqua-bg);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, p, ul, ol, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
button { font: inherit; cursor: pointer; }
input, select, textarea { font: inherit; color: inherit; }

.script { font-family: var(--font-script); font-weight: 500; }

.is-hidden { display: none !important; }

/* ---------- 3. Accessibility helpers ---------- */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: fixed;
  top: -60px; left: 12px;
  z-index: 1000;
  padding: 12px 18px;
  background: var(--coral);
  color: #fff;
  font-weight: 700;
  text-decoration: none;
  border-radius: 0 0 12px 12px;
  transition: top var(--move-fast);
}
.skip-link:focus { top: 0; }

:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 3px;
  border-radius: 6px;
}

/* ---------- 4. Single-viewport shell ---------- */
.invite-shell {
  position: relative;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

.panel {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;

  visibility: hidden;
  opacity: 0;
  transform: translateY(26px) scale(0.99);
  transition:
    opacity var(--move-fast),
    transform var(--move-slow),
    visibility 0s linear var(--move-fast);
}
.panel.active {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition:
    opacity var(--move-fast),
    transform var(--move-slow);
}
.panel.pruned { display: none; }

/* soft water background behind the card */
.stage-bg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  background: linear-gradient(180deg, var(--aqua-bg) 0%, var(--aqua-bg-2) 60%, #cdeee7 100%);
}
.bg-sun {
  position: absolute;
  top: -12vh; right: -6vw;
  width: 46vmin; height: 46vmin;
  border-radius: 50%;
  background: radial-gradient(circle at 42% 42%, rgba(233, 180, 76, 0.9) 0%, rgba(233, 180, 76, 0.35) 40%, rgba(233, 180, 76, 0) 70%);
  animation: sun-breathe 8s ease-in-out infinite alternate;
}
.bg-sun-right { right: auto; left: -8vw; top: 8vh; }
@keyframes sun-breathe {
  from { transform: scale(1); opacity: 0.9; }
  to { transform: scale(1.08); opacity: 1; }
}
.bg-palms { position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: 30vh; }

/* ---------- 5. The card ---------- */
.card-scroll {
  position: relative;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: calc(24px + env(safe-area-inset-top, 0px)) 16px calc(var(--nav-h) + var(--safe-b) + 24px);
}

.invite-card {
  position: relative;
  width: min(680px, 100%);
  margin: 0 auto;
  background: var(--sand);
  border: 1px solid rgba(12, 63, 73, 0.08);
  border-radius: 28px;
  box-shadow: var(--shadow-card);
  padding: clamp(26px, 6vw, 48px);
  text-align: center;
  overflow: hidden;
}

.card-stripe {
  display: flex;
  gap: 7px;
  justify-content: center;
  margin: -4px 0 22px;
}
.card-stripe span {
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--coral);
}
.card-stripe span:nth-child(2n) { background: var(--gold); }
.card-stripe span:nth-child(3n) { background: var(--lagoon); }

.wave-divider { width: 120px; margin: 0 auto 18px; }

.card-kicker {
  font-size: clamp(1.9rem, 7vw, 2.8rem);
  color: var(--coral);
  line-height: 1.05;
  margin-bottom: 6px;
}

.cover-names {
  font-family: var(--font-head);
  font-size: clamp(2.1rem, 7.5vw, 3.4rem);
  line-height: 1.08;
  letter-spacing: 0.005em;
  color: var(--ink);
  margin-bottom: 10px;
}

.card-subtitle {
  font-size: clamp(1rem, 3.4vw, 1.2rem);
  color: var(--ink-soft);
  max-width: 30ch;
  margin: 0 auto 22px;
}
.sub-em { color: var(--lagoon); font-weight: 700; }

/* ---------- 5b. Cover photo (optional) ----------
   The cover leads with a SINGLE photo by design — one calm hero shot for a
   one-event party card; every extra photo lives in the Photos gallery.
   Replace the src or delete the whole .cover-photo <figure> to hide it.
   Clicking opens the full-screen viewer with zoom (main.js). */
.cover-photo { margin: 0 0 20px; position: relative; }
.cover-photo img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 2 / 1;
  object-fit: cover;
  border-radius: 18px;
  border: 1px solid rgba(12, 63, 73, 0.1);
  box-shadow: 0 12px 28px rgba(12, 63, 73, 0.16);
  background: var(--sand-2);
}

/* Small "View photo" chip on the cover — makes the clickable photo
   discoverable on touch screens (no hover there). Only exists when JS is on
   (no JS → no viewer → no chip). */
.cover-photo-btn {
  position: absolute;
  right: 12px;
  bottom: 12px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px;
  border: 1px solid rgba(12, 63, 73, 0.14);
  border-radius: 999px;
  background: rgba(253, 246, 236, 0.92);
  color: var(--ink);
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.04em;
  cursor: pointer;
  box-shadow: 0 8px 20px -10px rgba(12, 63, 73, 0.5);
  transition: transform var(--move-fast), box-shadow var(--move-fast);
}
.cover-photo-btn:hover { transform: translateY(-2px); }
.cover-photo-btn:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }
html:not(.js) .cover-photo-btn { display: none; }

/* Personalized guest greeting (platform `name` global, private share links) */
.guest-greeting {
  margin: 0 0 14px;
  font-family: var(--font-head);
  font-size: 1rem;
  font-weight: 800;
  color: var(--coral);
  letter-spacing: 0.02em;
}
.guest-greeting::before { content: "🌞 "; }

/* ---------- 6. Hosts (multiple profiles) ---------- */
.host-list {
  display: flex;
  justify-content: center;
  gap: 26px;
  flex-wrap: wrap;
  margin-bottom: 24px;
}
.host { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.host-avatar {
  display: grid;
  place-items: center;
  width: 58px; height: 58px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--lagoon), #0f7d74);
  color: #fff;
  font-family: var(--font-head);
  font-size: 1.35rem;
  border: 3px solid var(--sand-2);
  box-shadow: var(--shadow-lift);
}
.host-avatar.avatar-alt { background: linear-gradient(135deg, var(--coral), #e8545f); }
.host-name { font-weight: 700; font-size: 0.92rem; color: var(--ink); }

/* ---------- 7. Cover facts ---------- */
.card-facts { margin: 0 auto 26px; display: grid; gap: 14px; max-width: 340px; }
.fact {
  display: flex;
  align-items: center;
  gap: 14px;
  text-align: left;
  background: var(--white);
  border: 1px solid rgba(12, 63, 73, 0.08);
  border-radius: 18px;
  padding: 12px 18px;
  box-shadow: 0 8px 20px rgba(12, 63, 73, 0.08);
}
.fact dt svg { width: 22px; height: 22px; color: var(--coral); }
.fact dd p { line-height: 1.4; }
.event-date, .event-place { font-weight: 800; color: var(--ink); }
.event-time, .event-address { font-size: 0.92rem; color: var(--ink-soft); }

.card-foot {
  margin-top: 18px;
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}

/* ---------- 8. Shared type on inner cards ---------- */
.section-kicker {
  font-size: clamp(1.8rem, 6.5vw, 2.5rem);
  color: var(--coral);
  line-height: 1.05;
  margin-bottom: 6px;
}
.section-title {
  font-family: var(--font-head);
  font-size: clamp(1.7rem, 5.6vw, 2.6rem);
  line-height: 1.1;
  color: var(--ink);
  margin-bottom: 12px;
}
.media-lead {
  color: var(--ink-soft);
  max-width: 46ch;
  margin: 0 auto 22px;
  font-size: 0.96rem;
}

/* ---------- 9. Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border: 0;
  border-radius: 999px;
  padding: 15px 30px;
  min-height: 52px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 0.92rem;
  color: #fff;
  background: linear-gradient(120deg, var(--lagoon), #0f8f83);
  box-shadow: var(--shadow-lift);
  transition: transform var(--move-fast), box-shadow var(--move-fast), filter var(--move-fast);
}
.btn:hover { transform: translateY(-2px); filter: brightness(1.06); box-shadow: 0 16px 32px rgba(12, 63, 73, 0.26); }
.btn:active { transform: translateY(0); }
.btn-arrow { font-size: 1.05rem; line-height: 1; }
.btn-block { width: 100%; }
.btn-next { animation: bob 2.6s ease-in-out infinite; }
@keyframes bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(5px); }
}

/* ---------- 10. Details: timeline & mini cards ---------- */
.timeline {
  position: relative;
  margin: 24px 0 30px;
  display: grid;
  gap: 28px;
  text-align: left;
}
.timeline::before {
  content: "";
  position: absolute;
  top: 16px; bottom: 16px;
  width: 3px;
  border-radius: 3px;
  background: linear-gradient(180deg, var(--lagoon-soft), var(--coral-soft));
}
.timeline-item { position: relative; }

/* Time chip — shared pill shape; placement flips per breakpoint below.
   The dot (:after) always sits ON the spine, vertically centered on the
   chip, so it stays aligned no matter how the chip wraps or reflows. */
.tl-time {
  position: relative;
  display: inline-block;
  padding: 4px 13px;
  border-radius: 999px;
  background: var(--white);
  border: 1px solid rgba(12, 63, 73, 0.1);
  box-shadow: 0 5px 14px rgba(12, 63, 73, 0.1);
  font-weight: 800;
  font-size: 0.8rem;
  letter-spacing: 0.05em;
  color: var(--ink);
  z-index: 1;
}
.tl-time::after {
  content: "";
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 13px; height: 13px;
  border-radius: 50%;
  background: var(--coral);
  border: 3px solid var(--sand);
  box-shadow: 0 0 0 1px rgba(12, 63, 73, 0.08);
}
.timeline-item:nth-child(2) .tl-time::after { background: var(--gold); }
.timeline-item:nth-child(3) .tl-time::after { background: var(--lagoon); }
.timeline-item:nth-child(4) .tl-time::after { background: var(--coral-soft); }

.tl-body {
  background: var(--white);
  border: 1px solid rgba(12, 63, 73, 0.08);
  border-radius: 18px;
  padding: 14px 18px;
  box-shadow: 0 8px 20px rgba(12, 63, 73, 0.07);
  flex: 1;
}
.tl-title { font-size: 1rem; font-weight: 800; color: var(--ink); margin-bottom: 3px; }
.tl-text { font-size: 0.92rem; color: var(--ink-soft); }

.split-cards {
  display: grid;
  grid-template-columns: 1fr 1.4fr;
  gap: 14px;
  margin-bottom: 16px;
  text-align: left;
}
.mini-card {
  background: var(--white);
  border: 1px solid rgba(12, 63, 73, 0.08);
  border-radius: 18px;
  padding: 18px;
  box-shadow: 0 8px 20px rgba(12, 63, 73, 0.07);
}
.mini-title {
  font-size: 0.8rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--coral);
  margin-bottom: 10px;
}
.mini-title-gap { margin-top: 16px; color: var(--lagoon); }
.mini-text { font-size: 0.92rem; color: var(--ink-soft); }
.pack-list { display: grid; gap: 8px; }
.pack-item {
  position: relative;
  padding-left: 24px;
  font-size: 0.92rem;
  color: var(--ink);
}
.pack-item::before {
  content: "";
  position: absolute;
  left: 2px; top: 0.42em;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--lagoon-soft);
}
.pack-item:nth-child(2)::before { background: var(--coral-soft); }
.pack-item:nth-child(3)::before { background: var(--gold); }
.pack-item:nth-child(4)::before { background: var(--lagoon); }

.note-card {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  text-align: left;
  background: #fdf0d9;
  border: 1px solid rgba(233, 180, 76, 0.4);
  border-radius: 18px;
  padding: 16px 18px;
  margin-bottom: 22px;
}
.ico-note { width: 22px; height: 22px; color: #b98a24; flex: none; margin-top: 2px; }
.note-text { font-size: 0.92rem; color: #7a5f22; }

/* ---------- 10b. Flyer / banner (optional "Flyer" panel) ----------
   A wide 8:3 slot for hosts who already have a designed flyer or poster:
   display it so guests can confirm they're in the right place. Clicking
   opens the full-screen photo viewer (main.js). Delete the block to hide it. */
.banner-flyer { margin: 0 0 8px; }
.banner-flyer img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 8 / 3;
  object-fit: cover;
  padding: 5px;
  background: var(--sand-2);
  border: 1px solid rgba(12, 63, 73, 0.12);
  border-radius: 16px;
  box-shadow: 0 12px 26px -18px rgba(12, 63, 73, 0.4);
}
.banner-flyer figcaption {
  margin-top: 10px;
  font-size: 0.9rem;
  font-style: italic;
  color: var(--ink-soft);
}

/* ---------- 10c. Photos gallery (optional "Photos" panel) ----------
   The hosts' personal photos in a gentle 2-up grid. Placeholder SVGs ship
   in assets/img/ so the slot looks right out of the box. Clicking any tile
   opens the full-screen viewer with zoom + swipe. Delete the section to
   hide the whole gallery (the nav tab vanishes too). */
.moments-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
  margin-bottom: 8px;
}
.moments-photo { margin: 0; }
.moments-photo img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 14px;
  border: 1px solid rgba(12, 63, 73, 0.1);
  box-shadow: 0 8px 18px rgba(12, 63, 73, 0.14);
  background: var(--sand-2);
}
/* The last tile spans the full width — a wide "hero" shot to close the grid. */
.moments-photo:last-child { grid-column: 1 / -1; }
.moments-photo:last-child img { aspect-ratio: 2 / 1; }
.moments-photo figcaption {
  margin-top: 7px;
  text-align: center;
  font-size: 0.82rem;
  font-style: italic;
  color: var(--ink-soft);
}

/* ---------- 10d. Clickable photos: zoom-in cursor + "view" badge ----------
   Pure visual hints that a photo opens in the viewer (built by main.js
   only when photo slots exist, so hiding the photos removes the viewer too). */
html.js .cover-photo img,
html.js .moments-photo img,
html.js .banner-flyer img,
html.js .free-figure img { cursor: zoom-in; }

html.js .moments-photo, html.js .banner-flyer, html.js .free-figure { position: relative; }
html.js .moments-photo::after,
html.js .banner-flyer::after,
html.js .free-figure::after {
  content: "";
  position: absolute;
  top: 12px;
  right: 12px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: rgba(253, 246, 236, 0.95)
    url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230c3f49' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='M15.5 15.5L21 21'/%3E%3C/svg%3E")
    center / 16px no-repeat;
  border: 1px solid rgba(12, 63, 73, 0.14);
  box-shadow: 0 4px 12px -4px rgba(12, 63, 73, 0.4);
  opacity: 0;
  transform: translateY(-3px);
  transition: opacity var(--move-fast), transform var(--move-fast);
  pointer-events: none;
}
html.js .moments-photo:hover::after,
html.js .moments-photo:focus-within::after,
html.js .banner-flyer:hover::after,
html.js .banner-flyer:focus-within::after,
html.js .free-figure:hover::after,
html.js .free-figure:focus-within::after {
  opacity: 1;
  transform: none;
}

/* ---------- 10e. Photo viewer (full-screen, built by main.js) ----------
   Click ANY photo (cover hero, gallery tile, flyer banner) to view it
   full-screen and zoom. Click/tap the photo again (or use the zoom button,
   or +/- keys) to zoom to 200% and pan by scrolling; ←/→ or swipe move
   between photos in the same gallery; Esc closes. Focus-trapped; a missing
   photo file shows an on-palette note instead of a broken icon. */
.photo-viewer {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: none;
  align-items: center;
  justify-content: center;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
  background: rgba(12, 63, 73, 0.94);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
.photo-viewer.is-open { display: flex; }
.photo-viewer figure {
  margin: 0;
  max-width: min(92vw, 960px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  text-align: center;
}
/* Scrollable pan area — becomes the zoom surface when .is-zoomed. */
.photo-viewer .pv-scroll {
  max-width: 100%;
  max-height: 76vh;
  max-height: 76dvh;
  overflow: hidden;
  border-radius: 14px;
}
.photo-viewer img {
  display: block;
  max-width: 100%;
  max-height: 76vh;
  max-height: 76dvh;
  width: auto;
  height: auto;
  border: 6px solid var(--sand);
  border-radius: 14px;
  background: var(--sand-2); /* mat while loading / if the file is missing */
  box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.75);
}
/* Zoomed: photo grows to 200% and the frame scrolls to pan. */
.photo-viewer.is-zoomed .pv-scroll {
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
.photo-viewer.is-zoomed img {
  width: 200%;
  max-width: none;
  max-height: none;
  height: auto;
}
.photo-viewer figcaption {
  font-family: var(--font-head);
  font-size: 1.02rem;
  font-weight: 700;
  color: var(--sand);
}
.photo-viewer .pv-unavailable {
  display: flex;
  align-items: center;
  justify-content: center;
  width: min(72vw, 520px);
  height: min(46vh, 360px);
  padding: 20px;
  border: 6px solid var(--sand);
  border-radius: 14px;
  background: var(--sand-2);
  color: var(--ink-soft);
  font-size: 0.9rem;
  font-style: italic;
  text-align: center;
}

.pv-btn {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid rgba(12, 63, 73, 0.25);
  background: rgba(253, 246, 236, 0.95);
  color: var(--ink);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 10px 24px -12px rgba(0, 0, 0, 0.6);
  transition: transform var(--move-fast), background-color var(--move-fast);
}
.pv-btn:hover { transform: scale(1.06); background: #fff; }
.pv-close { top: calc(14px + env(safe-area-inset-top)); right: calc(14px + env(safe-area-inset-right)); }
.pv-zoom  { top: calc(14px + env(safe-area-inset-top)); left: calc(14px + env(safe-area-inset-left)); }
.pv-prev  { left: 12px;  top: 50%; transform: translateY(-50%); }
.pv-next  { right: 12px; top: 50%; transform: translateY(-50%); }
.pv-prev:hover, .pv-next:hover { transform: translateY(-50%) scale(1.06); }
.photo-viewer :focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

/* Narrow screens: prev/next drop below the photo so they never cover it. */
@media (max-width: 520px) {
  .photo-viewer { flex-direction: column; gap: 10px; }
  .photo-viewer .pv-scroll, .photo-viewer img { max-height: 62vh; max-height: 62dvh; }
  .photo-viewer.is-zoomed img { max-height: none; }
  .pv-prev, .pv-next { position: static; transform: none; }
  .pv-prev:hover, .pv-next:hover { transform: scale(1.06); }
  .pv-prev, .pv-next { width: 40px; height: 40px; }
  .photo-viewer figure { flex: 1 1 auto; justify-content: center; }
  .photo-viewer .pv-close { top: calc(10px + env(safe-area-inset-top)); right: calc(10px + env(safe-area-inset-right)); }
  .photo-viewer .pv-zoom { top: calc(10px + env(safe-area-inset-top)); left: calc(10px + env(safe-area-inset-left)); }
}

/* ---------- 10f. Optional video feature (film-card, "Video" panel) ----------
   A poster + play button that lazy-loads an iframe embed from the
   data-video-url attribute on .film-card — nothing loads until the guest
   taps play. Delete the .film-card (or its whole panel) to hide the feature. */
.film-card { margin-top: 2px; }

.film-frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  padding: 5px;
  border-radius: 16px;
  background: var(--sand-2);
  border: 1px solid rgba(12, 63, 73, 0.12);
  box-shadow: 0 12px 26px -18px rgba(12, 63, 73, 0.4);
  overflow: hidden;
}
.film-open {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  border-radius: 12px;
  overflow: hidden;
  background: var(--sand-2);
  cursor: pointer;
}
.film-open img { display: block; width: 100%; height: 100%; object-fit: cover; }
.film-open:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }

.film-play {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 66px;
  height: 66px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--sand);
  color: var(--ink);
  box-shadow: 0 8px 24px rgba(12, 63, 73, 0.35);
  animation: film-pulse 2.6s ease-in-out infinite;
}
.film-play svg { width: 26px; height: 26px; margin-left: 3px; }
.film-open:hover .film-play { transform: translate(-50%, -50%) scale(1.08); }

.film-hint {
  position: absolute;
  left: 50%;
  bottom: 14px;
  transform: translateX(-50%);
  padding: 6px 14px;
  border-radius: 999px;
  background: rgba(12, 63, 73, 0.6);
  color: var(--sand);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
}

.film-frame iframe {
  position: absolute;
  inset: 5px;
  width: calc(100% - 10px);
  height: calc(100% - 10px);
  border: 0;
  border-radius: 12px;
}

.film-note {
  margin: 0;
  padding: 18px 20px;
  border-radius: 12px;
  background: var(--sand-2);
  color: var(--ink-soft);
  font-size: 0.9rem;
  font-style: italic;
  text-align: center;
}

.film-external {
  display: inline-block;
  margin-top: 14px;
  font-size: 0.88rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1.5px solid transparent;
  transition: border-color var(--move-fast), color var(--move-fast);
}
.film-external:hover { color: var(--coral); border-color: var(--coral); }
.film-external[hidden] { display: none; }

@keyframes film-pulse {
  0%, 100% { box-shadow: 0 8px 24px rgba(12, 63, 73, 0.35), 0 0 0 0 rgba(255, 111, 97, 0.5); }
  50%      { box-shadow: 0 8px 24px rgba(12, 63, 73, 0.35), 0 0 0 16px rgba(255, 111, 97, 0); }
}

/* ---------- 10g. Free page (optional host-defined page) ----------
   Repeatable .free-block cards: a free title, free text and an OPTIONAL
   photo. The platform clones the first block per row the host adds; a
   block with no photo reads as title + text (main.js removes the empty
   figure). Leave every block empty (or toggle Free Page off in the
   cockpit) and the whole page — and its nav tab — disappears. */
.free-blocks {
  display: grid;
  gap: 18px;
  margin-top: 4px;
}
.free-block {
  background: var(--white);
  border: 1px solid rgba(12, 63, 73, 0.08);
  border-radius: 18px;
  padding: 22px;
  box-shadow: 0 8px 20px rgba(12, 63, 73, 0.07);
  text-align: left;
}
.free-title {
  font-family: var(--font-head);
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--ink);
  margin-bottom: 8px;
}
.free-content {
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--ink-soft);
  white-space: pre-line; /* host line breaks are kept */
}
.free-content p { margin: 0; }
.free-figure { margin: 16px 0 0; }
.free-figure img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 14px;
  border: 1px solid rgba(12, 63, 73, 0.1);
  box-shadow: 0 8px 18px rgba(12, 63, 73, 0.14);
  background: var(--sand-2);
}
.free-cap {
  margin-top: 7px;
  text-align: center;
  font-size: 0.82rem;
  font-style: italic;
  color: var(--ink-soft);
}

/* ---------- 11. RSVP ---------- */
/* Feature-toggle sections carry the wrapper class on the <section> itself
   (plus an inner wrapper for layout) so the whole panel — id and nav target
   — is stripped when RSVP / Guestbook are OFF (the engine removes every
   .rsvp-wrap / .guestbook-section element). These overrides neutralize the
   wrapper styles on the section so the .panel chrome is untouched; the
   inner wrapper still carries the real layout rules above/below. */
.panel.rsvp-wrap,
.panel.guestbook-section {
  position: absolute;
  inset: 0;
  min-height: 0;
  display: block;
  padding: 0;
}

.rsvp-wrap {
  position: relative;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: calc(24px + env(safe-area-inset-top, 0px)) 16px calc(var(--nav-h) + var(--safe-b) + 24px);
}

.rsvp-description {
  color: var(--ink-soft);
  max-width: 44ch;
  margin: 0 auto 24px;
  font-size: 0.98rem;
}
.rsvp-deadline { color: var(--coral); font-weight: 700; }

/* Optional RSVP deadline countdown — the platform fills the numbers; the
   whole block is hidden until main.js sees a real deadline. */
.rsvp-countdown { margin: 0 0 26px; text-align: center; }
.rsvp-countdown[hidden] { display: none; }
.countdown-label {
  margin: 0 0 10px;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink);
}
.countdown-boxes { display: flex; justify-content: center; gap: 10px; }
.count-box {
  flex: 0 0 66px;
  background: var(--ink);
  color: var(--sand);
  border-radius: 14px;
  padding: 10px 4px;
}
.count-box span {
  display: block;
  font-family: var(--font-head);
  font-weight: 800;
  font-size: 1.4rem;
  line-height: 1;
}
.count-box small {
  display: block;
  margin-top: 4px;
  font-size: 0.66rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(253, 246, 236, 0.7);
}

.rsvp-form { display: grid; gap: 16px; text-align: left; }

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

.form-group { display: grid; gap: 7px; }
.form-group label { font-weight: 700; font-size: 0.9rem; color: var(--ink); }
.req { color: var(--coral); }
.opt-tag {
  font-weight: 600;
  font-size: 0.76rem;
  color: var(--ink-soft);
  background: var(--sand-2);
  border-radius: 999px;
  padding: 2px 10px;
  margin-left: 6px;
}
.field-hint, .contact-hint { font-size: 0.82rem; color: var(--ink-soft); }
.contact-hint { margin-top: -6px; }

.form-group input[type="text"],
.form-group input[type="email"],
.form-group input[type="tel"],
.form-group input[type="number"],
.form-group select,
.form-group textarea {
  width: 100%;
  border: 2px solid #e4ddd0;
  border-radius: 14px;
  background: var(--white);
  padding: 13px 15px;
  min-height: 50px;
  transition: border-color var(--move-fast), box-shadow var(--move-fast);
}
.form-group textarea { min-height: 84px; resize: vertical; }
.form-group select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 9l6 6 6-6' fill='none' stroke='%230c3f49' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 18px;
  padding-right: 42px;
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  outline: none;
  border-color: var(--lagoon);
  box-shadow: 0 0 0 4px rgba(23, 179, 163, 0.2);
}

/* platform validation states */
.error {
  display: none;
  color: #d7263d;
  font-size: 0.84rem;
  font-weight: 600;
}
.error:not(:empty) { display: block; }
.form-group .has-error,
.form-group input.has-error,
.form-group select.has-error,
.form-group textarea.has-error {
  border-color: #d7263d;
  box-shadow: 0 0 0 4px rgba(215, 38, 61, 0.13);
}

.btn-submit {
  width: 100%;
  background: linear-gradient(120deg, var(--coral), #e8545f);
  margin-top: 4px;
}

.loading {
  display: none;
  text-align: center;
  font-weight: 700;
  color: var(--ink-soft);
  padding: 8px 0;
}
.loading::before {
  content: "";
  display: inline-block;
  width: 18px; height: 18px;
  margin-right: 10px;
  vertical-align: -3px;
  border-radius: 50%;
  border: 3px solid var(--lagoon-soft);
  border-top-color: var(--lagoon);
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- 12. Guestbook ---------- */
.guestbook-section {
  position: relative;
  min-height: 100%;
  display: grid;
  gap: 18px;
  align-content: center;
  padding: calc(24px + env(safe-area-inset-top, 0px)) 16px calc(var(--nav-h) + var(--safe-b) + 24px);
}
.guestbook-description {
  color: var(--ink-soft);
  max-width: 44ch;
  margin: 0 auto;
  font-size: 0.96rem;
}

.guestbook-card { padding: clamp(20px, 4vw, 34px); text-align: left; }

/* the platform injects its form + list into .guestbook-body — style it to match */
.guestbook-body #guestbookForm { display: grid; gap: 14px; }
.guestbook-body input,
.guestbook-body textarea {
  width: 100%;
  border: 2px solid #e4ddd0;
  border-radius: 14px;
  background: var(--white);
  padding: 13px 15px;
  font: inherit;
  color: inherit;
}
.guestbook-body input:focus,
.guestbook-body textarea:focus {
  outline: none;
  border-color: var(--lagoon);
  box-shadow: 0 0 0 4px rgba(23, 179, 163, 0.2);
}
.guestbook-body button[type="submit"] {
  border: 0;
  border-radius: 999px;
  padding: 15px 28px;
  min-height: 50px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #fff;
  background: linear-gradient(120deg, var(--lagoon), #0f8f83);
  cursor: pointer;
}
.guestbook-body .error:not(:empty) { display: block; }

.guestbook-wrap { display: grid; gap: 12px; margin-top: 18px; }
.guestbook-entry {
  background: var(--white);
  border: 1px solid #e4ddd0;
  border-radius: 16px;
  padding: 14px 18px;
}
.guestbook-entry h5 { margin: 0 0 4px; font-size: 0.96rem; color: var(--ink); }
.guestbook-entry p { margin: 0 0 6px; font-size: 0.94rem; color: var(--ink); }
.guestbook-entry small { color: var(--ink-soft); font-size: 0.8rem; }

.more-guestbook-wrap { text-align: center; margin-top: 16px; }
#load-more {
  border: 2px solid var(--lagoon);
  border-radius: 999px;
  padding: 12px 26px;
  font-weight: 700;
  color: var(--ink);
  background: var(--white);
  cursor: pointer;
}

/* ---------- 13. Navigation chrome: TEXT tabs + prev/next ----------
   A fixed bottom bar. The middle is a list of TEXT tab buttons (label +
   icon) built by main.js from the panels that actually have content, so
   navigation is always easy to spot and operate. Sections the platform
   strips (or the host deletes) vanish from the bar too. The prev/next
   arrows keep the card's page-turn feel; on phones the tab list scrolls
   horizontally and tap targets stay comfortably large. */
.page-nav {
  position: fixed;
  left: 0; right: 0;
  bottom: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 10px calc(10px + var(--safe-b));
  background: rgba(12, 63, 73, 0.88);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}

.nav-btn {
  display: grid;
  place-items: center;
  flex: none;
  width: 46px; height: 46px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.28);
  background: transparent;
  color: #fff;
  transition: background var(--move-fast), border-color var(--move-fast), opacity var(--move-fast);
}
.nav-btn svg { width: 20px; height: 20px; }
.nav-btn:hover:not(:disabled) { background: rgba(255, 255, 255, 0.12); border-color: var(--gold); }
.nav-btn:disabled { opacity: 0.35; cursor: default; }

/* scrollable tab list between the arrows (edge fade hints at more tabs) */
.nav-tabs {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 1;
  min-width: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 10px, #000 calc(100% - 10px), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 10px, #000 calc(100% - 10px), transparent 100%);
}
.nav-tabs::-webkit-scrollbar { display: none; }
.nav-tabs:empty { display: none; }

.nav-tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 42px;
  padding: 10px 15px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: rgba(255, 255, 255, 0.82);
  font: inherit;
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: 0.03em;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--move-fast), color var(--move-fast);
  -webkit-tap-highlight-color: transparent;
}
.nav-tab svg { width: 15px; height: 15px; flex: none; opacity: 0.9; }
.nav-tab:hover { background: rgba(255, 255, 255, 0.14); }
.nav-tab[aria-current="true"] {
  background: var(--gold);
  color: var(--ink);
  box-shadow: 0 6px 18px -6px rgba(233, 180, 76, 0.7);
}
.nav-tab:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* ---------- 13b. Brand footer (tucked into the last panel by main.js) ---- */
.app-footer {
  margin-top: 34px;
  padding: 20px 0 0;
  border-top: 1px solid rgba(12, 63, 73, 0.12);
  text-align: center;
}
.app-footer .footer-brand {
  margin: 0 0 10px;
  font-family: var(--font-head);
  font-weight: 800;
  font-size: 1.15rem;
  color: var(--ink);
}
.app-footer .footer-brand-name { color: var(--lagoon); }
.app-footer .foot-meta {
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  font-size: 0.82rem;
  color: var(--ink-soft);
}
.footer-line { font-size: 0.82rem; color: var(--ink-soft); }

/* ---------- 13c. Powered by Kundangi (full-width brand strip) --------
   A slim, full-width "Powered by Kundangi" line. The engine swaps the
   literal Kundangi token inside .link-footer for the platform name at
   render; the cockpit's Free Powered By field can override the whole
   line. main.js tucks the strip into the last panel that exists, right
   after the footer brand. */
.powered-by {
  width: 100%;
  margin-top: 22px;
  padding: 14px 16px calc(14px + var(--safe-b));
  border-top: 1px solid rgba(12, 63, 73, 0.12);
  background: rgba(12, 63, 73, 0.06);
  text-align: center;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.powered-by .link-footer {
  font-weight: 800;
  color: var(--lagoon);
}

/* ---------- 14. No-JS fallback: stacked panels ---------- */
.no-js .invite-shell { height: auto; overflow: visible; }
.no-js .panel {
  position: static;
  visibility: visible;
  opacity: 1;
  transform: none;
  overflow: visible;
  min-height: 100vh;
  min-height: 100dvh;
}
.no-js .page-nav { display: none; }
.no-js .skip-link { display: none; }

/* ---------- 15. Responsive tweaks ---------- */
@media (min-width: 601px) {
  /* Desktop: alternate the cards around a center spine. Each card keeps
     the full column width; the time chip straddles the spine with its dot
     pinned exactly on the line (column-gap 72px = 2 × chip overhang 36px,
     so the chip edge meets the spine at 50%). */
  .timeline {
    grid-template-columns: 1fr 1fr;
    column-gap: 72px;
    padding: 10px 0 4px;
  }
  .timeline::before { left: 50%; transform: translateX(-50%); }
  /* padding-top parks the chip in the row's own vertical space, above the
     card, so long time labels never cover the card content */
  .timeline-item { grid-column: 1; justify-self: end; width: 100%; padding-top: 38px; }
  .timeline-item:nth-child(even) { grid-column: 2; justify-self: start; }

  .tl-time { position: absolute; top: 4px; right: -36px; white-space: nowrap; }
  .timeline-item:nth-child(even) .tl-time { right: auto; left: -36px; }
  /* 13px dot + 1px chip border: -7.5px centers the dot on the chip edge,
     which sits exactly on the spine */
  .tl-time::after { left: auto; right: -7.5px; }
  .timeline-item:nth-child(even) .tl-time::after { right: auto; left: -7.5px; }
}

@media (max-width: 600px) {
  .split-cards { grid-template-columns: 1fr; }
  .form-row { grid-template-columns: 1fr; }
  /* Mobile: single left rail — chip + dot on the line, card below at
     full width. The rail is 13px in; 44px padding keeps cards roomy. */
  .timeline { padding: 6px 0 2px; }
  .timeline::before { left: 13px; }
  .timeline-item { padding-left: 44px; }
  .tl-time { margin-bottom: 10px; padding: 4px 12px; font-size: 0.76rem; }
  .tl-time::after { left: -38.4px; }
  .invite-card { border-radius: 22px; }
  .nav-btn { width: 44px; height: 44px; }
}

@media (max-height: 640px) {
  .card-scroll, .rsvp-wrap, .guestbook-section { justify-content: flex-start; }
}

/* ---------- 16. Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001s !important;
  }
  .panel { transition: none; }
  .bg-sun, .btn-next, .film-play { animation: none; }
  .btn:hover { transform: none; }
  html { scroll-behavior: auto; }
}

/* ---------- 17. Print: show every panel, one page each ---------- */
@page { margin: 12mm; }

@media print {
  .invite-shell { height: auto; overflow: visible; display: block; }
  .panel {
    position: static;
    visibility: visible;
    opacity: 1;
    transform: none;
    overflow: visible;
    min-height: 0;
    height: auto;
    page-break-after: always;
    break-after: page;
  }
  .panel.active { transition: none; }
  .card-scroll, .rsvp-wrap, .guestbook-section {
    justify-content: flex-start;
    padding: 0;
  }
  .invite-card { box-shadow: none; width: 100%; }
  .page-nav, .skip-link, .bg-sun, .cover-photo-btn, .photo-viewer, .powered-by { display: none !important; }
  .free-block, .free-figure { page-break-inside: avoid; }
  .film-frame iframe { display: none; } /* a playing video can't print — the poster prints instead */
  body { background: #fff; }
  .card-stripe, .invite-card { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}
