/* =========================================================
   Wedding site — styles
   Mobile-first. Layered: tokens → base → layout → components.
   Envelope animation uses CSS Scroll-Driven Animations API
   when supported; otherwise main.js sets --progress via rAF.
   ========================================================= */

/* ---------- Tokens ---------- */
:root {
  /* Palette: soft cream / sage / dusty rose. Confirm before launch. */
  --bg: #faf6ef;
  --surface: #fffdf8;
  --ink: #2b2a26;
  --ink-soft: #5a564d;
  --accent: #8a9a7b;     /* sage */
  --accent-2: #c98c8c;   /* dusty rose */
  --line: #e6dfd2;
  --gold: #b48a4a;

  --radius: 14px;
  --radius-lg: 22px;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --shadow-md: 0 8px 24px rgba(60, 50, 30, 0.12);
  --shadow-lg: 0 22px 50px rgba(60, 50, 30, 0.18);

  --max-w: 720px;

  /* Driven by JS in fallback path; overridden by scroll-timeline when supported. */
  --progress: 0;
}

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

/* The HTML `hidden` attribute must always win over `display: flex/grid/...`
   rules elsewhere — otherwise gated fields (e.g. RSVP +1 name) leak through. */
[hidden] {
  display: none !important;
}

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  font-size: clamp(15px, 2.6vw, 17px);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  font-family: "Cormorant Garamond", "Iowan Old Style", Georgia, serif;
  font-weight: 500;
  letter-spacing: 0.01em;
  margin: 0;
  color: var(--ink);
}

p {
  margin: 0;
}

img {
  max-width: 100%;
  display: block;
}

button {
  font: inherit;
  color: inherit;
  cursor: pointer;
}

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* ---------- Layout primitives ---------- */
main {
  display: flex;
  flex-direction: column;
  gap: clamp(48px, 9vw, 96px);
  padding: clamp(48px, 9vw, 96px) clamp(20px, 5vw, 32px);
  max-width: var(--max-w);
  margin: 0 auto;
}

section {
  text-align: center;
}

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

.section-title {
  font-size: clamp(24px, 5vw, 34px);
  margin-bottom: 20px;
}

/* =========================================================
   1 — ENVELOPE HERO
   ========================================================= */
/* sceneWrapper: no overflow hidden, tall enough for the full sticky animation
   plus the scroll distance that drives --progress 0 → 1. */
.hero {
  min-height: 200svh;
  position: relative;
}

/* stickyScene: sits 12vh from viewport top with 76vh of height. The envelope
   is anchored to the bottom of this scene (justify-content: flex-end), so the
   space above the envelope (76vh − envelope.height) is the room the letter
   has to slide upward into. No overflow:hidden here — the letter must be
   able to extend visually above the envelope. */
.hero__sticky {
  position: sticky;
  top: 12vh;
  height: 76vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  background:
    radial-gradient(ellipse at 50% 70%, #fffdf6 0%, var(--bg) 70%);
}

.scroll-hint {
  position: absolute;
  bottom: max(24px, env(safe-area-inset-bottom));
  left: 0;
  right: 0;
  text-align: center;
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  opacity: calc(1 - var(--progress) * 2);
  pointer-events: none;
}

/* --- Envelope ---
   Four flat layers, ordered back→front. Animation timeline split into
   three phases via derived progress vars:
     0.00 – 0.25  →  flap rotates open  (rotateX 0deg → 160deg)
     0.25 – 0.88  →  letter translates upward until its body clears the pocket
     0.88 – 1.00  →  letter hands off to the escaped layer and settles
   transform-origin: top center on the flap; only translateY/rotateX/scale used. */
.envelope {
  --w: min(86vw, 420px);
  /* Envelope aspect 4:3 (landscape). */
  --h: calc(var(--w) * 0.75);

  /* Letter geometry — derived once so the slot clip can reference the
     same numbers that drive the .letter's width and aspect. */
  --letter-w: calc(var(--w) * 0.86);
  --letter-h: calc(var(--letter-w) * 10 / 7);
  /* Park the letter deep in the pocket: its top starts near the V tip, so
     only a small strip peeks through after the flap opens. */
  --letter-start-y: calc(var(--h) * 0.36);
  /* Travel far enough that the card's lower edge clears the pocket before
     the top-layer handoff starts. The 40px overlap keeps the final card
     visually resting on the envelope rather than floating above it. */
  --letter-travel: calc(var(--letter-start-y) + var(--letter-h) - 40px);
  --letter-reveal: calc(var(--letter-travel) + 24px);
  --final-center-lift: calc(var(--settle-progress) * clamp(120px, 31vw, 160px));
  --scene-y: calc((var(--letter-progress) * -64px) - var(--final-center-lift));
  --settle-down: calc(var(--settle-progress) * clamp(292px, 74vw, 382px));

  --flap-progress:   clamp(0, calc( var(--progress)         / 0.25), 1);
  --letter-progress: clamp(0, calc((var(--progress) - 0.25) / 0.63), 1);
  --settle-progress: clamp(0, calc((var(--progress) - 0.88) / 0.12), 1);
  --escape-progress: clamp(0, calc((var(--progress) - 0.88) / 0.01), 1);

  position: relative;
  width: var(--w);
  height: var(--h);
  perspective: 1400px;
  transform: translateY(var(--scene-y));
  will-change: transform;
}

/* 1 — envelope-back (z=1) — full rectangle behind everything */
.envelope-back {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, #fdfaf2 0%, #f1e9d3 100%);
  border-radius: 6px;
  box-shadow:
    0 1px 0 rgba(0, 0, 0, 0.04),
    0 18px 28px rgba(60, 50, 30, 0.16);
  z-index: 1;
}

/* 2a — envelope-slot (z=2) — the only masked area in the animation.
   During Phase 1, the top of this mask opens upward with the letter. That
   lets the visible part of the invitation escape the envelope while the
   front pocket still covers the portion that remains inside. The top-layer
   duplicate does not fade in until the slide-out phase is complete. */
.envelope-slot {
  position: absolute;
  inset: 0;
  clip-path: inset(
    calc(var(--letter-progress) * -1 * var(--letter-reveal)) 0 0 0
  );
  z-index: 2;
}

/* 2b — shared letter geometry. Top-positioned inside the pocket so the
   initial state reveals only a small edge through the V opening. */
.letter {
  position: absolute;
  top: var(--letter-start-y);
  left: 50%;
  width: var(--letter-w);
  aspect-ratio: 7 / 10;
  pointer-events: none;
  --letter-y: calc(var(--letter-progress) * -1 * var(--letter-travel));
  --bounce-y: calc(sin(var(--settle-progress) * 180deg) * -4px);
  transform: translate(-50%, calc(var(--letter-y) + var(--settle-down) + var(--bounce-y)));
  will-change: transform;
}

.letter--inside {
  opacity: calc(1 - var(--escape-progress));
}

/* Phase 2: once the invitation has escaped the pocket, this unclipped duplicate
   takes over above the front pocket and flap. It uses the same transform path,
   so the handoff feels like one continuous card rather than two layers. */
.letter--escaped {
  z-index: 10;
  opacity: var(--escape-progress);
}

.letter img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  border-radius: 2px;
  background: #fffdf8;
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.05),
    0 10px 24px rgba(40, 30, 10, 0.18);
}

/* 3 — envelope-front (z=3) — front pocket with V-cut at top
   Polygon vertices: top-left → V tip (50% 35%) → top-right → bottom-right → bottom-left.
   The V tip at 35% matches the flap height, so the closed flap covers the cut exactly. */
.envelope-front {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, #fcf8ec 0%, #ebe2c5 100%);
  clip-path: polygon(0 0, 50% 35%, 100% 0, 100% 100%, 0 100%);
  z-index: 3;
  border-radius: 6px;
}

/* Subtle vertical seam down the front pocket from the V tip */
.envelope-front::after {
  content: "";
  position: absolute;
  top: 35%;
  bottom: 0;
  left: 50%;
  width: 1px;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.05), transparent);
  pointer-events: none;
}

/* 4 — envelope-flap (z=4) — triangular flap, rotates 0deg → 160deg
   transform-origin: top center, so it hinges on the envelope's top fold line.
   backface-visibility: hidden hides the flap once it has rotated past 90°,
   which clears the area in front of the letter without needing a z-index swap. */
.envelope-flap {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 35%;
  background: linear-gradient(180deg, #fdfaf2 0%, #ebe2c5 100%);
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  transform-origin: top center;
  transform: rotateX(calc(var(--flap-progress) * 160deg));
  backface-visibility: hidden;
  z-index: 4;
  will-change: transform;
  pointer-events: none;
}

/* --progress is driven by JS in main.js (setupAnimationFallback) on every frame.
   We declare it as a number so calc() expressions in other rules type-check cleanly. */
@property --progress {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

/* --- Reduced motion: snap to fully-open state --- */
@media (prefers-reduced-motion: reduce) {
  :root { --progress: 1; }
  .hero { height: 100svh; }
}

/* =========================================================
   2/3 — INTRO
   ========================================================= */
.intro__eyebrow {
  font-family: "Great Vibes", "Apple Chancery", cursive;
  font-size: clamp(32px, 7vw, 52px);
  color: var(--accent);
  margin-bottom: 8px;
}

.intro__names {
  font-size: clamp(36px, 8vw, 64px);
  line-height: 1.1;
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: center;
}

.intro__amp {
  font-style: italic;
  color: var(--accent);
  font-size: 0.7em;
}

@media (min-width: 640px) {
  .intro__names {
    flex-direction: row;
    gap: 16px;
  }
}

/* =========================================================
   4 — DATE — clean clickable text, no card
   ========================================================= */
.date__display {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  display: inline-flex;
  flex-direction: column;
  gap: 4px;
  align-items: center;
  cursor: pointer;
  color: inherit;
  transition: opacity 0.15s ease;
}

.date__display:hover,
.date__display:focus-visible {
  opacity: 0.7;
  outline: none;
}

.date__primary {
  /* Same secondary-header tier as .venue__name and .dress__title. */
  font-family: "Cormorant Garamond", "Iowan Old Style", Georgia, serif;
  font-size: clamp(21px, 4.4vw, 28px);
  font-weight: 500;
  line-height: 1.2;
  /* Thin underline = link affordance. Soft by default, accent on hover/focus. */
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 6px;
  text-decoration-color: var(--line);
  transition: text-decoration-color 0.15s ease;
}

.date__display:hover .date__primary,
.date__display:focus-visible .date__primary {
  text-decoration-color: var(--accent);
}

.date__time {
  font-size: clamp(14px, 2.8vw, 16px);
  color: var(--ink-soft);
  letter-spacing: 0.04em;
}

/* =========================================================
   5 — VENUE — clean clickable text, no card
   ========================================================= */
.section-photo,
.venue__photo {
  width: min(90%, 576px);
  height: auto;
  margin: 0 auto 30px;
  opacity: 0.95;
  border-radius: var(--radius);
  filter: saturate(0.94) contrast(0.98) brightness(1.01);
}

.venue__trigger {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  display: inline-flex;
  flex-direction: column;
  gap: 6px;
  align-items: center;
  cursor: pointer;
  color: inherit;
  transition: opacity 0.15s ease;
}

.venue__trigger:hover,
.venue__trigger:focus-visible {
  opacity: 0.7;
  outline: none;
}

.venue__name {
  font-family: "Cormorant Garamond", "Iowan Old Style", Georgia, serif;
  font-size: clamp(21px, 4.4vw, 28px);
  font-weight: 500;
  line-height: 1.2;
  /* Thin underline = link affordance. Soft by default, accent on hover/focus. */
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 6px;
  text-decoration-color: var(--line);
  transition: text-decoration-color 0.15s ease;
}

.venue__trigger:hover .venue__name,
.venue__trigger:focus-visible .venue__name {
  text-decoration-color: var(--accent);
}

.venue__address {
  color: var(--ink-soft);
  font-size: clamp(13px, 2.7vw, 15px);
  max-width: 32ch;
}

/* =========================================================
   Dialog / bottom sheet
   ========================================================= */
.sheet {
  border: 0;
  padding: 0;
  background: transparent;
  margin: auto;
  max-width: min(420px, 92vw);
  width: 100%;
}

.sheet[open] {
  animation: sheet-in 0.22s ease-out;
}

.sheet::backdrop {
  background: rgba(30, 25, 20, 0.45);
  backdrop-filter: blur(2px);
}

.sheet__inner {
  background: var(--surface);
  border-radius: var(--radius-lg);
  padding: 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  box-shadow: var(--shadow-lg);
  position: relative;
}

.sheet__title {
  font-family: "Cormorant Garamond", "Iowan Old Style", Georgia, serif;
  font-size: 22px;
  text-align: center;
  margin: 0;
}

.sheet__actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.sheet__close {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 12px;
  color: var(--ink-soft);
  font: inherit;
  cursor: pointer;
}

.sheet__close-x {
  position: absolute;
  top: 8px;
  right: 12px;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border: 0;
  background: transparent;
  font-size: 24px;
  color: var(--ink-soft);
  cursor: pointer;
  border-radius: 50%;
}

.sheet__close-x:hover {
  background: var(--bg);
}

.map-btn {
  display: block;
  text-align: center;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
  font-size: 15px;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.map-btn:hover,
.map-btn:focus-visible {
  background: var(--bg);
  border-color: var(--accent);
}

@keyframes sheet-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* On phones, dock the sheet to the bottom edge */
@media (max-width: 540px) {
  .sheet {
    margin: auto auto 0;
    max-width: 100%;
  }
  .sheet__inner {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    padding-bottom: max(24px, env(safe-area-inset-bottom));
  }
}

.sheet--form {
  max-width: min(520px, 92vw);
}

/* =========================================================
   6 — DRESS
   ========================================================= */
.dress__title {
  /* Same secondary-header tier as .venue__name — matched font/size/weight. */
  font-family: "Cormorant Garamond", "Iowan Old Style", Georgia, serif;
  font-size: clamp(21px, 4.4vw, 28px);
  font-weight: 500;
  line-height: 1.2;
  margin-bottom: 6px;
}

.dress__desc {
  color: var(--ink-soft);
  max-width: 48ch;
  margin: 0 auto;
}

/* =========================================================
   8 — RSVP
   ========================================================= */
.rsvp__deadline {
  color: var(--ink-soft);
  margin-top: 12px;
}

.rsvp__form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  text-align: left;
}

/* Form children inherit body font + size by default; we explicitly reset any
   smaller-than-body overrides below so labels, hints, and status all read
   like body copy. Hierarchy is carried by colour (--ink-soft) and weight,
   not by size. */

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.field > span,
.field__label,
.field--radio legend {
  color: var(--ink-soft);
}

.field input[type="text"],
.field textarea {
  width: 100%;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font: inherit;
  color: inherit;
}

.field input:focus-visible,
.field textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.field--radio {
  border: 0;
  padding: 0;
  margin: 0;
}

.field--radio label {
  margin-right: 16px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
}

.field--check {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}

.field--check span {
  color: var(--ink);
}

.kids {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 8px;
}

.kid-row {
  display: grid;
  grid-template-columns: 2fr 1fr auto;
  gap: 8px;
}

.kid-row input {
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  font: inherit;
}

.kid-row button {
  background: transparent;
  border: 0;
  color: var(--ink-soft);
  padding: 0 8px;
  font-size: 18px;
}

.link-btn {
  background: none;
  border: 0;
  color: var(--accent);
  padding: 0;
  text-align: left;
  text-decoration: underline;
}

.honeypot {
  position: absolute;
  left: -10000px;
  opacity: 0;
  pointer-events: none;
}

.rsvp__hint {
  color: var(--ink-soft);
}

.rsvp__status {
  min-height: 1.4em;
  text-align: center;
  margin: 0;
}

.rsvp__status.is-success {
  color: var(--accent);
}

.rsvp__status.is-error {
  color: var(--accent-2);
}

/* =========================================================
   Buttons
   ========================================================= */
.primary-btn {
  display: inline-block;
  padding: 14px 28px;
  background: var(--ink);
  color: var(--surface);
  border: 0;
  border-radius: 999px;
  font-size: 15px;
  letter-spacing: 0.05em;
  text-decoration: none;
  text-align: center;
  transition: transform 0.15s ease, background 0.15s ease;
}

.primary-btn:hover,
.primary-btn:focus-visible {
  transform: translateY(-2px);
  background: var(--accent);
}

/* =========================================================
   7 — HOTELS
   ========================================================= */
.hotels__grid {
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr;
}

@media (min-width: 640px) {
  .hotels__grid {
    grid-template-columns: 1fr 1fr;
  }
}

.hotel-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  text-align: left;
  display: flex;
  flex-direction: column;
}

.hotel-card img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
}

.hotel-card__body {
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.hotel-card__name {
  font-family: "Cormorant Garamond", serif;
  font-size: 20px;
}

.hotel-card__meta {
  font-size: 13px;
  color: var(--ink-soft);
}

.hotel-card a {
  margin-top: auto;
  align-self: flex-start;
  font-size: 14px;
}

.hotels__empty {
  color: var(--ink-soft);
  font-style: italic;
}

/* =========================================================
   9 — HONEYMOON
   ========================================================= */
.honeymoon__desc {
  color: var(--ink-soft);
  max-width: 56ch;
  margin: 0 auto 24px;
}

.honeymoon__transfer {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: baseline;
  justify-content: center;
  color: var(--ink-soft);
}

.honeymoon__transfer-label {
  color: inherit;
}

.honeymoon__transfer-value {
  font: inherit;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--ink);
}

.honeymoon__copy {
  margin-left: 4px;
}

/* =========================================================
   11 — GALLERY
   ========================================================= */
.gallery__carousel {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) 40px;
  align-items: center;
  gap: 10px;
}

.gallery__track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 100%;
  gap: 16px;
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  padding: 2px 0 10px;
}

.gallery__track::-webkit-scrollbar {
  display: none;
}

.gallery__track img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border-radius: var(--radius);
  background: var(--line);
  scroll-snap-align: center;
}

.gallery__nav {
  width: 40px;
  aspect-ratio: 1;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--surface);
  color: var(--ink);
  font-size: 28px;
  line-height: 1;
  box-shadow: var(--shadow-sm);
  transition: transform 0.15s ease, opacity 0.15s ease, border-color 0.15s ease;
}

.gallery__nav:hover,
.gallery__nav:focus-visible {
  transform: translateY(-1px);
  border-color: var(--accent);
}

@media (min-width: 640px) {
  .gallery__track {
    grid-auto-columns: 100%;
    max-width: 520px;
    margin: 0 auto;
  }
}

/* =========================================================
   10 — IMPORTANT INFO
   ========================================================= */
.important-info__list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  text-align: left;
  max-width: 560px;
  margin: 0 auto;
}

.important-info__list details {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 18px;
}

.important-info__list summary {
  cursor: pointer;
  font-family: "Cormorant Garamond", serif;
  font-size: 19px;
  list-style: none;
  position: relative;
  padding-right: 28px;
}

.important-info__list summary::-webkit-details-marker {
  display: none;
}

.important-info__list summary::after {
  content: "+";
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  color: var(--accent);
  font-size: 22px;
  transition: transform 0.2s ease;
}

.important-info__list details[open] summary::after {
  content: "−";
}

.important-info__list p {
  margin-top: 8px;
  color: var(--ink-soft);
}

/* =========================================================
   Footer
   ========================================================= */
.footer {
  text-align: center;
  padding: 40px 20px max(40px, env(safe-area-inset-bottom));
  color: var(--ink-soft);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  font-size: clamp(15px, 2.6vw, 17px);
}
