/* ═══════════════════════════════════════════════════════════════════════
   CARD-SCREEN — greeting card, cover first · styles.css
   A warm paper card with a fine double gold border, script names
   (Great Vibes), serif body (Cormorant Garamond). The cover is its own
   full page; a bottom tab bar (Cover · The Card · RSVP · Guestbook) turns
   the card over in place.
   ─────────────────────────────────────────────────────────────────────────
   Conventions:
     · The whole shell is gated behind html.js — no-JS visitors get a normal
       stacked, scrollable document with every panel readable in order.
     · Only the ACTIVE panel scrolls (100dvh app shell).
     · prefers-reduced-motion and @media print are supported.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Design tokens ─────────────────────────────────────────────────────── */
:root {
  --paper: #e9e2d6;
  --paper-2: #f6f2ea;
  --card: #fdfbf7;
  --ink: #3a342c;
  --ink-soft: #5c554a;
  --muted: #948b7c;
  --line: #e3dcca;
  --gold: #b08a52;
  --gold-soft: #caa86b;
  --gold-line: rgba(176, 138, 82, 0.45);
  --error: #a94442;
  --radius: 16px;
  --font-script: "Great Vibes", "Segoe Script", cursive;
  --font-serif: "Cormorant Garamond", Georgia, serif;
  --font-sans: "Jost", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

/* ── Base / reset ──────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
  background:
    radial-gradient(90% 70% at 50% 0%, #f2ecdf, transparent 65%),
    var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg { max-width: 100%; vertical-align: middle; }
button { font: inherit; }
[hidden] { display: none !important; } /* keep the hidden attr reliable next to display-* utilities */
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; border: 0; overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap;
}
:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
::selection { background: rgba(176, 138, 82, 0.3); }

/* ── No-JS fallback: ordinary stacked document, everything readable ────── */
.app { min-height: 100vh; }
.shell-head, .shell-nav { display: none; }
.shell-body { display: block; }
.panel { padding: 18px 14px 36px; }
.card {
  width: min(600px, 100%);
  margin: 0 auto;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 18px;
  box-shadow: 0 24px 60px rgba(80, 60, 30, 0.16);
  position: relative;
}
.card::before {
  content: "";
  position: absolute;
  inset: 8px;
  border: 1px solid var(--gold-line);
  border-radius: 12px;
  pointer-events: none;
  z-index: 2;
}
.card-inner {
  padding: clamp(26px, 5vmin, 44px) clamp(18px, 4.5vmin, 38px) clamp(32px, 6vmin, 52px);
  text-align: center;
}

/* ── JS shell: single-viewport 100dvh app, only the active panel scrolls ── */
html.js body {
  height: 100vh; height: 100dvh;
  overflow: hidden;
}
html.js .app {
  height: 100vh; height: 100dvh;
  display: flex; flex-direction: column;
  background:
    radial-gradient(90% 70% at 50% 0%, #f2ecdf, transparent 65%),
    var(--paper);
}
html.js .shell-head {
  display: flex; align-items: center; gap: 10px;
  flex: 0 0 auto;
  padding: calc(8px + env(safe-area-inset-top)) 14px 8px;
  border-bottom: 1px solid var(--line);
  background: rgba(246, 242, 234, 0.85);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
html.js .shell-body {
  flex: 1 1 auto; min-height: 0; position: relative;
}
html.js .panel {
  position: absolute; inset: 0;
  display: none;
  overflow-y: auto; overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 12px;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
html.js .panel::-webkit-scrollbar { width: 8px; }
html.js .panel::-webkit-scrollbar-thumb { background: var(--line); border-radius: 4px; }
html.js .panel::-webkit-scrollbar-track { background: transparent; }
html.js .panel.is-active { display: block; }
html.js .card {
  height: auto; /* the card grows with its content so the frame never clips */
  min-height: 100%; /* short content still fills the viewport */
}
html.js .card--cover {
  height: auto; /* grow if the cover's content is a hair taller than the viewport */
  min-height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
html.js .card-inner {
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
}

/* ── App header ────────────────────────────────────────────────────────── */
.head-brand { display: inline-flex; align-items: center; }
.head-monogram {
  font-family: var(--font-script);
  font-size: 21px;
  color: var(--gold);
  line-height: 1;
}
.head-amp { font-family: var(--font-sans); font-style: italic; font-size: 12px; color: var(--gold-soft); padding: 0 2px; }
.head-title {
  flex: 1 1 auto; min-width: 0;
  font-size: 11px; letter-spacing: 0.28em;
  text-transform: uppercase; color: var(--muted);
  font-family: var(--font-sans);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.head-btn {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--gold-line); border-radius: 999px;
  background: transparent; color: var(--ink-soft);
  font-family: var(--font-sans);
  font-size: 12px; letter-spacing: 0.06em;
  padding: 6px 12px; cursor: pointer;
  transition: background-color 0.2s, color 0.2s;
}
.head-btn svg { width: 15px; height: 15px; }
.head-btn:hover { background: var(--gold); border-color: var(--gold); color: #fff; }

/* ── Cover page (its own full screen) ──────────────────────────────────── */
.cover__guest {
  margin: 0 0 10px;
  font-size: 15px;
  font-style: italic;
  color: var(--gold);
}

/* Optional hero photo (arch portrait — the single cover image for a couple).
   Framed like a printed photo insert; clicking opens the full-screen viewer.
   Sized by vh on wide screens (so the cover always fits one page) and by vw
   on portrait phones (where width is the binding constraint). */
.cover__photo {
  margin: 0 auto clamp(14px, 2.6vmin, 18px);
  width: clamp(150px, min(44vw, 28vh), 280px);
  display: flex;
  justify-content: center;
}
.cover__photo img {
  width: 100%;
  height: auto; /* beats the width/height attribute hints — aspect-ratio sets the height */
  aspect-ratio: 4 / 5;
  object-fit: cover;
  display: block;
  padding: 5px;
  background: var(--card);
  border: 1px solid var(--gold-line);
  border-radius: 999px 999px 14px 14px;
  box-shadow: 0 14px 30px -16px rgba(80, 60, 30, 0.45);
}

.cover__kicker {
  margin: 0 0 6px;
  font-size: 11px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  font-family: var(--font-sans);
  color: var(--muted);
}

.cover__names {
  margin: 0;
  font-family: var(--font-script);
  font-weight: 400;
  font-size: clamp(38px, 8vh, 62px);
  line-height: 1.05;
  color: var(--ink);
  text-align: center;
  overflow-wrap: anywhere;
}

.cover__name--first,
.cover__name--last {
  display: inline;
}

.cover__amp {
  color: var(--gold);
  font-size: 0.8em;
}

.cover__request {
  margin: 8px 0 0;
  font-size: 13px;
  font-style: italic;
  color: var(--ink-soft);
  line-height: 1.5;
}

.ornament {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  color: var(--gold);
  margin: 10px 0;
  font-size: 13px;
}

.ornament span:not(:nth-child(2)) {
  width: 34px;
  height: 1px;
  background: var(--line);
}

.cover__date {
  margin: 0;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-soft);
}

.cover__date em {
  font-style: italic;
  color: var(--muted);
}

.cover__place {
  margin: 6px 0 0;
  font-size: 13px;
  letter-spacing: 0.06em;
  font-family: var(--font-sans);
  color: var(--muted);
}

.cover__cta-wrap {
  margin-top: clamp(16px, 3vmin, 22px);
  display: flex;
  justify-content: center;
}

/* The primary "Open the invitation" action — a touch larger than the
   inline buttons so it reads as the one thing to do on the cover. */
.cover__cta {
  padding: 13px 26px;
  font-size: 13px;
}

.cover__cta svg { width: 16px; height: 16px; }

/* ── Shared panel typography ───────────────────────────────────────────── */
.panel-head {
  margin-bottom: clamp(20px, 3.6vmin, 30px);
}
.eyebrow {
  margin: 0 0 6px;
  font-size: 11px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  font-family: var(--font-sans);
  color: var(--gold);
}
.panel-title,
.rsvp-title,
.guestbook-title {
  margin: 0 0 10px;
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(28px, 6vmin, 36px);
  line-height: 1.1;
  color: var(--ink);
}
.panel-title:focus,
.rsvp-title:focus,
.guestbook-title:focus { outline: none; }
.lede {
  margin: 0 auto;
  max-width: 30em;
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink-soft);
}

/* ── The Card panel ────────────────────────────────────────────────────── */
.verse {
  font-family: var(--font-script);
  font-size: 24px;
  line-height: 1.3;
  color: var(--gold);
  margin: 0 0 22px;
}

.verse em { font-style: italic; }

/* Optional official flyer / banner — a wide framed image for hosts who
   already have a designed flyer or poster, so guests can confirm they're in
   the right place. Clicking it opens the full-screen viewer. */
.banner-flyer {
  margin: 0 0 clamp(26px, 5vmin, 38px);
  max-width: 620px;
  margin-inline: auto;
}
.banner-flyer img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 8 / 3;
  object-fit: cover;
  padding: 6px;
  background: var(--card);
  border: 1px solid var(--gold-line);
  border-radius: 10px;
  box-shadow: 0 14px 30px -22px rgba(80, 60, 30, 0.5);
}
.banner-flyer figcaption {
  margin-top: 8px;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 14px;
  color: var(--muted);
}

/* Optional "Our favourite moments" gallery (The Card panel) */
.story-gallery {
  margin-bottom: clamp(26px, 5vmin, 38px);
}

.gallery-label {
  margin: 0 0 14px;
  font-size: 11px;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  font-family: var(--font-sans);
  color: var(--gold);
}

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}

.gallery-item { margin: 0; }

.gallery-item img {
  display: block;
  width: 100%;
  height: auto; /* beats the width/height attribute hints — aspect-ratio sets the height */
  aspect-ratio: 4 / 5;
  object-fit: cover;
  padding: 4px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 8px 20px -14px rgba(80, 60, 30, 0.35);
  transition: transform 0.2s, border-color 0.2s, box-shadow 0.2s;
}

.gallery-item img:hover {
  transform: translateY(-2px);
  border-color: var(--gold-soft);
  box-shadow: 0 12px 26px -14px rgba(80, 60, 30, 0.5);
}

.gallery-item figcaption {
  margin-top: 7px;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 14px;
  color: var(--muted);
}

/* Optional film feature — a poster + play button that lazy-loads an
   <iframe> from the URL in data-video-url (YouTube / Vimeo / any embeddable
   URL). Nothing loads until the guest taps play — fast, consent-friendly. */
.film-card {
  margin-bottom: clamp(26px, 5vmin, 38px);
}
.film-frame {
  position: relative;
  width: 100%;
  max-width: 620px;
  margin: 14px auto 0;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: 12px;
  background: var(--paper-2); /* mat behind the poster / while loading */
  border: 1px solid var(--gold-line);
  box-shadow: 0 16px 34px -24px rgba(80, 60, 30, 0.5);
}
.film-open {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  padding: 0; border: 0; background: none;
  cursor: pointer;
}
.film-open img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.film-play {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: clamp(52px, 11vmin, 68px); height: clamp(52px, 11vmin, 68px);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--ink);
  background: radial-gradient(circle at 32% 28%, #fffdf7, var(--card) 60%, var(--paper-2));
  border: 1px solid var(--gold-line);
  box-shadow: 0 12px 28px -12px rgba(80, 60, 30, 0.65);
  animation: film-pulse 2.6s ease-in-out infinite;
  transition: transform 0.25s;
}
.film-play svg { width: 24px; height: 24px; margin-left: 3px; }
.film-open:hover .film-play { transform: translate(-50%, -50%) scale(1.08); }
.film-open:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.film-hint {
  position: absolute; left: 50%; bottom: 14px;
  transform: translateX(-50%);
  padding: 6px 14px;
  border-radius: 999px;
  background: rgba(58, 52, 44, 0.62);
  color: var(--paper-2);
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  font-family: var(--font-sans);
  pointer-events: none;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
.film-frame iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0;
}
.film-note {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  margin: 0; padding: 0 18px;
  color: var(--muted);
  font-size: 13.5px; font-style: italic; text-align: center;
  background: var(--paper-2);
}
.film-external {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 14px;
  font-size: 11.5px; letter-spacing: 0.14em; text-transform: uppercase;
  font-family: var(--font-sans);
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 1px solid var(--gold-line);
  padding-bottom: 2px;
  transition: color 0.2s, border-color 0.2s;
}
.film-external:hover { color: var(--gold); border-color: var(--gold); }
.film-external[hidden] { display: none; }
@keyframes film-pulse {
  0%, 100% { box-shadow: 0 12px 28px -12px rgba(80, 60, 30, 0.65), 0 0 0 0 rgba(176, 138, 82, 0.35); }
  50% { box-shadow: 0 12px 28px -12px rgba(80, 60, 30, 0.65), 0 0 0 14px rgba(176, 138, 82, 0); }
}

/* Schedule facts */
.facts {
  margin: 0 auto clamp(22px, 4vmin, 30px);
  max-width: 30em;
  border-top: 1px solid var(--line);
}

.fact {
  padding: 13px 0;
  border-bottom: 1px solid var(--line);
}

.fact dt {
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  font-family: var(--font-sans);
  color: var(--gold);
  margin-bottom: 4px;
}

.fact dd {
  margin: 0;
  font-size: 16px;
  line-height: 1.45;
}

.fact .fact__place {
  font-family: var(--font-sans);
  font-size: 12px;
  color: var(--muted);
  margin-top: 2px;
}

/* Actions: directions / calendar / copy link */
.actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-bottom: 16px;
}

.note__reply {
  margin: 0;
  font-size: 13px;
  color: var(--muted);
  font-family: var(--font-sans);
}

/* ── Buttons ───────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  appearance: none;
  border: 1px solid var(--gold);
  background: var(--gold);
  color: #fff;
  font-family: var(--font-sans);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 10px 18px;
  border-radius: 999px;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.2s, color 0.2s, transform 0.15s;
}

.btn:hover { background: var(--gold-soft); border-color: var(--gold-soft); }
.btn:active { transform: scale(0.98); }

.btn svg { width: 14px; height: 14px; }

.btn--ghost {
  background: transparent;
  color: var(--gold);
  border-color: var(--line);
}

.btn--ghost:hover {
  background: var(--gold);
  border-color: var(--gold);
  color: #fff;
}

.btn--block { width: 100%; justify-content: center; }

/* ── RSVP form (platform contract) ─────────────────────────────────────── */
.rsvp-head { margin-bottom: 18px; }

.rsvp-description,
.guestbook-description {
  margin: 0 auto 16px;
  max-width: 30em;
  font-size: 14px;
  line-height: 1.6;
  color: var(--muted);
  font-family: var(--font-sans);
}

.rsvp-form-display {
  max-width: 26em;
  margin: 0 auto;
  text-align: left;
}

.form-group {
  margin-bottom: 14px;
}

.form-group label {
  display: block;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-family: var(--font-sans);
  color: var(--muted);
  margin-bottom: 6px;
}

.form-control {
  width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 15px;
  transition: border-color 0.2s, box-shadow 0.2s;
  appearance: none;
  -webkit-appearance: none;
}

.form-control::placeholder { color: #c0b8a8; }

.form-control:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(176, 138, 82, 0.18);
}

select.form-control {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b08a52' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 16px;
  padding-right: 40px;
}

textarea.form-control { resize: vertical; }

.error {
  display: block;
  color: var(--error);
  font-size: 12px;
  margin-top: 4px;
}

.form-submit { margin-top: 4px; }

.loading,
.loading-guestbook {
  color: var(--muted);
  font-size: 13px;
  text-align: center;
  padding: 10px 0;
  font-family: var(--font-sans);
}

/* Attending = "No": gently dim the guest count (visual UX only — the
   platform still owns validation + submission). */
.form-group.is-dimmed {
  opacity: 0.45;
  filter: grayscale(0.5);
  transition: opacity 0.25s, filter 0.25s;
}

/* ── RSVP countdown-inline (only shown when platform sets a deadline) ── */
.countdown-inline {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  font-size: 13px;
  color: var(--ink-soft);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 8px 16px;
  margin-bottom: 4px;
  font-family: var(--font-sans);
}

.countdown-inline span:first-child {
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 11px;
  color: var(--muted);
  margin-right: 6px;
}

.countdown-inline .count-day,
.countdown-inline .count-hour,
.countdown-inline .count-minute,
.countdown-inline .count-second {
  font-family: var(--font-serif);
  font-size: 19px;
  color: var(--gold);
}

/* ── Guestbook (injected platform markup) ──────────────────────────────── */
.guestbook-head { margin-bottom: 18px; }
.guestbook-body { max-width: 26em; margin: 0 auto; text-align: left; }

#guestbookForm .form-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 14px;
}

#guestbookForm textarea.form-control { min-height: 84px; }

#guestbookForm .d-flex { display: flex; justify-content: center; }

#guestbookForm button[type="submit"] {
  appearance: none;
  border: 1px solid var(--gold);
  background: var(--gold);
  color: #fff;
  font-family: var(--font-sans);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 10px 22px;
  border-radius: 999px;
  cursor: pointer;
}

#guestbookForm button[type="submit"]:hover { background: var(--gold-soft); }

.guestbook-chapta { display: flex; justify-content: center; margin: 10px 0; }

#comments-container.guestbook-wrap {
  margin-top: 22px;
  border-top: 1px solid var(--line);
  padding-top: 6px;
}

.guestbook-entry {
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
}

.guestbook-entry:last-child { border-bottom: 0; }

.guestbook-entry h5 {
  margin: 0 0 4px;
  font-family: var(--font-serif);
  font-size: 18px;
  font-weight: 500;
  color: var(--ink);
}

.guestbook-entry p {
  margin: 0 0 4px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-soft);
  font-family: var(--font-sans);
  overflow-wrap: anywhere;
}

.guestbook-entry small {
  color: var(--muted);
  font-size: 11px;
  letter-spacing: 0.06em;
  font-family: var(--font-sans);
}

.more-guestbook-wrap {
  display: flex;
  justify-content: center;
  padding: 16px 0 4px;
}

#load-more {
  appearance: none;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink-soft);
  font-family: var(--font-sans);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 9px 20px;
  border-radius: 999px;
  cursor: pointer;
}

#load-more:hover { border-color: var(--gold); color: var(--ink); }

.thank-you-message { text-align: center; padding: 20px 0; }

.thank-you-message h3,
.thank-you-message h4 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 26px;
  margin: 0 0 6px;
  color: var(--gold);
}

.thank-you-message p {
  color: var(--muted);
  font-size: 13px;
  margin: 2px 0;
  font-family: var(--font-sans);
}

/* ── Free page (optional "In Our Words" panel, host-filled) ──────────────
   One repeatable block per entry: title + free text + OPTIONAL photo. The
   render engine removes the whole section when no blocks exist (or when the
   host toggles the section off), so the tab that main.js builds from this
   panel disappears with it. */
.free-blocks {
  display: grid;
  gap: clamp(30px, 6vmin, 48px);
}
.free-block { margin: 0; text-align: center; }
.free-title {
  margin: 0 0 clamp(14px, 3vmin, 20px);
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(24px, 5.5vmin, 32px);
  line-height: 1.15;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.free-title:focus { outline: none; }
.free-media {
  margin: 0 auto clamp(14px, 3vmin, 20px);
  max-width: 560px;
}
.free-media img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  padding: 5px;
  background: var(--card);
  border: 1px solid var(--gold-line);
  border-radius: 10px;
  box-shadow: 0 12px 26px -18px rgba(80, 60, 30, 0.45);
}
.free-content {
  margin: 0 auto;
  max-width: 30em;
  text-align: left;
  font-size: clamp(14px, 3.3vmin, 16.5px);
  line-height: 1.75;
  color: var(--ink-soft);
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* ── Brand footer (placeholder) ───────────────────────────────────────────
   No-JS: a plain closing line at the end of the stacked document. JS shell:
   hidden where it starts (after </main>), then initFooter() tucks it into
   the last existing panel so it reads as the invitation's closing line —
   even when RSVP / Guestbook are stripped. */
html:not(.js) .app-footer { display: block; padding: 22px 18px 40px; text-align: center; }
html.js .app-footer { display: none; }
html.js .panel .app-footer {
  display: block;
  margin-top: clamp(26px, 5vmin, 40px);
  padding-top: 16px;
  border-top: 1px solid var(--line);
}
.footer-brand {
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  font-family: var(--font-sans);
  color: var(--muted);
}
.footer-brand-name {
  font-family: var(--font-script);
  font-size: 1.3em;
  text-transform: none;
  letter-spacing: 0.02em;
  color: var(--gold);
}

/* ── Full-width powered-by brand strip ────────────────────────────────────
   A slim, full-width footer line pinned above the tab bar in the JS shell
   (and at the end of the stacked document without JS). The engine swaps the
   literal brand token inside .link-footer for the platform name at render. */
html:not(.js) .powered-by {
  width: 100%;
  text-align: center;
  padding: 14px 16px 22px;
  border-top: 1px solid var(--line);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  font-family: var(--font-sans);
  color: var(--muted);
}
html.js .powered-by {
  flex: 0 0 auto;
  width: 100%;
  text-align: center;
  padding: 5px 14px;
  border-top: 1px solid var(--line);
  background: rgba(246, 242, 234, 0.92);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  font-size: 9px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  font-family: var(--font-sans);
  color: var(--muted);
}
.powered-by .link-footer { color: var(--gold); }

/* ── Bottom section tabs (built by main.js) ────────────────────────────── */
html.js .shell-nav {
  display: flex; align-items: center; justify-content: center; gap: 4px;
  flex: 0 0 auto;
  padding: 8px calc(10px + env(safe-area-inset-right)) calc(8px + env(safe-area-inset-bottom)) calc(10px + env(safe-area-inset-left));
  border-top: 1px solid var(--line);
  background: rgba(246, 242, 234, 0.92);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  /* Scrollable, but never visibly scroll-marked — a clean bar on any width. */
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
html.js .shell-nav::-webkit-scrollbar { display: none; }

.nav-tab {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 13px;
  border: 0; border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font-family: var(--font-sans);
  font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.2s, color 0.2s;
}
.nav-tab svg { width: 15px; height: 15px; flex: none; }
.nav-tab[aria-selected="true"] {
  background: var(--gold);
  color: #fff;
  font-weight: 500;
}
.nav-tab:hover:not([aria-selected="true"]) { color: var(--ink); }
.nav-tab:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* ── Photo viewer (lightbox) — click any photo to view it full-screen ────
   Plain enhancement over the optional photo slots (#cover-photo, the flyer
   banner + the gallery). The viewer markup is built by main.js only when a
   photo slot exists, so removing those blocks removes the viewer entirely —
   nothing orphaned, no platform contract. */
html.js .cover__photo img,
html.js .banner-flyer img,
html.js .gallery-item img,
html.js .free-media img { cursor: zoom-in; }

/* Small "view full size" badge on hover / keyboard focus — shows the photo
   is clickable. Purely visual; without JS (no viewer) it never appears. */
html.js .cover__photo,
html.js .banner-flyer,
html.js .gallery-item,
html.js .free-media { position: relative; }
html.js .cover__photo::after,
html.js .banner-flyer::after,
html.js .gallery-item::after,
html.js .free-media::after {
  content: "";
  position: absolute;
  top: 10px; right: 10px;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: rgba(255, 253, 247, 0.94)
    url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a6a4a' 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 var(--gold-soft);
  box-shadow: 0 4px 12px -4px rgba(80, 60, 30, 0.4);
  opacity: 0;
  transform: translateY(-3px);
  transition: opacity 0.2s, transform 0.2s;
  pointer-events: none;
}
html.js .cover__photo:hover::after,
html.js .cover__photo:focus-within::after,
html.js .banner-flyer:hover::after,
html.js .banner-flyer:focus-within::after,
html.js .gallery-item:hover::after,
html.js .gallery-item:focus-within::after,
html.js .free-media:hover::after,
html.js .free-media:focus-within::after {
  opacity: 1;
  transform: none;
}

.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(46, 38, 27, 0.92);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
.photo-viewer.is-open { display: flex; }
.photo-viewer figure {
  margin: 0;
  max-width: min(92vw, 900px);
  display: flex; flex-direction: column; align-items: center;
  gap: 14px;
  text-align: center;
}
.photo-viewer img {
  display: block;
  max-width: 100%; max-height: 76vh; max-height: 76dvh;
  width: auto; height: auto;
  border: 6px solid var(--card);
  border-radius: 10px;
  background: var(--paper); /* mat while loading / if the file is missing */
  box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.75);
}
.photo-viewer figcaption {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 18px;
  color: var(--paper-2);
}
.photo-viewer .pv-unavailable {
  display: flex; align-items: center; justify-content: center;
  width: min(72vw, 520px); height: min(46vh, 360px);
  border: 6px solid var(--card); border-radius: 10px;
  background: var(--paper);
  color: var(--muted);
  font-size: 14px; font-style: italic;
  text-align: center; padding: 0 20px;
}

.pv-btn {
  position: absolute;
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1px solid rgba(246, 242, 234, 0.5);
  background: rgba(255, 253, 247, 0.94);
  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 0.2s, background-color 0.2s;
}
.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-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-soft); 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 img { max-height: 62vh; max-height: 62dvh; }
  .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)); }
}

/* ── Toast ─────────────────────────────────────────────────────────────── */
.toast {
  position: fixed;
  left: 50%;
  bottom: 20px;
  transform: translate(-50%, 20px);
  background: var(--ink);
  color: var(--paper-2);
  font-size: 13px;
  padding: 10px 18px;
  border-radius: 999px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s, transform 0.25s;
  z-index: 50;
  font-family: var(--font-sans);
}

.toast.is-visible { opacity: 1; transform: translate(-50%, 0); }

/* ── Reveal (progressive enhancement) ──────────────────────────────────── */
.js .panel.is-active .card-inner {
  animation: rise 0.55s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.js .no-motion .panel.is-active .card-inner { animation: none; }

@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ── Small screens: tighten the cover so it stays one comfortable page ───
   Three tiers — moderate (laptops/small tablets), tighter (shorter), and
   tightest (very short) — so the cover reads as one full page on every
   height that can reasonably hold it. Below that it scrolls internally,
   which the shell handles gracefully. */
@media (max-height: 860px) {
  .cover__photo { width: clamp(130px, min(38vw, 34vh), 230px); margin-bottom: 12px; }
  .cover__names { font-size: clamp(30px, 6.5vh, 46px); }
  .cover__request { margin-top: 6px; }
  .ornament { margin: 8px 0; }
  .cover__date { font-size: 14px; }
  .cover__place { margin-top: 4px; }
  .cover__cta-wrap { margin-top: 14px; }
  .card-inner { padding: 18px 16px 24px; }
}

@media (max-height: 720px) {
  .cover__photo { width: clamp(115px, min(34vw, 30vh), 195px); margin-bottom: 10px; }
  .cover__names { font-size: clamp(28px, 6vh, 40px); }
  .cover__date { font-size: 13.5px; }
  .card-inner { padding: 16px 16px 20px; }
}

/* Very short screens: shrink the hero photo so the cover still fits */
@media (max-height: 600px) {
  .cover__photo { width: clamp(96px, min(30vw, 28vh), 170px); margin-bottom: 8px; }
  .cover__names { font-size: clamp(26px, 5.5vh, 38px); }
  .cover__request { margin-top: 4px; }
  .cover__cta-wrap { margin-top: 10px; }
}

/* Narrow phones: the nav bar scrolls instead of overflowing, and the
   gallery drops to two bigger columns. */
@media (max-width: 440px) {
  html.js .shell-nav { justify-content: flex-start; }
  .nav-tab { padding: 7px 10px; font-size: 10px; gap: 4px; }
}

@media (max-width: 520px) {
  .gallery-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ── Motion preferences ────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001s !important;
    scroll-behavior: auto !important;
  }
  .film-play { animation: none; }
}

/* ── Print: full stacked card (cover → card → RSVP → guestbook) ────────── */
@media print {
  @page { margin: 12mm; }
  html.js body { height: auto; overflow: visible; }
  html.js .app { height: auto; display: block; background: #fff; }
  html.js .shell-head, html.js .shell-nav, .js-print, .powered-by { display: none !important; }
  html.js .shell-body { display: block; }
  html.js .panel {
    position: static; display: block !important;
    height: auto; overflow: visible;
    padding: 0 0 24px;
  }
  html.js .card { height: auto; }
  html.js .panel[data-panel]:not([data-panel="cover"]) .card { break-before: page; }
  .photo-viewer, .toast { display: none !important; }
  .film-frame iframe { display: none; } /* a playing video can't print — the poster prints instead */
  body { background: #fff; color: #222; }
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  a { color: inherit; }
}
