/* Components: the shared vocabulary every page is built from. */

/* ---------- Layout ---------- */
.wrap {
  max-width: var(--content-w);
  margin-inline: auto;
  padding-inline: var(--space-m);
}
@media (max-width: 640px) {
  .wrap { padding-inline: var(--space-s); }
}

.section { padding-block: var(--space-2xl); }
.section--tight { padding-block: var(--space-xl); }
.section--sunk { background: var(--paper-sunk); }

.section-head {
  max-width: var(--prose-w);
  margin-bottom: var(--space-l);
}
.eyebrow {
  display: block;
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--space-2xs);
}
.section-head p { color: var(--ink-soft); margin-top: var(--space-xs); }

.grid {
  display: grid;
  gap: var(--space-l);
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 760px) {
  .grid--2, .grid--3 { grid-template-columns: 1fr; }
}

/* ---------- Divider ---------- */
.divider {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  color: var(--accent-soft);
  margin-block: var(--space-l);
}
.divider::before, .divider::after {
  content: "";
  height: 1px;
  width: 3rem;
  background: var(--rule);
}
.divider svg { width: 1rem; height: 1rem; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  padding: 0.85em 1.6em;
  border-radius: var(--radius-m);
  border: var(--border-w) solid transparent;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--step--1);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--accent); color: var(--on-accent); }
.btn-primary:hover { background: var(--accent-strong); color: var(--on-accent); }
.btn-ghost { background: transparent; border-color: var(--rule); color: var(--ink); }
.btn-ghost:hover { border-color: var(--accent); color: var(--accent-strong); }
.btn-link {
  background: none; border: none; padding: 0; text-transform: none;
  letter-spacing: normal; font-weight: 600; color: var(--accent-strong);
  text-underline-offset: 0.2em; text-decoration: underline;
}
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }
.btn-block { width: 100%; }

/* ---------- Cards ---------- */
.card {
  background: var(--paper-raised);
  border: var(--border-w) solid var(--rule);
  border-radius: var(--radius-l);
  padding: var(--space-l);
}
.card h3 { font-size: var(--step-1); margin-bottom: var(--space-2xs); }
.card p { color: var(--ink-soft); }
.card .meta {
  font-size: var(--step--1);
  color: var(--accent);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-bottom: var(--space-2xs);
}

.card-link { text-decoration: none; color: inherit; display: block; }
.card-link .card { transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease); }
.card-link:hover .card { border-color: var(--accent-soft); box-shadow: var(--shadow-m); }

/* A grid of reference cards that are read rather than clicked through (Practical
   Info): the one under the cursor lifts off the page so it's easier to follow.
   Deliberately opt-in, because most .card grids elsewhere are decorative and
   shouldn't twitch when the mouse crosses them. focus-within covers keyboard
   users tabbing through the links inside each card. */
.cards-lift .card {
  transition:
    transform var(--dur-fast) var(--ease),
    box-shadow var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease);
}
.cards-lift .card:hover,
.cards-lift .card:focus-within {
  transform: translateY(-4px);
  box-shadow: var(--shadow-m);
  border-color: var(--accent-soft);
}
@media (prefers-reduced-motion: reduce) {
  .cards-lift .card:hover,
  .cards-lift .card:focus-within { transform: none; }
}

/* ---------- Photo grid ---------- */
.photo-grid {
  display: grid;
  gap: var(--space-s);
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  /* Dense, so a two-column photo that doesn't fit the current row doesn't
     leave a hole behind it. */
  grid-auto-flow: dense;
}
/* The drone shots carry the place; they get two columns where there's room. */
.photo-grid img.photo-wide { grid-column: span 2; aspect-ratio: 16 / 10; }
@media (max-width: 40rem) {
  .photo-grid img.photo-wide { grid-column: span 1; aspect-ratio: 4 / 3; }
}
.photo-grid img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-l);
  border: var(--border-w) solid var(--rule);
  box-shadow: var(--shadow-s);
  display: block;
}

/* ---------- Placeholders (personal content not yet supplied) ---------- */
.placeholder {
  border: 1.5px dashed var(--accent-soft);
  border-radius: var(--radius-l);
  padding: var(--space-l);
  background: var(--accent-tint);
  color: var(--ink-soft);
  text-align: center;
}
.placeholder .placeholder-label {
  display: block;
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-strong);
  margin-bottom: var(--space-2xs);
}
.placeholder-photo {
  aspect-ratio: 4 / 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

/* ---------- Photo carousel ---------- */
.photo-carousel-viewport {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-l);
  border: var(--border-w) solid var(--rule);
  box-shadow: var(--shadow-s);
  background: var(--paper-sunk);
}
.photo-carousel-track {
  display: flex;
  aspect-ratio: 4 / 5;
  transition: transform var(--dur-med) var(--ease);
}
.photo-carousel-slide {
  flex: 0 0 calc(100% / var(--per-view, 1));
  width: calc(100% / var(--per-view, 1));
  height: 100%;
}
/* Several photos side by side: the track grows with its contents instead of
   squeezing three portraits into one portrait-shaped box. */
.photo-carousel--multi .photo-carousel-track { aspect-ratio: auto; }
.photo-carousel--multi .photo-carousel-slide { padding: 0 2px; }
.photo-carousel--multi .photo-carousel-slide img { aspect-ratio: 3 / 4; height: auto; }
/* Valea Verde page: one big photo, the rest in a landscape carousel under it.
   Too many photos for a dot each, so the arrows do the work. */
/* Never wider than the photo itself (752px), so it isn't blown up, and
   shown in its own proportions rather than cropped. */
.vv-main-photo { display: block; width: 100%; max-width: 752px; height: auto; margin-inline: auto; border-radius: var(--radius-m); }
.vv-carousel { max-width: 752px; margin: var(--space-s) auto 0; }
.vv-carousel .photo-carousel--multi .photo-carousel-slide img { aspect-ratio: 4 / 3; }
.vv-carousel .photo-carousel-dots { display: none; }
.photo-carousel-slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.photo-carousel-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 50%;
  border: var(--border-w) solid var(--rule);
  background: color-mix(in srgb, var(--paper-raised) 88%, transparent);
  color: var(--ink);
  font-size: 1.4rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease);
}
.photo-carousel-btn:hover { background: var(--paper-raised); }
.photo-carousel-btn--prev { left: var(--space-2xs); }
.photo-carousel-btn--next { right: var(--space-2xs); }
.photo-carousel-dots {
  display: flex;
  justify-content: center;
  gap: var(--space-2xs);
  margin-top: var(--space-xs);
}
.photo-carousel-dot {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  border: var(--border-w) solid var(--accent-soft);
  background: transparent;
  padding: 0;
  cursor: pointer;
}
.photo-carousel-dot.is-active { background: var(--accent); border-color: var(--accent); }
@media (prefers-reduced-motion: reduce) {
  .photo-carousel-track { transition: none; }
}

/* Two photos side by side at a readable size, for a short chapter that
   doesn't need a carousel at all. */
.photo-pair {
  display: flex;
  gap: var(--space-s);
  justify-content: center;
  flex-wrap: wrap;
}
.photo-pair img {
  width: min(13rem, 42vw);
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--radius-l);
  border: var(--border-w) solid var(--rule);
  box-shadow: var(--shadow-s);
  display: block;
}

/* ---------- Photo strip: an auto-scrolling, black & white filmstrip of
   every photo we have, for a "look at all of them" gallery at the foot of
   a page. Hovering an image brings its colour back. ---------- */
.photo-strip {
  overflow: hidden;
  border-radius: var(--radius-l);
  mask-image: linear-gradient(to right, transparent, black 6%, black 94%, transparent);
}
.photo-strip-track {
  display: flex;
  width: max-content;
  gap: var(--space-2xs);
  animation: photo-strip-scroll var(--photo-strip-duration, 30s) linear infinite;
}
.photo-strip:hover .photo-strip-track { animation-play-state: paused; }
.photo-strip-item {
  flex: 0 0 auto;
  width: 9rem;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-m);
  overflow: hidden;
  border: var(--border-w) solid var(--rule);
}
.photo-strip-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  filter: grayscale(1);
  transition: filter var(--dur-med) var(--ease);
}
.photo-strip-item:hover img { filter: grayscale(0); }
@keyframes photo-strip-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .photo-strip { mask-image: none; overflow-x: auto; }
  .photo-strip-track { animation: none; }
}

/* ---------- Info panels ---------- */
.panel {
  border-left: 3px solid var(--accent);
  background: var(--paper-sunk);
  border-radius: 0 var(--radius-m) var(--radius-m) 0;
  padding: var(--space-s) var(--space-m);
}
.panel--note { border-left-color: var(--ink-faint); }
.panel p:last-child { margin-bottom: 0; }
.panel .panel-label {
  font-size: var(--step--1);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--accent-strong);
  display: block;
  margin-bottom: 0.3em;
}

/* ---------- Botanical motif: procedurally drawn by public/js/botanical.js ----------
   Each .panel / .placeholder / .card--kokedama gets its own generated SVG,
   sized to its actual measured dimensions. See that file for the generator. */
.brand { display: inline-flex; align-items: center; gap: 0.4em; }
.kokedama-icon { width: 1rem; height: 1.4rem; color: var(--accent-soft); flex-shrink: 0; }

.panel, .placeholder, .card--kokedama {
  position: relative;
  overflow: visible;
}
.botanical-deco {
  position: absolute;
  overflow: visible;
  pointer-events: none;
  z-index: 1;
  filter: drop-shadow(0 3px 4px rgba(20, 20, 15, 0.16));
}

/* ---------- Nav ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: blur(6px);
  border-bottom: var(--border-w) solid var(--rule);
}
.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 4.25rem;
}
.brand {
  font-family: var(--font-display);
  font-size: var(--step-1);
  text-decoration: none;
  color: var(--ink);
  letter-spacing: 0.02em;
  white-space: nowrap;
  flex-shrink: 0;
}
.main-nav { display: flex; align-items: center; gap: var(--space-s); min-width: 0; }
.main-nav ul { list-style: none; padding: 0; display: flex; align-items: center; gap: var(--space-s); flex-wrap: nowrap; flex-shrink: 0; }
/* Each item is its own flex box so every link is centred the same way, and
   the margin is cleared because base.css spaces stacked list items with
   `li + li { margin-top: 0.35em }`. In a horizontal nav that applied to every
   item except the first, which is why "Our Story" sat above the rest. */
.main-nav ul li { flex-shrink: 0; display: flex; align-items: center; margin-top: 0; }
.main-nav a {
  color: var(--ink-soft);
  text-decoration: none;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
.main-nav a:hover, .main-nav a[aria-current="page"] { color: var(--accent-strong); }
.main-nav a.btn, .main-nav a.btn:hover { color: var(--on-accent); text-transform: uppercase; }
.nav-toggle { display: none; }

@media (max-width: 1180px) {
  .main-nav ul {
    /* A compact dropdown sized to its own content, capped so it can never
       exceed the visible viewport (scrolling internally if it somehow would),
       rather than a full-screen takeover: the page stays visible and
       scrollable below/around it. */
    position: fixed; top: 4.25rem; left: 0; right: 0; max-height: calc(100vh - 4.25rem);
    flex-direction: column; gap: 0;
    background: var(--paper);
    padding: var(--space-m);
    overflow-y: auto;
    border-bottom: var(--border-w) solid var(--rule);
    border-radius: 0 0 var(--radius-l) var(--radius-l);
    box-shadow: var(--shadow-m);
    transform: translateY(-8px);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
  }
  .main-nav ul[data-open="true"] { opacity: 1; transform: none; pointer-events: auto; }
  .main-nav ul a:not(.btn) { display: block; padding: var(--space-s) 0; border-bottom: 1px solid var(--rule); }
  .main-nav ul li:has(> .btn) { margin-top: var(--space-s); }
  .nav-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.5rem; height: 2.5rem;
    background: none; border: 1px solid var(--rule); border-radius: var(--radius-m);
  }
  .theme-picker-inline, .lang-picker-inline { display: none; }
}

.site-footer {
  border-top: var(--border-w) solid var(--rule);
  padding-block: var(--space-xl);
  color: var(--ink-soft);
  font-size: var(--step--1);
}
.site-footer a { color: var(--ink-soft); }
.footer-grid { display: flex; flex-wrap: wrap; gap: var(--space-l); justify-content: space-between; }

/* ---------- Theme picker (small, persistent control) ---------- */
.theme-picker { display: flex; gap: var(--space-3xs); }
.theme-dot {
  width: 1.6rem; height: 1.6rem; border-radius: 50%;
  border: 2px solid var(--rule);
  cursor: pointer;
  padding: 0;
  background-size: 140%;
  background-position: center 30%;
  background-repeat: no-repeat;
  transition: transform var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.theme-dot:hover { transform: scale(1.1); }
.theme-dot[aria-pressed="true"] { border-color: var(--ink); }
/* Starter critter of each type stands in for its theme's icon. */
/* Unused since the site went black & white: the starter-critter theme dots.
   Kept so restoring the old picker only needs the markup back.
.theme-dot--fire { background-color: #e0a878; background-image: url("/images/critters/charmander.png"); }
.theme-dot--grass { background-color: #a9c19a; background-image: url("/images/critters/bulbasaur.png"); }
.theme-dot--water { background-color: #90b8c0; background-image: url("/images/critters/squirtle.png"); }
*/

/* ---------- Design picker (Colour set + Theme dropdowns) ---------- */
.design-picker { display: flex; flex-wrap: wrap; gap: var(--space-3xs); align-items: center; }
.select-picker {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--ink-soft);
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: var(--radius-s);
  padding: 0.25em 1.5em 0.25em 0.5em;
  cursor: pointer;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23565f4c' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.5em center;
  max-width: 9rem;
}
.select-picker:hover { border-color: var(--accent); color: var(--ink); }
.select-picker:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ---------- Language picker ---------- */
.lang-picker { display: flex; gap: var(--space-3xs); align-items: center; }
.lang-link {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--ink-faint);
  text-decoration: none;
  padding: 0.2em 0.45em;
  border-radius: var(--radius-s);
  border: 1px solid transparent;
}
.lang-link:hover { color: var(--ink); }
.lang-link.is-active { color: var(--accent-strong); border-color: var(--rule); background: var(--paper-sunk); }

/* ---------- Hero ---------- */
.hero {
  padding-block: var(--space-3xl) var(--space-2xl);
  text-align: center;
}
.hero .eyebrow { text-align: center; }
.hero h1 { margin-block: var(--space-xs) var(--space-s); }
.hero-date {
  max-width: var(--prose-w); 
  margin-inline: auto;
  font-family: var(--font-body);
  font-size: var(--step-1);
  color: var(--accent-strong);
  font-weight: 600;
  letter-spacing: 0.03em;
  text-align: center;
}
.hero-date-line { display: block; width: 100%; white-space: nowrap; }
/* Home page: 20 and 22 either side of a large 21, the wedding day itself,
   which sits between two flowering sprigs. */
.hero-days {
  display: flex; align-items: center; justify-content: center;
  gap: clamp(0.4rem, 2vw, 0.9rem); line-height: 1;
}
.hero-day { font-family: var(--font-display); font-weight: 400; font-size: var(--step-2); color: var(--ink-soft); }
.hero-day--main { font-size: var(--step-5); color: var(--ink); letter-spacing: 0; }
.hero-days-sprig { width: clamp(2.2rem, 9vw, 3.6rem); height: auto; flex: none; color: var(--accent-strong); }
.hero-days-sprig--right { transform: scaleX(-1); }
.hero-actions {
  display: flex; gap: var(--space-s); justify-content: center; flex-wrap: wrap;
  margin-top: var(--space-l);
}
.hero-sub { max-width: var(--prose-w); margin-inline: auto; color: var(--ink-soft); }
/* A button given the hidden attribute stays hidden: .btn sets its own display,
   which would otherwise win. */
.btn[hidden] { display: none; }

/* The stone house being built above the names on the home page
   (public/js/stone-house.js). The canvas is 320x140 and scaled up with hard
   pixels; the hero gives up most of its top padding to make room for it. */
.hero--house { padding-top: var(--space-l); }
.stone-house { max-width: 640px; margin: 0 auto var(--space-s); }
.stone-house canvas { display: block; width: 100%; height: auto; image-rendering: pixelated; }
.stone-house-caption {
  margin: var(--space-2xs, .3rem) 0 0; min-height: 1.4em;
  font-size: var(--step--1); color: var(--ink-soft); font-style: italic;
  opacity: 0; transition: opacity 900ms ease;
}
.stone-house-caption.is-built { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .stone-house-caption { transition: none; } }

.countdown-widget {
  display: inline-flex; flex-direction: column; align-items: center; gap: 0.15rem;
  margin-top: var(--space-l); padding: var(--space-m) var(--space-xl);
  background: var(--paper-raised); border: var(--border-w) solid var(--rule); border-radius: var(--radius-l);
  box-shadow: var(--shadow-s);
}
.countdown-number { font-family: var(--font-display); font-size: var(--step-4); font-weight: 700; color: var(--accent-strong); line-height: 1; }
.countdown-label { font-size: var(--step--1); text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-soft); }
@media (max-width: 480px) {
  .countdown-widget { padding: var(--space-s) var(--space-l); }
}

/* ---------- Timeline ---------- */
.timeline { position: relative; padding-left: var(--space-l); }
.timeline::before {
  content: "";
  position: absolute; left: 0.4rem; top: 0.5rem; bottom: 0.5rem;
  width: 2px; background: var(--rule);
}
.timeline-item { position: relative; padding-bottom: var(--space-l); }
.timeline-item:last-child { padding-bottom: 0; }
/* Weekend agenda: one time and one thing per line, times lined up. */
/* Same size as the event title above it; lighter text, bold time. */
.agenda { margin-top: var(--space-2xs); }
.agenda-row { display: grid; grid-template-columns: 5.5rem minmax(0, 1fr); gap: var(--space-s); padding-block: var(--space-2xs); }
.agenda-row + .agenda-row { border-top: 1px dashed var(--rule); }
.agenda-when { font-weight: 700; font-size: var(--step-1); font-variant-numeric: tabular-nums; line-height: 1.3; }
.agenda-when--word { font-size: var(--step-0); font-weight: 600; color: var(--ink-soft); padding-top: .2em; }
.agenda-title { font-size: var(--step-2); margin: 0; line-height: 1.2; }
.agenda-text { margin: .15rem 0 0; color: var(--ink-soft); font-weight: 300; }
@media (max-width: 420px) { .agenda-row { grid-template-columns: 4.2rem minmax(0, 1fr); } }
/* Practical Info dress code: a small heading per day, the shoes note set apart. */
.dress-day { margin: var(--space-s) 0 var(--space-3xs, .2rem); }
.dress-note { border-top: 1px solid var(--rule); padding-top: var(--space-2xs); color: var(--ink-soft); }
.timeline-item::before {
  content: "";
  position: absolute; left: -1.5rem; top: 0.35rem;
  width: 0.65rem; height: 0.65rem; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--paper);
  box-shadow: 0 0 0 2px var(--accent-soft);
}
.timeline-time {
  font-weight: 700; color: var(--accent-strong);
  font-size: var(--step--1); text-transform: uppercase; letter-spacing: 0.04em;
}

/* ---------- Forms ---------- */
.field { margin-bottom: var(--space-m); }
.field label {
  display: block; font-weight: 600; font-size: var(--step--1);
  margin-bottom: var(--space-3xs);
}
.field .hint { color: var(--ink-faint); font-size: var(--step--1); margin-top: 0.3em; }
.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field input[type="date"],
.field input[type="password"],
.field input[type="number"],
.field select,
.field textarea {
  width: 100%;
  padding: 0.75em 0.9em;
  border: var(--border-w) solid var(--rule);
  border-radius: var(--radius-m);
  background: var(--paper-raised);
  color: var(--ink);
}
.field textarea { min-height: 6rem; resize: vertical; }
/* RSVP contact phone: country code picker, then the number. */
.phone-row { display: flex; gap: var(--space-2xs); }
.field .phone-row select { flex: 0 1 12rem; min-width: 0; }
.field .phone-row input { flex: 1 1 auto; min-width: 0; }
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--accent);
}
.choice-group { display: flex; flex-wrap: wrap; gap: var(--space-xs); }
.choice-card {
  border: var(--border-w) solid var(--rule);
  border-radius: var(--radius-m);
  padding: var(--space-s) var(--space-m);
  cursor: pointer;
  flex: 1 1 10rem;
  text-align: center;
}
.choice-card input { position: absolute; opacity: 0; pointer-events: none; }
.choice-card:has(input:checked) { border-color: var(--accent); background: var(--accent-tint); }
.choice-card:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

.form-error { color: var(--accent-strong); font-size: var(--step--1); margin-top: 0.3em; }

/* ---------- FAQ (native <details>, no JS needed) ---------- */
.faq-item {
  border-bottom: var(--border-w) solid var(--rule);
  padding-block: var(--space-m);
}
.faq-item summary {
  cursor: pointer;
  font-family: var(--font-display);
  font-size: var(--step-1);
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "+";
  font-family: var(--font-body);
  font-size: 1.4rem;
  color: var(--accent);
  flex-shrink: 0;
  transition: transform var(--dur-fast) var(--ease);
}
.faq-item[open] summary::after { transform: rotate(45deg); }
.faq-item p { margin-top: var(--space-s); color: var(--ink-soft); }

/* ---------- Wandering critter (easter egg) ---------- */
.wandering-critter {
  position: fixed;
  left: -4rem;
  bottom: 0.5rem;
  z-index: 40;
  pointer-events: none;
  animation-name: critter-walk;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}
.wandering-critter--reverse {
  left: auto;
  right: -4rem;
  animation-name: critter-walk-reverse;
}
.wandering-critter-hopwrap {
  position: relative;
  display: block;
}
.wandering-critter-hopwrap.is-hopping {
  animation: critter-hop 0.5s ease-out;
}
.wandering-critter-sprite {
  width: 32px;
  height: 32px;
  background-repeat: no-repeat;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  transform-origin: bottom center;
  animation: critter-frame 0.5s steps(1) infinite, critter-bob 0.5s ease-in-out infinite alternate;
}
.wandering-critter-exclaim {
  position: absolute;
  top: -1.6rem;
  left: 50%;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.1rem;
  color: var(--accent-strong, #b5502f);
  -webkit-text-stroke: 2px var(--paper, #f6f4ec);
  paint-order: stroke fill;
  animation: critter-exclaim-pop 0.5s ease-out;
  pointer-events: none;
}

@keyframes critter-walk {
  from { transform: translateX(0); }
  to { transform: translateX(calc(100vw + 8rem)); }
}
@keyframes critter-walk-reverse {
  from { transform: translateX(0) scaleX(-1); }
  to { transform: translateX(calc(-100vw - 8rem)) scaleX(-1); }
}
@keyframes critter-frame {
  0%, 49% { background-position: var(--frame-a); }
  50%, 100% { background-position: var(--frame-b); }
}
@keyframes critter-bob {
  from { transform: scale(3) translateY(0); }
  to { transform: scale(3) translateY(-0.1rem); }
}
@keyframes critter-hop {
  0% { transform: translateY(0) scale(1, 1); }
  35% { transform: translateY(-16px) scale(1.08, 0.92); }
  60% { transform: translateY(0) scale(0.94, 1.06); }
  100% { transform: translateY(0) scale(1, 1); }
}
@keyframes critter-exclaim-pop {
  0% { opacity: 0; transform: translate(-50%, 4px) scale(0.6); }
  30% { opacity: 1; transform: translate(-50%, -4px) scale(1.15); }
  70% { opacity: 1; transform: translate(-50%, -2px) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -8px) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .wandering-critter { display: none; }
}

/* ---------- Table ---------- */
table { width: 100%; border-collapse: collapse; font-size: var(--step--1); }
th, td { text-align: left; padding: var(--space-2xs) var(--space-xs); border-bottom: 1px solid var(--rule); }
th { color: var(--ink-soft); font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; font-size: 0.8em; }
.table-scroll { overflow-x: auto; }
.table-scroll table { min-width: 42rem; }

/* ---------- RSVP concepts: passphrase+name popup ---------- */
#concepts-content-blur {
  filter: blur(14px);
  pointer-events: none; /* belt-and-suspenders alongside the inert attribute */
  user-select: none;
}
.concepts-auth-overlay {
  position: fixed; inset: 0; z-index: 999;
  background: rgba(0, 0, 0, .55);
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-m);
}
.concepts-auth-card {
  background: var(--paper-raised); border-radius: var(--radius-l); padding: var(--space-l);
  max-width: 24rem; width: 100%; box-shadow: var(--shadow-m); text-align: center;
}
.concepts-auth-card .field { text-align: left; }

/* ---------- RSVP concepts: review-everything panel ---------- */
.feedback-panel-overlay {
  position: fixed; inset: 0; z-index: 998;
  background: rgba(0, 0, 0, .55);
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-m);
}
.feedback-panel-card {
  background: var(--paper-raised); border-radius: var(--radius-l); padding: var(--space-l);
  max-width: 40rem; width: 100%; max-height: 88vh; display: flex; flex-direction: column;
  box-shadow: var(--shadow-m);
}
.feedback-panel-card > h2 { margin: 0 0 var(--space-2xs); }
.feedback-panel-list { overflow-y: auto; flex: 1; margin: var(--space-s) calc(var(--space-l) * -1); padding: 0 var(--space-l); }
.feedback-row { display: flex; gap: var(--space-s); align-items: flex-start; padding: var(--space-s) 0; border-bottom: 1px solid var(--rule); }
.feedback-row:last-child { border-bottom: none; }
.feedback-thumb {
  width: 2.8rem; height: 2.8rem; border-radius: var(--radius-s); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; font-size: 1.3rem;
  border: 1px solid var(--rule); background: var(--paper-raised);
}
.feedback-row-body { flex: 1; min-width: 0; }
.feedback-row-body h3 { margin: 0 0 .2rem; font-size: var(--step--1); }
.feedback-row-stars { display: flex; gap: .1rem; margin-bottom: .3rem; }
.feedback-row-stars .concept-feedback-star { font-size: 1.1rem; padding: 0; }
.feedback-row-comment {
  width: 100%; font: inherit; font-size: var(--step--2); padding: .3rem .4rem;
  border: 1px solid var(--rule); border-radius: var(--radius-s); background: var(--paper); color: var(--ink); resize: vertical; min-height: 2.2rem;
}
.feedback-row-status { font-size: var(--step--2); color: var(--ink-faint); display: block; margin-top: .2rem; }
.feedback-panel-actions { display: flex; justify-content: space-between; align-items: center; gap: var(--space-s); padding-top: var(--space-m); border-top: 1px solid var(--rule); margin-top: var(--space-s); }
.feedback-panel-close { position: absolute; top: .6rem; right: .8rem; background: none; border: none; font-size: 1.4rem; line-height: 1; color: var(--ink-faint); cursor: pointer; }
.feedback-panel-card { position: relative; }

/* ---------- RSVP concept viewer badge + feedback widget ---------- */
.concept-viewer-badge {
  font-size: var(--step--1);
  color: var(--ink-faint);
  text-align: center;
  padding: var(--space-2xs) var(--space-s);
  background: var(--paper-sunk);
  border-bottom: 1px solid var(--rule);
}
.concept-viewer-badge a { color: inherit; }
.concept-feedback {
  max-width: 30rem;
  margin: var(--space-2xl) auto var(--space-l);
  padding: var(--space-l);
  background: var(--paper-raised);
  border: var(--border-w) solid var(--rule);
  border-radius: var(--radius-m);
  text-align: center;
}
.concept-feedback h3 { margin-top: 0; font-size: var(--step-0); }
.concept-feedback-stars { display: flex; justify-content: center; gap: .25rem; margin-bottom: var(--space-s); }
.concept-feedback-star {
  background: none; border: none; cursor: pointer; font-size: 1.6rem; line-height: 1;
  color: var(--rule); padding: 0 .1rem; transition: color .15s, transform .15s;
}
.concept-feedback-star:hover { transform: scale(1.1); }
.concept-feedback-star.is-active { color: var(--gold); }
.concept-feedback-comment {
  width: 100%; min-height: 4rem; margin-bottom: var(--space-s); font: inherit;
  padding: var(--space-xs); border: var(--border-w) solid var(--rule); border-radius: var(--radius-s);
  background: var(--paper); color: var(--ink); resize: vertical;
}
.concept-feedback-row { display: flex; align-items: center; justify-content: center; gap: var(--space-s); flex-wrap: wrap; }
.concept-feedback-status { font-size: var(--step--1); color: var(--ink-faint); }

/* "Open in maps" next to the venue address: the pin sits on the text baseline
   rather than floating above it. */
.map-link { display: inline-flex; align-items: center; gap: .35em; }
.map-pin { flex: none; }

/* ---------- Opening curtain (partials/intro.ejs) ---------- */
/* The timeline is pure CSS so the page still reveals itself without JS:
   the panels part at 2.2s and the whole overlay stops existing at 3.2s. */
.intro {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  overflow: hidden;
  animation: intro-done 1ms linear 3.2s forwards;
}
.intro.is-gone { display: none; }
.intro-curtain {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 51%;
  background:
    repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.05) 0 3px, rgba(0, 0, 0, 0.12) 3px 14px),
    var(--ink);
  /* Longhands, not the shorthand: "animation: none ... forwards" reads the
     "none" as the fill mode, so the panels snapped shut again once open. */
  animation-duration: 900ms;
  animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1);
  animation-delay: 2.2s;
  animation-fill-mode: forwards;
}
.intro-curtain--left { left: 0; box-shadow: inset -14px 0 26px rgba(0, 0, 0, 0.45); animation-name: intro-part-left; }
.intro-curtain--right { right: 0; box-shadow: inset 14px 0 26px rgba(0, 0, 0, 0.45); animation-name: intro-part-right; }
.intro-card {
  position: relative;
  text-align: center;
  color: var(--paper);
  padding-inline: var(--space-m);
  animation: intro-card-out 500ms ease 2s forwards;
}
.intro-line {
  font-family: var(--font-display, Georgia, serif);
  font-size: clamp(2rem, 7vw, 3.4rem);
  margin: 0 0 0.3rem;
}
.intro-invite {
  margin: 0;
  font-size: clamp(1rem, 2.6vw, 1.25rem);
  letter-spacing: 0.02em;
  opacity: 0.88;
}
.intro-critters {
  display: flex;
  gap: var(--space-s);
  justify-content: center;
  margin-top: var(--space-l);
}
.intro-critter {
  width: 96px;
  height: 96px;
  background-size: 96px 768px;          /* 8 frames of 96px once scaled */
  background-repeat: no-repeat;
  image-rendering: pixelated;
  animation:
    intro-hop 620ms ease-in-out infinite,
    intro-frames 520ms steps(1) infinite;
}
/* Slightly different hop speeds so the row doesn't bounce in lockstep. */
.intro-critter:nth-child(2) { animation-duration: 700ms, 560ms; }
.intro-critter:nth-child(3) { animation-duration: 580ms, 500ms; }
.intro-critter:nth-child(4) { animation-duration: 660ms, 540ms; }
.intro-critter:nth-child(5) { animation-duration: 620ms, 600ms; }
@keyframes intro-hop {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  45% { transform: translateY(-20px) rotate(-5deg); }
  55% { transform: translateY(-20px) rotate(5deg); }
}
/* Frames 2 and 3 are the front-facing pair. */
@keyframes intro-frames {
  0%, 49.9% { background-position: 0 -192px; }
  50%, 100% { background-position: 0 -288px; }
}
@keyframes intro-part-left { to { transform: translateX(-101%); } }
@keyframes intro-part-right { to { transform: translateX(101%); } }
@keyframes intro-card-out { to { opacity: 0; transform: translateY(-10px); } }
@keyframes intro-done { to { visibility: hidden; pointer-events: none; } }
/* intro.js holds this on <html> while the curtain is up, so the page behind
   can't be scrolled and its scrollbar doesn't show through the overlay. */
.intro-lock, .intro-lock body { overflow: hidden; }
@media (max-width: 640px) {
  .intro-critter {
    width: 56px;
    height: 56px;
    background-size: 56px 448px;
  }
  @keyframes intro-frames {
    0%, 49.9% { background-position: 0 -112px; }
    50%, 100% { background-position: 0 -168px; }
  }
}
@media (prefers-reduced-motion: reduce) {
  .intro { display: none; }
}

/* Must stay last: wins the equal-specificity cascade against the unconditional
   .lang-picker rule declared earlier in this file, so the inline picker in the
   header actually hides below the nav breakpoint instead of forcing overflow. */
@media (max-width: 1180px) {
  .lang-picker-inline { display: none; }
}

/* Our Story: "closing the distance". Each row is one year, and the gap
   between the two marks is the distance between Ana and Migi at that point,
   from two countries down to one room. The convergence is spatial rather
   than animated, so the whole thing is static CSS: nothing to run, nothing
   to wait for, and nothing that needs disabling for reduced motion.
   The two people are told apart by shape (solid vs ring) rather than colour,
   because the site is black and white and so is the legend. */
.closer { display: flex; flex-direction: column; gap: var(--space-l); }

.closer-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
  align-items: center;
  margin-bottom: var(--space-xs);
  font-size: 0.85rem;
  color: var(--ink-soft);
}
.closer-key { display: inline-flex; align-items: center; gap: 0.45em; }

.closer-year {
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.closer-step h3 { margin: 0.15em 0 0; }
.closer-step p { margin-top: 0.35em; }

.closer-track { position: relative; height: 2.5rem; margin: var(--space-xs) 0 var(--space-2xs); }
.closer-rail {
  position: absolute; top: 50%; left: 0; right: 0;
  height: var(--border-w); background: var(--rule); transform: translateY(-50%);
}
/* The lit segment is only the part between the two marks, so the eye reads
   the gap itself rather than the full width of the row. */
.closer-span {
  position: absolute; top: 50%; height: var(--border-w);
  background: var(--ink); transform: translateY(-50%);
}
.closer-mark {
  position: absolute; top: 50%;
  width: 11px; height: 11px; border-radius: 50%;
  transform: translate(-50%, -50%);
  box-sizing: border-box;
}
.closer-mark--m { background: var(--ink); }
.closer-mark--a { background: var(--paper-sunk); border: 2px solid var(--ink); }

.closer-plane {
  position: absolute; top: 50%;
  transform: translate(-50%, -50%);
  color: var(--ink);
  background: var(--paper-sunk);
  padding: 0 0.4rem;
}

.closer-caption {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 0.35em var(--space-2xs);
  font-size: 0.85rem; color: var(--ink-soft);
}
.closer-where { font-variant-numeric: tabular-nums; }
.closer-gap { margin-left: auto; font-weight: 600; color: var(--ink); }

@media (max-width: 30rem) {
  .closer-track { height: 2rem; }
  .closer-gap { margin-left: 0; width: 100%; }
}
.closer-key .closer-mark { position: static; transform: none; flex: 0 0 auto; }
.closer-key .closer-mark--a { background: transparent; }

/* Contact page: a big WhatsApp button per person, then email and phone. */
.contact-icon { width: 1.15em; height: 1.15em; flex: none; }
.contact-wa { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: var(--space-s); margin-bottom: var(--space-m); }
.contact-wa-btn { display: flex; align-items: center; justify-content: center; gap: var(--space-xs); padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-m); background: #1f9d55; color: #ffffff; font-weight: 600; font-size: var(--step-1); text-decoration: none; }
.contact-wa-btn:hover { background: #198a49; }
.contact-wa-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.contact-wa-btn .contact-icon { width: 1.5em; height: 1.5em; }
.contact-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: var(--space-s) var(--space-m); }
.contact-person { display: grid; gap: var(--space-3xs); justify-items: start; min-width: 0; }
.contact-person a { display: inline-flex; align-items: center; gap: var(--space-2xs); color: var(--ink); text-underline-offset: 3px; overflow-wrap: anywhere; }
