:root {
  /* Colors sampled from the Figma file */
  --navy: #04192c;
  --navy-raise: #0a2a47;
  --gold-dark: #a08361;
  --gold: #e8c994;
  --gold-light: #efd099;
  --cream: #e0ddb2;
  --red: #c73a3a;
  --slate: #4b6775;
  --text: #f4ecd9;
  --text-muted: #a9b7c1;
  --line: rgb(239 208 153 / 0.16);
  --card: rgb(12 46 77 / 0.6);
  --gold-grad: linear-gradient(90deg, #a08361 0%, #b89b72 11%, #d6b887 27%, #e8c994 41%, #efd099 51%, #bdb08e 100%);

  /* Retro holiday script that echoes the Figma lettering */
  --display: 'Lobster Two', Georgia, serif;
  --sans: 'DM Sans', system-ui, -apple-system, sans-serif;

  /* 1 Figma unit of the 833 × 1233 art panel, in CSS px */
  --u: min(100svh / 1233, 50vw / 833);

  color-scheme: dark;
}

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

html, body {
  margin: 0;
  background: var(--navy);
  color: var(--text);
}

body {
  min-height: 100svh;
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

.preload .stage > *,
.preload [data-reveal] { visibility: hidden; }

#scene {
  position: fixed;
  inset: 0;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.over-ornament, .over-ornament * { cursor: grab; }
.is-grabbing, .is-grabbing * { cursor: grabbing !important; }

/* ---------- Layout ---------- */

.page {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  height: 100svh;
}

.art {
  display: grid;
  place-items: center;
  height: 100svh;
  padding-left: clamp(0px, 2vw, 40px);
}

/* No z-index / transform / contain here: the stage's children must share the
   root stacking context with the fixed WebGL canvas so they can sit above and below it. */
.stage {
  position: relative;
  width: calc(833 * var(--u));
  height: calc(1233 * var(--u));
  touch-action: pan-y;
  -webkit-user-select: none;
  user-select: none;
}

.stage > * { position: absolute; margin: 0; }

.layer { z-index: 0; pointer-events: none; }
.layer svg { display: block; width: 100%; height: 100%; overflow: visible; }

.layer-dust {
  left: calc(-1.84 * var(--u));
  top: calc(311.64 * var(--u));
  width: calc(832.94 * var(--u));
  height: calc(817.36 * var(--u));
}

.layer-sparkles {
  left: calc(39.1 * var(--u));
  top: calc(314.94 * var(--u));
  width: calc(749.68 * var(--u));
  height: calc(627.77 * var(--u));
}

.title, .tagline { z-index: 3; pointer-events: none; }

.title {
  left: calc(53 * var(--u));
  top: calc(50 * var(--u));
  width: calc(724.87 * var(--u));
  height: calc(219.94 * var(--u));
  font-size: inherit;
}

.title img, .tagline img { position: absolute; display: block; max-width: none; }

.title-union { inset: 0.05% 0.04% 0.39% 0; width: 99.96%; height: 99.56%; }

.title-year {
  position: absolute;
  right: calc(17.23 * var(--u));
  top: calc(14.98 * var(--u));
  width: calc(105.026 * var(--u));
  height: calc(50.613 * var(--u));
  display: flex;
  align-items: center;
  justify-content: center;
}

.title-year > img {
  position: relative;
  z-index: 1;
  flex: none;
  width: calc(101.909 * var(--u));
  height: calc(42.462 * var(--u));
  transform: rotate(-4.67deg);
}

/* "2026" is a button that opens the surprise. The hover lives on the numerals, which GSAP
   never animates (it resets scale/rotate on elements it tweens, like the button itself). */
button.title-year {
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  pointer-events: auto;
}

button.title-year > img { transition: scale 0.35s cubic-bezier(0.34, 1.56, 0.64, 1), rotate 0.35s cubic-bezier(0.34, 1.56, 0.64, 1); }
button.title-year:hover > img { scale: 1.12; rotate: 5deg; }
button.title-year:active > img { scale: 0.95; }

/* Tiny couple who peek out from behind "2026" now and then. The box's bottom edge sits
   partway down the numerals, so anything below it is hidden behind them. The mask fades
   the part behind the numerals, so the gaps between digits show no hard cut-off line. */
.peek {
  position: absolute;
  right: 0;
  bottom: 55%;
  left: 0;
  height: 160%;
  overflow: hidden;
  rotate: -4.67deg;
  transform-origin: 50% 100%;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to top, transparent, #000 24%);
  mask-image: linear-gradient(to top, transparent, #000 24%);
}

/* Positioned with `left` (not `translate`): GSAP folds CSS translate into its own transform. */
.peek img {
  left: 0;
  bottom: 0;
  width: 100%;
  height: auto;
  transform: translateY(100%);
}

.tagline {
  left: calc(53 * var(--u));
  top: calc(1059 * var(--u));
  width: calc(731.445 * var(--u));
  height: calc(131 * var(--u));
}

.tagline img { inset: 0; width: 100%; height: 100%; }

/* Light sweep clipped to the lettering */
.shine {
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 42%, rgb(255 250 232 / 0.75) 50%, transparent 58%) 150% 0 / 250% 100% no-repeat;
  -webkit-mask: var(--mask) center / 100% 100% no-repeat;
  mask: var(--mask) center / 100% 100% no-repeat;
}
.shine-title { --mask: url(assets/title-union.svg); inset: 0.05% 0.04% 0.39% 0; }
.shine-tagline { --mask: url(assets/tagline.svg); }

/* WebGL fallback: the original flat ornaments */
.fallback { display: none; inset: 0; z-index: 1; pointer-events: none; }
.no-webgl .fallback { display: block; }
.fallback img { position: absolute; display: block; max-width: none; }
.fb-159 { left: calc(234.86 * var(--u)); top: calc(241 * var(--u)); width: calc(269.6 * var(--u)); height: calc(799.16 * var(--u)); }
.fb-165 { left: calc(534.92 * var(--u)); top: calc(186 * var(--u)); width: calc(203.53 * var(--u)); height: calc(642.79 * var(--u)); }
.fb-179 { left: calc(402.92 * var(--u)); top: calc(184 * var(--u)); width: calc(180.03 * var(--u)); height: calc(414.61 * var(--u)); }
.fb-194 { left: calc(94.88 * var(--u)); top: calc(535.8 * var(--u)); width: calc(226.86 * var(--u)); height: calc(226.18 * var(--u)); }
.fb-208 { left: calc(190.42 * var(--u)); top: calc(492.18 * var(--u)); width: calc(32.02 * var(--u)); height: calc(48.56 * var(--u)); }
.fb-211 { left: calc(205 * var(--u)); top: calc(251 * var(--u)); width: calc(3 * var(--u)); height: calc(243 * var(--u)); }

/* ---------- Info panel ---------- */

.info {
  position: relative;
  z-index: 2;
  display: flex;
  height: 100svh;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}

.info-inner {
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 2.4vh, 26px);
  width: 100%;
  max-width: 600px;
  margin: auto;
  padding: clamp(28px, 6vh, 72px) clamp(24px, 4vw, 64px);
}

.eyebrow {
  margin: 0;
  color: var(--red);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

h2 {
  margin: 0;
  color: var(--text);
  font-family: var(--display);
  font-size: clamp(32px, 3.3vw, 50px);
  font-style: italic;
  font-weight: 700;
  line-height: 1.1;
  text-wrap: balance;
}

h2 em, .cd-num {
  background: var(--gold-grad);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

h2 em { font-style: italic; padding-right: 0.06em; }

.blurb {
  max-width: 52ch;
  margin: 0;
  color: var(--text-muted);
  font-size: 16.5px;
  text-wrap: pretty;
}

/* Countdown */
.countdown-wrap { display: grid; gap: 10px; }

.cd-title {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 4px 12px;
  margin: 0;
}

.cd-label {
  color: var(--gold);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.cd-date { color: var(--text); font-size: 14px; font-weight: 600; }

.countdown {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
}

.cd-unit {
  overflow: hidden;
  padding: 14px 6px 11px;
  border-radius: 14px;
  background: var(--card);
  text-align: center;
  backdrop-filter: blur(8px);
}

.cd-num {
  display: block;
  padding-right: 0.08em;
  font-family: var(--display);
  font-size: clamp(30px, 2.8vw, 40px);
  font-style: italic;
  font-weight: 700;
  line-height: 1.05;
}

.cd-lbl {
  display: block;
  margin-top: 7px;
  color: var(--text-muted);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.cd-done {
  grid-column: 1 / -1;
  margin: 0;
  padding: 16px;
  border-radius: 14px;
  background: var(--card);
  color: var(--gold-light);
  font-family: var(--display);
  font-size: 24px;
  font-style: italic;
  font-weight: 700;
  text-align: center;
}

/* Detail rows */
.details, .register {
  border-radius: 18px;
  background: var(--card);
  backdrop-filter: blur(10px);
}

.details { margin: 0; padding: 0; list-style: none; }

.detail {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) auto;
  column-gap: 16px;
  align-items: start;
  padding: 18px 20px;
}

.d-icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: rgb(239 208 153 / 0.08);
  color: var(--gold);
  transition: background-color 0.3s, box-shadow 0.3s;
}

.detail:hover .d-icon {
  background: rgb(239 208 153 / 0.16);
  box-shadow: 0 0 26px rgb(239 208 153 / 0.2);
}

svg[viewBox="0 0 24 24"] {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}

.chip svg { width: 16px; height: 16px; }

.d-label {
  margin: 1px 0 4px;
  color: var(--gold);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.d-value { margin: 0; color: var(--text); font-family: var(--display); font-size: 22px; font-style: italic; font-weight: 700; line-height: 1.25; }
.d-sub { margin: 2px 0 0; color: var(--text-muted); font-size: 15px; }
/* Notes run under the action button too, so they don't wrap into a narrow column. */
.d-note { grid-column: 2 / -1; margin: 8px 0 0; color: var(--text-muted); font-size: 14px; line-height: 1.5; text-wrap: pretty; }

.sessions { display: grid; gap: 8px; margin: 2px 0 0; padding: 0; list-style: none; }
.sessions li { display: flex; flex-wrap: wrap; column-gap: 10px; align-items: baseline; }
.s-day { min-width: 92px; color: var(--text); font-weight: 500; }
.s-time { color: var(--text); font-size: 17px; font-weight: 500; font-variant-numeric: tabular-nums; }
.s-note { flex-basis: 100%; color: var(--text-muted); font-size: 14px; line-height: 1.5; }
.s-note:empty { display: none; }

/* Buttons */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 15px;
  border: 0;
  border-radius: 999px;
  background: rgb(239 208 153 / 0.1);
  color: var(--gold-light);
  font: 500 13.5px/1 var(--sans);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.2s;
}

.chip:hover { background: rgb(239 208 153 / 0.2); }

:focus-visible { outline: 2px solid var(--gold-light); outline-offset: 3px; border-radius: 10px; }

.d-action { position: relative; }

.menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 5;
  min-width: 230px;
  padding: 6px;
  border-radius: 14px;
  background: var(--navy-raise);
  box-shadow: 0 18px 50px rgb(0 0 0 / 0.5);
}

.menu a, .menu button {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 11px 12px;
  border: 0;
  border-radius: 9px;
  background: none;
  color: var(--text);
  font: 500 14px/1.2 var(--sans);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.menu a:hover, .menu button:hover { background: rgb(239 208 153 / 0.1); }
.menu span { color: var(--text-muted); font-weight: 400; }

/* Registration */
.register { padding: 20px; }

.reg-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 4px 12px;
  margin-bottom: 14px;
}

.reg-head h3 { margin: 0; font-family: var(--display); font-size: 27px; font-style: italic; font-weight: 700; }
.fee { margin: 0; color: var(--text-muted); font-size: 13.5px; }
.fee strong { color: var(--gold-light); font-weight: 600; }

.tabs {
  position: relative;
  display: grid;
  grid-auto-columns: 1fr;
  grid-auto-flow: column;
  padding: 4px;
  border-radius: 12px;
  background: rgb(0 0 0 / 0.25);
}

.tab {
  position: relative;
  z-index: 1;
  padding: 10px 4px;
  border: 0;
  border-radius: 9px;
  background: none;
  color: var(--text-muted);
  font: 500 13.5px/1 var(--sans);
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.25s;
}

.tab:hover { color: var(--text); }
.tab[aria-selected="true"] { color: var(--navy); font-weight: 600; }
.tab[hidden] { display: none; }

.tab-indicator {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 0;
  width: 0;
  border-radius: 9px;
  background: var(--gold-grad);
  box-shadow: 0 6px 20px -6px rgb(239 208 153 / 0.6);
}

.panel { padding-top: 18px; }
.panel p { margin: 0 0 16px; color: var(--text-muted); }
.panel p:last-child { margin-bottom: 0; }

.btn-primary {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  overflow: hidden;
  padding: 15px 24px;
  border-radius: 999px;
  background: var(--gold-grad);
  box-shadow: 0 12px 32px -12px rgb(239 208 153 / 0.65);
  color: var(--navy);
  font: 600 15.5px/1 var(--sans);
  text-decoration: none;
}

.btn-primary::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 35%, rgb(255 255 255 / 0.55) 50%, transparent 65%);
  transform: translateX(-120%);
  transition: transform 0.7s ease;
}

.btn-primary:hover::after { transform: translateX(120%); }
.btn-primary svg { transition: transform 0.3s; }
.btn-primary:hover svg { transform: translateX(3px); }

.qr-wrap { display: flex; align-items: center; gap: 18px; }
.qr { flex: none; width: 132px; height: 132px; border-radius: 12px; background: #f6f1e1; }
.qr-wrap p { margin: 0; }

.contact-links { display: flex; flex-wrap: wrap; gap: 10px; }

/* ---------- "2026" surprise ---------- */

.surprise {
  position: fixed;
  inset: 0;
  z-index: 20;
  overflow: hidden;
  cursor: pointer;
}

.surprise[hidden] { display: none; }

.surprise-scrim {
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 80% at 50% 100%, rgb(4 25 44 / 0.3), rgb(4 25 44 / 0.78));
  backdrop-filter: blur(3px);
}

/* Sits 64px below the fold so the photo's cropped edge stays hidden while the slide overshoots.
   A little wider than phone screens on purpose: the faces stay big and only their outer arms
   get cropped. Capped near the photo's own 715px width so it stays sharp.
   Centred with a negative margin, not `translate`, which GSAP would fold into its transform. */
.surprise-pop {
  --pop-w: min(112vw, calc((70svh + 64px) * 715 / 612), 700px);
  position: absolute;
  bottom: -64px;
  left: 50%;
  width: var(--pop-w);
  margin: 0 0 0 calc(var(--pop-w) / -2);
}

/* Fades out before the bottom of the screen, so they rise out of the page instead of being cut off. */
.surprise-pop img {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 -12px 40px rgb(0 0 0 / 0.35));
  -webkit-mask-image: linear-gradient(to bottom, #000 50%, transparent 85%);
  mask-image: linear-gradient(to bottom, #000 50%, transparent 85%);
}

/* Holds the bubble above the gap between their heads, so GSAP only ever scales the bubble itself. */
.bubble-anchor {
  position: absolute;
  bottom: 94%;
  left: 43%;
  translate: -50% 0;
}

.bubble {
  position: relative;
  margin: 0;
  padding: 14px 26px 17px;
  border-radius: 28px;
  background: #f8f2e2;
  box-shadow: 0 18px 40px -12px rgb(0 0 0 / 0.55);
  color: var(--navy);
  font-family: var(--display);
  font-size: clamp(26px, 4vw, 38px);
  font-style: italic;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
}

.bubble::after {
  content: '';
  position: absolute;
  bottom: -9px;
  left: 50%;
  margin-left: -11px;
  width: 22px;
  height: 22px;
  border-radius: 0 0 6px 0;
  background: inherit;
  transform: rotate(45deg) skew(8deg, 8deg);
}

/* ---------- Stacked layout ---------- */

@media (max-width: 999px) {
  :root { --u: min((100vw - 32px) / 833, 600px / 833); }

  .page { grid-template-columns: minmax(0, 1fr); height: auto; }
  .art { height: auto; padding: 16px 16px 52px; }
  .info { height: auto; overflow: visible; }
  .info-inner { max-width: 640px; padding: 8px 16px 72px; }
}

@media (max-width: 520px) {
  .detail { grid-template-columns: 40px minmax(0, 1fr); column-gap: 14px; padding: 16px; }
  .d-icon { width: 40px; height: 40px; }
  .d-action { grid-column: 2; order: 1; margin-top: 12px; }
  .menu { right: auto; left: 0; }
  .countdown { gap: 6px; }
  .register { padding: 16px; }
  .tab { font-size: 12.5px; }
  .qr-wrap { flex-direction: column; align-items: flex-start; }
}

@media (prefers-reduced-motion: reduce) {
  .btn-primary::after, .btn-primary svg { transition: none; }
}
