/* ═══════════════════════════════════════════════════════════════════════
   graduation-card — "The Invitation"
   Ivory paper + ink + gold foil · Parisienne (script) + Prata (serif) + Inter
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  --bg: #efe7d6;              /* warm backdrop */
  --paper: #fbf6ea;           /* card paper */
  --paper-deep: #f6eede;
  --ink: #2b3350;             /* ink navy */
  --ink-soft: #454e70;
  --muted: #7a7f92;
  --gold: #a9822f;
  --gold-deep: #8a6a24;
  --gold-light: #c9a35c;
  --danger: #b3261e;
  --ok-ink: #2d5f5c;
  --line: rgba(43, 51, 80, 0.16);
  --shadow: 0 22px 60px rgba(74, 63, 40, 0.24);
  --radius: 18px;
  --font-script: "Parisienne", "Segoe Script", cursive;
  --font-serif: "Prata", "Iowan Old Style", Georgia, serif;
  --font-ui: "Inter", ui-sans-serif, system-ui, sans-serif;
}

/* ── base ─────────────────────────────────────────────────────────────── */
* { box-sizing: border-box; }
html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--font-ui);
  color: var(--ink);
  background:
    radial-gradient(circle at 20% 8%, rgba(169, 130, 47, 0.10), transparent 40%),
    radial-gradient(circle at 85% 90%, rgba(169, 130, 47, 0.08), transparent 45%),
    var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; display: block; }
a { color: inherit; }
ul, ol { list-style: none; margin: 0; padding: 0; }
[hidden] { display: none !important; }

/* ── single-viewport shell (JS on) ────────────────────────────────────── */
html.js .app {
  height: 100vh;
  height: 100dvh;
  display: grid;
  grid-template-rows: auto auto minmax(0, 1fr) auto auto;
  overflow: hidden;
}

html.js .panel { display: none; }
html.js .panels {
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
html.js .panel.is-active {
  display: block;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* hero panels (the card) centre their content when there's room */
html.js .panel.hero-panel.is-active { display: flex; }
html.js .panel.hero-panel.is-active > * { margin: auto; }

/* ── no-JS fallback: everything stacked, page scrolls ─────────────────── */
html:not(.js) .app { display: block; height: auto; }
html:not(.js) .panel { display: block; }
html:not(.js) .tabs { display: none; }
html:not(.js) .panel.is-active { overflow: visible; }

/* ── masthead ─────────────────────────────────────────────────────────── */
.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px clamp(14px, 3vw, 28px);
  background: rgba(251, 246, 234, 0.9);
  backdrop-filter: blur(6px);
  border-bottom: 1px solid rgba(169, 130, 47, 0.35);
  position: relative;
  z-index: 5;
}

.masthead__brand { display: flex; align-items: center; gap: 12px; min-width: 0; }
.masthead__monogram {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex: none;
  border-radius: 50%;
  border: 1.5px solid var(--gold);
  color: var(--gold-deep);
  font-family: var(--font-serif);
  font-size: 15px;
  letter-spacing: 0.06em;
  background: var(--paper);
  box-shadow: inset 0 0 0 3px var(--paper), 0 0 0 1px rgba(169, 130, 47, 0.4);
}
.masthead__text { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.masthead__top {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-deep);
}
.masthead__name {
  font-family: var(--font-serif);
  font-size: 15px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.masthead__actions { display: flex; align-items: center; gap: 8px; flex: none; }

.chip-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid rgba(169, 130, 47, 0.45);
  background: transparent;
  color: var(--ink);
  font: 500 12.5px var(--font-ui);
  cursor: pointer;
  transition: background 0.2s, border-color 0.2s, transform 0.15s;
}
.chip-btn:hover { background: rgba(169, 130, 47, 0.12); border-color: var(--gold); }
.chip-btn:active { transform: translateY(1px); }
.chip-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.chip-btn.is-done { border-color: #6f9c74; color: var(--ok-ink); }

/* ── tabs ─────────────────────────────────────────────────────────────── */
.tabs {
  display: flex;
  gap: 8px;
  padding: 8px clamp(14px, 3vw, 28px);
  overflow-x: auto;
  scrollbar-width: none;
  background: rgba(251, 246, 234, 0.9);
}
.tabs::-webkit-scrollbar { display: none; }

.tab {
  appearance: none;
  flex: none;
  padding: 8px 18px;
  border-radius: 999px;
  border: 1px solid rgba(169, 130, 47, 0.4);
  background: transparent;
  color: var(--muted);
  font: 500 13px var(--font-ui);
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.tab:hover { color: var(--ink); border-color: var(--gold); }
.tab.is-active { background: var(--gold); border-color: var(--gold); color: #fff; font-weight: 600; }
.tab:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* ── panels & inner ───────────────────────────────────────────────────── */
.panels { min-width: 0; }

.panel-inner {
  max-width: 780px;
  margin: 0 auto;
  padding: clamp(20px, 4vh, 40px) clamp(16px, 4vw, 32px) 56px;
}

.section-head { margin-bottom: 24px; }
.kicker {
  margin: 0 0 6px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--gold-deep);
}
.section-head h2 {
  margin: 0 0 8px;
  font-family: var(--font-serif);
  font-size: clamp(25px, 4.4vw, 36px);
  font-weight: 400;
  line-height: 1.1;
}
.lede { margin: 0; color: var(--muted); font-size: 15px; line-height: 1.6; max-width: 52ch; }

/* ── the invitation card ──────────────────────────────────────────────── */
.invitation {
  position: relative;
  max-width: 640px;
  width: 100%;
  margin: auto;
  padding: clamp(30px, 5.5vh, 52px) clamp(26px, 5vw, 52px) clamp(26px, 4.5vh, 40px);
  background:
    radial-gradient(circle at 50% -8%, rgba(201, 163, 92, 0.16), transparent 46%),
    var(--paper);
  border: 1px solid rgba(169, 130, 47, 0.55);
  border-radius: 4px;
  box-shadow: var(--shadow);
  color: var(--ink);
  text-align: center;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
/* fine inner gold frame — the classic invitation double border */
.invitation::before {
  content: "";
  position: absolute;
  inset: 8px;
  border: 1px solid rgba(169, 130, 47, 0.55);
  pointer-events: none;
}
/* hairline corner ticks */
.invitation::after {
  content: "";
  position: absolute;
  inset: 14px;
  border: 1px solid rgba(169, 130, 47, 0.25);
  pointer-events: none;
}

.invitation__pattern {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle, rgba(169, 130, 47, 0.18) 1px, transparent 1.6px);
  background-size: 22px 22px;
  opacity: 0.35;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 26%, #000 74%, transparent 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 26%, #000 74%, transparent 100%);
}

html.js:not(.no-motion) .invitation { animation: card-rise 0.7s cubic-bezier(0.2, 0.7, 0.3, 1) both; }
@keyframes card-rise {
  from { opacity: 0; transform: translateY(16px) scale(0.995); }
  to   { opacity: 1; transform: none; }
}

.invitation > * { position: relative; z-index: 1; }

.invitation__greeting {
  margin: 0 0 6px;
  font-family: var(--font-script);
  font-size: clamp(17px, 3vw, 21px);
  color: var(--gold-deep);
}
.invitation__greeting b { font-weight: 400; }

.invitation__crest { margin: 2px 0; }
.invitation__crest-ring {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 74px;
  height: 74px;
  border-radius: 50%;
  border: 1.5px solid var(--gold);
  box-shadow: inset 0 0 0 4px var(--paper), inset 0 0 0 5px rgba(169, 130, 47, 0.5);
  color: var(--gold-deep);
}
.invitation__crest-initials { font-family: var(--font-serif); font-size: 27px; letter-spacing: 0.08em; }

.invitation__prelude {
  margin: 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--muted);
}

.invitation__name {
  margin: 0;
  font-family: var(--font-script);
  font-size: clamp(2.4rem, 8vw, 3.9rem);
  font-weight: 400;
  line-height: 1.12;
  text-wrap: balance;
  color: var(--ink);
}
/* second honoree (twins, siblings…) gets a gold "&" divider */
.honoree + .honoree::before { content: " & "; color: var(--gold); }

.invitation__line {
  margin: 0;
  font-size: 13px;
  font-style: italic;
  color: var(--muted);
}
.invitation__degree {
  margin: 0;
  font-family: var(--font-serif);
  font-size: clamp(15px, 2.6vw, 19px);
  color: var(--ink);
}
.invitation__school {
  margin: 0;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

.invitation__rule {
  width: 130px;
  height: 1px;
  margin: 8px 0;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
}

.invitation__ask {
  margin: 0;
  max-width: 42ch;
  font-size: 14.5px;
  line-height: 1.7;
  color: var(--ink-soft);
}

.invitation__date {
  margin: 12px 0 0;
  font-family: var(--font-serif);
  font-size: clamp(15px, 2.6vw, 19px);
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--gold-deep);
}

.invitation__facts { margin: 4px 0 0; }
.invitation__fact { margin: 10px 0 0; }
.invitation__fact dt {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--gold-deep);
}
.invitation__fact dd { margin: 3px 0 0; font-size: 14.5px; color: var(--ink); }

.invitation__reply {
  margin: 2px 0 0;
  font-size: 12.5px;
  color: var(--muted);
}
.invitation__reply strong { color: var(--gold-deep); font-weight: 600; }

.invitation__cap-note { margin: 6px 0 0; opacity: 0.85; }

/* optional graduate portrait — gold-ringed round portrait under the school
   line. Clickable: opens the full-screen zoomable viewer (main.js). Sized
   a bit larger so the graduate's face reads clearly on small screens. */
.invitation__photo { margin: 4px 0; }
.invitation__photo img {
  width: clamp(112px, 26vw, 148px);
  height: clamp(112px, 26vw, 148px);
  object-fit: cover;
  border-radius: 50%;
  border: 2px solid var(--gold);
  background: var(--paper-deep);
  box-shadow: 0 0 0 4px var(--paper), 0 0 0 5px rgba(169, 130, 47, 0.5);
  transition: transform 0.35s ease, box-shadow 0.35s ease;
}
html.js .invitation__photo img { cursor: zoom-in; }
html.js .invitation__photo img:hover { transform: scale(1.05); }

/* ── countdown tiles ──────────────────────────────────────────────────── */
.countdown-tiles {
  margin: 0 0 28px;
  padding: 18px;
  border-radius: var(--radius);
  background: var(--paper);
  border: 1px solid rgba(169, 130, 47, 0.45);
  box-shadow: 0 6px 22px rgba(74, 63, 40, 0.08);
  text-align: center;
}
.countdown-tiles__label {
  margin: 0 0 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--gold-deep);
}
.tiles { display: flex; justify-content: center; gap: 10px; }
.tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 62px;
  padding: 10px 8px;
  border-radius: 12px;
  background: var(--paper-deep);
  border: 1px solid rgba(169, 130, 47, 0.3);
}
.tile-num {
  font-family: var(--font-serif);
  font-size: clamp(22px, 3.6vw, 30px);
  color: var(--gold-deep);
  font-variant-numeric: tabular-nums;
}
.tile-cap { font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.countdown-tiles__here { margin: 12px 0 0; font-family: var(--font-script); font-size: 20px; color: var(--gold-deep); }

/* ── event cards ──────────────────────────────────────────────────────── */
.event-list { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 640px) { .event-list { grid-template-columns: 1fr; } }

.event-item {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 18px;
  border-radius: var(--radius);
  background: var(--paper);
  border: 1px solid rgba(169, 130, 47, 0.4);
  box-shadow: 0 6px 22px rgba(74, 63, 40, 0.07);
}
.event-item__chip {
  align-self: flex-start;
  margin-bottom: 6px;
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--gold);
  color: #fff;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.event-item__title { margin: 0; font-family: var(--font-serif); font-size: 19px; font-weight: 400; }
.event-item__when { margin: 2px 0 0; font-size: 13.5px; font-weight: 600; color: var(--gold-deep); }
.event-item__where { margin: 0; font-size: 14px; }
.event-item__addr { margin: 0; font-size: 12.5px; color: var(--muted); }
.event-item__actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }

/* ── notes ────────────────────────────────────────────────────────────── */
.notes {
  margin-top: 26px;
  padding: 16px 18px;
  border-radius: var(--radius);
  background: rgba(169, 130, 47, 0.09);
  border: 1px dashed rgba(138, 106, 36, 0.45);
}
.note { margin: 0 0 8px; font-size: 13.5px; line-height: 1.6; }
.note:last-child { margin-bottom: 0; }
.note strong { color: var(--gold-deep); }

/* ── forms (RSVP + injected guestbook) ────────────────────────────────── */
.form-group { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.form-group label { font-size: 13px; font-weight: 600; }
.form-group label small { font-weight: 400; color: var(--muted); }
.form-group input,
.form-group select,
.form-group textarea {
  width: 100%;
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: #fff;
  color: var(--ink);
  font: 400 15px var(--font-ui);
  transition: border-color 0.2s, box-shadow 0.2s;
}
.form-group textarea { resize: vertical; min-height: 72px; }
.form-group input::placeholder, .form-group textarea::placeholder { color: #9ba1b1; }
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(169, 130, 47, 0.2);
}
.form-group select {
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%237a7f92' stroke-width='2' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 38px;
  cursor: pointer;
}

.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 560px) { .form-row { grid-template-columns: 1fr; } }

.form-hint { margin: -6px 0 16px; font-size: 12.5px; color: var(--muted); }

.error { display: block; color: var(--danger); font-size: 12.5px; }

/* decline state: hide party-size & meals, show the miss-you note */
.rsvp-extras { transition: opacity 0.25s; }
.rsvp-form.is-declining .rsvp-extras { display: none; }
.declined-note {
  display: none;
  margin: 0 0 14px;
  padding: 12px 16px;
  border-radius: 12px;
  background: rgba(45, 95, 92, 0.1);
  border: 1px solid rgba(45, 95, 92, 0.35);
  font-size: 13.5px;
  color: var(--ok-ink);
}
.rsvp-form.is-declining .declined-note { display: block; }

/* buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 13px 22px;
  border-radius: 999px;
  border: 1px solid transparent;
  font: 600 15px var(--font-ui);
  cursor: pointer;
  text-decoration: none;
  transition: transform 0.15s, box-shadow 0.2s, background 0.2s, border-color 0.2s, color 0.2s;
}
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.btn--primary { background: var(--gold); color: #fff; box-shadow: 0 8px 22px rgba(138, 106, 36, 0.4); }
.btn--primary:hover { background: var(--gold-deep); }
.btn--ghost { background: transparent; border-color: var(--line); color: var(--ink); }
.btn--ghost:hover { border-color: var(--gold); color: var(--gold-deep); }
.btn--quiet { border-color: transparent; color: var(--muted); padding-left: 10px; padding-right: 10px; }
.btn--quiet:hover { color: var(--gold-deep); border-color: transparent; }
.btn--block { width: 100%; }
.btn:disabled { opacity: 0.6; cursor: wait; }

/* loading node (driven by the platform script) */
.loading { display: none; text-align: center; color: var(--muted); font-size: 13.5px; padding: 10px 0 0; }

/* RSVP deadline countdown (platform-driven .count-*) */
.rsvp-countdown {
  margin: -6px 0 22px;
  padding: 12px 18px;
  border-radius: 14px;
  background: rgba(169, 130, 47, 0.09);
  border: 1px dashed rgba(138, 106, 36, 0.5);
  text-align: center;
  font-size: 13.5px;
}
.rsvp-countdown__label { margin: 0 0 4px; font-size: 11px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--gold-deep); }
.rsvp-countdown__nums { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; }
.rsvp-countdown__nums span { color: var(--gold-deep); font-size: 17px; }

/* ── guestbook (Style A: platform injects form + list into .guestbook-body) ── */
.guestbook-section #guestbookForm .form-group { margin-bottom: 14px; }
.guestbook-section #guestbookForm button[type="submit"] {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 8px auto 0;
  padding: 12px 26px;
  border-radius: 999px;
  border: none;
  background: var(--gold) !important;
  color: #fff !important;
  font: 600 15px var(--font-ui);
  cursor: pointer;
  box-shadow: 0 8px 22px rgba(138, 106, 36, 0.35);
}
.guestbook-section #guestbookForm button[type="submit"]:hover { background: var(--gold-deep) !important; }

/* injected message list — neutralise the engine's inline scroll box */
.guestbook-section #comments-container {
  margin-top: 28px !important;
  border-top: 1px solid var(--line) !important;
  max-height: none !important;
  overflow: visible !important;
}
.guestbook-section .guestbook-entry {
  padding: 14px 16px;
  margin-top: 12px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--paper);
}
.guestbook-section .guestbook-entry h5 { margin: 0 0 4px; font-size: 15px; font-weight: 600; }
.guestbook-section .guestbook-entry p { margin: 0 0 4px; font-size: 14px; line-height: 1.55; }
.guestbook-section .guestbook-entry small { color: var(--muted); font-size: 12px; }

.guestbook-section .more-guestbook-wrap { text-align: center; margin-top: 18px; }
.guestbook-section #load-more {
  padding: 10px 24px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink);
  font: 600 14px var(--font-ui);
  cursor: pointer;
}
.guestbook-section #load-more:hover { border-color: var(--gold); color: var(--gold-deep); }

/* thank-you / closed states injected by the platform scripts */
.thank-you-message { text-align: center; padding: 26px 12px; }
.thank-you-message h3 { margin: 0 0 8px; font-family: var(--font-serif); font-size: 25px; font-weight: 400; }
.thank-you-message p { margin: 4px 0; color: var(--muted); font-size: 14px; line-height: 1.6; }

/* ── memories gallery ─────────────────────────────────────────────────── */
.photo-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin: 0;
  padding: 0;
}
@media (max-width: 640px) { .photo-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; } }

.photo-frame {
  display: block;
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 5;
  padding: 0;
  border: 1px solid rgba(169, 130, 47, 0.4);
  border-radius: 12px;
  overflow: hidden;
  /* subtle gold "picture" glyph, visible while an image loads or if it fails */
  background-color: var(--paper-deep);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a9822f' stroke-width='1.3' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3.5' y='5' width='17' height='14' rx='2'/%3E%3Ccircle cx='9' cy='9.8' r='1.6'/%3E%3Cpath d='M4.5 17.5l4.5-4.5 3.6 3.6 2.9-2.9 4 4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 42px 42px;
  cursor: zoom-in;
  box-shadow: 0 6px 22px rgba(74, 63, 40, 0.1);
}
/* inner gold hairline, echoing the invitation's double frame */
.photo-frame::after {
  content: "";
  position: absolute;
  inset: 6px;
  border: 1px solid rgba(169, 130, 47, 0.4);
  border-radius: 8px;
  pointer-events: none;
}
.photo-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.4s ease;
}
.photo-frame:hover img { transform: scale(1.04); }

.photo-item__caption {
  margin: 8px 0 0;
  text-align: center;
  font-family: var(--font-script);
  font-size: 17px;
  color: var(--gold-deep);
}

/* ── photo lightbox ───────────────────────────────────────────────────── */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(30, 34, 52, 0.92);
  backdrop-filter: blur(5px);
  animation: lightbox-in 0.25s ease both;
}
@keyframes lightbox-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.lightbox__stage { margin: 0; max-width: min(90vw, 880px); text-align: center; }
.lightbox__img {
  max-width: 90vw;
  max-height: 76vh;
  object-fit: contain;
  border: 1px solid rgba(201, 163, 92, 0.55);
  border-radius: 10px;
  box-shadow: 0 26px 70px rgba(0, 0, 0, 0.5);
}
/* zoomed: the stage becomes a pan-able scroll container, the photo grows
   to 2× its fit size (drag to pan on desktop, pinch/scroll on touch) */
.lightbox__stage.is-zoomed {
  max-width: 92vw;
  max-height: 76vh;
  overflow: auto;
  cursor: grab;
  touch-action: pan-x pan-y;
}
.lightbox__stage.is-zoomed:active { cursor: grabbing; }
.lightbox__stage.is-zoomed .lightbox__img {
  max-width: none;
  max-height: none;
  width: 200%;
  height: auto;
  border-radius: 6px;
}
.lightbox__stage.is-zoomed .lightbox__caption { display: none; }
.lightbox__caption {
  margin: 14px 0 0;
  font-family: var(--font-script);
  font-size: clamp(20px, 3.4vw, 26px);
  color: var(--paper);
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
}
.lightbox__count {
  position: absolute;
  top: 26px;
  left: 74px;
  margin: 0;
  font-size: 12px;
  letter-spacing: 0.2em;
  color: rgba(251, 246, 234, 0.75);
  font-variant-numeric: tabular-nums;
}
.lightbox__close,
.lightbox__nav {
  position: absolute;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(201, 163, 92, 0.55);
  background: rgba(251, 246, 234, 0.1);
  color: var(--paper);
  cursor: pointer;
  transition: background 0.2s;
}
.lightbox__close:hover,
.lightbox__nav:hover { background: rgba(251, 246, 234, 0.22); }
.lightbox__zoom {
  position: absolute;
  top: 16px;
  left: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(201, 163, 92, 0.55);
  background: rgba(251, 246, 234, 0.1);
  color: var(--paper);
  cursor: pointer;
  transition: background 0.2s;
}
.lightbox__zoom:hover { background: rgba(251, 246, 234, 0.22); }
.lightbox__zoom[aria-pressed="true"] { background: rgba(169, 130, 47, 0.9); border-color: var(--gold-light); }
.lightbox__close { top: 16px; right: 16px; }
.lightbox__prev { left: 14px; top: 50%; transform: translateY(-50%); }
.lightbox__next { right: 14px; top: 50%; transform: translateY(-50%); }
@media (max-width: 640px) {
  .lightbox__prev, .lightbox__next { top: auto; bottom: 16px; transform: none; }
  .lightbox__stage { padding: 0 16px 64px; }
}

/* ── optional free page ("In Our Words") ────────────────────────────────
   Repeatable free blocks: title + free text + optional photo. The engine
   clones .free-block per block; when no blocks exist (or the host toggles
   the section off) the whole .panel-free is removed — and with it the tab
   that main.js builds from this panel. The photo is optional: leave it
   empty (or delete .free-media) and the block still reads as a clean
   title + text block. Clicking the photo opens the same full-screen
   zoomable viewer as every other photo slot. */
.free-blocks {
  display: grid;
  gap: clamp(30px, 6vmin, 48px);
}
.free-block { margin: 0; text-align: center; }
.free-title {
  margin: 0 0 clamp(12px, 2.6vmin, 18px);
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(24px, 5.8vmin, 36px);
  line-height: 1.15;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.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: 6px;
  background: var(--paper);
  border: 1px solid rgba(169, 130, 47, 0.5);
  border-radius: 8px;
  box-shadow: 0 14px 30px -22px rgba(74, 63, 40, 0.5);
}
html.js .free-media img { cursor: zoom-in; }
.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;
}

/* ── optional media labels ────────────────────────────────────────────── */
.media-label {
  margin: 0 0 12px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

/* ── optional official flyer / banner (Details) ─────────────────────────
   A wide framed slot for hosts who already have a designed flyer or
   poster — display it so guests confirm they're in the right place.
   Clicking it opens the same full-screen zoomable viewer as the photos.
   Delete the <figure> in index.html to hide the feature. */
.banner-flyer {
  margin: 30px auto 0;
  max-width: 640px;
  text-align: center;
}
.banner-flyer img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 8 / 3;
  object-fit: cover;
  padding: 6px;
  background: var(--paper);
  border: 1px solid rgba(169, 130, 47, 0.5);
  border-radius: 8px;
  box-shadow: 0 14px 30px -22px rgba(74, 63, 40, 0.5);
}
html.js .banner-flyer img { cursor: zoom-in; }
.banner-flyer figcaption {
  margin-top: 10px;
  font-family: var(--font-script);
  font-size: 19px;
  color: var(--gold-deep);
}

/* ── optional film feature (video URL embed, Details) ───────────────────
   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. Delete the .film-card block to hide. */
.film-card { margin-top: 30px; text-align: center; }
.film-frame {
  position: relative;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: 12px;
  background: var(--paper-deep);   /* mat behind the poster / while loading */
  border: 1px solid rgba(169, 130, 47, 0.45);
  box-shadow: 0 16px 34px -24px rgba(74, 63, 40, 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(56px, 12vmin, 72px);
  height: clamp(56px, 12vmin, 72px);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--gold-deep);
  background: radial-gradient(circle at 32% 28%, #fdf7e8, var(--paper) 60%, var(--paper-deep));
  border: 1.5px solid rgba(169, 130, 47, 0.6);
  box-shadow: 0 12px 28px -12px rgba(74, 63, 40, 0.65);
  animation: film-pulse 2.6s ease-in-out infinite;
  transition: transform 0.25s ease;
}
.film-play svg { width: 26px; height: 26px; 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(43, 51, 80, 0.62);
  color: var(--paper);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  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-deep);
}
.film-external {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 14px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold-deep);
  text-decoration: none;
  border-bottom: 1px solid rgba(169, 130, 47, 0.45);
  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(74, 63, 40, 0.65), 0 0 0 0 rgba(169, 130, 47, 0.35); }
  50% { box-shadow: 0 12px 28px -12px rgba(74, 63, 40, 0.65), 0 0 0 14px rgba(169, 130, 47, 0); }
}

/* ── "view full size" badge on the clickable portrait & flyer ───────────
   Signals these photos open the viewer. Purely visual; gallery frames are
   already obvious buttons. */
html.js .invitation__photo,
html.js .banner-flyer,
html.js .free-media { position: relative; }
html.js .invitation__photo::after,
html.js .banner-flyer::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='%238a6a24' 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(169, 130, 47, 0.5);
  box-shadow: 0 4px 12px -4px rgba(74, 63, 40, 0.45);
  opacity: 0;
  transform: translateY(-3px);
  transition: opacity 0.2s ease, transform 0.2s ease;
  pointer-events: none;
  z-index: 2;
}
html.js .invitation__photo:hover::after,
html.js .invitation__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;
}

/* ── brand footer (placeholder, tucked into the last panel by main.js) ── */
html:not(.js) .app-footer { display: block; padding: 26px 18px 42px; text-align: center; }
html.js .app-footer { display: none; }
html.js .panel .app-footer {
  display: block;
  margin-top: clamp(30px, 6vmin, 48px);
  padding-top: 18px;
  border-top: 1px solid var(--line);
}
.footer-brand {
  margin: 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}
.footer-brand-name {
  font-family: var(--font-script);
  font-size: 1.35em;
  text-transform: none;
  letter-spacing: 0.02em;
  color: var(--gold-deep);
}

/* ── full-width powered-by brand strip ──────────────────────────────────
   A slim full-width footer line pinned above the bottom 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: 12px 16px 20px;
  border-top: 1px solid var(--line);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
}
html.js .powered-by {
  width: 100%;
  text-align: center;
  padding: 6px 14px;
  border-top: 1px solid rgba(169, 130, 47, 0.3);
  background: rgba(251, 246, 234, 0.9);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
}
.powered-by .link-footer { color: var(--gold-deep); }

/* ── foot ─────────────────────────────────────────────────────────────── */
.foot {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px clamp(14px, 3vw, 28px);
  background: var(--ink);
  color: rgba(251, 246, 234, 0.85);
  border-top: 1px solid rgba(201, 163, 92, 0.4);
  font-size: 12px;
  white-space: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
.foot::-webkit-scrollbar { display: none; }
.foot__dot { opacity: 0.5; }

/* ── focus visibility (global) ────────────────────────────────────────── */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

/* ── short screens: reclaim vertical space ────────────────────────────── */
@media (max-height: 620px) {
  .masthead { padding-top: 6px; padding-bottom: 6px; }
  .masthead__top { display: none; }
  .foot { display: none; }
}
@media (max-width: 480px) {
  .chip-btn { padding: 8px 10px; }
  .chip-btn__label { display: none; }
  .tab { padding: 8px 13px; font-size: 12.5px; }
}

/* ── reduced motion ───────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
html.no-motion *, html.no-motion *::before, html.no-motion *::after {
  animation: none !important;
  transition: none !important;
}

/* ── print: flatten to readable pages ─────────────────────────────────── */
@media print {
  html.js .app { height: auto; display: block; overflow: visible; }
  html.js .panel { display: block !important; overflow: visible !important; }
  html.js .panel.hero-panel.is-active { display: block !important; }
  .masthead__actions, .tabs, .foot, .powered-by, .no-print { display: none !important; }
  body { background: #fff; }
  .panel-inner { max-width: none; padding: 12px; }
  .invitation { box-shadow: none; page-break-inside: avoid; border: 1px solid var(--gold); }
  .lightbox { display: none !important; }
  .film-frame iframe { display: none; } /* a playing video can't print — the poster prints instead */
  * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}
