/* =====================================================================
   townhall-all-hands-flyer-front-and-center
   "Front & Center" — a broadcast-style townhall meeting notice.

   Design language: a bold, stationery-grade meeting poster. Deep ink
   backdrop, ivory type, signal-amber accents, a radar "signal" motif
   (concentric arcs) and a mono ticker bar — the notice pinned to the
   office board and beamed to every screen. The template works as a
   single-viewport app (only the active panel scrolls) and degrades to
   a plain stacked page when JS is off.

   Palette is driven by CSS custom properties at the top — recolor the
   whole template by editing those values.
   ===================================================================== */

:root {
  --ink-950: #0f1620;          /* page / shell background */
  --ink-900: #131c29;          /* panel background */
  --ink-800: #1a2636;          /* raised cards, inputs */
  --ink-700: #26344a;          /* borders, hairline rules */
  --paper: #f2ecdd;            /* ivory primary text */
  --paper-soft: #c9d2de;       /* secondary text */
  --paper-dim: #93a0b2;        /* muted text */
  --amber-300: #f4c877;        /* soft amber (lives, focus) */
  --amber-400: #e8a33d;        /* primary accent */
  --amber-500: #c9821f;        /* deep amber */
  --signal: #e8a33d;           /* signal-arc stroke color */
  --ok: #67c58f;               /* live / success dot */
  --font-display: "Archivo", "Arial Narrow", "Helvetica Neue", Arial, sans-serif;
  --font-body: "Inter", "Segoe UI", Helvetica, Arial, sans-serif;
  --font-mono: "Space Mono", "SFMono-Regular", Consolas, monospace;
  --radius: 14px;
  --shell-pad: clamp(20px, 5vw, 48px);
}

/* ---------- reset & base ---------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

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

body {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  color: var(--paper);
  background: var(--ink-950);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg { display: block; max-width: 100%; }

h1, h2, h3, h4, p, ul, ol, figure, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }
dd { margin: 0; }

a { color: inherit; }

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

:focus-visible { outline: 2px solid var(--amber-300); outline-offset: 3px; border-radius: 4px; }

/* ---------- utilities ---------- */

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 12px 18px;
  background: var(--paper);
  color: var(--ink-950);
  font-weight: 700;
  border-radius: 0 0 10px 0;
}
.skip-link:focus { left: 0; }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

/* =====================================================================
   SHELL — progressive enhancement
   Without JS everything is a normal stacked page that scrolls.
   With .js it becomes a single-viewport app: 100dvh shell, absolutely
   positioned panels, only the active panel scrolls.
   ===================================================================== */

.shell { min-height: 100vh; }

.panel { display: block; }

/* A hidden panel (e.g. a hidden Free Page) never renders, even in the
   stacked no-JS document — main.js also drops it from the nav. */
.panel[hidden] { display: none; }

.panel-scroll {
  width: 100%;
  max-width: 1080px;
  margin: 0 auto;
  padding: var(--shell-pad) var(--shell-pad) 48px;
}

/* ---- app mode ---- */

.js body {
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

.js .shell {
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.js .panels {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
}

.js .panel {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: rgba(232, 163, 61, 0.4) transparent;
  padding: 0 0 104px;                    /* clearance for the bottom nav */
  visibility: hidden;
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.45s ease, transform 0.45s ease, visibility 0s linear 0.45s;
}

.js .panel::-webkit-scrollbar { width: 10px; }
.js .panel::-webkit-scrollbar-thumb {
  background: rgba(232, 163, 61, 0.35);
  border-radius: 8px;
  border: 3px solid var(--ink-950);
}

.js .panel.is-active {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition-delay: 0s;
}

.js .panel-scroll { min-height: 100%; }

/* Cover centers vertically; falls back to normal scroll on short screens. */
.js .cover-scroll {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* =====================================================================
   AMBIENT SIGNAL LAYER
   JS injects .fx-ring spans; each ring pulses like a broadcast wave.
   ===================================================================== */

.fx-layer { position: fixed; inset: 0; pointer-events: none; z-index: 0; overflow: hidden; }

.fx-ring {
  position: absolute;
  border-radius: 50%;
  border: 1px solid rgba(232, 163, 61, 0.22);
  transform: translate(-50%, -50%);
  opacity: 0;
  animation: signal-pulse 7s ease-out infinite;
  will-change: transform, opacity;
}

@keyframes signal-pulse {
  0%   { transform: translate(-50%, -50%) scale(0.15); opacity: 0; }
  12%  { opacity: 0.7; }
  100% { transform: translate(-50%, -50%) scale(1); opacity: 0; }
}

/* =====================================================================
   TYPOGRAPHY & SHARED BLOCKS
   ===================================================================== */

.eyebrow {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 12px;
  line-height: 1.6;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--amber-400);
}

.event-kicker { display: inline-flex; align-items: center; gap: 14px; }
.event-kicker::before,
.event-kicker::after {
  content: "";
  width: 34px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--amber-400));
}
.event-kicker::after { background: linear-gradient(90deg, var(--amber-400), transparent); }

.event-title {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(3rem, 10vw, 6.4rem);
  line-height: 0.96;
  letter-spacing: -0.015em;
  text-transform: uppercase;
  color: var(--paper);
  margin: 18px 0 0;
}

.event-title .title-accent {
  color: transparent;
  background: linear-gradient(100deg, var(--amber-300) 0%, var(--amber-400) 45%, var(--amber-500) 100%);
  -webkit-background-clip: text;
  background-clip: text;
}

.event-subtitle {
  max-width: 44ch;
  font-size: clamp(1.02rem, 2.2vw, 1.22rem);
  line-height: 1.55;
  color: var(--paper-soft);
  margin: 18px 0 0;
}

.guest-greeting {
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.06em;
  color: var(--amber-300);
  margin-top: 18px;
}
.guest-greeting .greeting-name { color: var(--paper); font-weight: 700; }

/* ---- cover top row: kicker + LIVE ---- */

.cover-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 26px;
}

.cover-live {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--paper-soft);
}

.live-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--ok);
  box-shadow: 0 0 0 0 rgba(103, 197, 143, 0.5);
  animation: live-ping 2.2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

@keyframes live-ping {
  0% { box-shadow: 0 0 0 0 rgba(103, 197, 143, 0.45); }
  70% { box-shadow: 0 0 0 9px rgba(103, 197, 143, 0); }
  100% { box-shadow: 0 0 0 0 rgba(103, 197, 143, 0); }
}

/* ---- signal ornament ---- */

.cover-ornament { display: flex; justify-content: flex-end; margin: -8px 0 10px; }

.ornament-signal {
  width: clamp(84px, 12vw, 132px);
  height: auto;
  color: var(--signal);
  opacity: 0.85;
}

/* ---- ticker bar (mono date/time/venue strip) ---- */

.ticker {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin: 30px 0 0;
  padding: 16px 20px;
  border: 1px solid var(--ink-700);
  background: rgba(19, 28, 41, 0.72);
  border-radius: 10px;
  font-family: var(--font-mono);
  font-size: 13.5px;
  letter-spacing: 0.04em;
  color: var(--paper);
}
/* amber reticle corners — reads like a locked-on broadcast readout,
   echoing the radar ornament, not a generic accent bar. */
.ticker::before,
.ticker::after {
  content: "";
  position: absolute;
  width: 12px;
  height: 12px;
  border: 2px solid var(--amber-400);
  pointer-events: none;
}
.ticker::before {
  top: -1px;
  left: -1px;
  border-right: 0;
  border-bottom: 0;
  border-top-left-radius: 4px;
}
.ticker::after {
  right: -1px;
  bottom: -1px;
  border-left: 0;
  border-top: 0;
  border-bottom-right-radius: 4px;
}

.ticker-item { display: inline-flex; align-items: baseline; gap: 8px; }
.ticker-label {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper-dim);
}
.ticker-sep { color: var(--amber-500); }

/* ---- agenda teaser ---- */

.agenda-teaser {
  margin: 26px 0 0;
  max-width: 560px;
}

.teaser-head {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--paper-dim);
  margin-bottom: 10px;
}

.teaser-list { border-top: 1px solid var(--ink-700); }

.teaser-item {
  display: flex;
  align-items: baseline;
  gap: 16px;
  padding: 9px 2px;
  border-bottom: 1px solid var(--ink-700);
  font-size: 15px;
  color: var(--paper-soft);
}

.teaser-time {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--amber-400);
  min-width: 3ch;
}

/* ---- cover actions + host ---- */

.cover-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin: 32px 0 0;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 15px 28px;
  border-radius: 999px;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.02em;
  text-decoration: none;
  transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.btn-primary {
  background: linear-gradient(100deg, var(--amber-300), var(--amber-400) 55%, var(--amber-500));
  color: var(--ink-950);
}
.btn-primary:hover { transform: translateY(-1px); filter: brightness(1.05); }

.btn-ghost {
  border: 1px solid var(--ink-700);
  color: var(--paper);
  background: transparent;
}
.btn-ghost:hover { border-color: var(--amber-400); color: var(--amber-300); }

.event-host {
  margin: 22px 0 0;
  font-size: 13.5px;
  color: var(--paper-dim);
}
.event-host::before {
  content: "";
  display: inline-block;
  width: 18px;
  height: 1px;
  background: var(--amber-500);
  vertical-align: middle;
  margin-right: 10px;
}

/* =====================================================================
   SECTION HEADS (details / rsvp / guestbook)
   ===================================================================== */

.section-head,
.rsvp-head,
.guestbook-head {
  max-width: 720px;
  margin-bottom: 30px;
}

.section-title,
.rsvp-title,
.guestbook-title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2rem, 5.5vw, 3.1rem);
  line-height: 1.04;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  color: var(--paper);
  margin-top: 12px;
}

.section-lead,
.rsvp-description,
.guestbook-description {
  margin-top: 14px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--paper-soft);
}

/* =====================================================================
   DETAILS PANEL — agenda timeline + logistics grid
   ===================================================================== */

.timeline {
  border: 1px solid var(--ink-700);
  border-radius: var(--radius);
  background: var(--ink-900);
  padding: 24px 26px;
  margin-bottom: 26px;
}

.timeline-title {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--paper-dim);
  margin-bottom: 16px;
}

.event-agenda { counter-reset: agenda; }

.agenda-item {
  display: flex;
  align-items: baseline;
  gap: 20px;
  padding: 11px 0;
  border-top: 1px dashed var(--ink-700);
  font-size: 15.5px;
  color: var(--paper-soft);
}
.agenda-item:first-of-type { border-top: 0; }

.agenda-time {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  color: var(--amber-400);
  min-width: 5.5ch;
}

.agenda-text { line-height: 1.5; }

.detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 16px;
  margin-bottom: 26px;
}

.info-card {
  background: var(--ink-900);
  border: 1px solid var(--ink-700);
  border-radius: var(--radius);
  padding: 22px;
}

.info-title {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--amber-400);
  margin-bottom: 12px;
}

.info-date,
.info-time,
.info-venue,
.info-audience {
  font-weight: 600;
  color: var(--paper);
  line-height: 1.45;
}

.info-address { color: var(--paper-soft); margin-top: 4px; }

.info-note {
  margin-top: 10px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--paper-dim);
}

.event-notes {
  position: relative;
  background: rgba(232, 163, 61, 0.08);
  border: 1px solid var(--ink-700);
  border-radius: 8px;
  padding: 18px 22px;
  font-size: 15px;
  line-height: 1.65;
  color: var(--paper-soft);
  max-width: 820px;
}
/* Mirrored reticle corners (opposite diagonal from .ticker) so the two
   blocks bracket the panel content, not echo the same accent bar. */
.event-notes::before,
.event-notes::after {
  content: "";
  position: absolute;
  width: 12px;
  height: 12px;
  border: 2px solid var(--amber-400);
  pointer-events: none;
}
.event-notes::before {
  top: -1px;
  right: -1px;
  border-left: 0;
  border-bottom: 0;
  border-top-right-radius: 4px;
}
.event-notes::after {
  left: -1px;
  bottom: -1px;
  border-right: 0;
  border-top: 0;
  border-bottom-left-radius: 4px;
}

/* =====================================================================
   OPTIONAL PHOTOGRAPHY
   Cover backdrop + "the room, in pictures" gallery. Both blocks are
   self-contained: delete the HTML and everything reflows cleanly (no
   orphaned CSS/JS).

   Cover: an event photo pinned behind the poster. The img is dimmed with
   CSS filter so ivory poster type keeps AA contrast over ANY user photo
   (bright or dark); the gradient scrim adds edge vignette + legibility.
   The layer is pointer-events:none and never blocks the poster's buttons.
   ===================================================================== */

/* ---- cover backdrop ---- */

.panel-cover { position: relative; }

/* The backdrop doubles as a photo link: tap the photo to open it in the
   lightbox. Clicks on the empty poster space fall through to it (see the
   .cover-scroll pointer-events rules below); interactive cover content
   stays clickable above it. */
.cover-photo {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: block;
  overflow: hidden;
  background: var(--ink-900);   /* shows while the image loads */
}

.cover-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: brightness(0.45) saturate(0.85);  /* keeps type readable over any photo */
}

.cover-photo-scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, rgba(15, 22, 32, 0.55), transparent 42%, rgba(15, 22, 32, 0.35)),
    linear-gradient(180deg, rgba(15, 22, 32, 0.92) 0%, rgba(15, 22, 32, 0.86) 40%, rgba(15, 22, 32, 0.82) 58%, rgba(15, 22, 32, 0.96) 100%);
}

.cover-photo-hint {
  position: absolute;
  right: 18px;
  bottom: 18px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid rgba(232, 163, 61, 0.55);
  background: rgba(15, 22, 32, 0.66);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-family: var(--font-mono);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--amber-300);
  opacity: 0.92;
  transition: opacity 0.2s ease, background-color 0.2s ease;
}
.cover-photo-hint svg { width: 15px; height: 15px; }
.cover-photo:hover .cover-photo-hint { background: rgba(15, 22, 32, 0.85); }
.cover-photo:focus-visible {
  outline: 2px solid var(--amber-300);
  outline-offset: -8px;
  border-radius: var(--radius);
}

.cover-scroll { position: relative; z-index: 1; }

/* Empty poster space passes clicks through to the photo link underneath.
   Only genuinely interactive cover content (links, buttons, the advance
   button) keeps receiving pointer events — the poster block itself must
   NOT trap taps on narrow screens, or the whole cover photo becomes
   unclickable in mobile view. */
.cover-scroll { pointer-events: none; }
.cover-scroll .cover-inner a,
.cover-scroll .cover-inner button,
.cover-scroll .panel-advance { pointer-events: auto; }

/* ---- "the room, in pictures" gallery (Agenda panel) ---- */

.photo-gallery { margin-bottom: 26px; }

.gallery-head { max-width: 720px; margin-bottom: 18px; }

.gallery-title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.5rem, 4vw, 2rem);
  line-height: 1.08;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  color: var(--paper);
  margin-top: 12px;
}

.gallery-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

@media (min-width: 720px) {
  .gallery-grid { grid-template-columns: repeat(3, 1fr); }
  .gallery-item:first-child { grid-column: 1 / -1; }  /* featured venue shot */
}

.gallery-figure {
  position: relative;
  margin: 0;
  overflow: hidden;
  border-radius: var(--radius);
  border: 1px solid var(--ink-700);
  background: var(--ink-900);
  transition: border-color 0.2s ease;
}

/* Every photo is a link — tap to open it full-size in the lightbox. */
.gallery-link {
  display: block;
  position: relative;
  border-radius: var(--radius);
}
.gallery-link:hover .gallery-figure { border-color: rgba(232, 163, 61, 0.55); }
.gallery-link:focus-visible {
  outline: 2px solid var(--amber-300);
  outline-offset: 3px;
  border-radius: var(--radius);
}

.gallery-figure img {
  width: 100%; height: auto;
  aspect-ratio: 4 / 3;          /* crops any user photo to fit the slot */
  object-fit: cover;
  transition: transform 0.45s ease;
}

.gallery-item:first-child .gallery-figure img { aspect-ratio: 16 / 9; }

.gallery-figure:hover img { transform: scale(1.03); }

.gallery-caption {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 30px 16px 12px;
  background: linear-gradient(180deg, transparent, rgba(15, 22, 32, 0.88));
  pointer-events: none;
}

.gallery-caption-label {
  font-family: var(--font-mono);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--amber-300);
}

.gallery-caption-note { font-size: 13px; color: var(--paper-soft); }

/* zoom affordance badge — revealed on hover/focus, always on touch */
.gallery-zoom {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(15, 22, 32, 0.72);
  border: 1px solid rgba(232, 163, 61, 0.5);
  color: var(--amber-300);
  opacity: 0;
  transition: opacity 0.2s ease;
  pointer-events: none;
}
.gallery-zoom svg { width: 17px; height: 17px; }
.gallery-link:hover .gallery-zoom,
.gallery-link:focus-visible .gallery-zoom { opacity: 1; }
@media (hover: none) { .gallery-zoom { opacity: 1; } }

/* ---- official banner (Agenda panel) ---- */

.event-banner { margin-bottom: 26px; }
.event-banner .eyebrow { margin-bottom: 14px; }

.banner-link { display: block; border-radius: var(--radius); }
.banner-link:focus-visible {
  outline: 2px solid var(--amber-300);
  outline-offset: 3px;
  border-radius: var(--radius);
}

.banner-figure {
  position: relative;
  margin: 0;
  overflow: hidden;
  border-radius: var(--radius);
  border: 1px solid var(--ink-700);
  background: var(--ink-900);
  transition: border-color 0.2s ease;
}
.banner-link:hover .banner-figure { border-color: rgba(232, 163, 61, 0.55); }

.banner-figure img {
  width: 100%; height: auto;
  aspect-ratio: 16 / 6;         /* wide banner strip — crops any user art to fit */
  object-fit: cover;
  transition: transform 0.45s ease;
}
.banner-link:hover .banner-figure img { transform: scale(1.02); }

.banner-caption {
  position: absolute;
  inset: auto 0 0 0;
  padding: 26px 16px 12px;
  background: linear-gradient(180deg, transparent, rgba(15, 22, 32, 0.85));
  font-family: var(--font-mono);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--amber-300);
  pointer-events: none;
}

/* ---- recap film (Video panel) ---- */

.film-card {
  max-width: 960px;
  border-radius: var(--radius);
  border: 1px solid var(--ink-700);
  background: var(--ink-900);
  overflow: hidden;
}

.film-trigger {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  cursor: pointer;
}

.film-poster {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  transition: transform 0.45s ease;
}
.film-trigger:hover .film-poster { transform: scale(1.02); }
.film-trigger:focus-visible { outline: none; }
.film-trigger:focus-visible .film-poster {
  outline: 2px solid var(--amber-300);
  outline-offset: -8px;
  border-radius: 10px;
}

.film-play {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: clamp(64px, 12vw, 92px);
  height: clamp(64px, 12vw, 92px);
  border-radius: 50%;
  background: linear-gradient(100deg, var(--amber-300), var(--amber-400) 55%, var(--amber-500));
  color: var(--ink-950);
  box-shadow: 0 10px 34px rgba(232, 163, 61, 0.35);
  transition: transform 0.2s ease, filter 0.2s ease;
}
.film-trigger:hover .film-play { transform: translate(-50%, -50%) scale(1.06); filter: brightness(1.05); }
.film-play svg { width: 30%; height: auto; margin-left: 6%; fill: currentColor; }

.film-frame { padding: 18px; }
.film-frame iframe {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  border-radius: 10px;
  background: var(--ink-950);
}

.film-note {
  padding: 22px;
  border: 1px dashed var(--ink-700);
  border-radius: 10px;
  color: var(--paper-soft);
  font-size: 14.5px;
  line-height: 1.6;
}

.film-cap {
  padding: 0 22px 18px;
  font-size: 13px;
  color: var(--paper-dim);
}
.film-external {
  color: var(--amber-300);
  font-weight: 600;
  text-decoration: none;
}
.film-external:hover { text-decoration: underline; }

/* =====================================================================
   FREE PAGE (optional, re-orderable page)
   A host-owned page of free blocks: each block is a card with a title,
   free text and an OPTIONAL photo. The photo is optional — leave the
   image empty (or delete the figure) and the block stays a clean text
   block. Photos open full-size in the lightbox. Optional: add `hidden`
   to the #free section to hide the whole page (the nav rebuilds
   itself), or move the <section> to re-order it.
   ===================================================================== */

.free-blocks {
  display: grid;
  gap: 18px;
  max-width: 820px;
}

.free-block {
  background: var(--ink-900);
  border: 1px solid var(--ink-700);
  border-radius: var(--radius);
  padding: 18px;
}

.free-block-figure {
  margin: 0;
}

/* Wide featured-shot crop for the free-page photo slot. */
.free-block-figure img {
  aspect-ratio: 16 / 9;
}

/* A block whose image slot is empty (host left it blank) collapses the
   whole photo frame — the block stays a clean text block. */
.free-block-figure:not(:has(img)),
.free-block-figure:empty { display: none; }

.free-block-title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.3rem;
  line-height: 1.2;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  color: var(--paper);
  margin-top: 14px;
}

.free-block-content {
  margin-top: 8px;
  font-size: 15.5px;
  line-height: 1.65;
  color: var(--paper-soft);
}

/* =====================================================================
   PANEL ADVANCE (bottom-of-panel CTA)
   ===================================================================== */

.panel-advance {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 34px;
  padding: 12px 20px;
  border: 1px solid var(--ink-700);
  border-radius: 999px;
  color: var(--paper-soft);
  font-weight: 600;
  font-size: 14px;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.panel-advance:hover { border-color: var(--amber-400); color: var(--amber-300); }

.advance-chevron { width: 16px; height: 16px; }

/* =====================================================================
   RSVP FORM
   ===================================================================== */

.rsvp-form {
  background: var(--ink-900);
  border: 1px solid var(--ink-700);
  border-radius: var(--radius);
  padding: clamp(22px, 4vw, 36px);
  max-width: 720px;
}

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

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

.form-group label,
.attending-fieldset legend {
  display: block;
  font-weight: 600;
  font-size: 14px;
  color: var(--paper);
  margin-bottom: 8px;
}

.label-optional { color: var(--paper-dim); font-weight: 400; font-size: 13px; }

.form-group input[type="text"],
.form-group input[type="email"],
.form-group input[type="tel"],
.form-group input[type="number"],
.form-group select,
.form-group textarea {
  width: 100%;
  font: inherit;
  font-size: 15px;
  color: var(--paper);
  background: var(--ink-800);
  border: 1px solid var(--ink-700);
  border-radius: 10px;
  padding: 12px 14px;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  outline: none;
  border-color: var(--amber-400);
  box-shadow: 0 0 0 3px rgba(232, 163, 61, 0.18);
}

.form-group input::placeholder,
.form-group textarea::placeholder { color: var(--paper-dim); opacity: 0.8; }

.form-group textarea { resize: vertical; min-height: 84px; }

.form-hint {
  font-size: 13px;
  line-height: 1.55;
  color: var(--paper-dim);
  margin-top: 8px;
}

.error {
  display: block;
  color: #f1997e;
  font-size: 13px;
  margin-top: 6px;
}

/* ---- attending segmented control ---- */

.attending-fieldset { border: 0; padding: 0; margin: 0 0 22px; min-inline-size: 0; }

.attending-control {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.attending-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border: 1px solid var(--ink-700);
  border-radius: 12px;
  background: var(--ink-800);
  font-weight: 600;
  font-size: 14.5px;
  color: var(--paper-soft);
  transition: border-color 0.2s ease, color 0.2s ease, background-color 0.2s ease;
}

.attending-btn:hover { border-color: var(--ink-700); color: var(--paper); }

.attending-btn.is-selected {
  border-color: var(--amber-400);
  color: var(--paper);
  background: rgba(232, 163, 61, 0.12);
}

.attending-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 2px solid var(--paper-dim);
  flex: none;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}

.attending-btn.is-selected .attending-dot {
  border-color: var(--amber-400);
  background: var(--amber-400);
  box-shadow: inset 0 0 0 3px var(--ink-800);
}

/* Declining collapses the guest/meal fields (CSS only — inputs stay in the
   DOM and enabled so the platform still serializes the form). */
.is-declining .rsvp-guest-fields { display: none; }
.is-declining .attending-fieldset { margin-bottom: 22px; }

/* ---- guest stepper ---- */

.stepper {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--ink-700);
  border-radius: 12px;
  background: var(--ink-800);
  overflow: hidden;
}

.stepper-btn {
  width: 52px;
  font-size: 22px;
  font-weight: 700;
  color: var(--amber-400);
  background: transparent;
  transition: background-color 0.2s ease;
}
.stepper-btn:hover { background: rgba(232, 163, 61, 0.12); }

.stepper input[type="number"] {
  width: 76px;
  text-align: center;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  font-family: var(--font-mono);
  font-size: 17px;
  font-weight: 700;
  -moz-appearance: textfield;
  appearance: textfield;
}
.stepper input::-webkit-outer-spin-button,
.stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* ---- submit ---- */

#submit-button {
  width: 100%;
  margin-top: 8px;
  padding: 16px 20px;
  border-radius: 12px;
  background: linear-gradient(100deg, var(--amber-300), var(--amber-400) 55%, var(--amber-500));
  color: var(--ink-950);
  font-weight: 800;
  font-size: 16px;
  letter-spacing: 0.02em;
  transition: transform 0.2s ease, filter 0.2s ease;
}
#submit-button:hover { transform: translateY(-1px); filter: brightness(1.05); }
#submit-button:disabled { opacity: 0.6; cursor: wait; transform: none; }

.loading {
  text-align: center;
  margin-top: 14px;
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.08em;
  color: var(--amber-300);
}

/* ---- RSVP deadline countdown ---- */

.rsvp-deadline { display: none; margin-top: 22px; }

.rsvp-deadline-live .rsvp-deadline { display: block; }

.rsvp-deadline-label {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--paper-dim);
  margin-bottom: 12px;
}

.count-wrap {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  max-width: 380px;
}

.count-block {
  background: var(--ink-800);
  border: 1px solid var(--ink-700);
  border-radius: 12px;
  padding: 14px 8px;
  text-align: center;
}

.count-day,
.count-hour,
.count-minute,
.count-second {
  font-family: var(--font-mono);
  font-size: clamp(1.5rem, 5vw, 2rem);
  font-weight: 700;
  color: var(--amber-300);
  line-height: 1.1;
}

.count-unit {
  display: block;
  margin-top: 6px;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper-dim);
}

/* =====================================================================
   GUESTBOOK (mount point styling)
   ===================================================================== */

.guestbook-body {
  max-width: 720px;
}

/* The platform injects entries; style them for a coherent look. */
.guestbook-body .guestbook-entry {
  background: var(--ink-900);
  border: 1px solid var(--ink-700);
  border-radius: var(--radius);
  padding: 20px 24px;
  margin-bottom: 14px;
}

.guestbook-body input[type="text"],
.guestbook-body input[type="email"],
.guestbook-body textarea {
  width: 100%;
  font: inherit;
  font-size: 15px;
  color: var(--paper);
  background: var(--ink-800);
  border: 1px solid var(--ink-700);
  border-radius: 10px;
  padding: 12px 14px;
}

.guestbook-body #load-more {
  display: inline-flex;
  margin-top: 8px;
  padding: 12px 22px;
  border: 1px solid var(--ink-700);
  border-radius: 999px;
  color: var(--paper-soft);
  font-weight: 600;
}
.guestbook-body #load-more:hover { border-color: var(--amber-400); color: var(--amber-300); }

/* The platform injects the functional guestbook form into .guestbook-body
   (Style A mount). The form's .form-group / inputs / .error are styled by
   the shared rules above, but its submit button ships with Bootstrap utility
   classes (.btn .badge-pill .bg-kundangan .d-flex) that this template does
   not load — style the injected bits so the form looks native. */
.guestbook-body .guestbook-form { max-width: 720px; }
.guestbook-body .guestbook-form .d-flex { display: flex; justify-content: center; }
.guestbook-body .guestbook-form button[type="submit"] {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  padding: 12px 26px;
  background: var(--amber-400);
  color: var(--ink-900);
  border: 0;
  border-radius: 999px;
  font-family: inherit;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
}
.guestbook-body .guestbook-form button[type="submit"]:hover { filter: brightness(1.05); }
.guestbook-body .guestbook-form .loading-guestbook { margin-top: 12px; font-size: 14px; color: var(--paper-dim); }

/* Typography inside the injected message list. */
.guestbook-body .guestbook-entry h5 { margin: 0 0 4px; color: var(--amber-300); font-size: 15px; }
.guestbook-body .guestbook-entry p { margin: 0 0 6px; color: var(--paper); font-size: 14px; line-height: 1.55; }
.guestbook-body .guestbook-entry small { color: var(--paper-dim); font-size: 12px; }

/* =====================================================================
   BOTTOM NAV
   ===================================================================== */

.panel-nav {
  flex: none;
  position: sticky;
  bottom: 0;
  z-index: 20;
  padding: 12px 14px calc(12px + env(safe-area-inset-bottom));
  background: rgba(15, 22, 32, 0.9);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-top: 1px solid var(--ink-700);
}

.panel-nav-list {
  display: flex;
  justify-content: center;
  gap: 6px;
  max-width: 560px;
  margin: 0 auto;
}

.panel-nav-item { flex: 1 1 0; min-width: 0; }

.panel-nav-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: 100%;
  padding: 8px 4px 6px;
  border-radius: 12px;
  color: var(--paper-dim);
  transition: color 0.2s ease, background-color 0.2s ease;
}

.panel-nav-btn svg { width: 20px; height: 20px; }

.panel-nav-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.panel-nav-btn:hover { color: var(--paper-soft); }

.panel-nav-btn.is-active {
  color: var(--amber-300);
  background: rgba(232, 163, 61, 0.1);
}

/* =====================================================================
   PHOTO VIEWER (lightbox)
   Full-screen viewer for every [data-lightbox] photo with click-to-zoom.
   Hidden via the [hidden] attribute; main.js reveals it (and removes
   [hidden]) only when a photo is opened.
   ===================================================================== */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
}
.lightbox[hidden] { display: none; }

.lightbox__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(7, 11, 17, 0.92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.lightbox__stage {
  position: relative;
  z-index: 1;
  margin: 0;
  width: min(96vw, 1100px);
  max-height: 92vh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: var(--radius);
  border: 1px solid var(--ink-700);
  background: var(--ink-900);
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.55);
  opacity: 0;
  transform: scale(0.97) translateY(8px);
  transition: opacity 0.22s ease, transform 0.22s ease;
}
.lightbox.is-open .lightbox__stage { opacity: 1; transform: none; }

.lightbox__img {
  display: block;
  max-width: 100%;
  max-height: 78vh;
  object-fit: contain;
  cursor: zoom-in;
  user-select: none;
  -webkit-user-select: none;
  transition: opacity 0.14s ease;
}
.lightbox__img.is-swapping { opacity: 0.25; }

/* zoomed: the image grows to 200% and the stage becomes a pan surface.
   Block layout (not flex) so the oversized image scrolls naturally. */
.lightbox.is-zoomed .lightbox__stage { display: block; overflow: auto; }
.lightbox.is-zoomed .lightbox__img {
  width: 200%;
  max-width: none;
  max-height: none;
  cursor: zoom-out;
}

.lightbox__close,
.lightbox__nav,
.lightbox__zoom {
  position: absolute;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(15, 22, 32, 0.78);
  border: 1px solid var(--ink-700);
  color: var(--paper-soft);
  font-size: 22px;
  line-height: 1;
  transition: color 0.2s ease, border-color 0.2s ease, background-color 0.2s ease;
}
.lightbox__close:hover,
.lightbox__nav:hover,
.lightbox__zoom:hover {
  color: var(--amber-300);
  border-color: var(--amber-400);
  background: rgba(232, 163, 61, 0.12);
}

.lightbox__close { top: 16px; right: 16px; }
.lightbox__zoom { bottom: 16px; right: 16px; font-size: 20px; }
.lightbox__nav { top: 50%; transform: translateY(-50%); }
.lightbox__nav--prev { left: 16px; }
.lightbox__nav--next { right: 16px; }

.lightbox__cap {
  position: absolute;
  left: 18px;
  bottom: 16px;
  right: 78px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  pointer-events: none;
}
.lightbox__name {
  font-size: 14px;
  font-weight: 600;
  color: var(--paper-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lightbox__count {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--paper-dim);
  flex: none;
}

.lightbox__hint {
  position: absolute;
  top: 14px;
  left: 18px;
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--paper-dim);
  pointer-events: none;
}
@media (max-width: 480px) { .lightbox__hint { display: none; } }

/* =====================================================================
   BRAND FOOTER
   Sits after </main>; main.js tucks it into the last live panel so it
   always closes the invitation (hidden in the shell until then).
   ===================================================================== */

.app-footer {
  margin-top: 42px;
  padding-top: 22px;
  border-top: 1px solid var(--ink-700);
  text-align: center;
}
.footer-brand {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 17px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--paper);
}
.footer-note {
  margin-top: 6px;
  font-size: 12.5px;
  color: var(--paper-dim);
}

/* In app mode the footer only shows once main.js has moved it into a panel. */
.js .shell > .app-footer { display: none; }

/* =====================================================================
   POWERED-BY (platform credit line)
   A slim full-width "Powered by Kundangi" strip below the panels in the
   JS shell (and at the end of the stacked document without JS). The
   engine swaps the literal Kundangi token inside .link-footer for the
   platform name at render; the cockpit's Free Powered By field can
   override the whole line. Hidden when printing like the rest of the
   chrome.
   ===================================================================== */

.powered-by {
  flex: none;
  width: 100%;
  padding: 8px 16px calc(8px + env(safe-area-inset-bottom));
  text-align: center;
  border-top: 1px solid var(--ink-700);
  background: rgba(15, 22, 32, 0.92);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--paper-dim);
}
.powered-by .link-footer { color: var(--amber-400); }

/* =====================================================================
   NO-JS FALLBACK
   The shell needs JS for the panel app; without it the stacked page must
   still be usable: show the attending select, hide JS-only widgets.
   ===================================================================== */

.no-js .attending-btn { display: none; }
.no-js .film-trigger { cursor: default; }
.no-js .film-play { display: none; }
.no-js #attending {
  position: static !important;
  width: 100% !important;
  height: auto !important;
  margin: 0 !important;
  clip: auto !important;
  clip-path: none !important;
  overflow: visible !important;
  min-height: 48px;
  padding: 11px 14px;
  font-size: 1rem;
  color: var(--paper);
  background: var(--ink-800);
  border: 1px solid var(--ink-700);
  border-radius: 10px;
}
.no-js .panel-advance { display: none; }

/* =====================================================================
   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;
  }
  .fx-layer { display: none !important; }
  .js .panel { transform: none; }
}

/* =====================================================================
   PRINT
   All panels print as stacked pages; nav and effects are hidden.
   ===================================================================== */

@media print {
  @page { margin: 12mm; }

  html, body { background: #ffffff !important; }
  body { color: #111; }

  .js body,
  .js .shell { height: auto !important; overflow: visible !important; }

  .js .panel {
    position: static !important;
    inset: auto !important;
    display: block !important;
    visibility: visible !important;
    opacity: 1 !important;
    transform: none !important;
    overflow: visible !important;
    padding: 0 !important;
    transition: none !important;
  }

  .panel + .panel { break-before: page; }

  .panel-scroll { max-width: none; padding: 6mm 0; }
  .cover-scroll { justify-content: flex-start; }

  .panel-nav,
  .fx-layer,
  .skip-link,
  .panel-advance,
  .rsvp-deadline,
  .cover-photo,
  .photo-gallery,
  .event-banner,
  .film-card,
  .powered-by,
  .lightbox { display: none !important; }

  .cover-actions { display: none; }

  .event-title .title-accent { color: #7a5200; background: none; -webkit-background-clip: initial; background-clip: initial; }

  .form-group input[type="text"],
  .form-group input[type="email"],
  .form-group input[type="tel"],
  .form-group input[type="number"],
  .form-group select,
  .form-group textarea,
  .guestbook-body input,
  .guestbook-body textarea {
    background: #ffffff !important;
    color: #111 !important;
    border-color: #999 !important;
  }

  * {
    -webkit-print-color-adjust: exact !important;
    print-color-adjust: exact !important;
  }
}
