/* =========================================================
   Blueprint — Workshop Flyer (workshop-modern-flyer)
   A program-poster style flyer for hands-on workshops.
   Contemporary editorial: paper tone, hairline grids, mono
   labels, numbered sections, capacity meter, hard-shadow CTA.
   ========================================================= */

/* ---------- design tokens ---------- */
:root {
  --paper: #f1eee6;
  --paper-2: #e8e4d8;
  --surface: #fffdf8;
  --ink: #17140e;
  --ink-soft: #6a6352;
  --line: rgba(23, 20, 14, 0.16);
  --line-strong: rgba(23, 20, 14, 0.45);
  --accent: #d8ff45;
  --accent-ink: #17140e;
  --danger: #b3261e;
  --radius: 14px;
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Menlo, Consolas, monospace;
}

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

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

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

[hidden] { display: none !important; }

h1, h2, h3, p, dl, ol, ul { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; }
img { max-width: 100%; height: auto; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
summary { list-style: none; }
summary::-webkit-details-marker { display: none; }

::selection { background: var(--accent); color: var(--accent-ink); }

.mono {
  font-family: var(--font-mono);
  font-size: 0.78em;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.muted { color: var(--ink-soft); }

.skip-link {
  position: fixed;
  left: 1rem;
  top: -100px;
  z-index: 100;
  padding: 0.6rem 1rem;
  background: var(--ink);
  color: var(--paper);
  border-radius: 8px;
  text-decoration: none;
  transition: top 0.2s ease;
}
.skip-link:focus { top: 1rem; }

/* ---------- shell: the whole document scrolls naturally ----------
   Middle row is 1fr so short panels (e.g. Guestbook) stretch to fill
   the viewport and the tab bar stays pinned to the bottom, while tall
   content grows the shell and the page scrolls. */
.shell {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  grid-template-rows: auto 1fr auto;
  background: var(--paper);
}

.masthead {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem 1rem;
  padding: 0.75rem clamp(1rem, 4vw, 2.5rem);
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  font-size: 0.82rem;
}
.masthead-brand { font-weight: 700; letter-spacing: 0.01em; }
.masthead-series { color: var(--ink-soft); font-weight: 500; }
.masthead-meta { color: var(--ink-soft); }

.shell-body { min-height: 0; }

/* With JS the shell shows one panel at a time, but the page itself
   scrolls naturally — no viewport lock, no content gets cut off. */
html.js .panel { display: none; }
html.js .panel.is-active { display: block; }

.panel {
  min-height: 0;
  scroll-behavior: smooth;
}

/* ---------- the poster (flyer content) ---------- */
.poster {
  position: relative;
  max-width: 1080px;
  margin: 0 auto;
  padding: clamp(1.5rem, 5vw, 4rem) clamp(1.25rem, 6vw, 4.5rem) clamp(2rem, 6vw, 4rem);
  background:
    radial-gradient(var(--line) 1px, transparent 1.5px) 0 0 / 26px 26px,
    var(--paper);
}
.poster::before {
  /* accent bar — the poster "spine" */
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 6px;
  background: linear-gradient(90deg,
    var(--accent) 0 52%,
    var(--ink) 52% 62%,
    var(--accent) 62% 100%);
}

.poster-head { padding-top: 1rem; }

.kicker {
  color: var(--ink-soft);
  font-weight: 600;
  margin-bottom: 0.75rem;
}

.poster-title {
  font-size: clamp(3rem, 12vw, 7.5rem);
  line-height: 0.95;
  letter-spacing: -0.035em;
  text-transform: uppercase;
  font-weight: 800;
  max-width: 12ch;
}
.accent-tag {
  background: var(--accent);
  padding: 0 0.08em;
  border-radius: 8px;
  display: inline-block;
}

.poster-tagline {
  margin-top: 1.25rem;
  max-width: 46ch;
  font-size: clamp(1.05rem, 2.2vw, 1.3rem);
  font-weight: 500;
}

/* meta grid — the at-a-glance facts */
.poster-meta {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  margin-top: clamp(1.5rem, 4vw, 2.5rem);
  background: var(--line);
  border: 1px solid var(--line);
}
.meta-item { background: var(--surface); padding: 1rem 1.1rem; }
.meta-item dt { color: var(--ink-soft); margin-bottom: 0.35rem; }
.meta-item dd { font-weight: 650; line-height: 1.35; }
.tz { color: var(--ink-soft); font-weight: 500; }

/* capacity meter — the capacity-focused CTA */
.capacity { margin-top: 1.5rem; max-width: 34rem; }
.capacity-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 0.85rem;
  margin-bottom: 0.5rem;
}
.capacity-head .mono { color: var(--ink-soft); }
.capacity-head strong { font-variant-numeric: tabular-nums; letter-spacing: 0.02em; }
.capacity-track {
  position: relative;
  height: 14px;
  border-radius: 999px;
  background: var(--ink);
  overflow: hidden;
}
.capacity-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  background: var(--accent);
  border-radius: 999px 0 0 999px;
  transition: width 0.9s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.capacity-note { margin-top: 0.5rem; font-size: 0.85rem; color: var(--ink-soft); }

/* poster sections */
.poster-sec {
  margin-top: clamp(2.25rem, 6vw, 4rem);
  padding-top: clamp(1.25rem, 3vw, 2rem);
  border-top: 1px solid var(--line-strong);
}
.sec-head {
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  font-size: clamp(1.3rem, 3vw, 1.75rem);
  text-transform: uppercase;
  letter-spacing: -0.02em;
}
.sec-num { color: var(--ink-soft); font-size: 0.62em; }
/* A numbered section whose title was left empty hides the stray "01" — the
   content sections below still render, just without a bare number. */
.poster-sec .sec-head:has(> .sec-num):not(:has(> span:not(.sec-num))) { display: none; }

.learn-list { margin-top: 1.25rem; display: grid; gap: 0.9rem; }
.learn-list li {
  display: flex;
  gap: 0.9rem;
  align-items: baseline;
  font-size: clamp(1rem, 2vw, 1.1rem);
}
.learn-num { color: var(--ink-soft); font-weight: 700; }

.program { margin-top: 1.25rem; border-top: 1px solid var(--line); }
.program li {
  display: grid;
  grid-template-columns: 6.5rem 1fr;
  gap: 1rem;
  padding: 0.8rem 0.25rem;
  border-bottom: 1px solid var(--line);
  align-items: baseline;
}
.program .mono { color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.program span:last-child { font-weight: 550; }

.hosts { margin-top: 1.25rem; display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.host {
  display: flex;
  gap: 1rem;
  padding: 1.25rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.host-avatar {
  flex: 0 0 auto;
  position: relative;
  overflow: hidden;            /* photos clip to the circle */
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--ink);
  color: var(--accent);
  display: grid;
  place-items: center;
  padding: 0;                  /* it is a <button> now — strip UA padding */
  cursor: zoom-in;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.03em;
}
.host-avatar:hover { box-shadow: 0 0 0 2px var(--accent); }
/* Portrait photo fills the circle; the initials sit behind it, so if the
   image is removed or fails to load the styled initials come back. */
.host-avatar img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.host-avatar-fallback { display: grid; place-items: center; }
.host h3 { font-size: 1.05rem; }
.host-role { color: var(--ink-soft); margin: 0.15rem 0 0.5rem; }
.host-bio { font-size: 0.92rem; color: var(--ink-soft); }

.practical { margin-top: 1.25rem; display: grid; gap: 0.9rem; }
.practical li {
  padding: 1rem 1.1rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: 0.98rem;
}
.practical-label::after { content: " \2014\00a0 "; white-space: pre; }
.practical-label { font-weight: 600; }

.faq { margin-top: 1.25rem; border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: baseline;
  padding: 0.9rem 0.25rem;
  font-weight: 650;
  cursor: pointer;
}
.faq summary::after {
  content: "+";
  font-family: var(--font-mono);
  color: var(--ink-soft);
  font-weight: 700;
  transition: transform 0.2s ease;
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq details p {
  padding: 0 2rem 1rem 0.25rem;
  color: var(--ink-soft);
  max-width: 60ch;
}
/* An FAQ entry whose answer was left empty collapses entirely — a question
   that expands to nothing would be a dead tap for guests. */
.faq details:not(:has(.faq-a)) { display: none; }

/* ---------- poster photos (all optional — delete the element to hide) ---------- */
.poster-photo {
  margin-top: clamp(1.5rem, 4vw, 2.5rem);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.poster-photo img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: var(--surface);
}
.photo-cap {
  padding: 0.7rem 1rem;
  border-top: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: 0.75rem;
  letter-spacing: 0.05em;
}
.photo-cap strong { color: var(--ink); font-weight: 700; }

.sec-intro { margin-top: 0.75rem; color: var(--ink-soft); max-width: 52ch; }
.gallery {
  margin-top: 1.25rem;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.1rem;
}
.gallery-item { margin: 0; display: grid; gap: 0.55rem; }
.gallery-photo {
  aspect-ratio: 4 / 3;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.gallery-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* A tile whose photo slot is empty (host left it blank, or the upload failed
   and main.js dropped the img) collapses to its caption instead of leaving an
   empty tap-target. Mirrors the free-block rule below. */
.gallery-photo:not(:has(img)) { display: none; }
.gallery-cap { display: grid; gap: 0.15rem; }
.gallery-cap-k { color: var(--ink-soft); font-size: 0.66rem; letter-spacing: 0.08em; }
.gallery-cap-line { font-size: 0.9rem; font-weight: 650; line-height: 1.35; }

/* ---------- clickable media (all photos open the zoomable lightbox) ----------
   Every photo slot is a real <button>, so the lightbox is keyboard-accessible
   by default. Hover gently lifts the image; focus keeps a visible ring. */
.media-trigger { padding: 0; border: 0; background: none; cursor: zoom-in; }
.poster-photo-btn { display: block; width: 100%; }
.poster-photo-btn img { transition: transform 0.5s ease; }
.poster-photo-btn:hover img { transform: scale(1.015); }
.gallery-photo .gallery-trigger {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
}
.gallery-trigger img { transition: transform 0.5s ease; }
.gallery-trigger:hover img { transform: scale(1.03); }
.media-trigger:focus-visible,
.gallery-trigger:focus-visible,
.video-trigger:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 3px;
  border-radius: var(--radius);
}

/* ---------- optional video feature (section 07) ---------- */
.video-stage { max-width: 820px; margin: 1.25rem 0 0; }
.video-trigger {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface);
  cursor: pointer;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.video-trigger:hover {
  transform: translateY(-2px);
  box-shadow: 0 14px 32px rgba(23, 20, 14, 0.14);
}
.video-poster {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: var(--surface);
}
.video-play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 4.2rem;
  height: 4.2rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--surface);
  color: var(--ink);
  box-shadow: 0 6px 18px rgba(23, 20, 14, 0.3);
  transition: transform 0.25s ease, background 0.25s ease;
}
.video-trigger:hover .video-play { transform: scale(1.06); background: var(--accent); }
.video-play svg { width: 1.5rem; height: 1.5rem; fill: currentColor; margin-left: 0.2rem; }
.video-cap { margin: 0.6rem 0 0; color: var(--ink-soft); font-size: 0.72rem; letter-spacing: 0.05em; }

/* CTA */
.poster-cta {
  margin-top: clamp(2.25rem, 6vw, 4rem);
  padding-top: clamp(1.5rem, 4vw, 2.5rem);
  border-top: 1px solid var(--line-strong);
  text-align: center;
}
.cta {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 1rem;
  padding: 1rem 1.6rem;
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 800;
  font-size: 1.05rem;
  text-decoration: none;
  border-radius: 999px;
  border: 1px solid var(--ink);
  box-shadow: 4px 4px 0 var(--ink);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.cta:hover { transform: translate(2px, 2px); box-shadow: 2px 2px 0 var(--ink); }
.cta-arrow { font-size: 1.2em; }
.cta-block { width: 100%; justify-content: center; margin-top: 0; }
.cta-note {
  margin: 1rem auto 0;
  font-size: 0.85rem;
  color: var(--ink-soft);
  max-width: 42ch;
}

.poster-foot {
  margin-top: 2.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: 0.72rem;
  text-align: center;
  letter-spacing: 0.06em;
}

/* ---------- footer brand placeholder ---------- */
.app-footer { margin-top: 2.5rem; text-align: center; }
.footer-brand {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  border-top: 1px solid var(--line);
  padding: 1rem 1.4rem 0;
}

/* ---------- optional free page (host-owned content) ----------
   The Notes page is a panel like RSVP/Guestbook, so it reuses the
   centered panel-head. Blocks are surface cards: photo (optional), title,
   then free text. */
.free-page {
  max-width: 720px;
  margin: 0 auto;
  padding: clamp(1.5rem, 6vw, 4rem) clamp(1.25rem, 6vw, 2.5rem) clamp(2rem, 6vw, 4rem);
}
.free-blocks { display: grid; gap: 1.25rem; }
.free-block {
  display: grid;
  gap: 0.9rem;
  padding: 1.25rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.free-block-figure { margin: 0; }
.free-block-figure .free-block-btn {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  overflow: hidden;
  border-radius: 8px;
}
.free-block-figure img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: var(--surface);
  transition: transform 0.5s ease;
}
.free-block-btn:hover img { transform: scale(1.015); }
/* A block whose photo slot is empty (host left it blank) collapses the whole
   photo frame — the block stays a clean title + text block. */
.free-block-figure:not(:has(img)),
.free-block-figure:empty { display: none; }
.free-block-title {
  font-size: 1.15rem;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}
.free-block-content { color: var(--ink-soft); max-width: 60ch; font-size: 0.98rem; }

/* ---------- full-width powered-by brand line ----------
   A slim brand strip across the bottom: "Powered by Kundangi". The render
   engine swaps the literal brand name for the platform name; the cockpit's
   Free Powered By field can override the whole line. */
.powered-by {
  width: 100%;
  text-align: center;
  padding: 0.9rem 1rem 1.4rem;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.powered-by .link-footer { color: var(--ink); font-weight: 700; }

/* ---------- photo viewer (native <dialog> lightbox) ----------
   Dark, quiet stage: the image fits first; the ⛶-style zoom button (or
   clicking the image) toggles to actual size inside a scrollable frame.
   "Open original" opens the full-resolution file in a new tab. */
.photo-lightbox {
  width: min(94vw, 1040px);
  max-width: none;
  max-height: 90vh;
  border: 0;
  padding: 0;
  border-radius: var(--radius);
  background: var(--ink);
  color: var(--paper);
  overflow: hidden;
}
.photo-lightbox::backdrop {
  background: rgba(23, 20, 14, 0.78);
  backdrop-filter: blur(4px);
}
.lightbox-frame { position: relative; padding: 1.25rem 1.25rem 1rem; }
.lightbox-figure { margin: 0; }
.lightbox-img {
  display: block;
  max-width: 100%;
  max-height: 76vh;
  margin: 0 auto;
  border-radius: 6px;
  object-fit: contain;
}
.lightbox-caption {
  margin: 0.9rem auto 0;
  max-width: 560px;
  font-size: 0.9rem;
  line-height: 1.5;
  color: rgba(241, 238, 230, 0.8);
  text-align: center;
}
.lightbox-original {
  display: block;
  margin: 0.9rem auto 0;
  width: fit-content;
  font-size: 0.85rem;
  color: rgba(241, 238, 230, 0.72);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.lightbox-original:hover { color: #fff; }
.lightbox-zoom {
  position: absolute;
  top: 0.6rem;
  left: 0.6rem;
  width: 2.2rem;
  height: 2.2rem;
  display: grid;
  place-items: center;
  border: 1px solid rgba(241, 238, 230, 0.3);
  border-radius: 50%;
  background: rgba(241, 238, 230, 0.08);
  color: var(--paper);
  cursor: pointer;
}
.lightbox-zoom:hover { background: rgba(241, 238, 230, 0.18); }
.lightbox-zoom svg {
  width: 1.05rem;
  height: 1.05rem;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.lightbox-img { cursor: zoom-in; }
.photo-lightbox.is-zoomed .lightbox-img { cursor: zoom-out; }
.photo-lightbox.is-zoomed .lightbox-frame {
  overflow: auto;
  max-height: calc(90vh - 0.1px);
}
.photo-lightbox.is-zoomed .lightbox-img {
  max-width: none;
  max-height: none;
  width: auto;
  height: auto;
}
.lightbox-close {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  width: 2.2rem;
  height: 2.2rem;
  display: grid;
  place-items: center;
  border: 1px solid rgba(241, 238, 230, 0.3);
  border-radius: 50%;
  background: rgba(241, 238, 230, 0.08);
  color: var(--paper);
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
}
.lightbox-close:hover { background: rgba(241, 238, 230, 0.18); }
.photo-lightbox[open] { animation: lightbox-in 0.25s ease; }

/* ---------- video viewer (native <dialog>) ---------- */
.video-lightbox {
  width: min(94vw, 980px);
  max-width: none;
  border: 0;
  padding: 0;
  border-radius: var(--radius);
  background: var(--ink);
  color: var(--paper);
  overflow: hidden;
}
.video-lightbox::backdrop {
  background: rgba(23, 20, 14, 0.78);
  backdrop-filter: blur(4px);
}
.video-frame { position: relative; padding: 1.25rem 1.25rem 1rem; }
.video-player {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #000;
  border-radius: 6px;
  overflow: hidden;
}
.video-player iframe,
.video-player video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
.video-notice {
  margin: 0;
  padding: 3rem 1.5rem;
  text-align: center;
  font-size: 0.95rem;
  line-height: 1.7;
  color: rgba(241, 238, 230, 0.82);
}
.video-open {
  display: inline-block;
  margin-top: 0.9rem;
  font-size: 0.85rem;
  color: rgba(241, 238, 230, 0.72);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.video-open:hover { color: #fff; }
.video-lightbox[open] { animation: lightbox-in 0.25s ease; }

@keyframes lightbox-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to { opacity: 1; transform: none; }
}

/* ---------- RSVP & guestbook panels ---------- */
.rsvp-wrap,
.guestbook-section {
  max-width: 640px;
  margin: 0 auto;
  padding: clamp(1.5rem, 6vw, 4rem) clamp(1.25rem, 6vw, 2.5rem) clamp(2rem, 6vw, 4rem);
}
.guestbook-section { max-width: 720px; }

.panel-head { margin-bottom: 1.75rem; }
.panel-head h2 {
  font-size: clamp(1.9rem, 5vw, 2.6rem);
  letter-spacing: -0.02em;
  text-transform: uppercase;
  margin: 0.2rem 0 0.5rem;
}
.panel-intro { color: var(--ink-soft); max-width: 52ch; }

/* ---------- RSVP form ---------- */
.rsvp-form { display: grid; gap: 1.35rem; }
.rsvp-field { display: grid; gap: 0.4rem; }
.rsvp-label { font-weight: 700; font-size: 0.92rem; }
.req { color: var(--danger); }
.opt {
  color: var(--ink-soft);
  font-weight: 500;
  text-transform: uppercase;
  font-size: 0.72em;
  margin-left: 0.35rem;
}
.rsvp-input {
  width: 100%;
  padding: 0.8rem 0.95rem;
  font: inherit;
  font-size: 1rem;            /* 16px minimum avoids iOS zoom-on-focus */
  color: var(--ink);
  background: var(--surface);
  border: 1.5px solid var(--line-strong);
  border-radius: 10px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.rsvp-input::placeholder { color: var(--ink-soft); opacity: 0.7; }
.rsvp-input:focus-visible {
  outline: none;
  border-color: var(--ink);
  box-shadow: 0 0 0 3px var(--accent);
}
.rsvp-input[aria-invalid="true"] { border-color: var(--danger); }
textarea.rsvp-input { resize: vertical; min-height: 96px; }

.field-hint { font-size: 0.8rem; color: var(--ink-soft); }
.field-error {
  display: none;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--danger);
}
.field-error:not(:empty) { display: block; }

.rsvp-fieldset { border: 0; padding: 0; margin: 0; }
.rsvp-choices {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  margin-top: 0.2rem;
}
.choice {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.9rem 1rem;
  border: 1.5px solid var(--line-strong);
  border-radius: 12px;
  background: var(--surface);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.choice input {
  accent-color: var(--ink);
  width: 18px;
  height: 18px;
  margin: 0;
  flex: 0 0 auto;
}
.choice-body { display: grid; gap: 0.1rem; }
.choice small { color: var(--ink-soft); font-size: 0.82rem; }
.choice:focus-within { border-color: var(--ink); }
.choice:has(input:checked) { border-color: var(--ink); background: var(--accent); }
.choice:has(input:checked) small { color: var(--accent-ink); }

.rsvp-conditional { display: grid; gap: 1.35rem; }

.rsvp-regrets {
  padding: 1rem 1.1rem;
  border: 1.5px dashed var(--line-strong);
  border-radius: 12px;
  background: var(--surface);
  color: var(--ink-soft);
  font-size: 0.95rem;
}

.rsvp-actions { display: grid; gap: 0.75rem; }
.rsvp-footnote { font-size: 0.82rem; color: var(--ink-soft); text-align: center; }

.loading {
  display: none;
  align-items: center;
  justify-content: center;
  gap: 0.7rem;
  padding: 0.8rem;
  font-weight: 650;
  font-size: 0.95rem;
  color: var(--ink-soft);
}
/* the platform reveals .loading (jQuery .show() works too — inline style wins) */
.loading.is-active,
.loading.is-visible { display: flex; }
.loading-spinner {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2.5px solid var(--line-strong);
  border-top-color: var(--ink);
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- bottom tab bar ---------- */
.site-tabs {
  position: sticky;
  bottom: 0;
  z-index: 20;
  display: flex;
  border-top: 1px solid var(--line-strong);
  background: var(--surface);
  backdrop-filter: blur(8px);
  padding-bottom: env(safe-area-inset-bottom);
}
.tab {
  flex: 1;
  min-height: 52px;
  padding: 0.75rem 1rem;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
  border-top: 3px solid transparent;
  transition: color 0.15s ease, background 0.15s ease;
}
.tab.is-active { color: var(--ink); background: var(--accent); border-top-color: var(--ink); }
.tab:hover { color: var(--ink); }
.tab:focus-visible { outline: 3px solid var(--ink); outline-offset: -3px; }

/* Desktop top nav — lives in the sticky masthead, shown in JS mode at wide
   widths; the sticky bottom bar stays for mobile/touch. Tabs mirror the
   bottom bar (same data-target / aria-controls) and stay in sync via main.js. */
.topnav { display: none; align-items: center; gap: 0.25rem; }
@media (min-width: 860px) { html.js .topnav { display: flex; } }
@media (min-width: 860px) { html.js .site-tabs { display: none; } }
.topnav .tab {
  flex: 0 0 auto;
  min-height: 0;
  padding: 0.45rem 0.9rem;
  font-size: 0.72rem;
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--ink-soft);
  background: none;
}
.topnav .tab:hover { color: var(--ink); border-color: var(--line); }
.topnav .tab.is-active { color: var(--accent-ink); background: var(--accent); border-color: var(--ink); }

.guestbook-body { min-height: 120px; }

.noscript-note {
  max-width: 60ch;
  margin: 1rem auto 2rem;
  padding: 0.9rem 1.1rem;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  color: var(--ink-soft);
  font-size: 0.9rem;
}

/* ---------- responsive ---------- */
@media (max-width: 900px) {
  .gallery { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 720px) {
  .poster-meta { grid-template-columns: 1fr 1fr; }
  .hosts { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  /* Four tabs on the sticky bottom bar need a little more room on small
     phones — tighten padding/type so every label stays on one line. */
  .site-tabs .tab {
    padding: 0.7rem 0.35rem;
    font-size: 0.72rem;
  }
}
@media (max-width: 480px) {
  .rsvp-choices { grid-template-columns: 1fr; }
  .program li { grid-template-columns: 5rem 1fr; }
  .gallery { grid-template-columns: 1fr; }
}

/* ---------- 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;
  }
  .capacity-fill { transition: none; }
  .skip-link { transition: none; }
}

/* ---------- print: the poster becomes a real flyer ---------- */
@media print {
  @page { margin: 14mm; }
  body { background: #fff !important; }
  .shell { height: auto; display: block; }
  .masthead, .site-tabs, .topnav, .skip-link, .powered-by { display: none !important; }
  html.js .panel { display: block !important; }
  .panel { overflow: visible !important; }
  .poster {
    max-width: none;
    padding: 0;
    background: #fff;
    break-after: page;          /* flyer gets its own page */
  }
  .poster::before { display: none; }
  .poster-sec, .poster-cta, .host, .meta-item, .practical li,
  .poster-photo, .gallery-item, .video-stage { break-inside: avoid; }
  .cta { box-shadow: none; }
  a { text-decoration: none; }
  .photo-lightbox, .video-lightbox { display: none !important; }
}


/* ── Guestbook (platform-injected form + message list) ─────────────── */
.guestbook-body .guestbook-form { text-align: left; }

.guestbook-body #guestbookForm {
  display: grid;
  gap: 1.35rem;
  padding: clamp(1.5rem, 4vw, 2.25rem);
  background: var(--surface);
  border: 1.5px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: 4px 4px 0 rgba(23, 20, 14, 0.14);
}

.guestbook-body #guestbookForm .form-group {
  display: grid;
  gap: 0.4rem;
  margin: 0;
}

.guestbook-body #guestbookForm .form-group label {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.guestbook-body #guestbookForm .form-control {
  width: 100%;
  padding: 0.8rem 0.95rem;
  font: inherit;
  font-size: 1rem;
  color: var(--ink);
  background: #fff;
  border: 1.5px solid var(--line-strong);
  border-radius: 10px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.guestbook-body #guestbookForm .form-control::placeholder { color: var(--ink-soft); opacity: 0.7; }
.guestbook-body #guestbookForm .form-control:focus {
  outline: none;
  border-color: var(--ink);
  box-shadow: 0 0 0 3px var(--accent);
}
.guestbook-body #guestbookForm textarea.form-control { resize: vertical; min-height: 96px; }

.guestbook-body #guestbookForm .error {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--danger);
}

.guestbook-body #guestbookForm .guestbook-chapta {
  max-width: 304px;
  margin: 0 auto;
}

/* !important beats Bootstrap .bg-kundangan / .text-white / .px-3 */
.guestbook-body #guestbookForm button[type="submit"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 1rem 1.6rem !important;
  background: var(--accent) !important;
  color: var(--accent-ink) !important;
  font: inherit;
  font-weight: 800;
  font-size: 1.05rem;
  border: 1px solid var(--ink);
  border-radius: 999px;
  box-shadow: 4px 4px 0 var(--ink);
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.guestbook-body #guestbookForm button[type="submit"]:hover { transform: translate(2px, 2px); box-shadow: 2px 2px 0 var(--ink); }

.guestbook-body .loading-guestbook {
  text-align: center;
  color: var(--ink-soft);
  font-size: 0.9rem;
  padding: 10px;
}

#comments-container.guestbook-wrap {
  border-top: 1px solid var(--line-strong) !important;
  margin-top: 2rem !important;
  max-height: none !important;
  padding-top: 1.25rem;
}

.guestbook-entry {
  padding: 1.1rem;
  margin-bottom: 0.9rem;
  background: var(--surface);
  border: 1.5px solid var(--line-strong);
  border-radius: 12px;
  text-align: left;
}
.guestbook-entry:last-child { margin-bottom: 0; }
.guestbook-entry h5 {
  margin: 0 0 0.35rem;
  font-weight: 800;
  font-size: 1.02rem;
  color: var(--ink);
}
.guestbook-entry p {
  margin: 0 0 0.4rem;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--ink-soft);
  overflow-wrap: anywhere;
}
.guestbook-entry small {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.more-guestbook-wrap { text-align: center; margin-top: 1.5rem; }
#load-more {
  padding: 0.75rem 1.6rem;
  background: transparent;
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  color: var(--ink);
  font: inherit;
  font-weight: 700;
  font-size: 0.95rem;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
#load-more:hover { background: var(--accent); color: var(--accent-ink); }
