/* ═══════════════════════════════════════════════════════════════════════════
   party-bbq-card-grill-and-greet — "Grill & Greet" (BBQ Party · Card)
   Warm printed-card feel: cream paper, ink text, gingham + checker accents.

   Layout contract:
     · .app-shell locks to the viewport (100dvh) when <html> has class "js".
     · Only the ACTIVE panel scrolls internally; inactive panels are hidden.
     · Without JS the page degrades to a normal stacked, scrolling document.
     · Navigation is a fixed bottom bar of TEXT tabs (built by main.js from
       panels that have content); it scrolls horizontally on narrow screens.
     · Every photo slot (cover, gallery, flyer banner) opens the full-screen
       photo viewer with zoom when clicked (built by main.js).
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  --ink:        #33271c;
  --ink-soft:   #57442f;
  --paper:      #faf3e3;
  --paper-2:    #f3e7cd;
  --cream:      #fffaf0;
  --ember:      #d95921;
  --ember-deep: #b94412;
  --ember-soft: rgba(217, 89, 33, .14);
  --leaf:       #6b7d3c;
  --danger:     #b3341f;
  --line:       rgba(51, 39, 28, .14);
  --line-card:  rgba(51, 39, 28, .18);
  --radius:     20px;
  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  --font-body:    "Karla", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
  font: 16px/1.65 var(--font-body);
  color: var(--ink);
  background: var(--paper-2);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ── Gingham / checker utilities ───────────────────────────────────────── */
.gingham {
  background: repeating-conic-gradient(var(--ember) 0% 25%, var(--cream) 0% 50%)
    0 0 / 22px 22px;
  border-radius: 4px;
}
.gingham-band {
  height: 22px;
  margin-top: 30px;
  opacity: .9;
}

.checker-dot {
  display: inline-block;
  width: 12px;
  height: 12px;
  background: var(--ember);
  border-radius: 50%;
  box-shadow: inset 0 0 0 2px var(--paper), inset 0 0 0 3px var(--ink);
}

/* ── Shell: single viewport, only the active panel scrolls ─────────────── */
.app-shell {
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

.panel { height: 100%; overflow: hidden; position: relative; }

/* No-JS fallback: everything visible, page scrolls naturally. */
.js .panel { display: none; }
.js .panel.is-active { display: block; }

/* Only the active panel scrolls internally. */
.panel.is-active {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

.panel-inner {
  max-width: 620px;
  margin: 0 auto;
  padding: calc(26px + env(safe-area-inset-top)) 24px calc(120px + env(safe-area-inset-bottom));
  min-height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* ── Panel themes ──────────────────────────────────────────────────────── */
.cover-panel  { background: var(--paper); }
.detail-panel { background: var(--cream); }
.flyer-panel  { background: var(--paper); }
.moments-panel { background: var(--cream); }
.film-panel   { background: var(--paper); }
.free-panel   { background: var(--cream); }
.rsvp-panel   { background: var(--paper); }
.guest-panel  { background: var(--paper); }

/* A subtle paper grain via layered gradients (no image file needed). */
.cover-panel .panel-inner {
  position: relative;
  background:
    radial-gradient(ellipse 80% 40% at 50% 8%, rgba(217, 89, 33, .10), transparent 65%),
    var(--paper);
}

/* ── Typography ────────────────────────────────────────────────────────── */
.kicker {
  margin: 0 0 10px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--ember);
}

.cover-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(38px, 10vw, 58px);
  line-height: 1.04;
  color: var(--ink);
}

.panel-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(28px, 7vw, 40px);
  line-height: 1.1;
  color: var(--ink);
}

.panel-lead { margin: 10px 0 0; color: var(--ink-soft); font-size: 16px; }

.invite-line {
  margin: 16px 0 20px;
  font-size: 17px;
  color: var(--ink-soft);
  max-width: 30ch;
}
.host-name { color: var(--ember); font-weight: 700; }

.cover-date {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-weight: 700;
  color: var(--ink);
  background: var(--cream);
  border: 1px solid var(--line-card);
  border-radius: 999px;
  padding: 9px 18px;
  box-shadow: 0 4px 0 rgba(51, 39, 28, .08);
}
.mini-ico { display: inline-flex; color: var(--ember); }

.closing-line {
  margin: 18px 0 0;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 600;
  font-size: 19px;
  color: var(--ember);
}

/* ── Personalized guest greeting (platform `name` global) ──────────────── */
.guest-greeting {
  margin: 0 0 14px;
  font-size: 15px;
  font-weight: 700;
  color: var(--ember);
  letter-spacing: .02em;
}
.guest-greeting::before { content: "🔥 "; }

/* ── Cover photo slot (optional; placeholder ships in assets/img) ─────── */
.cover-photo { margin: 0 0 22px; position: relative; }
.cover-photo img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 16px;
  box-shadow: 0 10px 24px rgba(51, 39, 28, .16);
  background: var(--paper-2);
}

/* Small "View photo" affordance 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 var(--line-card);
  border-radius: 999px;
  background: rgba(250, 243, 227, .92);
  color: var(--ember-deep);
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: .04em;
  cursor: pointer;
  box-shadow: 0 8px 20px -10px rgba(51, 39, 28, .5);
  transition: transform .15s ease, box-shadow .15s ease;
}
.cover-photo-btn:hover { transform: translateY(-2px); }
.cover-photo-btn:focus-visible { outline: 3px solid var(--ember); outline-offset: 3px; }
html:not(.js) .cover-photo-btn { display: none; }

/* ── Buttons ───────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font: 700 15px/1 var(--font-body);
  letter-spacing: .03em;
  text-decoration: none;
  border: 0;
  border-radius: 999px;
  padding: 14px 28px;
  cursor: pointer;
  transition: transform .15s ease, box-shadow .15s ease, background .15s ease;
}
.btn:focus-visible { outline: 3px solid var(--ember); outline-offset: 3px; }
.btn:active { transform: translateY(1px); }

.btn-primary {
  background: var(--ember);
  color: var(--cream);
  box-shadow: 0 5px 0 var(--ember-deep);
}
.btn-primary:hover { background: #e3642a; }

.btn-outline {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line-card);
}
.btn-outline:hover { background: var(--cream); }

.btn-block { width: 100%; }

.cover-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 26px;
}

.panel-foot { margin-top: 30px; text-align: center; }

.rsvp-by {
  margin: 28px 0 0;
  font-size: 15px;
  color: var(--ink-soft);
  background: var(--ember-soft);
  border: 1px dashed var(--ember);
  border-radius: 12px;
  padding: 12px 16px;
  text-align: center;
}

/* ── Details ───────────────────────────────────────────────────────────── */
.detail-list {
  margin: 28px 0 0;
  background: var(--paper);
  border: 1px solid var(--line-card);
  border-radius: var(--radius);
  padding: 8px 22px;
  box-shadow: 0 10px 24px rgba(51, 39, 28, .08);
}
.detail-row {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 16px 0;
  border-bottom: 1px solid var(--line);
}
.detail-row:last-child { border-bottom: 0; }
.detail-row dt {
  flex: 0 0 118px;
  display: flex;
  align-items: center;
  gap: 7px;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--ember);
}
.detail-row dd { margin: 0; font-size: 15.5px; color: var(--ink); }
/* Main + sub lines stack without a hard <br> so hiding an empty main line
   never leaves a stray blank line (degraded state). */
.detail-row dd .dd-main,
.detail-row dd .dd-sub { display: block; }
.dd-sub { color: var(--ink-soft); font-size: 13.5px; }

/* ── 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; }
.banner-flyer img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 8 / 3;
  object-fit: cover;
  padding: 5px;
  background: var(--paper-2);
  border: 1px solid var(--line-card);
  border-radius: 12px;
  box-shadow: 0 12px 26px -18px rgba(51, 39, 28, .4);
}
.banner-flyer figcaption {
  margin-top: 10px;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 600;
  font-size: 15px;
  text-align: center;
  color: var(--ink-soft);
}

/* ── Moments photo gallery (optional; placeholders ship in assets/img) ── */
.moments-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
  margin-top: 28px;
}
.moments-photo { margin: 0; }
.moments-photo img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 14px;
  box-shadow: 0 8px 18px rgba(51, 39, 28, .14);
  background: var(--paper-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: 13px;
  font-style: italic;
  color: var(--ink-soft);
}

/* ── Free page (optional; the cockpit's Free Page section) ──────────────
   A page of the host's own words: repeatable blocks, each with a title,
   free text and an optional photo. Toggle Free Page off in the cockpit
   (or clear all blocks) to remove the whole section — and its tab. */
.free-blocks {
  display: grid;
  gap: 32px;
  margin-top: 28px;
}
.free-block { margin: 0; text-align: center; }
.free-title {
  margin: 0 0 16px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(24px, 6vw, 34px);
  line-height: 1.15;
  color: var(--ember-deep);
  overflow-wrap: anywhere;
}
.free-media {
  margin: 0 auto;
  max-width: 560px;
}
.free-media img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  /* Spacing lives on the img, not the figure: an empty figure (host left
     the free-page photo blank) then collapses to zero height instead of
     leaving an 18px gap between title and text. */
  margin-bottom: 18px;
  object-fit: cover;
  border-radius: 14px;
  box-shadow: 0 8px 18px rgba(51, 39, 28, .14);
  background: var(--paper-2);
}
.free-content {
  margin: 0 auto;
  max-width: 32em;
  text-align: left;
  font-size: 16px;
  line-height: 1.75;
  color: var(--ink-soft);
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* ── Clickable photos: zoom-in cursor + a small "view" badge on hover /
   focus. Pure visual hints — the viewer itself is 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-media img { cursor: zoom-in; }

html.js .moments-photo, html.js .banner-flyer, html.js .free-media { position: relative; }
html.js .moments-photo::after,
html.js .banner-flyer::after,
html.js .free-media::after {
  content: "";
  position: absolute;
  top: 12px;
  right: 12px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: rgba(250, 243, 227, .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='%23b94412' 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(--line-card);
  box-shadow: 0 4px 12px -4px rgba(51, 39, 28, .4);
  opacity: 0;
  transform: translateY(-3px);
  transition: opacity .15s ease, transform .15s ease;
  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-media:hover::after,
html.js .free-media:focus-within::after {
  opacity: 1;
  transform: none;
}

/* ── 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; 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(51, 39, 28, .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: 12px;
}
.photo-viewer img {
  display: block;
  max-width: 100%;
  max-height: 76vh;
  max-height: 76dvh;
  width: auto;
  height: auto;
  border: 6px solid var(--cream);
  border-radius: 12px;
  background: var(--paper); /* mat while loading / if the file is missing */
  box-shadow: 0 30px 80px -30px rgba(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-display);
  font-style: italic;
  font-weight: 600;
  font-size: 17px;
  color: var(--cream);
}
.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(--cream);
  border-radius: 12px;
  background: var(--paper);
  color: var(--ink-soft);
  font-size: 14px;
  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(51, 39, 28, .25);
  background: rgba(250, 243, 227, .95);
  color: var(--ember-deep);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 10px 24px -12px rgba(0, 0, 0, .6);
  transition: transform .15s ease, background-color .15s ease;
}
.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(--ember); 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)); }
}

/* ── Optional video feature (film-card, in the "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: 12px;
  background: var(--paper-2);
  border: 1px solid var(--line-card);
  box-shadow: 0 12px 26px -18px rgba(51, 39, 28, .4);
  overflow: hidden;
}
.film-open {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  border-radius: 9px;
  overflow: hidden;
  background: var(--paper);
  cursor: pointer;
}
.film-open img { display: block; width: 100%; height: 100%; object-fit: cover; }
.film-open:focus-visible { outline: 3px solid var(--ember); 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(--cream);
  color: var(--ember-deep);
  box-shadow: 0 8px 24px rgba(51, 39, 28, .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(51, 39, 28, .55);
  color: var(--cream);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: .06em;
}

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

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

.film-external {
  display: inline-block;
  margin-top: 14px;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--ember-deep);
  text-decoration: none;
  border-bottom: 1.5px solid transparent;
  transition: border-color .15s ease, color .15s ease;
}
.film-external:hover { color: var(--ember); border-color: var(--ember); }
.film-external[hidden] { display: none; }

@keyframes film-pulse {
  0%, 100% { box-shadow: 0 8px 24px rgba(51, 39, 28, .35), 0 0 0 0 rgba(217, 89, 33, .5); }
  50%      { box-shadow: 0 8px 24px rgba(51, 39, 28, .35), 0 0 0 16px rgba(217, 89, 33, 0); }
}

/* ── Forms (RSVP) ──────────────────────────────────────────────────────── */
.rsvp-wrap { width: 100%; }
.rsvp-head { margin-bottom: 24px; }

.form-group { margin-bottom: 17px; }
.form-group label {
  display: block;
  font-size: 14px;
  font-weight: 700;
  margin-bottom: 7px;
  letter-spacing: .02em;
}
.form-control {
  width: 100%;
  padding: 12px 14px;
  font: 400 15px/1.4 var(--font-body);
  color: var(--ink);
  background: var(--cream);
  border: 2px solid #e0d2b4;
  border-radius: 12px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.form-control:focus {
  outline: none;
  border-color: var(--ember);
  box-shadow: 0 0 0 3px var(--ember-soft);
}
select.form-control { appearance: none; }
textarea.form-control { resize: vertical; }

.field-hint { display: block; margin-top: 6px; font-size: 13px; color: #8a7555; }

.error {
  display: block;
  min-height: 1.2em;
  margin-top: 5px;
  font-size: 13px;
  font-weight: 600;
  color: var(--danger);
}

.form-actions { margin-top: 22px; }

.loading {
  display: none;
  text-align: center;
  margin-top: 14px;
  font-size: 14px;
  color: var(--ember-deep);
  font-weight: 700;
}
.loading::before {
  content: "";
  display: inline-block;
  width: 14px;
  height: 14px;
  margin-right: 8px;
  vertical-align: -2px;
  border: 2px solid var(--ember-soft);
  border-top-color: var(--ember);
  border-radius: 50%;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* RSVP deadline countdown (platform fills the numbers when a deadline is set) */
.rsvp-countdown { margin: 0 0 26px; text-align: center; }
.countdown-label {
  margin: 0 0 10px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--ember-deep);
}
.countdown-boxes { display: flex; justify-content: center; gap: 10px; }
.count-box {
  flex: 0 0 66px;
  background: var(--ink);
  color: var(--cream);
  border-radius: 12px;
  padding: 10px 4px;
}
.count-box span {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 23px;
  line-height: 1;
}
.count-box small {
  display: block;
  margin-top: 4px;
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(250, 243, 227, .7);
}

/* "Thank you" / "RSVP closed" state — the platform swaps this into #rsvp-form */
.thank-you-message h3 {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 26px;
  color: var(--ember);
}
.thank-you-message p { margin: 4px 0; color: var(--ink-soft); }
.thank-you-message small { color: #8a7555; }

/* ── Guestbook (platform injects the markup into .guestbook-body) ──────── */
.guestbook-head { margin-bottom: 20px; }

/* injected form */
.guestbook-body form,
.guestbook-body #guestbookForm {
  background: var(--cream);
  border: 1px solid var(--line-card);
  border-radius: var(--radius);
  padding: 22px;
  box-shadow: 0 8px 20px rgba(51, 39, 28, .07);
}
.guestbook-body label { color: var(--ink); }
.guestbook-body .form-control {
  color: var(--ink);
  background: #fffdf7;
  border-color: #e0d2b4;
}
.guestbook-body .form-control:focus { border-color: var(--ember); }
.guestbook-body button[type="submit"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font: 700 15px/1 var(--font-body);
  color: var(--cream);
  background: var(--ember);
  border: 0;
  border-radius: 999px;
  padding: 13px 26px;
  cursor: pointer;
  box-shadow: 0 5px 0 var(--ember-deep);
}
.guestbook-chapta { margin: 12px 0; }

/* injected message list */
.guestbook-wrap {
  margin-top: 22px;
  max-height: 42vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  border-top: 1px solid var(--line);
}
.guestbook-entry {
  padding: 14px 2px;
  border-bottom: 1px solid var(--line);
}
.guestbook-entry h5 { margin: 0 0 3px; font-size: 15px; color: var(--ember); }
.guestbook-entry p { margin: 0 0 3px; font-size: 15px; color: var(--ink); }
.guestbook-entry small { font-size: 12px; color: var(--ink-soft); }

.loading-guestbook {
  display: none;
  text-align: center;
  color: var(--ink-soft);
  font-size: 14px;
  padding: 10px 0;
}
.more-guestbook-wrap { text-align: center; margin-top: 14px; }
#load-more {
  font: 700 14px/1 var(--font-body);
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--line-card);
  border-radius: 999px;
  padding: 10px 22px;
  cursor: pointer;
}
#load-more:hover { background: var(--cream); }

/* ── Brand footer (tucked into the last panel by main.js) ─────────────── */
.app-footer {
  margin-top: 34px;
  padding: 18px 0 0;
  border-top: 1px solid var(--line);
  text-align: center;
}
.app-footer .footer-brand {
  margin: 0 0 10px;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 600;
  font-size: 20px;
  color: var(--ember-deep);
}
.app-footer .footer-brand-name { color: var(--leaf); }
.app-footer .foot-meta {
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  font-size: 13px;
  color: var(--ink-soft);
}
.footer-line { font-size: 13px; color: var(--ink-soft); }

/* ── Full-width powered-by brand strip ──────────────────────────────────
   A slim, full-width brand line pinned above the tab bar in the JS shell
   (and at the end of the stacked document without JS). The engine swaps
   the brand token for the platform name at render; the cockpit's Free
   Powered By field can override the whole line. */
html:not(.js) .powered-by {
  width: 100%;
  text-align: center;
  padding: 14px 16px 22px;
  border-top: 1px solid var(--line);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
html.js .powered-by {
  position: fixed;
  z-index: 49;
  left: 0;
  right: 0;
  bottom: calc(74px + env(safe-area-inset-bottom));
  text-align: center;
  padding: 4px 16px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink-soft);
  background: rgba(250, 243, 227, .92);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  pointer-events: none;
}
.powered-by .link-footer { color: var(--ember-deep); }

/* ── Section switcher (TEXT tabs, built by main.js) ─────────────────────
   Clear, always-visible text navigation. On narrow screens the bar scrolls
   horizontally and prev/next arrow buttons appear when the tabs overflow
   (main.js toggles .is-visible); tap targets stay comfortably large. */
.nav-wrap {
  position: fixed;
  z-index: 50;
  left: 50%;
  bottom: calc(12px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 6px;
  max-width: min(96vw, 780px);
}
.nav-wrap[hidden] { display: none; }

.panel-nav {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 1 1 auto;
  min-width: 0;
  max-width: 100%;
  padding: 8px;
  border-radius: 999px;
  background: rgba(51, 39, 28, .82);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid rgba(250, 243, 227, .22);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 12px, #000 calc(100% - 12px), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 12px, #000 calc(100% - 12px), transparent 100%);
}
.panel-nav[hidden] { display: none; }
/* No tabs built (no-JS or single panel) → no bar at all. */
.panel-nav:empty { display: none; }
.panel-nav::-webkit-scrollbar { display: none; }

/* Prev/next arrows for the scrolling bar — hidden until the bar overflows
   (main.js adds .is-visible when there is more to see on that side). */
.nav-arrow {
  display: none;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid rgba(250, 243, 227, .22);
  border-radius: 50%;
  background: rgba(51, 39, 28, .82);
  color: var(--cream);
  font: inherit;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  transition: background .15s ease, transform .15s ease;
  -webkit-tap-highlight-color: transparent;
}
.nav-arrow.is-visible { display: inline-flex; }
.nav-arrow:hover { background: var(--ember); }
.nav-arrow:active { transform: scale(.94); }
.nav-arrow:focus-visible { outline: 2px solid var(--ember); outline-offset: 2px; }

.panel-nav .nav-tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 40px;
  padding: 9px 15px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: rgba(250, 243, 227, .82);
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: .03em;
  white-space: nowrap;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
  -webkit-tap-highlight-color: transparent;
}
.panel-nav .nav-tab svg { width: 15px; height: 15px; flex: none; opacity: .9; }
.panel-nav .nav-tab:hover { background: rgba(250, 243, 227, .14); }
.panel-nav .nav-tab.is-current {
  background: var(--ember);
  color: var(--cream);
  box-shadow: 0 6px 18px -6px rgba(217, 89, 33, .7);
}
.panel-nav .nav-tab:focus-visible { outline: 2px solid var(--ember); outline-offset: 2px; }

/* Wider screens: let the bar stretch so all tabs sit visible — scrolling
   is only needed on phones. */
@media (min-width: 700px) {
  .nav-wrap { max-width: min(94vw, 960px); }
}

/* ── Reduced motion ────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .loading::before { animation: none; }
}

/* ── Print: expand every panel so the whole invitation prints ──────────── */
@media print {
  body { background: #fff; color: #000; }
  .nav-wrap { display: none !important; }
  .panel-nav { display: none !important; }
  .photo-viewer { display: none !important; }
  .app-shell { height: auto !important; overflow: visible !important; }
  .panel { display: block !important; height: auto !important; overflow: visible !important; }
  .panel-inner {
    max-width: none;
    padding: 0;
    min-height: 0;
    page-break-after: always;
  }
  .cover-panel .panel-inner { background: none; }
  .cover-photo img, .moments-photo img, .banner-flyer img, .free-media img, .gingham, .guest-greeting,
  .cover-actions, .panel-foot, .detail-list { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .film-frame iframe { display: none; } /* a playing video can't print — the poster prints instead */
  a[href]::after { content: ""; }
  /* The brand strip prints as a normal closing line at the end of the document. */
  .powered-by { position: static; padding: 18px 16px 24px; }
}
