/* ---------- 01-foundation.css ---------- */
/* ==========================================================================
   FOUNDATION — tokens, fonts, reset, type primitives, layout helpers
   ========================================================================== */

/* ==========================================================================
   DESIGN TOKENS
   Change a value here and it updates everywhere on the site.
   ========================================================================== */
:root {
  /* --- Palette --------------------------------------------------------- */
  --espresso: #2C1B0E;
  --espresso-deep: #1E1209;
  --espresso-ink: #150C05;
  --creme: #FAF9F6;
  --white: #FFFFFF;

  /* Derived tones — all built from the two colors above */
  --on-creme: var(--espresso);
  /* Kyle's rule: every word on creme is espresso, every word on espresso is
     creme — no softened or faded text anywhere. */
  --on-creme-soft: var(--espresso);
  --on-creme-faint: var(--espresso);
  --rule-dark: rgba(44, 27, 14, 0.16);
  --rule-dark-strong: rgba(44, 27, 14, 0.30);

  --on-espresso: var(--creme);
  --on-espresso-soft: var(--creme);
  --on-espresso-faint: var(--creme);
  --rule-light: rgba(250, 249, 246, 0.20);
  --rule-light-strong: rgba(250, 249, 246, 0.38);

  /* --- Type ------------------------------------------------------------ */
  --font-script: 'New Icon Script', 'Snell Roundhand', 'Apple Chancery', cursive;
  --font-serif: 'New Icon Serif', 'Didot', 'Bodoni MT', 'Times New Roman', serif;
  --font-body: 'Outfit', ui-sans-serif, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif;

  --step-body: clamp(0.95rem, 0.25vw + 0.9rem, 1.0625rem);
  --step-small: clamp(0.8rem, 0.15vw + 0.77rem, 0.875rem);
  --step-eyebrow: clamp(0.66rem, 0.12vw + 0.63rem, 0.74rem);

  --tracking-wide: 0.16em;
  --tracking-wider: 0.26em;
  --tracking-widest: 0.34em;

  /* --- Space ----------------------------------------------------------- */
  --gutter: clamp(1.25rem, 5vw, 4rem);
  --container: 1240px;
  --container-narrow: 860px;
  --container-text: 700px;
  --section-y: clamp(4rem, 9vw, 8.5rem);
  --section-y-tight: clamp(2.75rem, 6vw, 5rem);

  /* --- Motion ---------------------------------------------------------- */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-soft: cubic-bezier(0.32, 0.72, 0.28, 1);
  --header-height: 0px;
}

/* ==========================================================================
   FONTS — self-hosted, nothing loads from Google or any other third party.
   Files live in /public/fonts and ship with the repository.

   New Icon Script  -> hero title, script accents  (from your Fonts folder)
   New Icon Serif   -> navigation, titles, labels  (from your Fonts folder)
   Outfit           -> paragraphs, schedules, FAQs (SIL Open Font License,
                       license text at /public/fonts/Outfit-OFL.txt)
   ========================================================================== */

@font-face {
  font-family: 'New Icon Script';
  src: url('/fonts/newicon-script.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'New Icon Serif';
  src: url('/fonts/newicon-serif.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Outfit';
  src: url('/fonts/outfit-400.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Outfit';
  src: url('/fonts/outfit-700.woff') format('woff');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* ==========================================================================
   BASE / RESET
   ========================================================================== */
*,
*::before,
*::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--creme);
  color: var(--on-creme);
  font-family: var(--font-body);
  font-size: var(--step-body);
  line-height: 1.75;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

body.is-locked { overflow: hidden; }

h1, h2, h3, h4, p, figure, blockquote, ul, ol, dl, dd {
  margin: 0;
}

ul, ol { padding: 0; list-style: none; }

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

a {
  color: inherit;
  text-decoration: none;
}

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

iframe { border: 0; }

::selection {
  background: var(--espresso);
  color: var(--creme);
}

/* Focus — visible, but only for keyboard users */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 4px;
}

.skip-link {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translate(-50%, -110%);
  z-index: 200;
  background: var(--espresso);
  color: var(--creme);
  padding: 0.85rem 1.5rem;
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: var(--step-eyebrow);
  transition: transform 0.25s var(--ease);
}
.skip-link:focus-visible { transform: translate(-50%, 0); }

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

/* ==========================================================================
   TYPOGRAPHY PRIMITIVES
   ========================================================================== */

.script {
  font-family: var(--font-script);
  font-weight: 400;
  letter-spacing: 0;
}

.display {
  font-family: var(--font-serif);
  font-weight: 400;
  text-transform: uppercase;
  line-height: 0.98;
  letter-spacing: 0.02em;
}

.eyebrow {
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  font-size: var(--step-eyebrow);
  line-height: 1.6;
  margin: 0 0 1.35rem;
}

.section-heading {
  font-family: var(--font-serif);
  text-transform: uppercase;
  font-weight: 400;
  line-height: 0.98;
  letter-spacing: 0.025em;
  font-size: clamp(2rem, 4.4vw, 3.4rem);
}

.lede {
  font-size: clamp(1rem, 0.5vw + 0.92rem, 1.1875rem);
  line-height: 1.75;
  color: var(--on-creme-soft);
  max-width: 58ch;
}

.prose p + p { margin-top: 1.15em; }

.hairline {
  display: block;
  width: 58px;
  height: 1px;
  background: currentColor;
  opacity: 0.35;
  margin: 1.75rem 0;
}
.hairline--center { margin-inline: auto; }

/* ==========================================================================
   LAYOUT HELPERS
   ========================================================================== */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--narrow { max-width: var(--container-narrow); }
.container--text { max-width: var(--container-text); }

.section { padding-block: var(--section-y); }
.section--tight { padding-block: var(--section-y-tight); }

.section--creme { background: var(--creme); color: var(--on-creme); }
.section--espresso { background: var(--espresso); color: var(--on-espresso); }

.section--espresso .lede { color: var(--on-espresso-soft); }

.section-intro {
  text-align: center;
  max-width: 62ch;
  margin-inline: auto;
  margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
}
.section-intro .section-heading { margin-bottom: 1.25rem; }

.rule-top { border-top: 1px solid var(--rule-dark); }
.section--espresso.rule-top { border-top-color: var(--rule-light); }

/* Two-column editorial grid used on several interior pages */
.split {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.4fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
}
@media (max-width: 860px) {
  .split { grid-template-columns: 1fr; gap: 1.75rem; }
}

.split__label {
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  line-height: 1;
  font-size: clamp(1.7rem, 3.6vw, 2.9rem);
}
.split__label span {
  display: block;
  font-family: var(--font-body);
  text-transform: none;
  letter-spacing: var(--tracking-wide);
  font-size: var(--step-eyebrow);
  color: var(--on-creme-faint);
  margin-top: 0.9rem;
}
.section--espresso .split__label span { color: var(--on-espresso-faint); }



/* ---------- 02-chrome.css ---------- */
/* ==========================================================================
   CHROME — site header, navigation, footer, buttons and links
   ========================================================================== */

/* ==========================================================================
   SITE HEADER + NAVIGATION
   ========================================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--creme);
  border-bottom: 1px solid var(--rule-dark);
}

.site-header__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(0.85rem, 1.8vw, 1.35rem);
  padding: clamp(1rem, 2.2vw, 1.6rem) var(--gutter) clamp(0.75rem, 1.5vw, 1.1rem);
}

/* --- Crest ------------------------------------------------------------- */
.crest { display: block; line-height: 0; }
.crest img {
  width: auto;
  height: clamp(74px, 8vw, 106px);
}

/* --- Desktop nav ------------------------------------------------------- */
.site-nav__list {
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: clamp(1rem, 1.9vw, 2.25rem);
  margin: 0;
}

.site-nav__link {
  position: relative;
  display: inline-block;
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: clamp(0.06em, 0.18vw, 0.12em);
  font-size: clamp(0.92rem, 1.06vw, 1.15rem);
  line-height: 1.2;
  color: var(--espresso);
  transform-origin: center bottom;
  transition: transform 0.4s var(--ease-soft), font-weight 0.2s linear;
  will-change: transform;
}

/* An invisible bold copy reserves the wider bold width up front, so the
   rest of the navigation never shifts when an item goes bold on hover. */
.site-nav__link::before {
  content: attr(data-text);
  display: block;
  height: 0;
  overflow: hidden;
  visibility: hidden;
  font-weight: 700;
  pointer-events: none;
}

.site-nav__link > span {
  position: relative;
  display: inline-block;
}
.site-nav__link > span::after {
  content: '';
  position: absolute;
  left: 0; bottom: -0.55em;
  width: 100%; height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: center;
  transition: transform 0.4s var(--ease-soft);
}

.site-nav__link:hover,
.site-nav__link:focus-visible {
  transform: scale(1.1);
  font-weight: 700;
}
.site-nav__link:hover > span::after,
.site-nav__link:focus-visible > span::after { transform: scaleX(1); }

.site-nav__link[aria-current='page'] > span::after { transform: scaleX(1); }
.site-nav__link[aria-current='page'] { font-weight: 700; }

/* --- Hamburger --------------------------------------------------------- */
.nav-toggle {
  display: none;
  align-items: center;
  gap: 0.7rem;
  padding: 0.5rem 0;
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: var(--step-eyebrow);
  color: var(--espresso);
}
.nav-toggle__bars {
  display: block;
  width: 26px;
}
.nav-toggle__bars i {
  display: block;
  height: 1px;
  background: currentColor;
  transition: transform 0.4s var(--ease), opacity 0.25s linear;
}
.nav-toggle__bars i + i { margin-top: 6px; }
.nav-toggle[aria-expanded='true'] .nav-toggle__bars i:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded='true'] .nav-toggle__bars i:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded='true'] .nav-toggle__bars i:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* --- Mobile panel ------------------------------------------------------ */
.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 55;
  background: var(--creme);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s var(--ease);
}
.mobile-nav[hidden] { display: none; }
.mobile-nav.is-open { opacity: 1; pointer-events: auto; }

.mobile-nav__inner {
  width: 100%;
  max-width: 420px;
  padding: calc(var(--header-height) + 2rem) var(--gutter) 3rem;
  text-align: center;
  max-height: 100vh;
  overflow-y: auto;
}

.mobile-nav__list { display: block; }
.mobile-nav__item { border-bottom: 1px solid var(--rule-dark); }
.mobile-nav__item:first-child { border-top: 1px solid var(--rule-dark); }

.mobile-nav__link {
  display: block;
  padding: 1.05rem 0;
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: clamp(1rem, 3.9vw, 1.25rem);
  color: var(--espresso);
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
}
.mobile-nav.is-open .mobile-nav__link {
  opacity: 1;
  transform: none;
  transition-delay: calc(90ms + var(--i) * 34ms);
}
.mobile-nav__link[aria-current='page'] { font-weight: 700; }



@media (max-width: 1119px) {
  .site-header__inner {
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    padding-block: 0.9rem;
  }
  .site-nav { display: none; }
  .nav-toggle { display: inline-flex; }
  .crest img { height: 62px; }
  /* keeps the crest optically centred with the menu button on the right */
  .site-header__inner::before {
    content: '';
    width: 86px;
    order: -1;
  }
}

@media (max-width: 420px) {
  .nav-toggle__label { display: none; }
  .site-header__inner::before { width: 30px; }
}

/* ==========================================================================
   FOOTER — crest, dividing line, back to top. Tone is set per page.
   ========================================================================== */
.site-footer { text-align: center; }

.site-footer--light {
  background: var(--creme);
  color: var(--on-creme);
  border-top: 1px solid var(--rule-dark);
}
.site-footer--dark {
  background: var(--espresso);
  color: var(--on-espresso);
  border-top: 1px solid var(--rule-light);
}

.site-footer__inner {
  max-width: var(--container);
  margin-inline: auto;
  padding: clamp(3rem, 6.5vw, 5.25rem) var(--gutter) clamp(2.5rem, 5vw, 4rem);
  display: flex;
  flex-direction: column;
  align-items: center;
}

.site-footer__crest {
  width: auto;
  height: clamp(86px, 11vw, 132px);
}

.site-footer__rule {
  display: block;
  width: min(300px, 62vw);
  height: 1px;
  margin: clamp(2rem, 4vw, 3rem) 0;
  background: currentColor;
  opacity: 0.26;
}

/* --- back to top ---------------------------------------------------------
   Deliberately unlike the outlined buttons elsewhere: a solid block that
   inverts against whichever ground the footer is sitting on. */
.to-top {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  padding: 1em 2.4em;
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  font-size: var(--step-eyebrow);
  line-height: 1;
  border: 1px solid currentColor;
  font-size: clamp(0.72rem, 0.85vw, 0.84rem);
  transition: background-color 0.4s var(--ease), color 0.4s var(--ease),
              border-color 0.4s var(--ease);
}

/* Outlined at rest, filling in on hover. */
.site-footer--light .to-top {
  background: transparent;
  color: var(--espresso);
  border-color: var(--rule-dark-strong);
}
.site-footer--light .to-top:hover,
.site-footer--light .to-top:focus-visible {
  background: var(--espresso);
  border-color: var(--espresso);
  color: var(--creme);
}

.site-footer--dark .to-top {
  background: transparent;
  color: var(--creme);
  border-color: var(--rule-light-strong);
}
.site-footer--dark .to-top:hover,
.site-footer--dark .to-top:focus-visible {
  background: var(--creme);
  border-color: var(--creme);
  color: var(--espresso);
}

.to-top__arrow {
  display: block;
  width: 14px;
  height: 14px;
  transition: transform 0.4s var(--ease-soft);
}
.to-top__arrow svg { width: 100%; height: 100%; display: block; }
.to-top:hover .to-top__arrow { transform: translateY(-3px); }

/* ==========================================================================
   BUTTONS & LINKS
   ========================================================================== */
.btn {
  display: inline-block;
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  font-size: var(--step-eyebrow);
  line-height: 1;
  padding: 1.15em 3.1em;
  border: 1px solid currentColor;
  background: transparent;
  transition: background-color 0.45s var(--ease), color 0.45s var(--ease),
              border-color 0.45s var(--ease);
  will-change: background-color, color;
}

/* Transparent with a white border — used over the hero photography */
.btn--ghost {
  color: var(--white);
  border-color: rgba(255, 255, 255, 0.9);
}
.btn--ghost:hover,
.btn--ghost:focus-visible {
  background: var(--white);
  border-color: var(--white);
  color: var(--espresso);
}

/* Espresso outline on creme */
.btn--dark { color: var(--espresso); border-color: var(--rule-dark-strong); }
.btn--dark:hover,
.btn--dark:focus-visible { background: var(--espresso); border-color: var(--espresso); color: var(--creme); }

/* Creme outline on espresso */
.btn--light { color: var(--creme); border-color: var(--rule-light-strong); }
.btn--light:hover,
.btn--light:focus-visible { background: var(--creme); border-color: var(--creme); color: var(--espresso); }

/* A link that isn't live yet — still legible, clearly not clickable. */
.btn[aria-disabled='true'],
.btn--pending {
  /* a notice shaped like the button, not a button: it cannot be clicked */
  border-style: dashed;
  pointer-events: none;
  cursor: default;
  max-width: 46ch;
  padding: 1.15em 2em;
  line-height: 1.6;
  letter-spacing: 0.08em;
  text-indent: 0;
  text-transform: none;
  font-size: clamp(0.85rem, 0.4vw + 0.76rem, 0.98rem);
}

/* A quiet inline link with an underline that draws itself in */
.link {
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: var(--step-eyebrow);
  position: relative;
  display: inline-block;
  padding-bottom: 0.35em;
}
.link::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: currentColor;
  opacity: 0.35;
  transform-origin: left;
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
}
.link:hover::after,
.link:focus-visible::after { opacity: 1; transform: scaleX(1.04); }


/* ---------- 03-home.css ---------- */
/* ==========================================================================
   HOME — hero, countdown, Our Story / The Proposal, placeholders
   ========================================================================== */

/* ==========================================================================
   HERO — a slow, continuous strip of photographs behind the title
   ========================================================================== */
.hero {
  position: relative;
  height: clamp(540px, 78svh, 900px);
  overflow: hidden;
  /* espresso, not creme: if the clamped height lands on a fractional pixel the
     sliver that shows matches the countdown below instead of flashing white */
  background: var(--espresso);
  isolation: isolate;
}

.hero__stage {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.hero__track {
  /* zero: the photographs run edge to edge with no line between them */
  --hero-gap: 0px;
  display: flex;
  gap: var(--hero-gap);
  height: 100%;
  width: max-content;
  animation: hero-drift var(--hero-duration, 150s) linear infinite;
  will-change: transform;
}

.hero__slide {
  flex: 0 0 auto;
  height: 100%;
  aspect-ratio: 2 / 3;
  margin: 0;
  overflow: hidden;
  background: var(--espresso);
}
.hero__slide picture,
.hero__slide img {
  width: 100%;
  height: 100%;
}
.hero__slide img { object-fit: cover; }

/* One full loop moves the strip by exactly half its content plus one gap,
   which lands the duplicate set precisely where the first set started. */
@keyframes hero-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(calc(-50% - (var(--hero-gap) / 2)), 0, 0); }
}

/* Just enough shading for the script to stay legible on any photograph */
.hero__scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 80% 66% at 50% 55%,
      rgba(28, 17, 9, 0.52) 0%,
      rgba(28, 17, 9, 0.38) 45%,
      rgba(28, 17, 9, 0.12) 78%,
      rgba(28, 17, 9, 0) 93%),
    linear-gradient(to bottom,
      rgba(28, 17, 9, 0.16) 0%,
      rgba(28, 17, 9, 0.04) 28%,
      rgba(28, 17, 9, 0.04) 72%,
      rgba(28, 17, 9, 0.20) 100%);
}

.hero__content {
  position: relative;
  z-index: 2;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 2rem var(--gutter);
  color: var(--white);
}

.hero__title {
  font-family: var(--font-script);
  font-weight: 400;
  font-size: clamp(2.7rem, 8.5vw, 7rem);
  line-height: 1;
  letter-spacing: 0;
  margin: 0;
  padding-bottom: 0.08em;
  text-shadow: 0 2px 38px rgba(28, 17, 9, 0.42);
}

.hero__meta {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.75rem clamp(0.9rem, 2.4vw, 1.5rem);
  margin-top: clamp(1.4rem, 3vw, 2.4rem);
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  font-size: clamp(0.98rem, 1.8vw, 1.32rem);
  text-shadow: 0 1px 22px rgba(28, 17, 9, 0.5);
}
.hero__meta-rule {
  display: inline-block;
  width: 1px;
  height: 0.95em;
  background: rgba(255, 255, 255, 0.55);
}

.hero__cta {
  margin-top: clamp(2.1rem, 4.2vw, 3.25rem);
  /* larger lettering, tighter padding — the button itself stays the same size */
  font-size: clamp(0.98rem, 1.6vw, 1.2rem);
  padding: 1em 2.95em;
  border-width: 1.5px;
}

@media (max-width: 640px) {
  .hero { height: clamp(500px, 76svh, 720px); }
  /* stacked on a narrow screen, the divider between the date and the
     location just floats between two lines — drop it */
  .hero__meta { flex-direction: column; gap: 0.45rem; }
  .hero__meta-rule { display: none; }
  .hero__track { --hero-gap: 0px; }
  .hero__cta { padding: 0.95em 2.5em; }
}

/* ==========================================================================
   COUNTDOWN — split-flap
   ========================================================================== */
.countdown {
  background: var(--espresso);
  color: var(--on-espresso);
  text-align: center;
  /* closes the same sub-pixel seam from the other side */
  margin-top: -1px;
  position: relative;
}

.countdown__inner {
  max-width: var(--container);
  margin-inline: auto;
  padding: clamp(2.75rem, 6vw, 5rem) var(--gutter);
}

.countdown__eyebrow {
  font-family: var(--font-script);
  font-size: clamp(1.7rem, 4vw, 2.8rem);
  line-height: 1.2;
  color: var(--on-espresso);
  opacity: 1;
  margin-bottom: clamp(1.25rem, 2.6vw, 2rem);
}

.countdown__grid {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: clamp(0.9rem, 4vw, 3.25rem);
}

.countdown__unit { flex: 0 0 auto; }

.countdown__digits {
  display: flex;
  justify-content: center;
  gap: clamp(2px, 0.5vw, 5px);
}

.countdown__label {
  margin-top: clamp(0.8rem, 1.7vw, 1.2rem);
  font-family: var(--font-serif);
  text-transform: uppercase;
  /* sized to match the hero's date and location line */
  letter-spacing: clamp(0.05em, 0.4vw, 0.24em);
  font-size: clamp(0.8rem, 1.8vw, 1.32rem);
  color: var(--on-espresso-soft);
  white-space: nowrap;
  /* the tracking on the last letter otherwise pushes the word off-centre */
  text-indent: clamp(0.05em, 0.4vw, 0.24em);
}

.countdown__done {
  font-family: var(--font-script);
  font-size: clamp(2rem, 5vw, 3.2rem);
  margin-top: 1.5rem;
}

/* --- the flipping digit ------------------------------------------------ */
.flip {
  transform-style: preserve-3d;
  --flip-w: clamp(1.7rem, 5.6vw, 3.6rem);
  --flip-h: clamp(2.9rem, 9.6vw, 6.2rem);
  --flip-size: clamp(2.5rem, 8.3vw, 5.4rem);
  /* New Icon Serif sits its lining figures high in the em box; this drops
     them so the fold line crosses the optical centre of the number. */
  --flip-nudge: 0.126em;
  /* Solid, never translucent. Two stacked translucent panels were what made
     the changing digit look smudged mid-flip. */
  --flip-face: #3A2514;
  --flip-fold: rgba(250, 249, 246, 0.14);

  position: relative;
  display: block;
  width: var(--flip-w);
  height: var(--flip-h);
  perspective: 620px;
  font-family: var(--font-serif);
  color: var(--creme);
}

.flip__panel {
  position: absolute;
  left: 0;
  width: 100%;
  height: 50%;
  overflow: hidden;
  background: var(--flip-face);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.flip__panel--upper,
.flip__panel--fold-upper {
  top: 0;
  border-bottom: 1px solid var(--flip-fold);
}
.flip__panel--lower,
.flip__panel--fold-lower { bottom: 0; }

.flip__char {
  display: block;
  width: 100%;
  height: var(--flip-h);
  font-size: var(--flip-size);
  line-height: var(--flip-h);
  text-align: center;
  font-variant-numeric: tabular-nums;
  transform: translateY(var(--flip-nudge));
}
.flip__panel--lower .flip__char,
.flip__panel--fold-lower .flip__char {
  transform: translateY(calc(-50% + var(--flip-nudge)));
}

/* The folding panels are always present. At rest the upper one lies flat over
   the static upper half showing the same digit, and the lower one stands
   edge-on and invisible. Nothing is ever shown or hidden mid-animation, so
   there is no flicker on the digit that is changing. */
.flip__panel--fold { z-index: 3; }
.flip__panel--fold-upper {
  transform-origin: bottom center;
  transform: rotateX(0deg);
}
.flip__panel--fold-lower {
  transform-origin: top center;
  transform: rotateX(90deg);
}

.flip.is-flipping .flip__panel--fold-upper {
  animation: flip-upper 0.22s cubic-bezier(0.45, 0, 0.75, 0.3) forwards;
}
.flip.is-flipping .flip__panel--fold-lower {
  animation: flip-lower 0.22s cubic-bezier(0.25, 0.7, 0.4, 1) 0.22s forwards;
}

@keyframes flip-upper {
  from { transform: rotateX(0deg); }
  to   { transform: rotateX(-90deg); }
}
@keyframes flip-lower {
  from { transform: rotateX(90deg); }
  to   { transform: rotateX(0deg); }
}

@media (max-width: 400px) {
  .countdown__grid { gap: 0.55rem; }
  .flip { --flip-w: 1.55rem; --flip-size: 2.2rem; --flip-h: 2.6rem; }
}

/* ==========================================================================
   OUR STORY  /  THE PROPOSAL
   ========================================================================== */
.story {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: stretch;
}

/* The photographs are stacked, in the order listed in src/data/story.js, each
   one in a frame of its own — the same frame design as the wedding party, at
   photo size. Every photo keeps its own shape at every screen width: nothing
   is cropped or stretched as the browser changes. */
.story__media {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(1.5rem, 2.6vw, 2.5rem);
  padding: clamp(2rem, 4vw, 4rem) clamp(1.5rem, 3.4vw, 3.5rem);
}
.story__frame {
  /* One size for all six photographs, on both sections. It is set from The
     Proposal, whose text is the shorter of the two: three of these frames
     plus their gaps come out about as tall as that paragraph column. The
     Our Story text is longer and simply runs a little past its photos. */
  margin: 0 auto;
  width: min(100%, 430px);
  padding: clamp(7px, 1vw, 11px);
}
.story__frame-inner {
  box-shadow: inset 0 0 0 1px var(--rule-light);
  padding: clamp(5px, 0.7vw, 8px);
}
.story__frame picture { display: block; }
.story__frame .photo {
  display: block;
  width: 100%;
  height: auto;
}
.story__frame .placeholder { display: flex; }

/* Espresso frames on the creme section, creme frames on the espresso one, so
   each frame reads clearly against its own ground. */
.story--light .story__frame,
.story--light .story__frame-inner { background: var(--espresso); }
.story--light .story__frame-inner { box-shadow: inset 0 0 0 1px var(--rule-light); }
.story--dark .story__frame,
.story--dark .story__frame-inner { background: var(--creme); }
.story--dark .story__frame-inner { box-shadow: inset 0 0 0 1px var(--rule-dark); }

.story__body {
  display: flex;
  align-items: center;
  padding: clamp(2.75rem, 6vw, 6.5rem) clamp(1.5rem, 5vw, 5.5rem);
}
.story__body-inner { max-width: 48ch; }

.story--light .story__body { background: var(--creme); color: var(--on-creme); }
.story--dark  .story__body { background: var(--espresso); color: var(--on-espresso); }

/* The ground behind the frames is the section's own. */
.story--light .story__media { background: var(--creme); }
.story--dark  .story__media { background: var(--espresso); }

.story__heading {
  font-family: var(--font-serif);
  font-weight: 400;
  text-transform: uppercase;
  line-height: 0.95;
  letter-spacing: 0.025em;
  font-size: clamp(2.4rem, 5.4vw, 4.4rem);
}

.story__rule {
  display: block;
  width: 56px;
  height: 1px;
  background: currentColor;
  opacity: 0.32;
  margin: clamp(1.5rem, 2.6vw, 2.1rem) 0;
}

.story__text {
  color: inherit;
  opacity: 1;
  line-height: 1.85;
}
.story__text + .story__text { margin-top: 1.15em; }

@media (max-width: 900px) {
  .story { grid-template-columns: 1fr; }
  /* phones: one framed photo only (the `mobileImage` one), no stacking */
  .story__media { display: block; padding: clamp(1.75rem, 7vw, 2.75rem) var(--gutter); }
  .story__frame { display: none; }
  .story__frame--mobile { display: block; }
  /* photo always leads on small screens, whichever way the desktop row runs */
  .story--flip .story__media { order: -1; }
  .story__body { padding: clamp(2.5rem, 9vw, 3.5rem) var(--gutter); }
}

/* ==========================================================================
   IMAGE + EMBED PLACEHOLDERS
   Quiet, intentional stand-ins for artwork that hasn't arrived yet.
   ========================================================================== */
.placeholder {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  width: 100%;
  aspect-ratio: var(--placeholder-ratio, 3 / 4);
  padding: 1.5rem;
  text-align: center;
}

.placeholder--light {
  background: #EFEAE2;
  color: var(--on-creme-faint);
  box-shadow: inset 0 0 0 1px var(--rule-dark);
}
.placeholder--dark {
  background: #3A2514;
  color: var(--on-espresso-soft);
  box-shadow: inset 0 0 0 1px var(--rule-light);
}

.placeholder::after {
  content: '';
  position: absolute;
  inset: 12px;
  border: 1px solid currentColor;
  opacity: 0.22;
  pointer-events: none;
}

.placeholder__mark svg {
  width: clamp(28px, 4vw, 40px);
  height: auto;
  opacity: 0.75;
}

.placeholder__label {
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: var(--step-eyebrow);
  line-height: 1.5;
}
.placeholder__hint {
  font-family: var(--font-body);
  font-size: 0.68rem;
  letter-spacing: 0.02em;
  opacity: 0.7;
  word-break: break-word;
}

.photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* --- embeds ------------------------------------------------------------ */
.embed {
  width: 100%;
  /* centres a provider's fallback link before its script swaps in the widget */
  text-align: center;
}
.embed iframe {
  width: 100%;
  min-height: var(--embed-height, 900px);
  display: block;
  margin-inline: auto;
}

.embed-placeholder {
  width: 100%;
  min-height: min(var(--embed-height, 900px), 460px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(2.5rem, 6vw, 5rem) 1.5rem;
  background: #EFEAE2;
  box-shadow: inset 0 0 0 1px var(--rule-dark);
  position: relative;
}
.embed-placeholder::after {
  content: '';
  position: absolute;
  inset: 14px;
  border: 1px solid var(--rule-dark);
  pointer-events: none;
}
.embed-placeholder__inner { text-align: center; max-width: 34ch; }
.embed-placeholder__mark {
  display: block;
  width: 46px;
  height: 1px;
  background: var(--rule-dark-strong);
  margin: 0 auto 1.5rem;
}
.embed-placeholder__label {
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  font-size: clamp(0.72rem, 1.4vw, 0.86rem);
  color: var(--on-creme-soft);
}
.embed-placeholder__hint {
  margin-top: 0.9rem;
  font-size: 0.78rem;
  color: var(--on-creme-faint);
  word-break: break-word;
}

/* Same panel, sitting on an espresso section. */
.embed-placeholder--dark {
  background: #3A2514;
  box-shadow: inset 0 0 0 1px var(--rule-light);
}
.embed-placeholder--dark::after { border-color: var(--rule-light); }
.embed-placeholder--dark .embed-placeholder__mark { background: var(--rule-light-strong); }
.embed-placeholder--dark .embed-placeholder__label { color: var(--on-espresso-soft); }
.embed-placeholder--dark .embed-placeholder__hint { color: var(--on-espresso-faint); }




/* ---------- 04-pages.css ---------- */
/* ==========================================================================
   INTERIOR PAGES — page header, schedule, wedding party, FAQ, favorites, panels
   ========================================================================== */

/* ==========================================================================
   INTERIOR PAGE HEADER — the espresso title band
   ========================================================================== */
.page-header {
  background: var(--espresso);
  color: var(--on-espresso);
  text-align: center;
}

.page-header__inner {
  max-width: var(--container-narrow);
  margin-inline: auto;
  padding: clamp(3rem, 8vw, 6.5rem) var(--gutter) clamp(2.75rem, 6.5vw, 5.25rem);
}

.page-header__eyebrow {
  font-family: var(--font-script);
  font-size: clamp(1.4rem, 3.4vw, 2.3rem);
  line-height: 1.25;
  color: #EFEAE2;
  margin-bottom: clamp(0.6rem, 1.4vw, 1rem);
}

.page-header__title {
  font-family: var(--font-serif);
  font-weight: 400;
  text-transform: uppercase;
  font-size: clamp(2.5rem, 7.6vw, 5.75rem);
  line-height: 1;
  letter-spacing: 0.05em;
  /* the tracking on the final letter otherwise pulls the word left */
  text-indent: 0.05em;
}

.page-header__intro {
  margin-top: clamp(1.25rem, 2.6vw, 1.85rem);
  color: var(--on-espresso-soft);
  font-size: clamp(0.95rem, 0.4vw + 0.88rem, 1.0625rem);
  max-width: 56ch;
  margin-inline: auto;
}

/* ==========================================================================
   SCHEDULE
   ========================================================================== */
.day { position: relative; }
.day--creme { background: var(--creme); color: var(--on-creme); }
.day--creme + .day--creme { border-top: 1px solid var(--rule-dark); }
.day--primary { background: var(--espresso); color: var(--on-espresso); }

.day__inner {
  max-width: var(--container);
  margin-inline: auto;
  padding: clamp(2.75rem, 6vw, 5.5rem) var(--gutter);
  display: grid;
  grid-template-columns: minmax(200px, 0.75fr) minmax(0, 2fr);
  gap: clamp(1.75rem, 4vw, 4.5rem);
  align-items: start;
}

.day__aside { position: sticky; top: calc(var(--header-height) + 2rem); }
.day__name {
  font-family: var(--font-serif);
  font-weight: 400;
  text-transform: uppercase;
  font-size: clamp(2rem, 4.4vw, 3.6rem);
  line-height: 0.98;
  letter-spacing: 0.03em;
}
.day__date {
  margin-top: 0.9rem;
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: clamp(0.9rem, 1.8vw, 1.32rem);
  opacity: 1;
}

/* one dress code for the whole day, under the date */
.day__attire {
  margin-top: 0.9rem;
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: clamp(0.85rem, 1.6vw, 1.15rem);
  opacity: 1;
}
.day__note {
  margin-top: 1.1rem;
  font-size: var(--step-small);
  line-height: 1.7;
  opacity: 1;
  max-width: 30ch;
}
.day__flag {
  display: inline-block;
  margin-bottom: 1rem;
  padding: 0.45em 1.1em;
  border: 1px solid var(--rule-light-strong);
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  font-size: 0.62rem;
}

.day__events { border-top: 1px solid currentColor; border-color: var(--rule-dark); }
.day--primary .day__events { border-color: var(--rule-light); }

.event {
  display: grid;
  grid-template-columns: minmax(120px, 190px) minmax(0, 1fr);
  gap: clamp(1rem, 2.5vw, 2.5rem);
  padding: clamp(1.4rem, 2.6vw, 2.1rem) 0;
  border-bottom: 1px solid var(--rule-dark);
}
.day--primary .event { border-bottom-color: var(--rule-light); }
.event:last-child { border-bottom: 0; }

.event__time {
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: clamp(0.9rem, 1.8vw, 1.32rem);
  line-height: 1.5;
  padding-top: 0.05em;
}

.event__title {
  font-family: var(--font-serif);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: clamp(1.15rem, 2.2vw, 1.65rem);
  line-height: 1.15;
}
.event__location {
  margin-top: 0.5rem;
  font-size: var(--step-small);
  letter-spacing: 0.06em;
  opacity: 1;
}
.event__address {
  margin-top: 0.4rem;
  font-size: var(--step-small);
  line-height: 1.65;
  opacity: 1;
}
.event__address span { display: block; }

.event__description {
  margin-top: 0.85rem;
  font-size: var(--step-small);
  line-height: 1.8;
  opacity: 1;
  max-width: 60ch;
}
.event__attire {
  display: inline-block;
  margin-top: 1rem;
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: clamp(0.85rem, 1.6vw, 1.15rem);
  opacity: 1;
}
.event__attire::before { content: 'Attire — '; }

@media (max-width: 860px) {
  .day__inner { grid-template-columns: 1fr; gap: 1.5rem; }
  .day__aside { position: static; }
  .day__note { max-width: none; }
}
@media (max-width: 560px) {
  .event { grid-template-columns: 1fr; gap: 0.45rem; }
  .event__time { padding-top: 0; }
}

/* ==========================================================================
   WEDDING PARTY & FAMILY
   ========================================================================== */
.party { background: var(--creme); color: var(--on-creme); }

/* the espresso page header already supplies the breathing room above */
.party__top { padding-block: clamp(1.5rem, 3vw, 2.75rem) clamp(3rem, 6vw, 5.5rem); }
.party__bottom {
  padding-block: clamp(3rem, 6vw, 5.5rem);
  border-top: 1px solid var(--rule-dark);
}

.party__side + .party__side { padding-top: clamp(3rem, 6vw, 5.5rem); }

.party__heading {
  text-align: center;
  font-family: var(--font-serif);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: clamp(1.6rem, 3.6vw, 2.6rem);
  line-height: 1.1;
  text-indent: 0.06em;
}

.party__lead {
  display: flex;
  justify-content: center;
  margin-top: clamp(2rem, 4vw, 3rem);
}

/* Every frame on the page is the same size: --member-w is worked out from
   the width of the side (4 across on desktop) and shared by both grids.
   A grid of six is simply narrowed so it wraps as two rows of three.
   Flex rather than grid so a short final row stays centred. */
.party__side {
  container-type: inline-size;
  --cols: 4;
  --col-gap: clamp(1rem, 2.6vw, 2.25rem);
  --member-w: calc((100cqi - (var(--cols) - 1) * var(--col-gap)) / var(--cols));
}
.party__grid {
  --per-row: var(--cols);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(1.5rem, 3.4vw, 3rem) var(--col-gap);
  max-width: calc(var(--per-row) * var(--member-w) + (var(--per-row) - 1) * var(--col-gap) + 1px);
  margin-inline: auto;
  margin-top: clamp(2.75rem, 5vw, 4rem);
}
.party__grid--threes { --per-row: 3; }
.party__grid > .member {
  flex: 0 0 var(--member-w);
  max-width: var(--member-w);
}

/* --- one person -------------------------------------------------------- */
.member { margin: 0; text-align: center; }
.member--lead { width: min(300px, 70vw); }

.member__frame {
  padding: clamp(7px, 1vw, 11px);
  background: var(--espresso);
}
.member__frame-inner {
  box-shadow: inset 0 0 0 1px var(--rule-light);
  padding: clamp(5px, 0.7vw, 8px);
  background: var(--espresso);
}
.member__frame-inner .placeholder {
  background: #3A2514;
  box-shadow: none;
  color: var(--on-espresso-soft);
}
.member__frame-inner .placeholder::after { inset: 8px; }

.member__photo { aspect-ratio: 4 / 5; }

.member__caption { margin-top: clamp(0.9rem, 1.6vw, 1.25rem); }
.member__name {
  font-family: var(--font-body);
  font-size: clamp(0.88rem, 1.4vw, 1.02rem);
  letter-spacing: 0.02em;
  line-height: 1.4;
}
.member--lead .member__name { font-size: clamp(1rem, 1.8vw, 1.2rem); }
.member__role {
  margin-top: 0.4rem;
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: clamp(0.76rem, 1.1vw, 0.88rem);
  font-weight: 700;
  color: var(--on-creme);
  text-indent: var(--tracking-wide);
}
.member__note {
  margin-top: 0.7rem;
  font-size: 0.78rem;
  line-height: 1.7;
  color: var(--on-creme-faint);
  max-width: 28ch;
  margin-inline: auto;
}

/* --- family ------------------------------------------------------------ */
.families {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(2.5rem, 5vw, 5rem);
}
.family__heading {
  text-align: center;
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: clamp(1.25rem, 2.6vw, 1.85rem);
  margin-bottom: clamp(1.75rem, 3vw, 2.5rem);
  text-indent: 0.05em;
}
.family__list { border-top: 1px solid var(--rule-dark); }

/* officiant, flower girl and guest book attendants, under Our Families */
.party__roles {
  margin-top: clamp(2.75rem, 5.5vw, 4.5rem);
  max-width: 34rem;
  margin-inline: auto;
}
.family__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.25rem;
  padding: clamp(0.85rem, 1.8vw, 1.15rem) 0;
  border-bottom: 1px solid var(--rule-dark);
}
.family__name {
  font-family: var(--font-body);
  font-size: clamp(0.95rem, 1.6vw, 1.08rem);
  letter-spacing: 0.02em;
}
.family__role {
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: clamp(0.76rem, 1.1vw, 0.88rem);
  font-weight: 700;
  color: var(--on-creme);
  text-align: right;
}

@media (max-width: 1000px) {
  .party__side { --cols: 3; }
}
@media (max-width: 760px) {
  .families { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .party__side { --cols: 2; }
  .party__grid--threes { --per-row: 2; }
}

/* ==========================================================================
   FAQ ACCORDION — built on native <details> so it works without JS
   ========================================================================== */
.faq { border-top: 1px solid var(--rule-dark); }

.faq__item { border-bottom: 1px solid var(--rule-dark); }

.faq__question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: clamp(1.15rem, 2.4vw, 1.75rem) 0;
  cursor: pointer;
  list-style: none;
  transition: color 0.3s var(--ease);
}
.faq__question::-webkit-details-marker { display: none; }
.faq__question:hover { color: var(--espresso); }

.faq__question-text {
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: clamp(0.92rem, 1.8vw, 1.2rem);
  line-height: 1.4;
}

.faq__icon {
  position: relative;
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
}
.faq__icon i {
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transition: transform 0.4s var(--ease-soft), opacity 0.3s linear;
}
.faq__icon i:last-child { transform: rotate(90deg); }
.faq__item[open] .faq__icon i:last-child { transform: rotate(0deg); opacity: 0; }

.faq__answer { overflow: hidden; }
.faq__answer-inner {
  padding-bottom: clamp(1.3rem, 2.6vw, 1.9rem);
  padding-right: clamp(0, 6vw, 3rem);
  max-width: 68ch;
  color: var(--on-creme-soft);
  font-size: var(--step-small);
  line-height: 1.85;
}
.faq__answer-inner p + p { margin-top: 1em; }

/* JS measures and animates the panel height; without JS it simply opens. */
.js-accordion .faq__answer {
  height: 0;
  transition: height 0.42s var(--ease-soft);
}
.js-accordion .faq__item[open] .faq__answer { height: auto; }

/* ==========================================================================
   LOCAL FAVORITES
   ========================================================================== */
.favorites .faq__question-text { font-size: clamp(1.25rem, 2.6vw, 1.9rem); letter-spacing: 0.05em; }
.favorites .faq__icon { width: 18px; height: 18px; }
.favorites__panel { padding-bottom: clamp(1rem, 2vw, 1.5rem); }
.favorites__panel > ul > .place:first-child { border-top: 1px solid var(--rule-dark); }

/* the extra names at the foot of a category's drop-down */
.more-box {
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
  padding: clamp(1.1rem, 2.2vw, 1.6rem) clamp(1.25rem, 2.6vw, 2rem);
  box-shadow: inset 0 0 0 1px var(--rule-dark-strong);
  text-align: center;
}
.more-box__label {
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  font-size: 0.82rem;
  text-indent: var(--tracking-wider);
}
.more-box__text {
  margin-top: 0.55rem;
  font-size: clamp(0.95rem, 1.4vw, 1.1rem);
  letter-spacing: 0.02em;
}

.place {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(240px, 26vw, 340px);
  align-items: start;
  gap: 1rem clamp(1.5rem, 4vw, 3rem);
  padding: clamp(1.5rem, 2.8vw, 2.1rem) 0;
  border-bottom: 1px solid var(--rule-dark);
}

/* the framed map beside a place — espresso frame, click opens Google Maps */
.place__map {
  --map-frame: clamp(6px, 0.8vw, 9px);
  position: relative;
  aspect-ratio: 4 / 3;
  padding: var(--map-frame);
  background: var(--espresso);
  overflow: hidden;
}
.place__map iframe {
  position: absolute;
  top: var(--map-frame);
  left: var(--map-frame);
  width: calc(100% - 2 * var(--map-frame));
  height: calc(100% - 2 * var(--map-frame));
  border: 0;
  display: block;
}
.place__map-link {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* the map sits quietly dimmed until you point at it */
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: clamp(0.85rem, 1.1vw, 1rem);
  text-indent: var(--tracking-wide);
  color: var(--creme);
  text-decoration: none;
  background: rgba(44, 27, 14, 0.45);
  text-shadow: 0 1px 3px rgba(44, 27, 14, 0.85);
  transition: background-color 0.4s var(--ease), opacity 0.35s var(--ease);
}
.place__map-link > span { transition: opacity 0.3s var(--ease); }
/* hovering clears both the dim and the label so the map reads clearly */
.place__map-link:hover,
.place__map-link:focus-visible { background-color: rgba(44, 27, 14, 0); }
.place__map-link:hover > span { opacity: 0; }

.place__name {
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: 0.045em;
  font-size: clamp(0.95rem, 1.8vw, 1.15rem);
  line-height: 1.3;
}
.place__description + .place__description { margin-top: 0.85rem; }
.place__note { grid-column: 1 / -1; }
.games {
  grid-column: 1 / -1;
  margin-top: 1.1rem;
}
/* each game is its own row: details on the left, framed map on the right */
.game {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(240px, 26vw, 340px);
  align-items: start;
  gap: 1rem clamp(1.5rem, 4vw, 3rem);
}
.game + .game { margin-top: clamp(1.5rem, 2.6vw, 2.1rem); }
.game__day {
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: 0.8rem;
  text-indent: var(--tracking-wide);
}
.game__matchup {
  margin-top: 0.3rem;
  font-size: var(--step-small);
  line-height: 1.6;
}
.game__venue {
  margin-top: 0.15rem;
  font-size: var(--step-small);
  line-height: 1.6;
}
.game .place__address { margin-top: 0.15rem; }
.game .place__meta { margin-top: 0.3rem; }
.game .place__map { margin-top: 0; }
.place__meta {
  margin-top: 0.75rem;
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: clamp(0.92rem, 1.1vw, 1.05rem);
  text-indent: var(--tracking-wide);
}
.place__description {
  margin-top: 0.55rem;
  font-size: var(--step-small);
  line-height: 1.8;
  color: var(--on-creme-soft);
  max-width: 62ch;
}
.place__address {
  margin-top: 0.6rem;
  font-size: 0.86rem;
  line-height: 1.6;
  letter-spacing: 0.03em;
  font-style: italic;
  color: var(--on-creme-faint);
}
.place__address + .place__address { margin-top: 0.15rem; }
.place__link { align-self: center; white-space: nowrap; }

@media (max-width: 640px) {
  .place,
  .place--with-photo,
  .game { grid-template-columns: 1fr; }
  .place__map { max-width: 100%; }
  .place__link { align-self: start; }
}

/* ==========================================================================
   PANELS — hotels, transportation, attire, dessert, registry links
   ========================================================================== */
.panel {
  border: 1px solid var(--rule-dark);
  padding: clamp(1.6rem, 3.4vw, 2.75rem);
  background: var(--creme);
}
.section--espresso .panel { border-color: var(--rule-light); background: transparent; }

.panel__tag {
  display: inline-block;
  margin-bottom: 1.1rem;
  padding: 0.45em 1em;
  border: 1px solid var(--rule-dark-strong);
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  font-size: 0.6rem;
}
.panel__title {
  font-family: var(--font-serif);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: clamp(1.3rem, 2.6vw, 1.9rem);
  line-height: 1.15;
}
.panel__sub {
  margin-top: 0.7rem;
  font-size: var(--step-small);
  color: var(--on-creme-soft);
  line-height: 1.7;
}
.panel__body {
  margin-top: 1.35rem;
  font-size: var(--step-small);
  line-height: 1.85;
  color: var(--on-creme-soft);
  max-width: 62ch;
}
.panel__actions { margin-top: 1.75rem; }

.panel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}

/* definition rows inside a panel */
.spec { margin-top: 1.5rem; border-top: 1px solid var(--rule-dark); }
.spec__row {
  display: grid;
  grid-template-columns: minmax(110px, 0.6fr) minmax(0, 1fr);
  gap: 1rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--rule-dark);
}
.spec__key {
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: clamp(0.78rem, 1.15vw, 0.9rem);
  color: var(--on-creme-soft);
  padding-top: 0.15em;
}
.spec__value { font-size: clamp(0.95rem, 1.2vw, 1.08rem); line-height: 1.6; }

/* numbered / timed steps (transportation, dessert) */
.steps { border-top: 1px solid var(--rule-dark); }
.section--espresso .steps { border-top-color: var(--rule-light); }
.step {
  display: grid;
  grid-template-columns: minmax(90px, 140px) minmax(0, 1fr);
  gap: clamp(1rem, 2.5vw, 2.5rem);
  padding: clamp(1.2rem, 2.4vw, 1.75rem) 0;
  border-bottom: 1px solid var(--rule-dark);
}
.section--espresso .step { border-bottom-color: var(--rule-light); }
.step__marker {
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: clamp(0.92rem, 1.65vw, 1.12rem);
  padding-top: 0.1em;
  white-space: nowrap;
}
.step__title {
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: 0.045em;
  font-size: clamp(1rem, 2vw, 1.3rem);
  line-height: 1.25;
}
.step__body {
  margin-top: 0.6rem;
  font-size: var(--step-small);
  line-height: 1.8;
  opacity: 1;
  max-width: 62ch;
}

.notes { margin-top: 1.75rem; }
.notes li {
  position: relative;
  padding-left: 1.4rem;
  font-size: var(--step-small);
  line-height: 1.8;
  opacity: 1;
}
.notes li + li { margin-top: 0.55rem; }
.notes li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.85em;
  width: 10px; height: 1px;
  background: currentColor;
  opacity: 0.6;
}

/* checklists (attire) */
.checklist { margin-top: 1.5rem; border-top: 1px solid var(--rule-dark); }
.section--espresso .checklist { border-top-color: var(--rule-light); }
.checklist li {
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--rule-dark);
  font-size: var(--step-small);
  line-height: 1.6;
}
.section--espresso .checklist li { border-bottom-color: var(--rule-light); }

/* colour palette swatches (attire) */
.swatches {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1rem, 2.4vw, 1.75rem);
  margin-top: 1.75rem;
}
.swatch { text-align: center; }
.swatch__chip {
  width: clamp(54px, 9vw, 74px);
  height: clamp(54px, 9vw, 74px);
  box-shadow: inset 0 0 0 1px var(--rule-dark-strong);
}
.swatch__label {
  margin-top: 0.7rem;
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.6rem;
  color: var(--on-creme-faint);
}

/* big statement line (attire, dessert) */
.statement {
  font-family: var(--font-serif);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: 1.05;
  font-size: clamp(2.1rem, 5.6vw, 4.25rem);
}
.statement--script {
  font-family: var(--font-script);
  text-transform: none;
  letter-spacing: 0;
  line-height: 1.15;
  font-size: clamp(2.4rem, 6.4vw, 4.75rem);
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 0;
  border-top: 1px solid var(--rule-dark);
  border-left: 1px solid var(--rule-dark);
}
.section--espresso .cards { border-color: var(--rule-light); }
.card {
  padding: clamp(1.5rem, 3vw, 2.4rem);
  border-right: 1px solid var(--rule-dark);
  border-bottom: 1px solid var(--rule-dark);
}
.section--espresso .card { border-color: var(--rule-light); }
.card__heading {
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: clamp(0.95rem, 1.8vw, 1.15rem);
  line-height: 1.3;
}
.card__body {
  margin-top: 0.9rem;
  font-size: var(--step-small);
  line-height: 1.85;
  opacity: 1;
}



/* ==========================================================================
   ATTIRE — examples image
   ========================================================================== */
.examples-frame {
  margin-top: clamp(2.25rem, 4.5vw, 3.5rem);
  padding: clamp(8px, 1vw, 13px);
  box-shadow: inset 0 0 0 1px var(--rule-light);
}
.examples-frame picture { display: block; }
.examples-frame .photo { width: 100%; height: auto; }

/* ==========================================================================
   PANELS ON AN ESPRESSO SECTION
   The panel styles default to creme-ground colours; these flip them.
   ========================================================================== */
.section--espresso .panel__sub,
.section--espresso .panel__body { color: var(--on-espresso-soft); }
.section--espresso .panel__tag { border-color: var(--rule-light-strong); }
.section--espresso .spec { border-top-color: var(--rule-light); }
.section--espresso .spec__row { border-bottom-color: var(--rule-light); }
.section--espresso .spec__key { color: var(--on-espresso-faint); }
.section--espresso .notes li,
.section--espresso .step__body { color: var(--on-espresso-soft); opacity: 1; }

/* ==========================================================================
   NOTICE — the banner that sits under a page header, separate from it
   ========================================================================== */
.notice {
  background: #EFEAE2;
  border-bottom: 1px solid var(--rule-dark);
  text-align: center;
}
.notice .container {
  padding-block: clamp(2.25rem, 4.5vw, 3.5rem);
}
.notice__heading {
  font-family: var(--font-serif);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wider);
  font-size: clamp(0.92rem, 1.6vw, 1.15rem);
  line-height: 1.3;
  text-indent: var(--tracking-wider);
}
.notice__body {
  margin-top: clamp(1.1rem, 2.2vw, 1.6rem);
  font-size: var(--step-small);
  line-height: 1.85;
  color: var(--on-creme-soft);
  max-width: 68ch;
  margin-inline: auto;
}
.notice__body p + p { margin-top: 1em; }

/* ==========================================================================
   AFTER-NOTE — the paragraphs under an embed
   ========================================================================== */
.after-note {
  margin-top: clamp(2.25rem, 4vw, 3rem);
  text-align: center;
  max-width: 62ch;
  margin-inline: auto;
  font-size: clamp(1rem, 0.5vw + 0.9rem, 1.2rem);
  line-height: 1.85;
  color: var(--on-creme-soft);
}
.section--espresso .after-note { color: var(--on-espresso-soft); }
.after-note p + p { margin-top: 1em; }
.after-note strong { font-weight: 700; }

/* second role line, e.g. "Brother of the Groom" under "Best Man" */
.member__subrole {
  margin-top: 0.3rem;
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-size: clamp(0.72rem, 1.05vw, 0.84rem);
  font-weight: 700;
  color: var(--on-creme-faint);
  text-indent: var(--tracking-wide);
}


/* Every subheading on an espresso page header uses the same darker creme as
   the "A Note on Hotel Rates" band on the Travel page (#EFEAE2). */
.page-header__intro,
.page-header__eyebrow { color: #EFEAE2; opacity: 1; }

/* ==========================================================================
   COOKIE TABLE SIGN-UP
   One row per cookie; each chip below it is one dozen.
   ========================================================================== */
.cookie-table {
  margin-top: clamp(2.25rem, 4.5vw, 3.5rem);
  border-top: 1px solid var(--rule-light);
}

.cookie-row {
  display: grid;
  grid-template-columns: minmax(200px, 0.85fr) minmax(0, 1.9fr);
  gap: clamp(1rem, 2.5vw, 2.5rem);
  align-items: baseline;
  padding: clamp(1.35rem, 2.6vw, 1.9rem) 0;
  border-bottom: 1px solid var(--rule-light);
}

.cookie-row__name {
  font-family: var(--font-serif);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.045em;
  font-size: clamp(1.05rem, 2vw, 1.4rem);
  line-height: 1.2;
}
.cookie-row__count {
  margin-top: 0.55rem;
  font-size: clamp(0.98rem, 1.35vw, 1.1rem);
  letter-spacing: 0.03em;
  color: var(--on-espresso-faint);
}
.cookie-row--full .cookie-row__name { opacity: 0.55; }

.cookie-row__slots {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
}

/* --- one dozen -----------------------------------------------------------
   .cookie-slot--available  a mailto link
   .cookie-slot--claimed    a disabled button                              */
.cookie-slot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 3.1rem;
  padding: 0.8em 1.4em;
  font-family: var(--font-serif);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: clamp(0.8rem, 1vw, 0.88rem);
  line-height: 1;
  text-align: center;
  border: 1px solid;
  transition: background-color 0.35s var(--ease), color 0.35s var(--ease),
              border-color 0.35s var(--ease);
}

.cookie-slot--available {
  color: var(--creme);
  border-color: var(--rule-light-strong);
  background: transparent;
  cursor: pointer;
}
.cookie-slot--available:hover,
.cookie-slot--available:focus-visible {
  background: var(--creme);
  border-color: var(--creme);
  color: var(--espresso);
}

.cookie-slot--claimed {
  color: var(--on-espresso-faint);
  border-color: transparent;
  background: rgba(250, 249, 246, 0.07);
  cursor: default;
  pointer-events: none;
}

@media (max-width: 720px) {
  .cookie-row {
    grid-template-columns: 1fr;
    gap: 0.9rem;
  }
  .cookie-row__slots { gap: 0.45rem; }
  /* two per row at a fixed width — an odd last box stays left, same size */
  .cookie-slot {
    flex: 0 0 calc(50% - 0.225rem);
    font-size: 0.76rem;
    padding: 0.8em 0.5em;
    letter-spacing: 0.07em;
  }
}

/* ==========================================================================
   REGISTRY — our own button, then Zola's product preview
   --------------------------------------------------------------------------
   Zola draws its widget inside its own frame (an iframe from zola.com), so
   nothing inside it can be restyled and its CONTRIBUTE buttons stay theirs.
   Its header — Zola logo, "Sneak Peek of Our Zola Wedding Registry" and a
   black button — is cut off with `clip-path`, which trims the top of the
   frame WITHOUT moving the frame's box. That matters: an earlier version
   pulled the frame upwards with a negative margin, so its box reached up
   behind our button and some browsers let the frame swallow the clicks.
   Now the frame starts where it sits and nothing overlaps the button.

   Nothing here may clip or shorten the BOTTOM of the frame: Zola's widget
   measures its own content and reports a new height whenever the registry
   gains or loses products, and the frame has to be free to grow with it.
   If Zola ever changes its header, adjust --zola-trim.
   ========================================================================== */
.registry-cta {
  text-align: center;
  /* just enough that the button's edge and the frame's edge never meet; the
     clipped strip at the top of Zola's frame supplies the rest of the space */
  margin-bottom: 12px;
}
.registry-cta .btn {
  font-size: clamp(0.85rem, 0.45vw + 0.74rem, 1rem);
  padding: 1.25em 3.4em;
  letter-spacing: 0.16em;
  text-indent: 0.16em;
}

.registry-embed {
  --zola-trim: 176px;
  container-type: inline-size;
}
.registry-embed a.zola-registry-embed { display: none; }
.registry-embed .zola-registry-iframe {
  display: block;
  min-height: 0;
  clip-path: inset(var(--zola-trim) 0 0 0);
  mix-blend-mode: multiply;
}
/* the heading inside Zola's frame wraps on narrow screens, making it taller */
@media (max-width: 500px) {
  .registry-embed { --zola-trim: 200px; }
}
@container (max-width: 430px) {
  .registry-embed { --zola-trim: 200px; }
}

/* ==========================================================================
   RSVP HOLDING PANEL — the espresso box standing in for the form
   It fills the space the RSVP embed will occupy. Turn it off with
   `holdingNotice.show = false` in src/data/rsvp.js and the form takes over.
   ========================================================================== */
.holding {
  background: var(--espresso);
  color: var(--on-espresso);
  padding: clamp(3rem, 8vw, 6rem) clamp(1.5rem, 5vw, 4.5rem);
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: clamp(320px, 42vw, 460px);
}
.holding__message {
  max-width: 28ch;
  text-align: center;
  font-family: var(--font-serif);
  text-transform: uppercase;
  letter-spacing: 0.055em;
  line-height: 1.45;
  font-size: clamp(1.15rem, 2.4vw, 1.9rem);
  text-indent: 0.055em;
}


/* ---------- 05-motion.css ---------- */
/* ==========================================================================
   MOTION
   Everything here is deliberately small. Reduced-motion users get none of it.
   ========================================================================== */
.js-reveal [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity 0.9s var(--ease) var(--reveal-delay, 0ms),
    transform 0.9s var(--ease) var(--reveal-delay, 0ms);
}
.js-reveal [data-reveal].is-revealed {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  /* the hero strip settles on its first frame rather than drifting */
  .hero__track { animation: none !important; }

  .js-reveal [data-reveal] { opacity: 1; transform: none; }

  /* the countdown still counts — the flip just resolves instantly */
  .flip.is-flipping .flip__panel--fold { animation-delay: 0ms !important; }
}
