/* ==========================================================================
   Jatnna & Rainerd — Design tokens (from Figma: AzMZzYkXyzVgsSOdlVEMYR)
   ========================================================================== */

@font-face {
  font-family: 'Venetian 301';
  src: url('fonts/venetian-301.otf') format('opentype');
  font-style: italic;
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'New Icon Serif';
  src: url('fonts/new-icon-serif-regular.otf') format('opentype');
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'New Icon Script';
  src: url('fonts/new-icon-script-regular.otf') format('opentype');
  font-weight: 400;
  font-display: swap;
}

:root {
  --cream: #ddd9ce;
  --olive-deep: #535931;
  --olive-mid: #757547;
  --olive-dark: #2a2a1e;
  --gold: #9a782e;
  --ink: #0c171d;
  --ink-2: #0e191f;
  --ink-3: #272a19;
  --rust: #6e2f1e;

  --serif: 'New Icon Serif', 'Playfair Display', serif;
  --script: 'New Icon Script', 'Snell Roundhand', cursive;
  --italic: 'Venetian 301', 'EB Garamond', serif;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--italic);
  overflow-x: hidden;
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

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

/* ==========================================================================
   Nav
   ========================================================================== */

.site-nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 500;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 22px clamp(20px, 4vw, 64px);
  font-family: var(--italic);
  font-style: italic;
  letter-spacing: 0.08em;
  font-size: 14px;
  color: var(--cream);
  mix-blend-mode: difference;
  transition: padding .3s ease;
}
.site-nav__mark { width: 40px; height: 32px; color: var(--cream); }
/* While the nav sits over the hero (see site.js ScrollTrigger), force
   plain white instead of the adaptive difference-blend look used
   everywhere else — the hero's dark background image already guarantees
   contrast, so there's no need for the blend trick there, and explicit
   white reads more intentional against it. */
.site-nav--on-hero {
  color: #fff;
  mix-blend-mode: normal;
}
.site-nav--on-hero .site-nav__mark { color: #fff; }
/* Explorar's olive-mid background is close enough in value to the nav's
   own cream that the difference blend washes out to a grayish tone
   instead of reading dark like it does over lighter sections — forced
   dark here (see site.js ScrollTrigger) to match. */
.site-nav--on-explorar {
  color: var(--ink);
  mix-blend-mode: normal;
}
.site-nav--on-explorar .site-nav__mark { color: var(--ink); }
/* Mobile menu open (see nav-toggle.js) — the full-screen overlay needs to
   render as a plain solid block, but mix-blend-mode:normal set only on
   the overlay itself isn't enough: without isolating the WHOLE nav bar,
   .site-nav's own difference blend still diffs the overlay's already-
   rendered pixels against the page behind it, which read as washed-out/
   see-through instead of solid over sections that don't already force
   mix-blend-mode:normal (--on-hero/--on-explorar/--inner). Switching the
   ancestor itself off is the only reliable fix. */
.site-nav--menu-open { mix-blend-mode: normal; }
.site-nav__links { display: flex; gap: clamp(14px, 2vw, 28px); list-style: none; margin: 0; padding: 0; }
.site-nav__links a:hover { opacity: .7; }
.site-nav__rsvp-toggle { display: none; }
.site-nav__overlay { display: none; }

/* Burger button — hidden on desktop (the full link list shows instead,
   see above). Three bars built from currentColor so it automatically
   follows whatever color state the nav bar is in (--on-hero, --inner,
   --on-explorar, etc.) with no separate per-variant overrides needed. */
.site-nav__burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 32px;
  height: 32px;
  padding: 0;
  background: none;
  border: none;
  z-index: 2;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.site-nav__burger span {
  display: block;
  width: 22px;
  height: 1.5px;
  background: currentColor;
  transition: transform .3s ease, opacity .2s ease;
}
.site-nav__burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.site-nav__burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.site-nav__burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }
.site-nav--inner .site-nav__burger { color: #ffeac3; }

@media (max-width: 780px) {
  .site-nav__burger {
    display: flex;
    /* A plain line icon floating directly on the hero photo / textured
       section backgrounds was hard to read and didn't feel like a real
       tappable button — a solid chip behind it fixes both. Same cream
       the monogram already uses everywhere, so the two keep reading as
       one consistent nav palette. mix-blend-mode/isolation here keep the
       chip itself legible while closed; while the menu is OPEN,
       .site-nav--menu-open (above) additionally switches the whole bar
       off blend mode, since isolating this element alone isn't enough
       — see that rule's comment. */
    width: 38px;
    height: 38px;
    background: var(--olive-dark);
    color: var(--cream);
    border-radius: 50%;
    mix-blend-mode: normal;
    isolation: isolate;
  }
  .site-nav--inner .site-nav__burger { color: var(--cream); }
  /* Dim, blurred backdrop behind the drawer (below) — covers the rest of
     the screen so the page still reads as "there," just backgrounded,
     rather than swapped out for a flat color. Click-to-close target,
     see nav-toggle.js. position:fixed takes both this and the drawer out
     of the nav's own flex flow, so the bar still lays out as just mark +
     burger (space-between) underneath. */
  .site-nav__overlay {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 0;
    background: rgba(12, 15, 8, .45);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    mix-blend-mode: normal;
    isolation: isolate;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .3s ease;
  }
  .site-nav__overlay.is-open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
  }
  /* Right-side drawer — only part of the screen, not a full-bleed panel.
     Slides in via transform instead of the old fade, sitting above the
     dim overlay above (z-index 1 > 0, both scoped inside .site-nav's own
     z-index:500 stacking context). */
  .site-nav__links {
    position: fixed;
    top: 0; right: 0; bottom: 0; left: auto;
    width: min(78vw, 300px);
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: clamp(22px, 5vh, 30px);
    margin: 0;
    padding: 80px 36px 40px;
    background: var(--olive-dark);
    color: var(--cream);
    mix-blend-mode: normal;
    isolation: isolate;
    box-shadow: -16px 0 40px rgba(0,0,0,.35);
    transform: translateX(100%);
    transition: transform .32s ease;
  }
  .site-nav__links.is-open { transform: translateX(0); }
  .site-nav__links a {
    color: var(--cream);
    font-size: clamp(17px, 4.2vw, 21px);
    text-align: left;
  }
  .site-nav--inner .site-nav__links a,
  .site-nav--inner .site-nav__links a.rsvp-accent { color: var(--cream); }
}
/* Locked by nav-toggle.js while the mobile overlay is open, so the page
   behind it can't scroll. */
body.nav-open { overflow: hidden; }


/* ==========================================================================
   Section 1 — Invitación
   ========================================================================== */

.section-invitacion {
  position: relative;
  min-height: 100vh;
  padding: 150px 20px 80px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  background: #4b4a2e;
}

/* Outer visual stage — centers the envelope/card group on the COMBINED
   visual bounds of the settled composition (open flap above + envelope
   body + foreground card, which together render taller than, and off-
   center from, .envelope-perspective's own closed-envelope-ratio box),
   not on that box's plain geometric center. Absolute + translate(-50%,
   -50%) rather than flex centering specifically because flex would
   center .envelope-perspective's OWN box — the thing that needs fixing
   is exactly that this box's center doesn't match the visual content's
   center. The extra translateY() is that correction: the open flap adds
   height above the box while the settled card adds comparatively little
   below it, so plain centering alone still reads top-heavy — this nudges
   the whole stage down by a fraction of its OWN rendered height
   (translateY %, unlike top/left %, resolves against the element's own
   box), so it scales correctly at every viewport size instead of only
   the one it was tuned against. Pulls the stage out of the section's
   flex flow, which is why .invitacion__foot (below) is independently
   pinned near the section's bottom edge rather than following it. */
.envelope-stage {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) translateY(30%);
}
/* Mobile-only hero-level foreground for the settled card (see
   #invitation-card-foreground-layer in index.html and the reparent
   logic in site.js) — a direct child of .section-invitacion, deliberately
   OUTSIDE the envelope hierarchy (.env2-frame / .envelope-object /
   .envelope__card-clip), so nothing about it is sized or bounded by the
   envelope's own geometry. overflow:visible + no width/left/right here
   at all: the card that gets moved into this layer carries its own
   explicit inline position (set in site.js at reparent time), this is
   just an unbounded stage for it to sit in. pointer-events:none so this
   full-hero-sized layer never blocks clicks/taps to anything beneath it
   while empty or around the card's own edges — the card itself restores
   pointer-events:auto (see .envelope__card), so it stays interactive.
   z-index:50 is deliberately high — this must paint above the entire
   envelope stage (which has no z-index of its own, i.e. stacks at 0). */
.invitation-card-foreground-layer {
  position: absolute;
  inset: 0;
  overflow: visible;
  pointer-events: none;
  z-index: 50;
}
/* Mobile-only hero-level EXTRACTION stage (see index.html's own comment
   and reparentCardToHeroExtractionLayer() in site.js) — a direct child
   of .section-invitacion, entirely outside .envelope-object's
   perspective/preserve-3d/backface-visibility hierarchy, unlike
   #envelope-card-extraction-layer which is still inside it. z-index:40
   is deliberately between .envelope-stage's implicit 0 (must paint
   above the whole open envelope/flap) and this foreground layer's own
   50 (the card must still hand off to that layer, above this one, once
   fully clear — see PHASE C in site.js).
   top:0 + overflow:hidden + a runtime `height` (set in site.js to the
   envelope's own live bottom edge, in this layer's coordinate space) is
   what gives the card unlimited room to rise ABOVE the envelope while
   still hard-clipping anything that would render BELOW the envelope's
   physical bottom — the old #envelope-card-extraction-layer clipped
   the card to the envelope's own transformed 3D face (the actual top-
   clipping bug), whereas this box's top edge sits at the HERO's own
   top, far above the envelope, so only the BOTTOM edge ever clips. No
   `left`/`right`/`bottom` here — those are irrelevant to what this
   layer needs to constrain. */
.invitation-card-extraction-hero-layer {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 40;
}
/* Temporary duplicate of .env2-body-front, pinned by site.js over the
   real one only while the card is mid-rise inside the layer above (see
   that layer's own comment). display:none by default — an inline style
   set directly in index.html and toggled the same way in site.js, not
   the `hidden` attribute, so there's no risk of an author rule with
   equal/higher specificity silently winning the cascade (a real bug hit
   elsewhere on this site with .mensajes-empty). */
.hero-body-front-overlay {
  position: absolute;
  pointer-events: none;
}
/* Static full-bleed hero background — same treatment on every viewport,
   no mobile-specific rotation: object-fit:cover already crops/fills
   correctly at any aspect ratio on its own, and the source photo is shot
   portrait, not landscape, so there's no "sideways clip" problem the old
   video version needed a 90deg rotate hack to fix. */
.section-invitacion__wallpaper {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
/* Reusable masked monogram mark — color comes from `color`, sized by the
   caller. Used in nav, footer and hero so the one JR SVG can be tinted
   differently per background instead of needing separate colored exports. */
.jr-mark {
  display: block;
  background-color: currentColor;
  -webkit-mask: url('images/jr-monogram.svg') center / contain no-repeat;
  mask: url('images/jr-monogram.svg') center / contain no-repeat;
}

/* ── Cinematic intro: perspective stage > flipping object > two faces ──────
   .envelope-perspective establishes the 3D viewing context (perspective).
   .envelope-object is the ONE rigid body that rotates on its Y axis —
   nothing inside it animates independently while it's turning; the flip
   is a single parent transform, never combined with child transforms.
   Its two faces (address side / flap side) are stacked via
   backface-visibility:hidden on opposite sides of the same 3D object,
   same size and position, so the flip reads as one physical envelope
   turning over rather than a crossfade between two images.

   Master frame is the real envelope artwork's own ratio (624x466,
   landscape) — every layer inside .envelope-flap-side shares this exact
   box (inset:0 or top:0/width:100%) so nothing is independently cropped,
   stretched or offset; the assets were designed to align on their own. */
.envelope-perspective {
  /* ~14% wider than the previous min(70vw,430px) — within the 15-25%
     ask, tuned down from an initial 520px cap once measuring the
     rendered combined bounds (flap + envelope + card) showed that size
     pushed well past the 55-65%-of-viewport-height target and crowded
     the nav. margin:0 auto is dead weight now that the positioning
     parent (.envelope-stage) centers this via absolute+translate rather
     than flex/block layout, but harmless to leave. */
  width: min(72vw, 490px);
  aspect-ratio: 624 / 466;
  margin: 0 auto;
  perspective: 2200px;
}
.envelope-object {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.envelope-side {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

/* STAGE 1 face — the real closed-back artwork, name overlaid on top. */
.envelope-address-side {
  overflow: hidden;
  box-shadow: 0 18px 40px rgba(0,0,0,.35);
}
.envelope-address-side img { position: absolute; inset: 0; width: 100%; height: 100%; }
.envelope-address-name {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--script);
  color: var(--ink-3);
  /* --name-scale is set by site.js (fitGuestName) so long names step down
     in size instead of wrapping onto a third line. */
  font-size: calc(clamp(20px, 3.2vw, 32px) * var(--name-scale, 1));
  line-height: 1.25;
  letter-spacing: .03em;
  padding: 0 12%;
  text-align: center;
}

/* STAGE 2 face — the physical envelope, rotated 180deg so it only faces
   the viewer once the parent .envelope-object has finished flipping. */
.envelope-flap-side {
  transform: rotateY(180deg);
  box-shadow: 0 18px 40px rgba(0,0,0,.35);
}

/* ONE persistent envelope frame. Body, the card and Body-front never fade
   or swap — they sit at fixed positions for the entire sequence. Only the
   flap (closed ↔ open) and the seal, both confined to their own small
   region at the top, ever toggle. Paint order (DOM order) is the
   stacking order: body (back) < flap-open (the risen card must sit IN
   FRONT of the open flap's gold lining, never behind/under it) < card <
   body-front (front pocket, physically hides the card's lower portion)
   < flap-closed (must stay above body-front — a closed flap covers the
   whole top corner-to-corner, including in front of body-front's own
   peaks) < seal. */
.env2-frame {
  position: absolute;
  inset: 0;
  /* Local 3D viewing context for the flap's own rotateX hinge fold below
     — independent of the outer whole-envelope Y-flip's perspective, so
     the two 3D systems never interact or compound. */
  perspective: 900px;
}
.env2-body,
.env2-body-front {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* Flap region — two DIFFERENT physical orientations sharing ONE
   world-space hinge line (the envelope body's own top edge), not one
   shared CSS box. This is the geometry that was wrong before:
   env2-flap-closed.png points DOWNWARD (wide at ITS OWN top, tapering
   to a tip at ITS OWN bottom) — its hinge is its top edge, so top:0 +
   transform-origin:top is correct for it. env2-flap-open.png is a
   vertical MIRROR of that (points UPWARD: wide at its own bottom,
   tapering to a tip at its own top) — its hinge is its BOTTOM edge. Two
   opposite-oriented assets anchored at the same CSS top:0 would put the
   open flap's hinge at the WRONG end (its tip, not its base), which is
   exactly why it used to read as interior artwork changing in place
   instead of a flap physically unfolding upward and back. bottom:100%
   puts env2-flap-open's own box-bottom at the frame's top edge — but
   the PNG has ~0.69% of its own rendered height as transparent padding
   below its actual visible fold edge (measured: canvas row 288, last
   opaque row 286, on a 288px-tall canvas), which read as a hairline gap
   at the hinge. -0.43% (that 0.69%, converted from "% of the flap's own
   height" to "% of the frame's height" via the flap/frame aspect ratio)
   corrects it so the VISIBLE fold edge — not the transparent canvas
   boundary — sits exactly on the hinge. env2-flap-closed's own padding
   (~1px out of 294) is sub-pixel at any real render size and left alone.
   backface-visibility guards against a mirrored flash right at the
   edge-on (90deg) frame some browsers can produce mid-fold. */
.env2-flap {
  position: absolute;
  left: 0;
  width: 100%;
  height: auto;
  display: block;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.env2-flap-closed {
  top: 0;
  bottom: auto;
  transform-origin: 50% 0%;
}
.env2-flap-open {
  top: auto;
  /* 97.8% — a further ~0.8% (≈3px at this envelope's now-larger rendered
     size) below the previous 98.6%, since that still left the flap's
     lower border sitting slightly too high above Body. Hinge/rotation
     geometry (transform-origin, the rotateX fold in site.js) is
     untouched — this is a pure resting-position nudge. */
  bottom: 97.8%;
  transform-origin: 50% 100%;
}

/* Seal sits at the closed flap's tip — real wax-seal.png artwork (JR
   monogram pressed into olive wax), replacing the earlier CSS-drawn
   circle + masked monogram placeholder. The source canvas (1254x1254) is
   mostly transparent margin/glow around the actual disc — the wax itself
   only fills ~67% of the image's own width (measured: opaque columns
   17%-83%) — so this is sized to 22.5% of the frame (15% / 0.67) rather
   than the 15% the old CSS circle used, which puts the VISIBLE wax disc
   at that same 15%, matching the previous scale exactly. No box-shadow
   here — the art's own shadow is baked in. */
.env2-seal {
  position: absolute;
  top: 58%;
  left: 50%;
  /* 15% bigger than the previous 22.5% (22.5 * 1.15 = 25.875%). Centered
     via translate(-50%,-50%), so growing the box keeps the same center
     point automatically — no position change needed. */
  width: 25.875%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  display: block;
}

/* Card clip stage — a hard boundary pinned to the envelope's own bottom
   edge (bottom:3px — a hairline of intentional overscan so an antialiased
   edge on Body-front never shows a sliver of the card's own fill peeking
   underneath it) so the card can rise freely (top pulled generously above
   the frame — -120% is overscan headroom, not a tuned value, since the
   card's actual travel is now a live pixel measurement, see site.js) but
   can never render below the envelope's physical bottom. Sits between
   Body (behind) and Body-front (in front) in the open group's paint
   order — see the HTML — so Body-front always physically occludes the
   card's lower portion; nothing here uses z-index tricks or opacity to
   hide it. overflow:clip + contain:paint is a defensive second layer
   alongside overflow:hidden — Safari has a known history of failing to
   clip a GPU-composited descendant (which the card is, moved via GSAP
   `y`) against an ancestor's plain overflow:hidden alone.

   .envelope__card-extraction-layer (see HTML: #envelope-card-extraction-
   layer, sits right after this clip stage and before Body-front) and
   .envelope__card-clip--foreground (see HTML: #envelope-card-foreground,
   last child of .env2-frame so it paints above everything else) both
   share this EXACT box — same left/right/top/bottom — but drop the
   overflow/contain entirely. site.js reparents the card (same element,
   not a clone) first from the clipped stage into the extraction layer
   (right as the rise begins, so it can keep rising past this box's own
   top edge without being cut off, while Body-front — painted after the
   extraction layer in the HTML — still occludes its lower portion), then
   later from there into the foreground/hero layer once fully clear.
   Because every one of these boxes is geometrically identical, the
   card's own `top:100%` base position and its GSAP `y` transform resolve
   to the exact same pixels in all of them, so every hop produces zero
   visual shift — only the occlusion rule changes. */
.envelope__card-clip,
.envelope__card-clip--foreground,
.envelope__card-extraction-layer {
  position: absolute;
  left: 15%; right: 15%;
  top: -120%;
  bottom: 3px;
  pointer-events: none;
}
.envelope__card-clip {
  overflow: hidden;
  overflow: clip;
  contain: paint;
}
/* .envelope__card-clip--foreground (#envelope-card-foreground) is no
   longer used for the final settled card on either platform — desktop
   now hands off to the hero-level #invitation-card-foreground-layer
   just like mobile already did (see reparentCardToHeroForegroundDesktop()
   in site.js), so the final size is driven by a GSAP `width` tween
   instead of by swapping into a differently-sized CSS parent — that
   parent swap (15% extraction insets vs. an earlier 11% foreground
   override here) was exactly what caused the old instant size "pop".
   This box is left in the DOM (still shares the extraction stage's
   original 15%/15% geometry below) in case anything else ever needs
   it, but nothing currently reparents into it. */
/* top:100% of THIS box's own (generously tall) height puts the card's
   un-transformed top edge exactly at the envelope's own bottom edge —
   a clean, single reference point. From there site.js's `y` transform
   (a pixel offset measured live off the envelope's rendered height) is
   the only thing that ever moves it, up into the hidden or risen
   position — no nested-percentage math to keep in sync by hand. */
.envelope__card {
  position: absolute;
  left: 0; right: 0;
  top: 100%;
  width: 100%;
  /* Card art's own ratio (1054x1492) — height derives from width so it's
     never distorted. The new card asset (typography now baked into the
     art itself, no HTML text overlay) kept the same intrinsic 1054x1492
     pixels, so this ratio is unchanged. */
  aspect-ratio: 1054 / 1492;
  pointer-events: auto;
  box-shadow: 0 18px 40px rgba(0,0,0,.35);
  border-radius: 2px;
  overflow: hidden;
}
.envelope__card img { width: 100%; display: block; }

/* The previous mobile approach (.card--foreground-mobile, an
   envelope-relative %-width override on the OLD #envelope-card-foreground
   slot) is gone — even unclipped, that slot's own box was still sized
   off the envelope (left:15%/right:15% of .env2-frame), which read as an
   invisible margin/boundary around the enlarged card. Mobile now uses an
   entirely different, hero-level foreground — see
   .invitation-card-foreground-layer near .envelope-stage above, and the
   reparent-with-captured-rect logic in site.js — with no envelope-
   derived geometry at all. Desktop is untouched: it still uses
   #envelope-card-foreground exactly as before. */

/* Pinned to the section's own bottom edge — see .envelope-stage above for
   why this can no longer just follow the envelope group in normal flow:
   that group is now absolutely centered on its own combined visual
   bounds, so it no longer occupies flex space this could flow after. */
.invitacion__foot {
  position: absolute;
  left: 50%;
  bottom: 44px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
}
.invitacion__cue,
.scroll-arrow {
  opacity: 0;
  visibility: hidden;
}
.invitacion__cue.is-visible,
.scroll-arrow.is-visible {
  opacity: .8;
  visibility: visible;
}
/* Contrast against the hero photo — a plain color + thin text-
   shadow got lost in the floral image's lighter passages. The
   text-shadow stack itself reads as soft/atmospheric (large blur radii,
   low-to-moderate opacity, no hard offset) rather than a sharp drop
   shadow; the ::before adds a diffuse dark radial glow behind the text
   for the same reason (blurred further, so it reads as ambient darkness
   rather than a visible shape) — deliberately not a solid rectangle. */
.invitacion__cue {
  position: relative;
  font-size: 13px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: #f3efe5;
  /* Alphas are the original values +10% relative darkness
     (.75/.55/.42 -> .82/.61/.46). */
  text-shadow:
    0 2px 8px rgba(0, 0, 0, .82),
    0 4px 18px rgba(0, 0, 0, .61),
    0 8px 32px rgba(0, 0, 0, .46);
  transition: opacity .6s ease;
}
.invitacion__cue::before {
  content: '';
  position: absolute;
  inset: -24px -40px;
  /* Same +10% relative darkening as the text-shadow above
     (.32/.14 -> .35/.15). */
  background: radial-gradient(
    ellipse at center,
    rgba(0,0,0,.35) 0%,
    rgba(0,0,0,.15) 45%,
    transparent 75%
  );
  filter: blur(12px);
  z-index: -1;
  pointer-events: none;
}
.scroll-arrow.is-visible { transition: opacity .6s ease; }

.scroll-arrow {
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: none;
  padding: 8px;
  margin-top: 8px;
  cursor: pointer;
  color: var(--cream);
  /* Same intent as the cue's text-shadow above, via drop-shadow since
     this is an inline SVG stroke, not text. Alphas +10% relative
     darkness to match (.7/.4 -> .77/.44). */
  filter: drop-shadow(0 4px 10px rgba(0,0,0,.77))
          drop-shadow(0 8px 22px rgba(0,0,0,.44));
  animation: bob 2.4s ease-in-out infinite;
}
.scroll-arrow svg { display: block; width: 22px; height: 22px; }
@keyframes bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(8px); }
}

/* ==========================================================================
   Section 2 — Countdown
   ========================================================================== */

.section-countdown {
  position: relative;
  background: #e7e0cf url('images/emboss-bg.webp') center/cover no-repeat;
  padding: 106px 20px 0;
  text-align: center;
}
.section-countdown__names {
  font-family: var(--script);
  color: var(--olive-deep);
  font-size: clamp(34px, 6vw, 56px);
  letter-spacing: .05em;
  margin: 0 0 14px;
}
.section-countdown__date {
  font-family: var(--italic);
  font-style: italic;
  color: var(--olive-deep);
  font-size: clamp(15px, 2vw, 21px);
  letter-spacing: .08em;
  margin: 0 0 34px;
}
.countdown__label {
  font-family: var(--italic);
  font-style: italic;
  letter-spacing: .1em;
  color: var(--olive-deep);
  font-size: clamp(20px, 2.6vw, 28px);
  margin: 0 0 10px;
}
.countdown__row {
  display: flex;
  justify-content: center;
  gap: clamp(20px, 5vw, 64px);
  flex-wrap: nowrap;
}
.countdown__unit {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: clamp(70px, 10vw, 100px);
}
.countdown__value {
  font-family: var(--script);
  color: var(--olive-deep);
  font-size: clamp(42px, 8vw, 72px);
  line-height: 1;
  display: block;
  width: 100%;
  text-align: center;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
.countdown__unit-label {
  font-family: var(--italic);
  font-style: italic;
  letter-spacing: .1em;
  color: var(--olive-deep);
  font-size: clamp(14px, 1.6vw, 18px);
  margin-top: 6px;
}

.stripe-divider {
  height: clamp(90px, 12vw, 168px);
  background-image: repeating-linear-gradient(
    90deg,
    var(--olive-deep) 0 16px,
    transparent 16px 32px
  );
  margin-top: 60px;
  /* Full-bleed regardless of the parent section's own side padding. */
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}

/* Mobile: a portrait-oriented emboss asset instead of the landscape one
   above — background-size:cover on the landscape version would crop
   down to a thin strip of the pattern once the section gets taller,
   while this one is drawn for a tall narrow box. Section made
   deliberately longer (more top padding + more room before the stripe)
   to match; padding-bottom stays 0 so the background still ends flush
   at the stripe divider, same reasoning as the desktop rule. */
@media (max-width: 760px) {
  .section-countdown {
    background-image: url('images/emboss-bg-vertical.webp');
    padding-top: 150px;
  }
  .stripe-divider { margin-top: 100px; }
}

/* ==========================================================================
   Section 3 — Nuestra Historia
   ========================================================================== */

.section-historia {
  position: relative;
  background: #e7e0cf;
  padding: 90px 20px 110px;
  overflow: hidden;
}
.historia__grid {
  position: relative;
  z-index: 1;
  max-width: 1100px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(220px, 340px) 1fr;
  gap: clamp(30px, 6vw, 80px);
  align-items: center;
}

/* Wraps the frame so it can sit centered in its grid column; the script
   flourishes and the gold backing card now live inside .historia__frame
   itself (see below) rather than floating relative to this outer box. */
.historia__photo {
  position: relative;
  z-index: 1;
  padding: clamp(28px, 5vw, 56px) clamp(24px, 5vw, 48px);
}

/* The illustration's own box. Layering, back to front:
   1. .historia__frame::before (z-index -2) — a solid gold backing card, a
      physical sheet sitting behind everything, slightly larger on all
      four sides (NOT a border/frame around the image).
   2. .historia__script (z-index -1) — both words, painted above the gold
      card but still behind the illustration below, so where a word
      crosses into the image's own footprint the image masks it; only
      the portion overlapping the exposed gold border reads.
   3. the <img> itself — left as a plain non-positioned element (no
      z-index of its own) so it naturally paints in front of both
      negative-z-index layers above, per normal stacking order, without
      needing an explicit stacking value. Topmost. */
.historia__frame {
  position: relative;
  z-index: 2;
  width: fit-content;
  max-width: 100%;
  margin: 0 auto;
  box-shadow: 0 10px 22px rgba(0,0,0,.16);
}
/* Tight backing card — a narrow gold edge showing around the illustration
   (~12-18px), not a large panel behind it. Shadow kept close/soft rather
   than a big offset+blur, so the shadow itself doesn't read as extra
   "gold panel" bleeding further out than the actual gold rectangle. */
.historia__frame::before {
  content: '';
  position: absolute;
  top: clamp(-18px, -2.2vw, -12px);
  left: clamp(-18px, -2.2vw, -12px);
  right: clamp(-18px, -2.2vw, -12px);
  bottom: clamp(-18px, -2.2vw, -12px);
  z-index: -2;
  background: linear-gradient(135deg, #e2c584, #9a782e 55%, #7c5c22);
  box-shadow: 0 10px 20px rgba(0,0,0,.25);
}
.historia__script {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
  font-family: var(--script);
  color: var(--ink);
  font-size: clamp(38px, 5.5vw, 66px);
  letter-spacing: .04em;
  white-space: nowrap;
  pointer-events: none;
  z-index: -1;
}
/* Centered above the image, not anchored to a corner — reads as a single
   composition wrapping the frame instead of two diagonal flourishes. */
.historia__script--1 {
  top: -34px;
}
/* Centered below the image. */
.historia__script--2 {
  bottom: -34px;
}
/* Desktop-only nudge: pulls the pair further apart vertically, on top of
   the base placement above. "para ustedes" sits 25px higher than a plain
   symmetric offset would put it, closing the gap to the image slightly. */
@media (min-width: 761px) {
  .historia__script--1 { top: -59px; }
  .historia__script--2 { bottom: -64px; }
}
.historia__break-mobile { display: none; }
.historia__copy h2 {
  font-family: var(--serif);
  color: var(--ink);
  font-size: clamp(25px, 3.4vw, 41px);
  letter-spacing: .03em;
  line-height: 1.15;
  margin: 0 0 26px;
}
.historia__copy p {
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink-2);
  font-size: clamp(16px, 1.8vw, 21px);
  line-height: 1.7;
  max-width: 46ch;
  margin: 0 0 30px;
}
.historia__signoff {
  display: flex;
  flex-direction: column;
  margin: 8px 0 0;
}
.historia__signoff-label {
  font-family: var(--italic);
  font-style: italic;
  color: var(--rust);
  font-size: clamp(15px, 1.6vw, 18px);
}
.historia__signoff-name {
  font-family: var(--script);
  color: var(--rust);
  font-size: clamp(22px, 2.7vw, 29px);
  line-height: 1.3;
}

@media (max-width: 760px) {
  .historia__grid { grid-template-columns: 1fr; text-align: center; }
  .historia__photo { justify-self: center; max-width: 280px; }
  .historia__copy p { margin-left: auto; margin-right: auto; }
  /* "Nuestra" stays at its base position; "Historia" moves 10px further down. */
  .historia__script--2 { bottom: -44px; }
  .historia__break-mobile { display: block; }
}

/* ==========================================================================
   Section 4 — Explorar la boda
   ========================================================================== */

.section-explorar {
  position: relative;
  background: var(--olive-mid);
  color: #fff;
  padding: 110px 20px 130px;
  overflow: hidden;
}
/* Single pre-rendered asset (monogram-mask.png) now carries the JR shape,
   the photo fill, AND the recessed inner-shadow effect baked directly
   into its pixels — replaces the old live CSS mask-image + ::after
   inset-shadow overlay, which was fragile to size/reposition precisely
   across breakpoints. This wrapper is just a positioning box; the image
   inside sizes itself via its own intrinsic aspect ratio (width:100%;
   height:auto) rather than being stretched/contained into a fixed box. */
.section-explorar__monogram {
  position: absolute;
  z-index: 0;
  right: -6%;
  top: 50%;
  width: 60%;
  transform: translateY(-50%);
  opacity: .55;
  pointer-events: none;
}
.section-explorar__monogram img {
  display: block;
  width: 100%;
  height: auto;
}
.section-explorar__title {
  position: relative;
  z-index: 1;
  font-family: var(--serif);
  font-size: clamp(34px, 5vw, 56px);
  letter-spacing: .03em;
  max-width: 900px;
  margin: 0 auto 60px;
  text-transform: uppercase;
}

.explore-list {
  position: relative;
  z-index: 1;
  list-style: none;
  margin: 0 auto;
  padding: 0;
  max-width: 900px;
  border-top: 1px solid rgba(255,255,255,.35);
}
.explore-list__item {
  display: grid;
  grid-template-columns: 80px 1fr 60px;
  align-items: center;
  gap: 20px;
  padding: 30px 0;
  border-bottom: 1px solid rgba(255,255,255,.35);
  transition: opacity .25s ease;
}
.explore-list__item:hover { opacity: .75; }
.explore-list__num {
  font-family: var(--script);
  font-size: clamp(38px, 5vw, 56px);
  color: rgba(255,255,255,.5);
}
.explore-list__eyebrow {
  display: block;
  font-family: var(--italic);
  font-style: italic;
  letter-spacing: .1em;
  font-size: clamp(13px, 1.4vw, 16px);
  margin-bottom: 6px;
}
.explore-list__title {
  display: block;
  font-family: var(--serif);
  font-size: clamp(20px, 2.4vw, 30px);
}
.explore-list__arrow {
  font-family: var(--italic);
  font-size: clamp(26px, 3vw, 40px);
  transition: transform .25s ease;
}
.explore-list__item:hover .explore-list__arrow { transform: translateX(8px); }

/* Mobile-only: the monogram becomes an oversized, deliberately-cropped
   background graphic instead of the desktop's small contained side
   accent — same asset, just repositioned and enlarged for this
   breakpoint. Desktop rule above is untouched. min-height gives the
   giant lower-half graphic room to exist instead of the empty olive
   padding that used to sit below row 4 (padding-bottom is now 0 here —
   the monogram itself fills that space instead of blank section).
   Sized/positioned so it starts around row 3, its recognizable central
   junction reads clearly rather than only a sliver surviving the crop,
   and only a modest amount bleeds past the right/bottom edges (an
   earlier pass pushed it almost entirely out of frame — pulled back in
   here). */
@media (max-width: 760px) {
  .section-explorar {
    padding: 90px 0 0;
    min-height: 100vh;
  }
  .section-explorar__title,
  .explore-list {
    padding-left: 20px;
    padding-right: 20px;
  }
  .section-explorar__monogram {
    width: 125vw;
    right: -20vw;
    top: 78%;
    transform: translateY(-50%);
    opacity: .6;
  }
}

/* ==========================================================================
   Section 5 — RSVP (Confirmación)
   ========================================================================== */

.section-confirmacion {
  position: relative;
  background: var(--olive-dark);
  color: var(--cream);
  min-height: 90vh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 100px 20px;
  overflow: hidden;
}
.section-confirmacion__cloud {
  position: absolute;
  width: min(77vw, 616px);
  max-width: none;
  opacity: .1;
  z-index: 0;
}
/* Mobile-only: flower 50% bigger than the desktop size above, then a
   further 15% on top of that (132.825vw ≈ 115.5vw * 1.15). */
@media (max-width: 760px) {
  .section-confirmacion__cloud {
    width: min(132.825vw, 1062.6px);
  }
}
.section-confirmacion__inner { position: relative; z-index: 1; max-width: 640px; }
.section-confirmacion__title {
  font-family: var(--italic);
  font-style: italic;
  font-size: clamp(38px, 6vw, 60px);
  letter-spacing: .04em;
  margin: 0 0 30px;
}
.section-confirmacion__body {
  font-family: var(--italic);
  font-style: italic;
  font-size: clamp(18px, 2.2vw, 26px);
  line-height: 1.6;
  margin: 0 0 44px;
}
.btn-primary {
  display: inline-block;
  background: var(--rust);
  color: #fff;
  font-family: var(--italic);
  font-style: italic;
  font-size: clamp(16px, 2vw, 22px);
  letter-spacing: .05em;
  padding: 18px 46px;
  border: none;
  border-radius: 2px;
  cursor: pointer;
  transition: transform .25s ease, box-shadow .25s ease;
}
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 14px 30px rgba(0,0,0,.35); }

/* ==========================================================================
   Footer
   ========================================================================== */

.site-footer {
  background: var(--olive-dark);
  color: var(--cream);
  text-align: center;
  padding: 50px 20px 60px;
  font-family: var(--italic);
  font-style: italic;
  border-top: 1px solid rgba(255,255,255,.15);
}
.site-footer__mark { width: 46px; height: 36px; margin: 0 auto 14px; color: var(--cream); }
.site-footer__links {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 20px;
  list-style: none;
  padding: 0;
  margin: 18px 0 0;
  font-size: 14px;
  letter-spacing: .05em;
}

/* ==========================================================================
   Inner pages — shared solid nav bar (Programa, RSVP, etc.)
   The homepage nav floats transparent over the wallpaper with a
   mix-blend-mode trick; inner pages use a solid dark bar instead, per
   Figma (bg #262c1d, cream/gold links, RSVP always accent-white).
   ========================================================================== */

.site-nav--inner {
  position: relative;
  background: var(--olive-dark);
  mix-blend-mode: normal;
  padding: 20px clamp(20px, 4vw, 64px);
}
/* On mobile this was still position:relative, so it scrolled away with
   the page instead of staying on screen like the homepage nav (plain
   .site-nav, position:fixed from the base rule) already does. This has
   to come AFTER the unconditional rule above — same specificity, so
   source order (not just being inside an active media query) decides
   which one wins. The matching padding-top on body keeps each page's
   own first section from starting underneath it now that the nav no
   longer takes up space in normal flow. */
@media (max-width: 780px) {
  .site-nav--inner {
    position: fixed;
    top: 0; left: 0; right: 0;
  }
  body:has(.site-nav--inner) { padding-top: 78px; }
}
.site-nav--inner .site-nav__links a { color: #ffeac3; }
.site-nav--inner .site-nav__links a.rsvp-accent { color: #fff; }
.site-nav--inner .jr-mark { color: #ffeac3; }

/* ==========================================================================
   Página: Programa
   ========================================================================== */

.programa-hero {
  position: relative;
  height: clamp(320px, 42vw, 464px);
  background:
    linear-gradient(rgba(10,12,6,.35), rgba(10,12,6,.35)),
    #14180f url('images/programa-hero-harlequin.webp') center/cover no-repeat;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  overflow: hidden;
}
.programa-hero__inner { position: relative; z-index: 1; color: var(--cream); }
.programa-hero__mark {
  width: 72px;
  height: 58px;
  margin: 0 auto 18px;
  color: var(--cream);
  filter: drop-shadow(0 4px 4px rgba(0,0,0,.55));
}
.programa-hero__date {
  font-family: var(--italic);
  font-style: italic;
  font-size: clamp(14px, 1.6vw, 18px);
  letter-spacing: .09em;
  text-shadow: 0 4px 4px rgba(0,0,0,.25);
  margin: 0 0 6px;
}
.programa-hero__title {
  font-family: var(--serif);
  font-size: clamp(38px, 6vw, 60px);
  letter-spacing: .05em;
  text-shadow: 0 4px 4px rgba(0,0,0,.25);
  margin: 0;
}

.programa-events {
  max-width: 1000px;
  margin: 0 auto;
  padding: 70px 20px 30px;
  text-align: center;
}
.programa-events__ornament { width: clamp(180px, 22vw, 282px); margin: 0 auto 50px; opacity: .8; }
.programa-events__grid {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: clamp(24px, 5vw, 60px);
  align-items: start;
}
/* Same masked-shape + currentColor technique as .jr-mark (see Nav) so
   these reuse the site's own olive-deep green via CSS rather than
   needing pre-colored SVG exports. mask-size:contain preserves each
   icon's own aspect ratio regardless of this box being square. */
.programa-event__icon {
  display: block;
  width: clamp(121.5px, 14.1vw, 178.5px);
  height: clamp(121.5px, 14.1vw, 178.5px);
  margin: 0 auto 18px;
  background-color: var(--olive-deep);
}
.programa-event__icon--rings {
  -webkit-mask: url('images/Rings.svg') center / contain no-repeat;
  mask: url('images/Rings.svg') center / contain no-repeat;
}
.programa-event__icon--reception {
  -webkit-mask: url('images/Reception.svg') center / contain no-repeat;
  mask: url('images/Reception.svg') center / contain no-repeat;
}
.programa-event h2 {
  font-family: var(--italic);
  font-style: italic;
  color: var(--olive-deep);
  font-size: clamp(26px, 3vw, 40px);
  letter-spacing: .05em;
  margin: 0 0 20px;
}
.programa-event p {
  font-family: var(--italic);
  font-style: italic;
  color: var(--olive-deep);
  font-size: clamp(17px, 1.8vw, 24px);
  letter-spacing: .04em;
  margin: 0 0 6px;
}
.programa-events__divider { width: 1px; background: var(--olive-deep); opacity: .5; align-self: stretch; }
@media (max-width: 700px) {
  .programa-events__grid { grid-template-columns: 1fr; }
  .programa-events__divider { display: none; }
  .programa-event { padding-bottom: 20px; }
}

.programa-info {
  max-width: 900px;
  margin: 40px auto 100px;
  padding: clamp(32px, 5vw, 56px) clamp(24px, 5vw, 56px);
  background: #eee7d4;
  border-radius: 6px;
}
.programa-info__title {
  font-family: var(--serif);
  color: var(--olive-deep);
  font-size: clamp(24px, 2.8vw, 32px);
  letter-spacing: .04em;
  text-align: center;
  margin: 0 0 40px;
}
.programa-info__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 32px;
}
.programa-info__item h3 {
  font-family: var(--italic);
  font-style: italic;
  color: var(--rust);
  font-size: clamp(17px, 1.8vw, 21px);
  letter-spacing: .04em;
  margin: 0 0 10px;
}
.programa-info__item p {
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink-2);
  font-size: clamp(15px, 1.6vw, 18px);
  line-height: 1.6;
  margin: 0;
}
.programa-info__item code {
  background: rgba(83,89,49,.12);
  padding: 2px 8px;
  border-radius: 2px;
  font-family: var(--italic);
  font-style: normal;
  font-weight: 600;
}

/* ==========================================================================
   Página: Vestimenta
   ========================================================================== */

.vestimenta-page { background: var(--olive-mid); min-height: 100vh; }
.vestimenta-main {
  max-width: 1200px;
  margin: 0 auto;
  padding: clamp(50px, 8vw, 90px) clamp(24px, 5vw, 60px) 100px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(30px, 6vw, 90px);
  align-items: center;
}
/* Whole left column as one centered vertical composition — flex column +
   align-items:center handles horizontal centering for every child
   uniformly (images, heading, paragraphs, the bordered rule box) instead
   of the previous mix of default-left block images and an unspecified
   text-align, which read as ragged/off-balance against the frame on the
   right. Each margin-bottom below is a deliberate step in one graduated
   rhythm: tight within the ornament/title/underline "header unit", then
   progressively more breathing room moving down into the body copy. */
.vestimenta-copy {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  color: var(--cream);
}
.vestimenta-copy__ornament { width: clamp(180px, 20vw, 282px); margin: 0 0 20px; }
.vestimenta-copy__title {
  font-family: var(--serif);
  font-size: clamp(34px, 4.2vw, 53px);
  letter-spacing: .04em;
  margin: 0 0 16px;
}
.vestimenta-copy__underline { width: min(100%, 420px); margin: 0 0 28px; }
.vestimenta-copy__intro {
  max-width: 40ch;
  font-family: var(--italic);
  font-style: italic;
  font-size: clamp(19px, 2.2vw, 28px);
  letter-spacing: .03em;
  line-height: 1.5;
  margin: 0 0 32px;
}
.vestimenta-copy__rule {
  display: block;
  width: fit-content;
  max-width: 100%;
  border: 1px solid var(--cream);
  padding: 12px 28px;
  margin: 0 0 36px;
  font-family: var(--italic);
  font-style: italic;
  font-size: clamp(16px, 1.8vw, 20px);
  letter-spacing: .03em;
  line-height: 1.5;
  text-align: center;
}
.vestimenta-copy__closing {
  max-width: 40ch;
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink);
  font-size: clamp(17px, 1.9vw, 21px);
  letter-spacing: .03em;
  line-height: 1.5;
}

.vestimenta-frame {
  position: relative;
  width: 100%;
  max-width: 450px;
  margin: 0 auto;
  aspect-ratio: 529 / 800;
}
.vestimenta-frame__collage {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border: 16px solid #DDD9CE;
  box-shadow: 0 18px 40px rgba(0,0,0,.25);
}
.vestimenta-frame__collage img { width: 100%; height: 100%; object-fit: cover; }

@media (max-width: 860px) {
  .vestimenta-main { grid-template-columns: 1fr; text-align: center; }
  .vestimenta-copy__ornament, .vestimenta-copy__underline, .vestimenta-copy__rule { margin-left: auto; margin-right: auto; }
  .vestimenta-frame { order: -1; max-width: 320px; }
}

/* ==========================================================================
   Página: RSVP
   ========================================================================== */

.rsvp-page { min-height: 100vh; background: var(--cream); }
.rsvp-layout {
  display: grid;
  grid-template-columns: minmax(280px, 43%) 1fr;
  min-height: calc(100vh - 76px);
}
.rsvp-layout__photo {
  background-size: cover;
  background-position: center;
  min-height: 320px;
}
.rsvp-layout__content {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(40px, 6vw, 90px) clamp(24px, 5vw, 70px);
}
@media (max-width: 860px) {
  .rsvp-layout { grid-template-columns: 1fr; }
}

.rsvp-panel { width: 100%; max-width: 560px; text-align: center; }
.rsvp-panel__mark { width: 92px; height: 116px; margin: 0 auto 20px; color: var(--olive-deep); }
.rsvp-panel__eyebrow {
  font-family: var(--italic);
  font-style: italic;
  color: var(--olive-deep);
  font-size: clamp(17px, 1.8vw, 20px);
  letter-spacing: .06em;
}
.rsvp-panel__rule {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin: 14px 0 28px;
}
.rsvp-panel__rule::before,
.rsvp-panel__rule::after {
  content: '';
  height: 1px;
  width: 90px;
  background: var(--olive-deep);
  opacity: .5;
}
.rsvp-panel__rule span { color: var(--olive-deep); font-size: 12px; }

.rsvp-panel__greeting {
  font-family: var(--italic);
  font-style: italic;
  font-weight: 600;
  color: var(--olive-deep);
  font-size: clamp(22px, 2.6vw, 28px);
  letter-spacing: .04em;
  margin: 0 0 18px;
}
.rsvp-panel__question {
  font-family: var(--italic);
  font-style: italic;
  color: var(--olive-deep);
  font-size: clamp(18px, 2vw, 22px);
  letter-spacing: .03em;
  line-height: 1.5;
  margin: 0 0 18px;
}
.rsvp-panel__deadline {
  font-family: var(--italic);
  font-style: italic;
  font-weight: 600;
  color: var(--olive-deep);
  font-size: clamp(14px, 1.5vw, 17px);
  letter-spacing: .05em;
  margin: 0 0 26px;
}
.rsvp-panel__dots { color: var(--olive-deep); opacity: .6; letter-spacing: .3em; margin: 0 0 26px; }

.rsvp-steps__dots { display: flex; justify-content: center; gap: 8px; margin: 0 0 26px; }
.rsvp-steps__dots[hidden] { display: none; }
.rsvp-steps__dot { width: 7px; height: 7px; border-radius: 50%; background: rgba(83,89,49,.25); transition: background .3s ease; }
.rsvp-steps__dot.is-active { background: var(--olive-deep); }

.rsvp-choice {
  display: block;
  width: 100%;
  max-width: 439px;
  margin: 0 auto 16px;
  padding: 16px 20px;
  border: none;
  border-radius: 2px;
  font-family: var(--italic);
  font-style: italic;
  font-size: clamp(16px, 1.8vw, 20px);
  letter-spacing: .04em;
  color: #fff;
  cursor: pointer;
  transition: transform .2s ease, box-shadow .2s ease;
}
.rsvp-choice:hover { transform: translateY(-2px); box-shadow: 0 12px 26px rgba(0,0,0,.25); }
.rsvp-choice--yes { background: var(--olive-deep); }
.rsvp-choice--no { background: var(--rust); }

/* Detailed form (revealed after "Sí, acepto") — one scrollable set of
   blocks, per the plan: no multi-step wizard, matches "confirman en
   segundos". */
.rsvp-form { text-align: left; }
.rsvp-form[hidden], .rsvp-landing[hidden], .rsvp-confirm[hidden] { display: none; }

/* Name-lookup step (bare main-domain link, no ?token=) — reuses
   .rsvp-subfield/.rsvp-submit/.rsvp-error as-is; only the "already
   confirmed" banner needs its own rules. */
.rsvp-lookup__confirmed {
  border: 1px solid rgba(83,89,49,.35);
  background: rgba(83,89,49,.06);
  border-radius: 4px;
  padding: 16px 18px;
  margin-bottom: 18px;
}
.rsvp-lookup__confirmed[hidden] { display: none; }
.rsvp-lookup__confirmed p {
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink-2);
  font-size: 15px;
  margin: 0 0 8px;
}
.rsvp-lookup__confirmed a {
  color: var(--olive-deep);
  font-size: 14px;
  text-decoration: underline;
}

.rsvp-person {
  border-top: 1px solid rgba(83,89,49,.25);
  padding: 26px 0;
}
.rsvp-person:last-of-type { border-bottom: 1px solid rgba(83,89,49,.25); }
.rsvp-person__name {
  font-family: var(--script);
  color: var(--olive-deep);
  font-size: clamp(22px, 2.6vw, 28px);
  margin: 0 0 16px;
}
.rsvp-event-q {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.rsvp-event-q__label {
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink-2);
  font-size: clamp(15px, 1.6vw, 17px);
}
.rsvp-event-q__options { display: flex; gap: 8px; }
.rsvp-toggle {
  font-family: var(--italic);
  font-style: italic;
  font-size: 14px;
  padding: 8px 16px;
  border: 1px solid var(--olive-deep);
  background: transparent;
  color: var(--olive-deep);
  border-radius: 20px;
  cursor: pointer;
  transition: background .2s ease, color .2s ease;
}
.rsvp-toggle.is-selected { background: var(--olive-deep); color: #fff; }
.rsvp-toggle--decline.is-selected { background: var(--rust); border-color: var(--rust); }

.rsvp-subfield { margin-top: 14px; }
.rsvp-subfield label {
  display: block;
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink-2);
  font-size: 14px;
  margin-bottom: 6px;
}
.rsvp-subfield input[type="text"],
.rsvp-subfield textarea {
  width: 100%;
  font-family: var(--italic);
  font-style: italic;
  font-size: 15px;
  padding: 10px 12px;
  border: 1px solid rgba(83,89,49,.4);
  border-radius: 2px;
  background: #fff;
  color: var(--ink-2);
}
.rsvp-subfield textarea { min-height: 80px; resize: vertical; }
.rsvp-plusone { display: flex; align-items: center; gap: 10px; margin-top: 14px; }

.rsvp-shared { padding-top: 10px; }
.rsvp-submit {
  display: block;
  width: 100%;
  margin-top: 24px;
  padding: 16px 20px;
  border: none;
  border-radius: 2px;
  background: var(--rust);
  color: #fff;
  font-family: var(--italic);
  font-style: italic;
  font-size: clamp(16px, 1.8vw, 20px);
  letter-spacing: .04em;
  cursor: pointer;
}
.rsvp-submit:hover { transform: translateY(-2px); }
.rsvp-submit:disabled { opacity: .5; cursor: wait; }

.rsvp-back {
  background: none;
  border: none;
  font-family: var(--italic);
  font-style: italic;
  color: var(--olive-deep);
  font-size: 14px;
  margin-bottom: 20px;
  cursor: pointer;
  text-decoration: underline;
}

.rsvp-confirm { text-align: center; }
.rsvp-confirm__mark { width: 60px; height: 76px; margin: 0 auto 16px; color: var(--olive-deep); }
.rsvp-confirm__title {
  font-family: var(--italic);
  font-style: italic;
  font-weight: 600;
  color: var(--olive-deep);
  font-size: clamp(24px, 3vw, 32px);
  margin: 0 0 16px;
}
.rsvp-confirm__body {
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink-2);
  font-size: clamp(16px, 1.8vw, 19px);
  line-height: 1.6;
  margin: 0 0 26px;
}
.rsvp-confirm__links { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }
.rsvp-confirm__links a {
  font-family: var(--italic);
  font-style: italic;
  color: var(--rust);
  border-bottom: 1px solid currentColor;
}
.rsvp-error {
  color: var(--rust);
  font-family: var(--italic);
  font-style: italic;
  font-size: 14px;
  margin-top: 10px;
}

/* ==========================================================================
   Página: Historia
   ========================================================================== */

.historia-page { background: #928d5d; min-height: 100vh; }
.historia-hero {
  text-align: center;
  padding: clamp(40px, 6vw, 70px) 20px clamp(50px, 7vw, 80px);
}
.historia-hero__title {
  font-family: var(--serif);
  color: var(--ink);
  font-size: clamp(28px, 4vw, 42px);
  letter-spacing: .06em;
  margin: 0 0 8px;
}
.historia-hero__subtitle {
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink);
  font-size: clamp(22px, 3vw, 32px);
  letter-spacing: .04em;
  margin: 0;
}

.timeline { position: relative; max-width: 1100px; margin: 0 auto; padding: 0 24px 80px; }
.timeline::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--ink);
  opacity: .6;
}
/* Each event is now ONE unified polaroid/editorial card — image as the
   main object, title+copy overlaid directly on the photo — rather than a
   separate text column next to a separate photo column. The row itself
   is just a positioning slot: the diamond marks the chapter's place on
   the central line, and the card sits to whichever side is alternating,
   via margin-left/right:auto on .polaroid below (not grid columns —
   there's only one real child now). */
.timeline-row {
  position: relative;
  padding: clamp(36px, 6vw, 70px) 0;
}
/* Centered on the timeline's own center line regardless of which side
   the card sits on — simpler and more robust than the old per-side
   offset math tied to text-column width, since card height now varies
   with photo+overlay content instead of being a predictable text block. */
.timeline-row__diamond {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 13px;
  transform: translate(-50%, -50%);
  z-index: 1;
}

.timeline-row--right .polaroid { margin-left: auto; transform: rotate(-6deg); }
.timeline-row--left .polaroid { margin-right: auto; transform: rotate(5deg); }

/* The physical print border + the card's own drop shadow — strong enough
   to read as a printed piece sitting on the page, on both breakpoints. */
.polaroid {
  background: #f5f5f5;
  padding: 14px;
  box-shadow: 0 18px 38px rgba(0,0,0,.32), 0 4px 10px rgba(0,0,0,.18);
  max-width: 320px;
}
.polaroid__inner {
  position: relative;
  /* Taller than Figma's placeholder square (477:468) — every real photo
     here is a portrait shot, and a near-square crop cut off heads/feet.
     4:5 keeps the actual subject in frame without per-photo tuning. */
  aspect-ratio: 4 / 5;
  background: #d9d9d9;
  overflow: hidden;
}
.polaroid img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Per-photo vertical anchor so the subject (faces/embrace), not empty
   headroom or cropped feet, stays in frame at this taller-than-square
   ratio. */
.polaroid img[data-anchor="top"] { object-position: center 15%; }
.polaroid img[data-anchor="high"] { object-position: center 30%; }

/* Text overlay — a soft cream panel that fades up from the card's own
   bottom edge into the photo, rather than a hard bar or a dark scrim, so
   it reads as an elegant caption area instead of a generic UI overlay.
   Solid enough at the bottom for the title/copy to stay legible over any
   photo, fully transparent by 60% up so the top of the image stays
   clear. */
.polaroid__overlay {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 34px 18px 18px;
  background: linear-gradient(
    to top,
    rgba(221, 217, 206, .97) 0%,
    rgba(221, 217, 206, .93) 38%,
    rgba(221, 217, 206, 0) 100%
  );
}
/* "El encuentro" reads better with the caption at the top of this
   particular photo (the doorway arch leaves clear open space up top) —
   same panel treatment, just flipped to anchor top and fade downward
   instead of up. */
.polaroid__overlay--top {
  top: 0; bottom: auto;
  padding: 18px 18px 34px;
  background: linear-gradient(
    to bottom,
    rgba(221, 217, 206, .97) 0%,
    rgba(221, 217, 206, .93) 38%,
    rgba(221, 217, 206, 0) 100%
  );
}
.polaroid__overlay h2 {
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink);
  font-size: clamp(22px, 3vw, 28px);
  letter-spacing: .04em;
  margin: 0 0 8px;
}
.polaroid__overlay p {
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink-2);
  font-size: clamp(13px, 1.4vw, 15px);
  line-height: 1.55;
  margin: 0;
}

@media (max-width: 760px) {
  .timeline::before { left: 24px; }
  .timeline-row__diamond { left: 24px; }
  .timeline-row--right .polaroid,
  .timeline-row--left .polaroid {
    margin: 0 0 0 56px;
    max-width: 260px;
  }
  /* Tilt kept (not flattened to 0) — just a touch subtler than desktop
     so the stacked cards still read as an intentional, slightly organic
     composition rather than a rigid list. */
  .timeline-row--right .polaroid { transform: rotate(-3deg); }
  .timeline-row--left .polaroid { transform: rotate(3deg); }
  .polaroid__overlay { padding: 26px 15px 15px; }
  .polaroid__overlay--top { padding: 15px 15px 26px; }
}

/* ==========================================================================
   Página: Regalos
   ========================================================================== */

.regalos-page {
  min-height: 100vh;
  background: #ded9c8 url('images/regalos-wallpaper.webp') center/cover no-repeat;
  padding: clamp(50px, 8vw, 90px) 20px 100px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.regalos-clipboard {
  position: relative;
  width: min(90vw, 552px);
  aspect-ratio: 1200 / 1800;
}
.regalos-clipboard__bg { position: absolute; inset: 0; width: 100%; height: 100%; }
.regalos-clipboard__paper {
  position: absolute;
  left: 13.5%; right: 13.5%;
  top: 25.5%;
  text-align: center;
}
.regalos-clipboard__title {
  font-family: var(--serif);
  color: var(--ink);
  font-size: clamp(15px, 2.1vw, 21px);
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1.4;
  margin: 0 0 18px;
}
.regalos-clipboard__body {
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink);
  font-size: clamp(12px, 1.7vw, 16px);
  letter-spacing: .02em;
  line-height: 1.6;
  margin: 0 0 22px;
}

.regalos-clipboard__ornament {
  width: clamp(120px, 16vw, 180px);
  margin: 0 auto clamp(20px, 3vw, 32px);
  opacity: .8;
}

.regalos-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(8px, 1.4vw, 14px);
}
.regalos-card {
  border: 1px solid rgba(12,23,25,.35);
  padding: clamp(18px, 2.6vw, 28px) clamp(8px, 1.4vw, 12px);
  min-height: clamp(160px, 22vw, 210px);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-decoration: none;
  color: inherit;
  transition: border-color .2s ease, box-shadow .2s ease;
}
a.regalos-card:hover { border-color: var(--olive-deep); box-shadow: 0 10px 24px rgba(0,0,0,.12); }
.regalos-card--compact { min-height: clamp(130px, 16vw, 160px); padding-top: clamp(14px, 2vw, 20px); padding-bottom: clamp(14px, 2vw, 20px); }
.regalos-card--wide {
  grid-column: 1 / -1;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  gap: clamp(28px, 5vw, 56px);
  min-height: 0;
  padding-top: clamp(14px, 2vw, 20px);
  padding-bottom: clamp(14px, 2vw, 20px);
}
.regalos-card__wide-head { text-align: center; flex: 0 0 auto; }
.regalos-card__wide-body { display: flex; flex-direction: column; align-items: flex-start; }
.regalos-card__wide-body .regalos-card__arrow { margin-top: 4px; }
.regalos-card__eyebrow {
  font-family: var(--italic);
  font-style: italic;
  color: var(--rust);
  font-size: clamp(8px, 1vw, 10px);
  letter-spacing: .12em;
  text-transform: uppercase;
  margin-bottom: 8px;
}
.regalos-card__name {
  font-family: var(--serif);
  color: var(--ink);
  font-size: clamp(18px, 2.6vw, 26px);
  margin: 0 0 8px;
}
.regalos-card__desc {
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink-2);
  font-size: clamp(9px, 1.15vw, 12px);
  line-height: 1.5;
  margin: 0 0 10px;
}
.regalos-card__bank {
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink-2);
  font-size: clamp(9px, 1.2vw, 12px);
  line-height: 1.8;
  text-align: left;
  margin: 0 0 12px;
}
.regalos-card__bank em { font-style: italic; font-weight: 600; color: var(--ink-2); }
.regalos-card__arrow {
  margin-top: auto;
  font-family: var(--italic);
  font-style: italic;
  font-size: clamp(8px, 1vw, 11px);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--olive-deep);
  border-bottom: 1px solid currentColor;
}

.regalos-clipboard__signature {
  font-family: var(--script);
  color: var(--olive-deep);
  font-size: clamp(20px, 2.8vw, 28px);
  line-height: 1.5;
  margin: clamp(36px, 6vw, 56px) 0 0;
}

/* Mobile: dedicated tall clipboard asset (regalos-clipboard-long.png,
   1200x3774 — see the <picture> source in regalos.html), not the desktop
   art stretched. Its header (clip + paper's top border corner) is pixel-
   identical to the short asset's, just with extra paper height inserted
   before the closing border — so the paper content box's own `top` is
   recalculated from that shared raw pixel offset (459px) against the
   long asset's total height, not just reused from the desktop percentage.
   Horizontal insets (13.5%) stay the same since neither asset is
   stretched horizontally, only the short one is used past this
   breakpoint. Card stacking now lives here (was a separate, narrower
   480px rule) so "cards go full-width" lines up with "clipboard goes
   tall" as one mobile treatment instead of two mismatched breakpoints. */
@media (max-width: 760px) {
  .regalos-clipboard {
    width: min(88vw, 420px);
    aspect-ratio: 1200 / 3774;
  }
  .regalos-clipboard__paper { top: 12.2%; }
  .regalos-clipboard__title { margin-bottom: 14px; }
  .regalos-clipboard__body { font-size: 15px; margin-bottom: 18px; }
  .regalos-clipboard__ornament { margin: 0 auto 18px; }
  .regalos-cards { grid-template-columns: 1fr; gap: 12px; }
  .regalos-card { padding: 14px 20px; min-height: auto; }
  .regalos-card--wide { flex-direction: column; gap: 0; }
  .regalos-card__wide-body { align-items: center; }
  .regalos-card__wide-body .regalos-card__arrow { margin-top: auto; }
  .regalos-card__eyebrow { font-size: 10px; }
  .regalos-card__desc { font-size: 12px; }
  .regalos-card__bank { font-size: 12px; }
  .regalos-clipboard__signature { margin-top: 28px; }
}

/* ==========================================================================
   Página: Recomendaciones
   Format borrowed from the Theresa & Juanma site's travel/recommendations
   page (tabbed categories + linked cards), restyled to this site's fonts
   and palette.
   ========================================================================== */

.recs-page { background: var(--cream); min-height: 100vh; }
.recs-hero {
  text-align: center;
  padding: clamp(50px, 7vw, 80px) 20px clamp(30px, 5vw, 50px);
}
.recs-hero__eyebrow {
  font-family: var(--italic);
  font-style: italic;
  color: var(--rust);
  letter-spacing: .1em;
  text-transform: uppercase;
  font-size: clamp(13px, 1.4vw, 16px);
  margin: 0 0 10px;
}
.recs-hero__title {
  font-family: var(--serif);
  color: var(--ink);
  font-size: clamp(32px, 4.4vw, 48px);
  letter-spacing: .04em;
  margin: 0 0 14px;
}
.recs-hero__intro {
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink-2);
  font-size: clamp(16px, 1.8vw, 20px);
  max-width: 60ch;
  margin: 0 auto;
  line-height: 1.6;
}

.recs-tabs {
  display: flex;
  justify-content: center;
  gap: clamp(10px, 2vw, 24px);
  flex-wrap: wrap;
  padding: 0 20px 40px;
  border-bottom: 1px solid rgba(83,89,49,.25);
  max-width: 900px;
  margin: 0 auto;
}
.recs-tab {
  background: none;
  border: none;
  font-family: var(--italic);
  font-style: italic;
  letter-spacing: .08em;
  text-transform: uppercase;
  font-size: clamp(13px, 1.4vw, 15px);
  color: var(--ink-2);
  padding: 8px 4px 14px;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.recs-tab.is-active { color: var(--rust); border-bottom-color: var(--rust); }

.recs-panel { max-width: 1100px; margin: 0 auto; padding: 50px 20px 100px; }
.recs-panel[hidden] { display: none; }
.recs-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 24px;
}
.recs-card {
  display: block;
  border: 1px solid rgba(83,89,49,.3);
  padding: 26px 24px;
  text-decoration: none;
  color: inherit;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.recs-card:hover { border-color: var(--olive-deep); box-shadow: 0 10px 24px rgba(0,0,0,.1); }
.recs-card__label {
  display: block;
  font-family: var(--italic);
  font-style: italic;
  letter-spacing: .08em;
  text-transform: uppercase;
  font-size: 12px;
  color: var(--rust);
  margin-bottom: 10px;
}
.recs-card__name {
  font-family: var(--serif);
  color: var(--ink);
  font-size: clamp(22px, 2.6vw, 27px);
  margin: 0 0 10px;
}
.recs-card__desc {
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink-2);
  font-size: 15px;
  line-height: 1.6;
  margin: 0;
}
.recs-placeholder-note {
  grid-column: 1 / -1;
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink-2);
  opacity: .7;
  font-size: 14px;
  text-align: center;
  margin: 0 0 10px;
}

/* ==========================================================================
   Página: FAQ
   ========================================================================== */

.faq-page { min-height: 100vh; }
.faq-layout {
  display: grid;
  grid-template-columns: 1fr minmax(280px, 38%);
  min-height: calc(100vh - 76px);
}
.faq-main {
  padding: clamp(40px, 6vw, 80px) clamp(24px, 5vw, 96px);
}
.faq-title {
  font-family: var(--serif);
  color: var(--rust);
  letter-spacing: .05em;
  margin: 0 0 30px;
  line-height: 1.15;
}
.faq-title span { display: block; }
.faq-title .faq-title__small { font-size: clamp(20px, 2.4vw, 28px); text-transform: uppercase; }
.faq-title .faq-title__big { font-size: clamp(26px, 3.2vw, 38px); text-transform: uppercase; }

.faq-list { border-top: 1px solid rgba(12,23,25,.3); }
.faq-item { border-bottom: 1px solid rgba(12,23,25,.3); }
.faq-item__q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  background: none;
  border: none;
  padding: 20px 0;
  cursor: pointer;
  text-align: left;
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink);
  font-size: clamp(17px, 1.9vw, 22px);
  letter-spacing: .03em;
}
.faq-item__icon {
  flex: none;
  font-family: var(--italic);
  font-size: 26px;
  color: var(--ink);
  transition: transform .3s ease;
}
.faq-item.is-open .faq-item__icon { transform: rotate(45deg); }
.faq-item__a {
  max-height: 0;
  overflow: hidden;
  transition: max-height .35s ease, padding .35s ease;
}
.faq-item.is-open .faq-item__a { max-height: 200px; padding-bottom: 20px; }
.faq-item__a p {
  margin: 0;
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink-2);
  font-size: clamp(15px, 1.6vw, 18px);
  line-height: 1.6;
  max-width: 60ch;
}
.faq-item__a a { color: var(--rust); border-bottom: 1px solid currentColor; }

.faq-side {
  position: relative;
  background: #4b5b32 url('images/faq-side-bg.webp') center/cover no-repeat;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
}
.faq-side__photo {
  width: 70%;
  max-width: 340px;
  box-shadow: 0 20px 50px rgba(0,0,0,.4);
}

@media (max-width: 860px) {
  .faq-layout { grid-template-columns: 1fr; }
  .faq-side { min-height: 280px; order: -1; }
}

/* ==========================================================================
   Página: Mensajes (hidden guestbook)
   Reference: Regina & Gianmarco's messages page — same corkboard-of-notes
   idea (dark board, tilted paper cards, click for the full message in a
   modal), restyled with this site's own fonts/palette/nav instead of its
   standalone Typekit/Google-Fonts styling.
   ========================================================================== */

.mensajes-page { background: var(--cream); min-height: 100vh; }

.mensajes-hero {
  text-align: center;
  max-width: 640px;
  margin: 0 auto;
  padding: clamp(50px, 8vw, 90px) 20px clamp(40px, 6vw, 60px);
}
.mensajes-hero__eyebrow {
  font-family: var(--italic);
  font-style: italic;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--rust);
  font-size: 14px;
  margin: 0 0 14px;
}
.mensajes-hero__title {
  font-family: var(--serif);
  color: var(--ink);
  font-size: clamp(28px, 4vw, 42px);
  letter-spacing: .03em;
  line-height: 1.2;
  margin: 0 0 14px;
}
.mensajes-hero__intro {
  font-family: var(--italic);
  font-style: italic;
  color: var(--ink-2);
  font-size: clamp(16px, 1.8vw, 19px);
  line-height: 1.6;
  margin: 0;
}

.mensajes-board-wrap {
  background: var(--olive-dark);
  padding: clamp(40px, 6vw, 70px) 20px clamp(60px, 8vw, 100px);
}
.mensajes-board {
  max-width: 1100px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
  align-items: flex-start;
  justify-content: center;
}

.mensajes-empty {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 60px 24px;
  text-align: center;
  color: rgba(255,255,255,.35);
}
/* Equal specificity to the rule above (both single selectors), so without
   this the browser's default [hidden]{display:none} UA rule loses to our
   own display:flex and mensajes.js's `empty.hidden = true` silently does
   nothing — this makes hiding it actually win. */
.mensajes-empty[hidden] { display: none; }
.mensajes-empty p {
  font-family: var(--script);
  font-size: 22px;
}

.mensajes-card {
  width: 240px;
  min-height: 170px;
  text-align: left;
  background: linear-gradient(145deg, #fdfbf5, var(--cream));
  border: none;
  border-radius: 3px;
  padding: 20px 20px 22px;
  box-shadow:
    0 2px 4px rgba(0,0,0,.18),
    0 8px 24px rgba(0,0,0,.25),
    inset 0 1px 0 rgba(255,255,255,.6);
  cursor: pointer;
  transition: transform .2s ease, box-shadow .2s ease;
  flex-shrink: 0;
}
.mensajes-card:hover {
  box-shadow:
    0 4px 10px rgba(0,0,0,.22),
    0 16px 36px rgba(0,0,0,.3),
    inset 0 1px 0 rgba(255,255,255,.6);
}
.mensajes-card__name {
  font-family: var(--serif);
  color: var(--ink);
  font-size: 14px;
  letter-spacing: .02em;
  margin: 0 0 4px;
}
.mensajes-card__date {
  font-family: var(--italic);
  font-style: italic;
  color: rgba(14,25,31,.45);
  font-size: 11px;
  letter-spacing: .03em;
  margin: 0 0 12px;
  text-transform: lowercase;
}
.mensajes-card__message {
  font-family: var(--script);
  color: var(--ink-3);
  font-size: 21px;
  line-height: 1.4;
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 6;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Modal — full message on click. Same fixed + isolate pattern as the
   mobile nav drawer and for the same reason: keeps this robust against
   .site-nav's own mix-blend-mode even though in practice the nav closes
   itself on any link click before this could open at the same time. */
.mensajes-modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 600;
  background: rgba(12,15,8,.65);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  mix-blend-mode: normal;
  isolation: isolate;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .2s ease;
}
.mensajes-modal-backdrop.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}
.mensajes-modal {
  position: relative;
  width: 100%;
  max-width: 500px;
  background: linear-gradient(145deg, #fdfbf5, var(--cream));
  border-radius: 4px;
  padding: 52px 40px 44px;
  box-shadow: 0 20px 60px rgba(0,0,0,.4);
}
.mensajes-modal__close {
  position: absolute;
  top: 14px; right: 16px;
  background: none;
  border: none;
  font-size: 18px;
  color: rgba(14,25,31,.35);
  cursor: pointer;
  padding: 6px;
  line-height: 1;
  transition: color .15s ease;
}
.mensajes-modal__close:hover { color: var(--ink); }
.mensajes-modal__name {
  font-family: var(--serif);
  color: var(--ink);
  font-size: 20px;
  margin: 0 0 4px;
}
.mensajes-modal__date {
  font-family: var(--italic);
  font-style: italic;
  color: rgba(14,25,31,.45);
  font-size: 12px;
  letter-spacing: .03em;
  margin: 0 0 22px;
  text-transform: lowercase;
}
.mensajes-modal__message {
  font-family: var(--script);
  color: var(--ink-3);
  font-size: 28px;
  line-height: 1.5;
  margin: 0;
}

@media (max-width: 520px) {
  .mensajes-card { width: 44vw; min-width: 150px; padding: 16px 16px 18px; }
  .mensajes-card__message { font-size: 18px; }
  .mensajes-board { gap: 18px; }
  .mensajes-modal { padding: 44px 26px 32px; }
  .mensajes-modal__message { font-size: 22px; }
}

/* ==========================================================================
   Site-wide music toggle (see .site-music in every page + music-widget.js)
   ========================================================================== */

.site-music {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 90;
}
.site-music__toggle {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: none;
  background: var(--olive-deep);
  color: var(--cream);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(0,0,0,.25);
  transition: transform .2s ease;
}
.site-music__toggle:hover { transform: scale(1.06); }
.site-music__icon { width: 18px; height: 18px; }
/* Only one of the two icons shows at a time — music-widget.js toggles
   .is-playing on the button once Spotify's playback_update confirms the
   actual state (not just on click), so the icon never lies about
   whether audio is really playing. */
.site-music__icon--pause { display: none; }
.site-music__toggle.is-playing .site-music__icon--play { display: none; }
.site-music__toggle.is-playing .site-music__icon--pause { display: block; }
/* The Spotify embed itself is never shown — kept off-screen (not
   display:none, which can throttle/stop media in some browsers) and
   driven entirely through the IFrame API in music-widget.js. */
.site-music__embed {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}

/* ==========================================================================
   Scroll reveal (GSAP ScrollTrigger hooks)
   ========================================================================== */

.reveal { opacity: 0; transform: translateY(40px); }

/* ==========================================================================
   La Centella badge (footer, every page). Text + star use the footer's
   cream so it reads as part of the footer. The margin-bottom keeps it
   clear of the fixed .site-music button in the bottom-right corner.
   ========================================================================== */

.centella-badge {
  display: inline-flex; align-items: center; gap: 7px;
  margin: 26px 0 20px;
  padding: 7px 13px; border-radius: 999px;
  font-family: -apple-system, "Helvetica Neue", Arial, sans-serif;
  font-style: normal;
  font-size: 12.5px; font-weight: 500; letter-spacing: 0.01em;
  text-decoration: none; white-space: nowrap;
  background: rgba(255,255,255,0.08);
  color: var(--cream);
  border: 1px solid rgba(255,255,255,0.12);
  transition: opacity .15s ease, transform .15s ease;
}
.centella-badge:hover { opacity: 0.85; transform: translateY(-1px); }
.centella-badge__icon { width: 13px; height: 13px; flex-shrink: 0; }
.centella-badge__icon path { fill: currentColor; }
