/* ==========================================================================
   The Little Extraordinary — invitation stylesheet

   The printed invitation is a portrait, phone-shaped page. To keep the exact
   proportions of the artwork at any screen size, the content lives in a fixed
   max-width column and every type size is expressed in `cqi` — a percentage of
   that column's width. Change --col and the whole design scales as one piece.
   ========================================================================== */

:root {
  /* Width of the invitation column. Everything else is relative to this. */
  --col: 34rem;

  /* Ink */
  --cream: #F7EFE2;
  --cream-dim: #E9DCC7;
  --cream-warm: #F8E2BE;
  --dark-ink: #3A3244;

  /* Gold gradients, sampled straight off the PDF artwork.
     Each family is a little different, so they are kept apart rather than
     averaged into one. Applied through the .gilt rule below. */
  --gold-grad:         linear-gradient(180deg, #ECC486 0%, #F4D49C 48%, #FAE0B2 100%);
  --gold-grad-pale:    linear-gradient(180deg, #EFE2C4 0%, #F6ECD3 45%, #F9EACD 100%);
  --gold-grad-label:   linear-gradient(180deg, #F1D59A 0%, #F8D9A1 50%, #EECF96 100%);
  --gold-grad-promise: linear-gradient(180deg, #E7C88C 0%, #F2D497 55%, #E9CC90 100%);
  --gold-grad-mantra:  linear-gradient(180deg, #DED3C0 0%, #F1E9D6 45%, #DCD2BA 100%);
  --gold-grad-menu:    linear-gradient(180deg, #F1E5A6 0%, #F5EAAB 50%, #E3D493 100%);
  --gold-grad-confirm: linear-gradient(180deg, #EFAC7A 0%, #E7A881 50%, #EAB389 100%);
  --gold-line: rgba(219, 179, 111, .55);

  /* Ground */
  --maroon: #2E0707;
  --maroon-deep: #170202;

  /* Scrim laid over each background photo so text stays readable.
     Set to `none` on a section that needs the photo completely untouched. */
  --scrim: linear-gradient(to bottom,
            rgba(18, 3, 3, .38) 0%,
            rgba(18, 3, 3, .05) 26%,
            rgba(18, 3, 3, .05) 72%,
            rgba(18, 3, 3, .42) 100%);

  --font: "Cormorant Garamond", Cormorant, Garamond, "Times New Roman", serif;
}

/* --------------------------------------------------------------- reset --- */

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

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

body {
  margin: 0;
  background: var(--maroon-deep);
  color: var(--cream);
  font-family: var(--font);
  font-weight: 400;
  line-height: 1.25;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color .3s ease, color .3s ease;
}
a:hover,
a:focus-visible { color: #F6E2B2; border-bottom-color: rgba(246, 226, 178, .8); }

/* ------------------------------------------------------- language --- */

/* Both languages are in the page; this shows the one <html lang> names, so
   switching is instant and nothing — the film, the form, the scroll — is
   thrown away. display:contents keeps the wrapper out of the layout. */
.i18n { display: contents; }

html[lang="en"] .i18n[data-lang="pt"],
html[lang="pt"] .i18n[data-lang="en"] { display: none; }


/* Pinned to the foot of the strip, out of the artwork's way. */
.langswitch {
  position: fixed;
  left: 50%;
  bottom: 12px;
  z-index: 50;
  display: flex;
  justify-content: flex-end;
  width: 100%;
  max-width: 420px;          /* the same strip as .invitation */
  padding-inline: 5.5%;
  transform: translateX(-50%);
  transition: opacity 1.2s ease;
  pointer-events: none;      /* only the track takes clicks */
}

/* Out of the way until the envelope has been opened. */
.intro-lock .langswitch { opacity: 0; }

.langswitch__track {
  display: inline-flex;
  padding: 3px;
  border: 1px solid rgba(233, 196, 134, .5);
  border-radius: 999px;
  background: rgba(26, 4, 6, .72);
  box-shadow: 0 2px 16px rgba(0, 0, 0, .5);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  pointer-events: auto;
}

.langswitch__opt {
  padding: .36em .95em;
  border: 0;
  border-radius: 999px;
  color: #D9B071;
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-indent: .14em;        /* balance the trailing letter-space */
  white-space: nowrap;
  transition: background-color .35s ease, color .35s ease;
}

.langswitch__opt:hover,
.langswitch__opt:focus-visible { color: #F6E2B2; border-bottom-color: transparent; }

/* The chosen side reads as the thrown half of a switch. */
.langswitch__opt.is-active {
  background: linear-gradient(180deg, #F6E2B2 0%, #D2A45E 100%);
  color: #2B0508;
}

.langswitch__opt.is-active:hover,
.langswitch__opt.is-active:focus-visible { color: #2B0508; }

/* -------------------------------------------------------------- scenes --- */

/* The invitation is a phone-shaped piece. On anything wider it stays that
   shape rather than stretching the artwork across a desktop window. 420px sits
   just inside a large phone — an iPhone 16 Pro Max is 440 CSS px — so the
   desktop view is close to the piece a guest holds in their hand. */
.invitation {
  max-width: 420px;
  margin-inline: auto;
}

@media (min-width: 420px) {
  .invitation { box-shadow: 0 0 4rem rgba(0, 0, 0, .65); }
}

/* The document is the scroller, so the snapping belongs here — on
   .invitation, which does not scroll, it would do nothing. Proximity, so a
   section taller than the screen never traps anyone. */
html { scroll-snap-type: y proximity; }

.scene {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, var(--col));
  justify-content: center;
  min-height: 100svh;
  padding-inline: 5.5%;
  scroll-snap-align: start;
  isolation: isolate;
  overflow: hidden;

  /* Photo on top of the per-section fallback ground. Sections whose artwork
     has words in it carry one per language; the rest carry the same file
     twice, so this one rule covers both. */
  background-image: var(--bg-en, none), var(--bg-fallback);
  background-repeat: no-repeat;
  background-position: center center;
  background-size: cover, cover;
}

html[lang="pt"] .scene {
  background-image: var(--bg-pt, var(--bg-en, none)), var(--bg-fallback);
}

/* The scrim sits between the photo and the text. */
.scene::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--scrim);
  pointer-events: none;
}

.scene__inner {
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-width: 0;
}

.block {
  position: relative;
  text-align: center;
}

.block--top { padding-top: 8cqi; }
.block--bottom { padding-bottom: 12cqi; margin-top: auto; }

/* ----------------------------------------------------------- ornaments --- */

/* Both ornaments are supplied artwork (assets/img/star.png and
   star-border.png). Widths are set; height follows the file. */

.star {
  display: inline-block;
  width: 1em;
  height: auto;
  vertical-align: middle;
}

/* On its own, under the hero title. */
.star--solo {
  display: block;
  width: 10cqi;
  margin: 3.6cqi auto 4cqi;
}

/* Between words — PLAY * DISCOVER * IMAGINE, FRESH * HEALTHY * DELICIOUS. */
.star--inline {
  width: .92em;
  margin-inline: .26em;
  vertical-align: -.12em;
}

/* Leading a list item. */
.star--bullet {
  width: 4.8cqi;
  margin-top: .12em;
  justify-self: center;
  align-self: start;
}

.rule {
  display: block;
  width: 62%;
  height: auto;
  margin: 4.5cqi auto;
}

.rule--short { width: 42%; }

/* ---------------------------------------------------------- type scale --- */

/* Small tracked caps — "YOU ARE CORDIALLY INVITED TO" */
.eyebrow {
  font-size: max(12px, 4.4cqi);
  font-weight: 500;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--cream);
  text-indent: .2em;              /* balance the trailing letter-space */
}

/* Large tracked caps under a heading — "A MAGICAL COSTUME ADVENTURE" */
.lede {
  font-size: max(13px, 4cqi);
  font-weight: 400;
  letter-spacing: .16em;
  line-height: 1.55;
  text-transform: uppercase;
  color: var(--cream);
  text-indent: .16em;
}

.lede--tight { letter-spacing: .1em; text-indent: .1em; }

/* Cream caps used for the closing lines of several pages */
.caption {
  font-size: max(14px, 5.2cqi);
  font-weight: 400;
  letter-spacing: .07em;
  line-height: 1.45;
  text-transform: uppercase;
  color: var(--cream);
  text-indent: .07em;
}

.caption--small {
  font-size: max(12px, 4.5cqi);
  letter-spacing: .14em;
  line-height: 1.6;
  text-indent: .14em;
}

/* Gold field labels — DATE / TIME / LOCATION */
.label {
  font-size: max(12px, 4.6cqi);
  font-weight: 500;
  letter-spacing: .26em;
  text-transform: uppercase;
  text-indent: .26em;
  --grad: var(--gold-grad-label);
}

/* -------------------------------------------------------- display type --- */

.display {
  font-weight: 500;
  line-height: 1.02;
  letter-spacing: .02em;
  text-transform: uppercase;
}

.display__line { display: block; }

/* Gold leaf. Paints the glyphs with a gradient rather than a flat colour,
   which is how every gold word is set in the artwork. Because the text is
   transparent, depth has to come from drop-shadow, not text-shadow. */
.display--gold,
.hero-title,
.label,
.promise,
.mantra,
.menu__heading,
.closing__confirm {
  background-image: var(--grad, var(--gold-grad));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.display--gold {
  filter: drop-shadow(0 .04em .09em rgba(40, 6, 6, .55));
}

.display--cream {
  color: var(--cream);
  text-shadow: 0 .03em .12em rgba(30, 5, 5, .5);
}

.display--airy { letter-spacing: .1em; text-indent: .1em; }

/* ============================================================= 0. INTRO ===
   PDF pages 1 and 2 — the sealed envelope, and the film of it opening.

   The scroll is held (html.intro-lock) until the film has run. That class is
   added by a small script in the head, so it only ever applies when
   JavaScript is running; assets/js/intro.js takes it off again, and every
   failure path there takes it off too.
   ========================================================================= */

.intro-lock,
.intro-lock body {
  height: 100%;
  overflow: hidden;
}

.scene--intro {
  --scrim: none;
  --bg-fallback: radial-gradient(120% 80% at 50% 45%, #46100F 0%, #2A0605 55%, #150202 100%);
}

.intro__media {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
}

.intro__video,
.intro__poster,
.intro__still {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The film's last frame, laid over the paused video when it ends. */
.intro__still {
  opacity: 0;
  transition: opacity var(--intro-stillIn, 260ms) ease;
}

.intro__still.is-visible { opacity: 1; }

/* The still covers the film until its first frame is actually painted. */
.intro__poster { transition: opacity var(--intro-posterOut, 600ms) ease; }
.intro__poster.is-hidden { opacity: 0; }

/* The two states share the stage, so one can fade out as the other fades in. */
.scene--intro .scene__inner { position: relative; }

.intro__layer {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.intro__layer--sealed { transition: opacity var(--intro-sealedOut, 700ms) ease; }
.intro__layer--sealed.is-gone { opacity: 0; pointer-events: none; }

.intro__layer--opened {
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--intro-openedIn, 1600ms) ease;
}

.intro__layer--opened.is-visible { opacity: 1; }

/* ---- page 1, sealed ---- */

/* The two states sit on different artwork, so each keeps its own margins. */
.intro__layer--sealed .block--top    { padding-top: 25.6cqi; }
.intro__layer--sealed .block--bottom { padding-bottom: 20cqi; }
.intro__layer--opened .block--top    { padding-top: 36.4cqi; }
.intro__layer--opened .block--bottom { padding-bottom: 52.5cqi; }

.intro__invite {
  font-size: 5.5cqi;
  line-height: 1.16;
  letter-spacing: .09em;
  text-transform: uppercase;
  text-indent: .09em;
  --grad: var(--gold-grad-label);
  background-image: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 .04em .12em rgba(30, 5, 5, .6));
}

.intro__opens {
  font-size: 4.6cqi;
  line-height: 1.21;
  letter-spacing: .075em;
  text-transform: uppercase;
  text-indent: .075em;
  --grad: var(--gold-grad-label);
  background-image: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 .04em .12em rgba(30, 5, 5, .6));
}

/* The whole stage is tappable; this is the visible invitation to do it. */
.intro__tap {
  margin-top: 5cqi;
  padding: 2.6cqi 9cqi;
  border: 1px solid var(--gold-line);
  border-radius: 999px;
  background: rgba(20, 3, 3, .35);
  font-family: inherit;
  font-size: 3.4cqi;
  letter-spacing: .3em;
  text-indent: .3em;
  text-transform: uppercase;
  color: #EFD6A4;
  cursor: pointer;
  animation: intro-breathe 2.8s ease-in-out infinite;
  transition: border-color .3s ease, color .3s ease, background-color .3s ease;
}

.intro__tap:hover,
.intro__tap:focus-visible {
  border-color: #E9C68C;
  color: #FBEFD2;
  background: rgba(233, 198, 140, .12);
}

@keyframes intro-breathe {
  0%, 100% { opacity: .72; }
  50%      { opacity: 1; }
}

/* ---- page 2, opened ---- */

.intro__title {
  font-size: 11.6cqi;
  font-weight: 500;
  line-height: 1.07;
  letter-spacing: .012em;
  text-transform: uppercase;
  --grad: var(--gold-grad);
  background-image: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 .03em .1em rgba(30, 10, 6, .5));
}

.intro__title-line { display: block; }
.intro__title-line--wide { font-size: 10.2cqi; letter-spacing: -.004em; }

.intro__lede { margin-top: 1.5cqi; font-size: 4cqi; }

.intro__aboard {
  font-size: 3.4cqi;
  letter-spacing: .14em;
  text-transform: uppercase;
  text-indent: .14em;
  --grad: var(--gold-grad-label);
  background-image: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.intro__venue {
  margin-top: 1.2cqi;
  font-size: 6.3cqi;
  font-weight: 500;
  letter-spacing: .074em;
  text-transform: uppercase;
  text-indent: .074em;
  color: var(--cream);
  text-shadow: 0 .03em .14em rgba(30, 5, 5, .55);
}

/* ---- scroll cue ---- */

.intro__cue {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 10.5svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .7rem;
  opacity: 0;
  transition: opacity var(--intro-cueIn, 1200ms) ease;
  pointer-events: none;
}

.intro__cue.is-visible { opacity: .85; }

.intro__cue-label {
  font-size: .72rem;
  letter-spacing: .34em;
  text-indent: .34em;
  text-transform: uppercase;
  color: var(--cream-dim);
}

.intro__cue-line {
  width: 1px;
  height: 2.6rem;
  background: linear-gradient(to bottom, rgba(226, 190, 128, .75), transparent);
  animation: intro-cue 2.4s ease-in-out infinite;
  transform-origin: top;
}

@keyframes intro-cue {
  0%, 100% { transform: scaleY(.45); opacity: .45; }
  50%      { transform: scaleY(1);   opacity: 1; }
}

/* Without JavaScript nothing can play, so the opened state is the only
   sensible one — and the scroll is never locked in the first place. */
.no-js .intro__video,
.no-js .intro__tap { display: none; }

.no-js .intro__still { opacity: 1; }
.no-js .intro__layer--sealed { opacity: 0; pointer-events: none; }
.no-js .intro__layer--opened { opacity: 1; }
.no-js .intro__cue { opacity: .85; }

@media (prefers-reduced-motion: reduce) {
  .intro__tap,
  .intro__cue-line { animation: none; }
}


/* ============================================================== 1. HERO === */

.scene--hero {
  --bg-fallback: radial-gradient(120% 80% at 50% 18%, #4A3350 0%, #2B1E2E 45%, #180F1A 100%);
}

.hero-title {
  font-size: 12.8cqi;
  font-weight: 500;
  line-height: 1.07;
  letter-spacing: .012em;
  text-transform: uppercase;
}

.hero-title__line { display: block; }

.hero-title__line--wide {
  font-size: 11.6cqi;
  letter-spacing: -.004em;
}

/* "Extraordinário" is a letter longer than "Extraordinary" and would run past
   the column at the English size. */
html[lang="pt"] .hero-title__line--wide { font-size: 10.7cqi; }

.scene--hero .hero-title { filter: drop-shadow(0 .03em .1em rgba(30, 10, 6, .5)); }

.scene--hero .eyebrow { margin-bottom: 9.3cqi; }
.scene--hero .lede { margin-top: 0; }

/* =========================================================== 2. DETAILS === */

.scene--details {
  --bg-fallback: radial-gradient(115% 75% at 50% 40%, #5A1512 0%, #34090A 52%, #1C0304 100%);
}

.scene--details .scene__inner { justify-content: center; }
.scene--details .block--top { padding-top: 0; margin-bottom: 7cqi; }

.details__value {
  font-size: 8.8cqi;
  font-weight: 400;
  letter-spacing: .015em;
  line-height: 1.16;
  text-transform: uppercase;
  color: var(--cream);
  margin-top: 1.4cqi;
}

.details__value + .label { margin-top: 8.5cqi; }

.details__value sup {
  font-size: .52em;
  vertical-align: .52em;
  letter-spacing: .02em;
}

.details__venue-line { display: block; }

.rule--details { margin-block: 8cqi 7cqi; }

.promise {
  font-size: 4.7cqi;
  letter-spacing: .12em;
  line-height: 1.95;
  text-transform: uppercase;
  text-indent: .12em;
  --grad: var(--gold-grad-promise);
}

/* Link out to the venue on Google Maps. */
.details__map {
  margin-top: 3.2cqi;
  font-size: 3.2cqi;
  letter-spacing: .18em;
  text-transform: uppercase;
  text-indent: .18em;
}

.details__map a {
  color: var(--cream-dim);
  border-bottom-color: rgba(219, 179, 111, .45);
  padding-bottom: .2em;
}

/* =========================================================== 3. COSTUME === */

.scene--costume {
  --bg-fallback: radial-gradient(120% 70% at 50% 22%, #6A3A40 0%, #3A1E26 48%, #1F1015 100%);
}

.scene--costume .block--top { padding-top: 3cqi; }
.scene--costume .display { font-size: 13cqi; line-height: 1.03; }
.scene--costume .rule { margin-block: 5.5cqi 5cqi; }
.scene--costume .lede { margin-top: 3.4cqi; font-size: 4.5cqi; }

/* ===================================================== 4. ENTERTAINMENT === */

.scene--entertainment {
  --bg-fallback: radial-gradient(105% 62% at 50% 40%, #56100E 0%, #300707 50%, #170202 100%);
  --scrim: none;
}

.scene--entertainment .block--top { padding-top: 14cqi; }
.scene--entertainment .block--bottom { padding-bottom: 30cqi; }

.scene--entertainment .display {
  --grad: var(--gold-grad-pale);
  font-size: 9.1cqi;
  letter-spacing: .045em;
  text-indent: .045em;
}

.scene--entertainment .lede { margin-top: 3cqi; font-size: 4.4cqi; }

.programme {
  margin-top: 11cqi;
  display: grid;
  gap: 4cqi;
}

.programme__item {
  display: grid;
  grid-template-columns: 20cqi 1fr;
  align-items: center;
  gap: 3.2cqi;
  text-align: left;
}

.programme__icon {
  width: 100%;
  max-height: 15cqi;
  object-fit: contain;
  object-position: center;
}

.programme__text {
  font-size: 5.3cqi;
  line-height: 1.28;
  color: var(--cream);
}

.mantra {
  font-size: 3.9cqi;
  letter-spacing: .2em;
  line-height: 1.75;
  text-transform: uppercase;
  text-indent: .2em;
  --grad: var(--gold-grad-mantra);
}

.mantra .star--inline { margin-inline: .4em; }

/* ============================================================== 5. FOOD === */

.scene--food {
  --bg-fallback: radial-gradient(110% 60% at 50% 30%, #4E1410 0%, #2C0908 52%, #170403 100%);
}

.scene--food .block--top { padding-top: 5cqi; }
.scene--food .display { font-size: 14.7cqi; letter-spacing: .06em; text-indent: .06em; }
.scene--food .lede { margin-top: 3cqi; font-size: 4.5cqi; letter-spacing: .18em; text-indent: .18em; }

.menu {
  text-align: left;
  margin-top: 10cqi;
  padding-left: 5cqi;
}

.menu__heading {
  font-size: 4.8cqi;
  font-weight: 400;
  letter-spacing: .055em;
  text-transform: uppercase;
  --grad: var(--gold-grad-menu);
}

.menu__list {
  margin-top: 2.6cqi;
  display: grid;
  gap: 2cqi;
  padding-left: 2.9cqi;
}

.menu__item {
  display: grid;
  grid-template-columns: 4.8cqi 1fr;
  align-items: start;
  gap: 1.9cqi;
  font-size: 4.6cqi;
  line-height: 1.32;
  color: var(--cream);
}



/* ========================================================= 6. BEVERAGES === */

.scene--beverages {
  --bg-fallback: radial-gradient(105% 62% at 50% 38%, #54100E 0%, #2E0707 52%, #160202 100%);
  --scrim: none;
}

.scene--beverages .block--top { padding-top: 17cqi; }
.scene--beverages .display { font-size: 10.6cqi; letter-spacing: .03em; }

.scene--beverages .lede { margin-top: 3.4cqi; font-size: 4.45cqi; letter-spacing: .055em; text-indent: .055em; }

.notice {
  position: relative;
  margin: 5cqi auto 0;
  padding: 8cqi 12cqi;
  width: 100%;
  font-size: 3.8cqi;
  letter-spacing: .085em;
  line-height: 1.5;
  text-transform: uppercase;
  color: var(--cream);
  text-indent: .085em;

  /* The supplied frame (assets/img/border.png), stretched to the box. Export
     it at roughly the proportions the box ends up — one line of text wide. */
  background-image: var(--notice-image, none);
  background-size: 100% 100%;
  background-repeat: no-repeat;
}

.menu__heading--offer { margin-top: 7cqi; display: block; text-align: left; padding-left: 7cqi; font-size: 5.2cqi; }

.menu__list--drinks {
  text-align: left;
  padding-left: 10.7cqi;
  gap: 2.4cqi;
  margin-top: 3cqi;
}

.menu__list--drinks .menu__item { font-size: 5.7cqi; gap: 3.6cqi; }

/* =========================================================== 7. DESSERT === */

.scene--dessert {
  --bg-fallback: radial-gradient(110% 55% at 50% 26%, #55201B 0%, #33100E 55%, #1B0605 100%);
}

.scene--dessert .block--top { padding-top: 2cqi; }
.scene--dessert .display { font-size: 10.2cqi; letter-spacing: .13em; text-indent: .13em; }

.dessert__name {
  margin-top: 4cqi;
  font-size: 6cqi;
  line-height: 1.2;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--cream);
  text-shadow: 0 .03em .12em rgba(30, 5, 5, .5);
}

.dessert__volume { font-size: .72em; letter-spacing: .03em; }

.scene--dessert .caption--small { margin-top: 3.6cqi; font-size: 4cqi; letter-spacing: .17em; text-indent: .17em; }

/* =========================================================== 8. TOUCHES === */

.scene--touches {
  --bg-fallback: radial-gradient(110% 60% at 50% 22%, #5A1A14 0%, #34100C 52%, #1A0504 100%);
}

.scene--touches .display { font-size: 7.1cqi; letter-spacing: .035em; line-height: 1.16; }
.scene--touches .display--cream { color: var(--cream-warm); }
.scene--touches .rule { margin-block: 2.6cqi 0; }

.prose {
  margin-top: 4.6cqi;
  font-size: 6.1cqi;
  line-height: 1.16;
  color: var(--cream);
  text-shadow: 0 .03em .12em rgba(30, 5, 5, .45);
}

.flanked {
  margin-top: 4.5cqi;
  font-size: 4.5cqi;
  font-variant-caps: small-caps;
  letter-spacing: .09em;
  line-height: 1.6;
  color: var(--cream);
}

/* ============================================================== 9. RSVP === */

.scene--rsvp {
  --bg-fallback: radial-gradient(105% 60% at 50% 30%, #4E0F0C 0%, #2B0605 52%, #150202 100%);
}

.scene--rsvp .display { font-size: 11cqi; letter-spacing: .12em; text-indent: .12em; }
.scene--rsvp .rule { margin-block: 3cqi 5.5cqi; }
.scene--rsvp .lede { font-size: 4.3cqi; letter-spacing: .075em; text-indent: .075em; }

.rsvp__word {
  margin-top: 2cqi;
  font-size: 6.2cqi;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--cream);
  text-indent: .09em;
  text-shadow: 0 .03em .12em rgba(30, 5, 5, .5);
}

/* ---- the attendance form ---- */

.rsvp {
  margin-top: 5cqi;
  display: grid;
  gap: 3.6cqi;
  padding: 5cqi 4cqi;
  text-align: left;

  /* The photograph is busy behind the fields, so the form carries its own
     soft pool of shade rather than dimming the whole scene. */
  background: radial-gradient(115% 80% at 50% 50%,
              rgba(18, 3, 3, .82) 0%, rgba(18, 3, 3, .58) 58%, rgba(18, 3, 3, 0) 100%);
}

/* Once a reply is in, the fields give way to the thank-you message. */
.rsvp.is-sent .rsvp__choices,
.rsvp.is-sent .rsvp__field,
.rsvp.is-sent .rsvp__submit { display: none; }

.rsvp__choices {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 2cqi 6cqi;
}

.rsvp__choice {
  display: flex;
  align-items: center;
  gap: 2.2cqi;
  cursor: pointer;
  font-size: 3.6cqi;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--cream);
}

.rsvp__choice input { position: absolute; opacity: 0; pointer-events: none; }

.rsvp__dot {
  flex: none;
  width: 3.6cqi;
  height: 3.6cqi;
  border: 1px solid var(--gold-line);
  border-radius: 50%;
  position: relative;
  transition: border-color .25s ease;
}

.rsvp__dot::after {
  content: "";
  position: absolute;
  inset: 22%;
  border-radius: 50%;
  background: var(--gold-grad);
  opacity: 0;
  transition: opacity .25s ease;
}

.rsvp__choice input:checked ~ .rsvp__dot { border-color: #E9C68C; }
.rsvp__choice input:checked ~ .rsvp__dot::after { opacity: 1; }
.rsvp__choice input:focus-visible ~ .rsvp__dot { outline: 2px solid #E9C68C; outline-offset: 3px; }

.rsvp__field { display: grid; gap: 1.2cqi; }
.rsvp__field[hidden] { display: none; }

.rsvp__label {
  font-size: 3.4cqi;
  letter-spacing: .2em;
  text-transform: uppercase;
  text-indent: .2em;
  color: var(--cream-dim);
}

/* Hairline fields, so the form reads as part of the stationery. */
.rsvp__control,
.rsvp__count {
  width: 100%;
  padding: 1.6cqi 0;
  border: 0;
  border-bottom: 1px solid var(--gold-line);
  background: transparent;
  font-family: inherit;
  font-size: 4.6cqi;
  color: var(--cream);
  transition: border-color .25s ease;
}

.rsvp__control:focus,
.rsvp__count:focus { outline: none; border-bottom-color: #E9C68C; }

/* The headcount: a row per age group, each counting on its own, with the
   total underneath. Name to the left, counter to the right, so the four
   read down the page as one list rather than four separate fields. */
.rsvp__tally {
  display: grid;
  gap: 2.4cqi;
  margin: 0;
  padding: 0;
  list-style: none;
}

.rsvp__tally-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 3cqi;
  padding-bottom: 2.2cqi;
  border-bottom: 1px solid rgba(233, 198, 140, .22);
}

.rsvp__tally-row:last-child { border-bottom: 0; padding-bottom: 0; }

.rsvp__tally-name {
  font-size: 3.7cqi;
  letter-spacing: .06em;
  line-height: 1.3;
  color: var(--cream);
}

.rsvp__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 3cqi;
  margin-top: 1cqi;
  padding-top: 2.6cqi;
  border-top: 1px solid var(--gold-line);
}

.rsvp__total-label {
  font-size: 3.2cqi;
  letter-spacing: .2em;
  text-transform: uppercase;
  text-indent: .2em;
  color: var(--cream-dim);
}

.rsvp__total-value {
  font-size: 5cqi;
  letter-spacing: .04em;
  color: #EFD6A4;
}

.rsvp__stepper {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex: none;
  gap: 2.4cqi;
}

.rsvp__step {
  width: 7.4cqi;
  height: 7.4cqi;
  border: 1px solid var(--gold-line);
  border-radius: 50%;
  background: transparent;
  color: #E9C68C;
  font-family: inherit;
  font-size: 4.2cqi;
  line-height: 1;
  cursor: pointer;
  transition: border-color .25s ease, color .25s ease, opacity .25s ease;
}

.rsvp__step:hover:not(:disabled) { border-color: #E9C68C; color: #F6E2B2; }
.rsvp__step:disabled { opacity: .45; cursor: default; }

.rsvp__count {
  width: 8cqi;
  padding-block: 0;
  text-align: center;
  border-bottom: 0;
  font-size: 5cqi;
  -moz-appearance: textfield;
}

.rsvp__count::-webkit-outer-spin-button,
.rsvp__count::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.rsvp__submit {
  justify-self: center;
  margin-top: .5cqi;
  padding: 2.4cqi 10cqi;
  border: 1px solid var(--gold-line);
  background: transparent;
  font-family: inherit;
  font-size: 3.8cqi;
  letter-spacing: .26em;
  text-indent: .26em;
  text-transform: uppercase;
  color: #EFD6A4;
  cursor: pointer;
  transition: border-color .25s ease, color .25s ease, background-color .25s ease;
}

.rsvp__submit:hover:not(:disabled) {
  border-color: #E9C68C;
  color: #FBEFD2;
  background-color: rgba(233, 198, 140, .08);
}

.rsvp__submit:disabled { opacity: .45; cursor: default; }

.rsvp__message {
  min-height: 1.4em;
  text-align: center;
  font-size: 3.8cqi;
  letter-spacing: .06em;
  line-height: 1.5;
  color: var(--cream-dim);
}

.rsvp__message.is-good { color: #EFD6A4; }
.rsvp__message.is-bad  { color: #E9A98F; }

.scene--rsvp .rule--short { margin-block: 0 4cqi; }

/* The closing note sits over the rope and velvet, so it brings its own shade. */
.scene--rsvp .block--bottom {
  padding-top: 6cqi;
  padding-bottom: 12cqi;
  background: linear-gradient(to top,
              rgba(18, 3, 3, .8) 0%, rgba(18, 3, 3, .62) 55%, rgba(18, 3, 3, 0) 100%);
}
.scene--rsvp .caption--small { font-size: 3.5cqi; letter-spacing: .08em; text-indent: .08em; line-height: 1.75; }

/* =========================================================== 10. CLOSING === */

.scene--closing {
  --bg-fallback: linear-gradient(to bottom, #4C5678 0%, #9A7C7A 38%, #C99A6E 62%, #6B4A46 100%);
  --scrim: none;
}

.scene--closing .block--top { padding-top: 9cqi; }
.scene--closing .block--top .caption--small { font-size: 4.6cqi; letter-spacing: .13em; text-indent: .13em; }
.scene--closing .block--bottom .caption--small { font-size: 3.1cqi; letter-spacing: .13em; text-indent: .13em; }
.scene--closing .rule { margin-block: 2.6cqi; }

/* The closing lines fall on the brightest part of the sky, so the foot of the
   scene carries a soft shade to hold them. */
.scene--closing .block--bottom {
  padding-top: 20cqi;
  background: linear-gradient(to top,
              rgba(30, 10, 6, .72) 0%, rgba(30, 10, 6, .70) 78%, rgba(30, 10, 6, 0) 100%);
}

.scene--closing .block--bottom .caption--small { text-shadow: 0 .04em .16em rgba(40, 18, 8, .75); }

.display--journey { font-size: 5.8cqi; line-height: 1.35; letter-spacing: .035em; }
.display--journey .display__line--wide { letter-spacing: .01em; }

.closing__dream {
  margin-top: 5.5cqi;
  font-size: 4.6cqi;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--dark-ink);
  text-shadow: 0 0 .5em rgba(255, 240, 216, .55);
}

.closing__dream-lead {
  display: block;
  margin-bottom: .5em;
  font-size: .73em;
  letter-spacing: .1em;
  text-indent: .1em;
}

.closing__confirm {
  font-size: 4.8cqi;
  line-height: 1.32;
  letter-spacing: .05em;
  text-transform: uppercase;
  text-indent: .05em;
  --grad: var(--gold-grad-confirm);
  filter: drop-shadow(0 .03em .1em rgba(48, 20, 8, .85))
          drop-shadow(0 0 .4em rgba(48, 20, 8, .5));
}

/* ------------------------------------------------- scroll-in behaviour --- */

.reveal {
  opacity: 0;
  transform: translateY(1.6rem);
}

.reveal.is-visible {
  opacity: 1;
  transform: none;
  transition: opacity 1.1s cubic-bezier(.22, .61, .36, 1),
              transform 1.1s cubic-bezier(.22, .61, .36, 1);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-snap-type: none; }
  .reveal,
  .reveal.is-visible { opacity: 1; transform: none; transition: none; }
}

