/* ==========================================================================
   site.css — the stylesheet of the hosted wedding website (site/index.html).

   WHERE THIS COMES FROM
   This is the design the couple chose (the claude.ai artifact "Irwingh &
   Dominique", exported 2026-11-04), ported rule for rule: same tokens, same
   layout, same components, same phone layout.  Only these things differ from
   the artifact:
     - the invitation card lays its text out as one centred stack of content
       slots (a slot that is empty simply takes no room);
     - the RSVP section's form (name lookup, party answers, thank-you summary);
     - the "Preview — not live" strip and a few preview-only marks;
     - three small base rules the artifact host used to supply (page margin,
       image width, the [hidden] attribute).
   Fonts come from css/fonts.css (self-hosted); nothing here contacts any
   other website.  The envelope intro has its own stylesheet, css/intro.css.

   HOW IT IS ORGANISED
     1. Tokens        2. Base        3. Layout       4. Components
     5. Pages (home, schedule, FAQs, RSVP)            6. Utilities
     7. Motion        8. Phone layout (≤ 699px)       9. Language switch
   Every declaration carries a short comment, per the project's code style.
   ========================================================================== */

/* ==========================================================================
   1. TOKENS
   Every color, font stack, type size and spacing constant used by the site.
   The palette is sampled from the invitation card: white paper, charcoal
   ink, mauve caps, and the watercolor flower colors for tiny accents. This is
   a single deliberate light theme (a letterpress invitation), so there is no
   dark-mode block.
   ========================================================================== */
:root {
  color-scheme: light;                 /* Light form controls and scrollbars, always. */
  --paper: #FFFFFF;                    /* Card white — the page background. */
  --paper-blush: #FDEFF4;              /* Whisper of blush — draft banner and one soft band. */
  --ink: #403D3E;                      /* Card charcoal — names, address, body text. */
  --ink-soft: #6E6567;                 /* Secondary text, warm mauve-grey (5.6:1 on white). */
  --rose: #BD2163;                     /* Card mauve — LARGE display text and ornaments only (3.5:1). */
  --rose-deep: #A3154F;                /* Darker mauve — links, small labels, buttons (6.2:1). */
  --rose-deeper: #830F3E;              /* Pressed/hover shade of the primary button. */
  --plum: #A82E78;                     /* Peony — sparing accent. */
  --blush: #F7CADB;                    /* Small pink flowers — hover wash, draft chip fill. */
  --coral: #F0607E;                    /* Bright small flowers — tiny accents, never text. */
  --peach: #F7B26B;                    /* Blossom — tiny accents. */
  --sage: #9AA52A;                     /* Leaf — ornament lines and check marks. */
  --leaf-deep: #4F6A1F;                /* Deep leaf — reserved accent. */
  --gold: #D2AF6E;                     /* Daisy centers — tiny accents. */
  --line: #EEDDE5;                     /* Hairline rules. */

  --font-script: "Corinthia", "Snell Roundhand", "Apple Chancery", cursive;   /* Calligraphy of the names. */
  --font-caps: "Gilda Display", "Didot", "Bodoni 72", Georgia, serif;          /* Tracked caps for labels, nav and the card's small lines. */
  --font-num: "DM Serif Display", Georgia, serif;                              /* Bold numerals for times, dates and the countdown. */
  --font-body: Lora, Georgia, "Times New Roman", serif;                        /* Readable text serif. */

  --fs-xs: 0.8125rem;                  /* Type scale: labels, chips, nav. */
  --fs-sm: 1rem;                       /* Type scale: secondary text. */
  --fs-md: 1.1875rem;                  /* Type scale: body on wide screens. */
  --fs-lg: 1.5rem;                     /* Type scale: event names, small headings. */
  --fs-xl: 2rem;                       /* Type scale: section titles, page titles on phones. */
  --fs-2xl: 2.75rem;                   /* Type scale: page titles, script subtitles. */
  --fs-3xl: 4rem;                      /* Type scale: countdown number. */

  --track: 0.22em;                     /* Letter-spacing of display caps (like the card). */
  --track-sm: 0.16em;                  /* Letter-spacing of small caps labels. */
  --gutter: clamp(16px, 4vw, 40px);    /* THE side gutter — defined once, used by every full-width block. */
  --column: 1040px;                    /* Maximum width of the content column. */
  --section-gap: clamp(56px, 9vw, 104px); /* Vertical space between page sections. */
}

/* ==========================================================================
   2. BASE
   Element defaults: paper background, charcoal body serif, comfortable
   line-height, calm links, and a visible mauve keyboard focus ring. The
   artifact's host page used to supply three of these (page margin, image
   width, the hidden attribute); the hosted site has to state them itself.
   ========================================================================== */
*, *::before, *::after {
  box-sizing: border-box;              /* Widths and min-heights include padding and border (tap targets stay as sized). */
}
[hidden] { display: none !important; } /* The hidden attribute always wins, even over a rule such as .draft-banner { display: flex }. */
body {
  margin: 0;                           /* No default page margin (the artifact host used to reset it). */
  background: var(--paper);            /* Explicit page background (white paper). */
  color: var(--ink);                   /* Explicit text color (charcoal ink). */
  font-family: var(--font-body);       /* Body text in Lora. */
  font-size: 1.125rem;                 /* 18px body on phones. */
  line-height: 1.65;                   /* Comfortable reading rhythm. */
  -webkit-font-smoothing: antialiased; /* Crisper light serifs on macOS/iOS. */
  text-rendering: optimizeLegibility;  /* Kerning and ligatures on. */
}
@media (min-width: 900px) {
  body { font-size: var(--fs-md); }    /* 19px body on desktop (spec §10a). */
}
h1, h2, h3 {
  margin: 0;                           /* Spacing is set per component, not by defaults. */
  font-weight: 400;                    /* Display faces are single-weight; avoid faux bold. */
  text-wrap: balance;                  /* Even line lengths for multi-line headings. */
}
p { margin: 0; }                       /* Paragraph spacing is set per component. */
a {
  color: var(--rose-deep);             /* Links in the readable mauve. */
  text-decoration-thickness: 1px;      /* Hairline underline, like the card's address rule. */
  text-underline-offset: 0.22em;       /* Underline sits clear of descenders. */
}
a:hover { color: var(--rose-deeper); } /* Slightly deeper mauve on hover. */
img { display: block; max-width: 100%; } /* No stray inline gaps under images; pictures never outgrow their column. */
:focus-visible {
  outline: 2px solid var(--rose-deep); /* Visible keyboard focus everywhere. */
  outline-offset: 3px;                 /* Ring sits just outside the element. */
}
[tabindex="-1"]:focus { outline: none; } /* Headings focused by the router/RSVP steps show no ring (not interactive). */
::selection { background: var(--blush); color: var(--ink); } /* Blush text selection. */

/* ==========================================================================
   3. LAYOUT
   The site wrapper, the draft banner, the sticky header with its script
   monogram and tracked-caps nav, the content column, the wide-screen floral
   side bands, and the footer with the card's bottom arcs.
   ========================================================================== */
.site {
  position: relative;                  /* Anchor for layered decoration. */
  overflow-x: clip;                    /* Belt and braces: nothing can scroll the page sideways (clip keeps sticky working). */
  min-width: 0;                        /* Never force a width wider than the screen. */
}

/* --- Preview strip: "Preview — not live", across the very top of the admin preview only --- */
.preview-ribbon {
  position: relative;                  /* Takes part in stacking… */
  z-index: 32;                         /* …above the draft banner and the floral side bands. */
  background: var(--rose-deep);        /* Readable mauve strip: this page is NOT what guests see. */
  color: var(--paper);                 /* White text on mauve (6.2:1). */
  padding-block: 0.3rem;               /* Slim strip. */
  padding-inline: var(--gutter);       /* The one side gutter. */
  font-family: var(--font-caps);       /* Display caps, like the nav. */
  font-size: var(--fs-xs);             /* Small print. */
  letter-spacing: var(--track-sm);     /* Tracked like a small label. */
  text-transform: uppercase;           /* Caps label. */
  line-height: 1.5;                    /* Readable when it wraps (the Spanish wording is longer). */
  text-align: center;                  /* Centered like the rest of the site. */
}

/* --- Draft banner (admin preview only: explains the dashed notes and toggles the guest view) --- */
.draft-banner {
  position: relative;                  /* Takes part in stacking… */
  z-index: 31;                         /* …above the floral side bands. */
  background: var(--paper-blush);      /* Soft blush strip above the header. */
  color: var(--ink);                   /* Readable charcoal text. */
  border-bottom: 1px solid var(--line);/* Hairline edge under the strip. */
  padding-block: 0.5rem;               /* Slim vertical padding. */
  padding-inline: var(--gutter);       /* The one side gutter. */
  font-size: var(--fs-xs);             /* Small print. */
  line-height: 1.45;                   /* Tight but readable when it wraps. */
  display: flex;                       /* Message and toggle on one row when they fit. */
  flex-wrap: wrap;                     /* Wrap the toggle under the message on phones. */
  align-items: center;                 /* Vertically center message and button. */
  justify-content: center;             /* Centered like the rest of the site. */
  gap: 0.35rem 1rem;                   /* Space between message and button. */
  text-align: center;                  /* Centered message text. */
}
.draft-banner strong {
  font-family: var(--font-caps);       /* "Preview" label in the display caps. */
  font-weight: 400;                    /* Single-weight face. */
  letter-spacing: var(--track-sm);     /* Tracked like a small label. */
  text-transform: uppercase;           /* Caps label. */
  color: var(--rose-deep);             /* Mauve label. */
}
.draft-toggle {
  font: inherit;                       /* Same small print as the banner. */
  font-family: var(--font-caps);       /* Caps label face. */
  letter-spacing: var(--track-sm);     /* Tracked. */
  text-transform: uppercase;           /* Caps. */
  color: var(--rose-deep);             /* Mauve text. */
  background: var(--paper);            /* White pill on the blush strip. */
  border: 1px solid var(--rose-deep);  /* Outlined like a secondary button. */
  border-radius: 2px;                  /* Square-ish, per the design system. */
  padding: 0.3rem 0.75rem;             /* Compact but tappable with the row height. */
  min-height: 32px;                    /* Comfortable tap height inside the slim strip. */
  cursor: pointer;                     /* It's a button. */
}
.draft-toggle:hover {
  background: var(--blush);            /* Blush hover wash. */
  color: var(--rose-deeper);           /* Deeper mauve keeps small text ≥4.5:1 on blush (5.6:1). */
}

/* --- Header: script monogram above a row of tracked caps --- */
.site-header {
  position: sticky;                    /* Stays in reach while scrolling. */
  top: env(safe-area-inset-top, 0px);  /* Sits under a phone notch, never behind it. */
  z-index: 20;                         /* Above page content and side bands. */
  background: var(--paper);            /* Solid white so content scrolls beneath cleanly. */
  border-bottom: 1px solid var(--line);/* Hairline bottom border. */
  padding-inline: var(--gutter);       /* The one side gutter. */
  padding-block: 0.6rem 0;             /* Air above the monogram; nav supplies its own bottom padding. */
  text-align: center;                  /* Monogram and nav are centered. */
}
.monogram {
  display: inline-block;               /* Only as wide as its text (for the link hit area). */
  font-family: var(--font-script);     /* Calligraphy, like the names. */
  font-weight: 700;                    /* The bolder cut reads at this small size. */
  font-size: 2.1rem;                   /* Large enough for Corinthia's small x-height. */
  line-height: 1;                      /* Tight vertical footprint. */
  color: var(--ink);                   /* Charcoal, like the names on the card. */
  text-decoration: none;               /* A mark, not a text link. */
}
.monogram .amp { color: var(--rose); } /* The ampersand picks up the card's mauve (large ornament). */
.nav-list {
  list-style: none;                    /* No bullets. */
  margin: 0;                           /* Reset list margins. */
  padding: 0;                          /* Reset list padding. */
  display: flex;                       /* One row of items. */
  flex-wrap: wrap;                     /* Allowed to wrap to a second row on tiny screens. */
  justify-content: center;             /* Centered row. */
  gap: 0 clamp(1.1rem, 5vw, 3rem);     /* Generous spacing between items, tighter on phones. */
}
.nav-link {
  display: inline-block;               /* Padding creates a comfortable tap target. */
  padding-block: 0.55rem 0.7rem;       /* Vertical tap area; the active rule sits in the bottom padding. */
  font-family: var(--font-caps);       /* Tracked display caps. */
  font-size: var(--fs-xs);             /* Small nav labels. */
  letter-spacing: var(--track-sm);     /* Small-label tracking. */
  text-transform: uppercase;           /* Caps like "SAVE THE DATE". */
  color: var(--ink);                   /* Charcoal by default. */
  text-decoration: none;               /* No underline; the active item gets a rule instead. */
  position: relative;                  /* Anchor for the active rule. */
}
.nav-link .nocase { text-transform: none; } /* Keeps the lowercase "s" of "FAQs". */
.nav-link:hover { color: var(--rose-deep); } /* Mauve on hover. */
.nav-link[aria-current="page"] { color: var(--rose-deep); } /* Active page in mauve. */
.nav-link[aria-current="page"]::after {
  content: "";                         /* Decorative rule. */
  position: absolute;                  /* Positioned under the label. */
  left: 0;                             /* Starts at the first letter. */
  right: var(--track-sm);              /* Ends at the last letter (ignores trailing tracking). */
  bottom: 0.35rem;                     /* Just below the caps. */
  height: 1px;                         /* A thin line. */
  background: var(--rose);             /* Card mauve (ornament use). */
}

/* --- Main column --- */
.main {
  position: relative;                  /* Stacks above the fixed side bands. */
  z-index: 1;                          /* Above bands, below the header. */
  padding-inline: var(--gutter);       /* The one side gutter. */
  padding-block: clamp(28px, 5vw, 56px) 0; /* Space under the header; the footer adds its own. */
}
.page {
  max-width: var(--column);            /* The 1040px content column. */
  margin-inline: auto;                 /* Centered column. */
  scroll-margin-top: calc(var(--header-h, 4rem) + 0.5rem); /* Jumps land just below the sticky header. */
}
.divider.section-break { max-width: 520px; margin-top: calc(var(--section-gap) * 0.9); margin-bottom: calc(var(--section-gap) * 0.9 + clamp(28px, 5vw, 56px)); } /* A flower with a soft line either side marks each new section (extra space below because each section heading tucks upward). */
.divider.section-break::before, .divider.section-break::after { display: none; } /* No lines: just the flower, like the one above The Essentials. */
.divider.section-break img { width: clamp(56px, 16vw, 84px); height: auto; -webkit-mask-image: none; mask-image: none; } /* Full flower, no soft crop. */
.rsvp-reminder { max-width: 30rem; margin: 0 auto 1.25rem; font-size: var(--fs-sm); color: var(--ink-soft); border-left: 2px solid var(--blush); padding-left: 1rem; text-align: left; } /* Last reminders before the form. */

/* --- Wide-screen floral side bands (sub-pages only, ≥1360px) --- */
.band {
  display: none;                       /* Hidden unless the wide-screen rule below applies. */
  position: fixed;                     /* Pinned to the viewport edges. */
  top: 0;                              /* Full height: from the top… */
  bottom: 0;                           /* …to the bottom of the viewport. */
  z-index: 30;                         /* Over the header's white gutters (never over content: they stay in the gutters). */
  width: min(200px, calc((100vw - var(--column)) / 2 - 32px)); /* Never reaches the 1040px column. */
  pointer-events: none;                /* Purely decorative; clicks pass through. */
}
.band-left { left: 8px; --inner-fade: to left; }    /* Hugs the left edge; its inner (right) edge fades. */
.band-right { right: 8px; --inner-fade: to right; } /* Hugs the right edge; its inner (left) edge fades. */
.band img {
  width: 100%;                         /* Fill the band's width… */
  height: 100%;                        /* …and the full viewport height… */
  object-fit: cover;                   /* …cropping (never stretching) to fill any screen shape… */
  object-position: center top;         /* …anchored at the top of the flowers (each side re-anchors below). */
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 9%, #000 86%, transparent), linear-gradient(var(--inner-fade), transparent, #000 12%); /* Fade the cropped ends and inner edge (WebKit). */
  mask-image: linear-gradient(to bottom, transparent, #000 9%, #000 86%, transparent), linear-gradient(var(--inner-fade), transparent, #000 12%);         /* Fade the cropped ends and inner edge. */
  -webkit-mask-composite: source-in;   /* Keep only where both fades are opaque (WebKit syntax). */
  mask-composite: intersect;           /* Keep only where both fades are opaque. */
}
.band-left img { object-position: left top; }       /* Anchor to the outer edge so cover crops only the faded inner side. */
.band-right img { object-position: right top; }     /* Mirror: anchor right, so any side crop lands on the faded inner edge. */
@media (min-width: 1360px) {
  .band { display: block; opacity: 0; transition: opacity 300ms ease; } /* Always present, but invisible on the home section… */
  .site:not([data-route="home"]) .band { opacity: 1; } /* …and fading in once the reader scrolls past it. */
  .site:not([data-route="home"]) .site-footer {
    max-width: var(--column);          /* Keep the footer arcs inside the column… */
    margin-inline: auto;               /* …centered, so they never tangle with the side bands. */
    padding-inline: 0;                 /* The column already sits clear of the edges. */
  }
}

/* --- Footer: signature between the card's bottom arcs --- */
.site-footer {
  position: relative;                  /* Stacks above the side bands. */
  z-index: 1;                          /* Same layer as main. */
  margin-top: var(--section-gap);      /* Breathing room after the last section. */
  padding-inline: var(--gutter);       /* The one side gutter. */
  display: grid;                       /* Arcs and signature arranged on a grid. */
  grid-template-columns: 1fr 1fr;      /* Phones: two arcs side by side under the signature. */
  grid-template-areas: "sig sig" "left right"; /* Signature on top, arcs below. */
  align-items: end;                    /* Arcs sit on the page bottom. */
  column-gap: 8px;                     /* Small gap where the stems meet. */
}
.footer-sig {
  grid-area: sig;                      /* Top row on phones, center column on wide screens. */
  text-align: center;                  /* Centered signature. */
  padding-bottom: 0.5rem;              /* A little air above the arcs on phones. */
}
.footer-names {
  font-family: var(--font-script);     /* Calligraphy signature. */
  font-size: var(--fs-2xl);            /* Large enough for Corinthia. */
  line-height: 1.1;                    /* Compact. */
  color: var(--ink);                   /* Charcoal ink. */
}
.footer-date {
  font-family: var(--font-num);        /* Card numerals. */
  font-size: var(--fs-sm);             /* Small date line. */
  letter-spacing: 0.2em;               /* Tracked like the card's date. */
  color: var(--rose-deep);             /* Readable mauve at small size. */
  margin-top: 0.25rem;                 /* Tuck under the names. */
}
.footer-city {
  font-family: var(--font-caps);       /* Tracked caps. */
  font-size: var(--fs-xs);             /* Small label. */
  letter-spacing: var(--track-sm);     /* Small-label tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--ink-soft);              /* Secondary text. */
  margin-top: 0.2rem;                  /* Small gap above. */
}
.footer-arc {
  width: 100%;                         /* Arcs scale with the screen… */
  height: auto;                        /* …keeping their proportions… */
  max-width: 440px;                    /* …capped at a card-like size. */
  -webkit-mask-image: linear-gradient(to top, #000 70%, transparent), linear-gradient(var(--edge-fade), #000 62%, transparent); /* Fade the cropped top and inner edges (WebKit). */
  mask-image: linear-gradient(to top, #000 70%, transparent), linear-gradient(var(--edge-fade), #000 62%, transparent);         /* Fade the cropped top and inner edges. */
  -webkit-mask-composite: source-in;   /* Keep only where both fades are opaque (WebKit syntax). */
  mask-composite: intersect;           /* Keep only where both fades are opaque. */
}
.footer-arc-left { --edge-fade: to right; }   /* Left arc: its inner (right) edge fades. */
.footer-arc-right { --edge-fade: to left; }   /* Right arc: its inner (left) edge fades. */
.footer-arc-left { grid-area: left; justify-self: start; }   /* Left arc hugs the left edge… */
.footer-arc-right { grid-area: right; justify-self: end; }   /* …right arc the right edge, stems curling in. */
@media (min-width: 760px) {
  .site-footer {
    grid-template-columns: 1fr auto 1fr; /* Wide: arc · signature · arc on one row. */
    grid-template-areas: "left sig right"; /* The signature sits where the stems meet. */
    column-gap: clamp(8px, 2vw, 24px); /* A little space around the signature. */
  }
  .footer-sig { padding-bottom: clamp(24px, 3vw, 48px); } /* Lift the signature to the arcs' curl. */
}

/* ==========================================================================
   4. COMPONENTS
   Reusable pieces: tracked-caps eyebrows and titles, buttons, text links,
   the blossom divider, sub-page headers with the card's top corners, the
   draft-view status marks (dashed "To add" notes and "Please confirm" chips),
   and form controls.
   ========================================================================== */

/* --- Tracked caps: eyebrows, labels, section titles --- */
.eyebrow {
  font-family: var(--font-caps);       /* Display caps. */
  font-size: var(--fs-xs);             /* Small label. */
  letter-spacing: var(--track-sm);     /* Small-label tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--rose-deep);             /* Readable mauve at small size. */
  line-height: 1.7;                    /* Airy when it wraps. */
}
.section-title {
  font-family: var(--font-caps);       /* Display caps. */
  font-size: clamp(1.5rem, 3.2vw, var(--fs-xl)); /* 24px phones → 32px desktop (large text only). */
  letter-spacing: var(--track);        /* Card tracking. */
  padding-inline-start: var(--track);  /* Re-centers text whose trailing tracking would push it left. */
  text-transform: uppercase;           /* Caps. */
  color: var(--rose);                  /* Card mauve (large display text). */
  text-align: center;                  /* Centered like the card. */
  line-height: 1.3;                    /* Tight display leading. */
}
.label {
  display: block;                      /* Sits on its own line above its value. */
  font-family: var(--font-caps);       /* Display caps. */
  font-size: var(--fs-xs);             /* Small label. */
  letter-spacing: var(--track-sm);     /* Small-label tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--rose-deep);             /* Readable mauve. */
  line-height: 1.5;                    /* Compact. */
}

/* --- Buttons: square-ish, tracked caps --- */
.btn {
  display: inline-flex;                /* Centers the label in the box. */
  align-items: center;                 /* Vertical centering. */
  justify-content: center;             /* Horizontal centering. */
  min-height: 48px;                    /* Comfortable tap target. */
  padding: 0.7rem 1.6rem;              /* Roomy label padding. */
  font-family: var(--font-caps);       /* Tracked display caps. */
  font-size: var(--fs-xs);             /* Small caps label. */
  letter-spacing: var(--track-sm);     /* Small-label tracking. */
  text-transform: uppercase;           /* Caps. */
  text-decoration: none;               /* Link-buttons lose the underline. */
  line-height: 1.2;                    /* Tight label leading. */
  border: 1px solid var(--rose-deep);  /* Mauve edge. */
  border-radius: 2px;                  /* Square-ish corners. */
  cursor: pointer;                     /* Clickable. */
  transition: background-color 160ms ease, color 160ms ease; /* Gentle hover. */
}
.btn-primary { background: var(--rose-deep); color: var(--paper); } /* Filled mauve, white text. */
.btn-primary:hover { background: var(--rose-deeper); border-color: var(--rose-deeper); color: var(--paper); } /* Deeper on hover. */
.btn-secondary { background: var(--paper); color: var(--rose-deep); } /* Outlined mauve. */
.btn-secondary:hover { background: var(--paper-blush); color: var(--rose-deeper); } /* Blush wash on hover. */
.btn[disabled] { opacity: 0.6; cursor: progress; } /* Busy state while sending. */
.actions {
  display: flex;                       /* Buttons in a row… */
  flex-wrap: wrap;                     /* …wrapping when narrow. */
  gap: 0.75rem;                        /* Space between buttons. */
}

/* --- Text links row (e.g. "Add to Google Calendar · Get directions") --- */
.text-links {
  display: flex;                       /* Links in a row. */
  flex-wrap: wrap;                     /* Wrap on phones. */
  align-items: baseline;               /* Align text baselines. */
  gap: 0.25rem 0.75rem;                /* Row and column gaps. */
  font-size: var(--fs-sm);             /* Slightly smaller than body. */
}
.text-links .dot { color: var(--rose); } /* Mauve middle dot separators (ornament). */
.link-pair { display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 0.1rem 0.5rem; max-width: 100%; } /* "Get directions: Google Maps · Apple Maps": lead-in, then the two app links; wraps instead of scrolling sideways. */
.link-pair .dot { color: var(--rose); } /* Mauve middle dot between the two apps. */
.link-apps { display: inline-flex; flex-wrap: nowrap; align-items: baseline; gap: 0.1rem 0.5rem; } /* The two app links move to a new line together, so the dot is never left at a line's end. */
.text-links .break { flex-basis: 100%; height: 0; } /* Starts a new line between link groups (calendars, then maps). */

/* --- Blossom divider: hairline · blossom · hairline --- */
.flower-trio { display: flex; align-items: flex-end; justify-content: center; gap: clamp(12px, 5vw, 56px); margin: var(--section-gap) auto 0; max-width: 560px; } /* Three flowers in a row above The Essentials. */
.flower-trio img { height: auto; } /* Keep proportions. */
.ft-side { display: none; } /* The two bouquets. */
.ft-mid { width: clamp(56px, 16vw, 84px); margin-bottom: 0; } /* The big pink flower in the middle. */
.ft-left { transform: rotate(-3deg); } /* A little life: bouquets lean in toward the flower. */
.ft-right { transform: rotate(3deg); } /* …and the right one leans in from its side. */
.divider {
  display: flex;                       /* Rule, flower, rule in a row. */
  align-items: center;                 /* Rules meet the flower's middle. */
  justify-content: center;             /* Centered. */
  gap: 1rem;                           /* Space around the flower. */
  margin-block: var(--section-gap);    /* Generous space above and below. */
  max-width: 360px;                    /* A small, quiet ornament. */
  margin-inline: auto;                 /* Centered in the column. */
}
.divider::before, .divider::after {
  content: "";                         /* Decorative rules. */
  flex: 1;                             /* Each rule takes half the remaining width. */
  height: 1px;                         /* Hairline. */
  background: var(--line);             /* Soft rule color. */
}
.divider img {
  width: 64px;                         /* ~60px blossom. */
  height: auto;                        /* Keep proportions. */
  -webkit-mask-image: radial-gradient(closest-side, #000 72%, transparent); /* Soften the cutout's hard crop edges (WebKit). */
  mask-image: radial-gradient(closest-side, #000 72%, transparent);         /* Soften the cutout's hard crop edges. */
}

/* --- Sub-page header: the card's top corners flanking the title --- */
.page-head {
  position: relative;                  /* Anchor for the corners. */
  overflow: hidden;                    /* Corners may bleed but never cause sideways scroll. */
  text-align: center;                  /* Centered title and subtitle. */
  padding-top: 70px;                   /* Phones: title below the corners; desktop overridden below. */
  margin-top: calc(clamp(28px, 5vw, 56px) * -1); /* Tuck up to the header so corners start at the top of the page. */
  padding-bottom: 0.5rem;              /* Small space before the page body. */
}
.corner {
  position: absolute;                  /* Layered behind the title. */
  top: 0;                              /* Flush with the top of the page. */
  width: clamp(120px, 18vw, 200px);    /* 120px phones → 200px desktop. */
  height: auto;                        /* Keep the 481×260 proportions. */
  -webkit-mask-image: linear-gradient(to bottom, #000 66%, transparent), linear-gradient(var(--edge-fade), #000 62%, transparent); /* Fade the cropped bottom and inner edges (WebKit). */
  mask-image: linear-gradient(to bottom, #000 66%, transparent), linear-gradient(var(--edge-fade), #000 62%, transparent);         /* Fade the cropped bottom and inner edges. */
  -webkit-mask-composite: source-in;   /* Keep only where both fades are opaque (WebKit syntax). */
  mask-composite: intersect;           /* Keep only where both fades are opaque. */
  pointer-events: none;                /* Decoration only. */
}
.corner-left { left: 0; --edge-fade: to right; }   /* Top-left flowers; the inner (right) edge fades. */
.corner-right { right: 0; --edge-fade: to left; }  /* Top-right flowers; the inner (left) edge fades. */
.page-title {
  position: relative;                  /* Above the corners. */
  font-family: var(--font-caps);       /* Display caps like "SAVE THE DATE". */
  font-size: clamp(var(--fs-xl), 5vw, var(--fs-2xl)); /* 32px phones → 44px desktop. */
  letter-spacing: var(--track);        /* Card tracking. */
  padding-inline-start: var(--track);  /* Re-center despite trailing tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--rose);                  /* Card mauve (large display text). */
  line-height: 1.2;                    /* Tight display leading. */
}
.page-title .nocase { text-transform: none; } /* Keeps the "s" of "FAQs" lowercase. */
.page-title:has(.nocase) { font-size: calc(clamp(var(--fs-xl), 5vw, var(--fs-2xl)) * 1.2); } /* "FAQs" is short, so it gets a bit more size to match the other titles. */
@media (max-width: 699px) { .page-title:has(.nocase) { font-size: 1.85rem; } } /* Phones: bigger than the 1.5rem other titles, still clear of the flowers. */
.page-subtitle {
  position: relative;                  /* Above the corners. */
  font-family: var(--font-script);     /* Calligraphy subtitle. */
  font-size: clamp(var(--fs-2xl), 6vw, 3.4rem); /* ≥44px so Corinthia stays legible. */
  line-height: 1.1;                    /* Compact. */
  color: var(--ink);                   /* Charcoal ink. */
  margin-top: 0.1rem;                  /* Tucked under the title. */
}
@media (max-width: 699px) {
  .page-head {
    --corner-w: 22vw;                  /* Phones: smaller corner flowers so the title fits between them. */
    --corner-h: calc(var(--corner-w) * 0.5394); /* Their height (the artwork is 330 x 178). */
    margin-inline: calc(var(--gutter) * -1); /* Phones: bleed to the screen edges like the card's corners. */
    padding-inline: var(--gutter);     /* Keep the text inside the gutter. */
    padding-top: calc((var(--corner-h) - 1.8rem) / 2); /* Title sits level with the middle of the flowers. */
    min-height: var(--corner-h);       /* Room for the whole corner flowers. */
  }
  .corner { width: var(--corner-w); }  /* Smaller corners on phones. */
  .page-title { font-size: 1.5rem; letter-spacing: 0.16em; padding-inline-start: 0.16em; } /* A little smaller so it fits between the flowers. */
  .page-subtitle { margin-top: calc(var(--corner-h) - (var(--corner-h) - 1.8rem) / 2 - 1.8rem + 0.1rem); } /* Subtitle starts just below the flowers. */}
@media (min-width: 700px) {
  .page-head { padding-top: clamp(30px, 3.4vw, 40px); } /* Wide: title sits between the corners. */
  .page-head .page-title, .page-head .page-subtitle { max-width: calc(100% - 2 * clamp(120px, 18vw, 200px)); margin-inline: auto; } /* Text stays between the corners. */
}

/* --- Draft-view status marks --- */
.todo {
  border: 1px dashed var(--rose-deep); /* Dashed box = "still to add". */
  border-radius: 2px;                  /* Square-ish. */
  background: var(--paper);            /* White inside, even on the blush band. */
  padding: 0.6rem 0.85rem;             /* Comfortable note padding. */
  font-size: var(--fs-sm);             /* Slightly smaller than body. */
  line-height: 1.5;                    /* Compact note leading. */
  color: var(--ink-soft);              /* Secondary text. */
  text-align: left;                    /* Notes read left-aligned even in centered blocks. */
  font-style: normal;                  /* Upright even inside an italic context (the example stays italic). */
  letter-spacing: normal;              /* Never inherits tracking. */
  text-transform: none;                /* Never inherits caps. */
}
.todo b {
  font-family: var(--font-caps);       /* "To add" label in caps. */
  font-weight: 400;                    /* Single-weight face. */
  font-size: var(--fs-xs);             /* Small label. */
  letter-spacing: var(--track-sm);     /* Small-label tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--rose-deep);             /* Mauve label. */
  margin-right: 0.1em;                 /* A hair of extra room; the real space after "To add:" does the rest. */
}
.todo i { font-style: italic; }        /* The "e.g." example is set in italic. */
span.todo { display: inline-block; max-width: 100%; } /* A to-do note inside a sentence (preview only) is a box that still wraps inside its column. */
.prov {
  -webkit-text-decoration: underline dotted var(--rose-deep); /* Dotted underline = "please confirm" (older WebKit prefix). */
  text-decoration-line: underline;     /* Longhand: WebKit drops the multi-value shorthand, so draw the underline… */
  text-decoration-style: dotted;       /* …dotted, meaning "please confirm"… */
  text-decoration-color: var(--rose-deep); /* …in the readable mauve. */
  text-decoration-thickness: 1.5px;    /* Visible dots. */
  text-underline-offset: 0.25em;       /* Clear of descenders. */
}
.chip {
  display: inline-block;               /* Pill that doesn't break across lines. */
  margin-left: 0.5em;                  /* Space after the text it annotates. */
  padding: 0.05em 0.6em;               /* Slim pill padding. */
  background: var(--blush);            /* Blush fill for draft chips. */
  color: var(--ink);                   /* Charcoal on blush (high contrast). */
  border-radius: 2px;                  /* Square-ish. */
  font-family: var(--font-body);       /* Readable body face at small size. */
  font-style: normal;                  /* Upright even inside italic text. */
  font-weight: 500;                    /* A touch heavier for the small size. */
  font-size: var(--fs-xs);             /* Small. */
  letter-spacing: 0.02em;              /* Slight opening at small size. */
  line-height: 1.6;                    /* Pill height. */
  vertical-align: 0.12em;              /* Optically centered on the text line. */
  white-space: nowrap;                 /* Never splits. */
  text-decoration: none;               /* No inherited underline. */
  text-transform: none;                /* Never inherits caps from a heading. */
}
.why {
  display: block;                      /* Explanation on its own line. */
  font-size: var(--fs-xs);             /* Small print. */
  color: var(--ink-soft);              /* Secondary text. */
  font-style: italic;                  /* Reads as an aside. */
  margin-top: 0.2rem;                  /* Tucked under the value. */
}

/* --- Form controls --- */
.field { display: grid; gap: 0.35rem; } /* Label, hint, control, error stacked. */
.field label, .field-label {
  font-family: var(--font-caps);       /* Caps label. */
  font-size: var(--fs-xs);             /* Small. */
  letter-spacing: var(--track-sm);     /* Small-label tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--ink);                   /* Charcoal (labels must be clearly readable). */
}
.hint { font-size: var(--fs-sm); color: var(--ink-soft); line-height: 1.45; } /* Helper text under a label. */
.input, .select, .textarea {
  width: 100%;                         /* Fill the field. */
  box-sizing: border-box;              /* Padding stays inside the width. */
  min-height: 48px;                    /* Comfortable tap height. */
  padding: 0.6rem 0.8rem;              /* Text padding. */
  font: inherit;                       /* Lora, like the body. */
  font-size: 1.125rem;                 /* ≥16px so phones don't zoom on focus. */
  color: var(--ink);                   /* Charcoal text. */
  background: var(--paper);            /* White field. */
  border: 1px solid var(--ink-soft);   /* Clearly visible edge (≥3:1). */
  border-radius: 2px;                  /* Square-ish. */
}
.textarea { min-height: 7rem; resize: vertical; line-height: 1.5; } /* Taller note box, vertical resize only. */
.input:focus-visible, .select:focus-visible, .textarea:focus-visible {
  outline: 2px solid var(--rose-deep); /* Mauve focus ring. */
  outline-offset: 1px;                 /* Tight to the field. */
  border-color: var(--rose-deep);      /* Edge matches the ring. */
}
.input[aria-invalid="true"] { border-color: var(--rose-deep); } /* Invalid fields pick up the mauve edge. */
.field-error {
  color: var(--rose-deep);             /* Readable mauve error text. */
  font-size: var(--fs-sm);             /* Small. */
  line-height: 1.45;                   /* Compact. */
  font-style: italic;                  /* Gentle, not alarming. */
}
.optional { text-transform: none; letter-spacing: 0; color: var(--ink-soft); font-family: var(--font-body); font-style: italic; } /* "(optional)" in quiet italics. */

/* ==========================================================================
   5. PAGES
   Home (the card as an object + welcome column, story, essentials),
   Schedule (timeline + "Good to know"), FAQs (grouped accordion) and RSVP
   (three-step form).
   ========================================================================== */

/* --- HOME: hero grid --- */
.hero {
  display: grid;                       /* Card and welcome column. */
  gap: clamp(32px, 6vw, 72px);         /* Space between them. */
  align-items: center;                 /* Welcome column centered against the card. */
}
.hero-card { width: 100%; max-width: 520px; margin-inline: auto; } /* Phones: full width; tablets: capped at a card size. */
@media (min-width: 900px) {
  .hero { grid-template-columns: minmax(0, 460px) minmax(0, 1fr); } /* Two columns: card (≤460px) left, welcome right. */
  .hero-card { max-width: 460px; }     /* The card never grows past ~460px. */
}

/* --- HOME: the invitation card, its text re-set live in container units ---
   The card is the floral frame picture with ONE centred stack of text laid over
   its clear middle. Every line is a content slot (card.topLine, names,
   inviteLine, dateLine, placeLine, replyLine); a slot with no text is simply not
   drawn, so the other lines stay centred without a gap. All sizes are in cqw
   (percent of the card's own width), so the text scales with the card on a
   phone, a laptop and inside the opening animation. The widths were checked
   against the real font files: the longest names line ("Dominique Del Real") is
   about 61cqw wide at 11cqw, and the clear area between the flowers is about 62cqw. */
.card {
  position: relative;                  /* Anchor for the live text. */
  container-type: inline-size;         /* Children size their text in cqw (card widths). */
  aspect-ratio: 922 / 1294;           /* The card's own proportions. */
  background: #EEE1D3;                 /* Cream card stock, like the invitation. */
  box-shadow: 0 1px 2px rgba(64, 61, 62, 0.08), 0 14px 32px -12px rgba(131, 15, 62, 0.22), 0 36px 60px -30px rgba(64, 61, 62, 0.18); /* Soft paper shadow: a card lying on the page. */
}
.card-frame {
  position: absolute;                  /* Fills the card. */
  inset: 0;                            /* Edge to edge. */
  width: 100%;                         /* Full card width. */
  height: 100%;                        /* Full card height. */
}
.card-body {
  position: absolute;                  /* Laid over the floral frame… */
  top: 16%;                            /* …below the flowers along the top edge… */
  bottom: 13%;                         /* …above the flowers along the bottom edge… */
  left: 19%;                           /* …and between the flowers down both sides (the clear width is about 62% of the card). */
  right: 19%;                          /* Same on the right. */
  display: flex;                       /* One stack of lines… */
  flex-direction: column;              /* …read from top to bottom… */
  align-items: center;                 /* …each line centred… */
  justify-content: center;             /* …and the whole stack centred in the clear area, whichever lines are present. */
  gap: 4.4cqw;                         /* Even air between the lines. */
  text-align: center;                  /* Centered like the card. */
}
.card-line {
  margin: 0;                           /* No default margins. */
  max-width: 100%;                     /* A long line wraps inside the clear area instead of running onto the flowers. */
  text-wrap: balance;                  /* A wrapped line comes out even, never one lonely word. */
}
.card-top {
  font-family: var(--font-caps);       /* Tracked display caps. */
  font-size: 5cqw;                     /* Display size, a little under the old "SAVE THE DATE" line. */
  letter-spacing: var(--track);        /* Card tracking. */
  padding-inline-start: var(--track);  /* Re-center despite trailing tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--rose-deep);             /* Readable mauve (small text on cream is below the large-text size). */
  line-height: 1.32;                   /* Stacked lines sit close, like the card. */
}
.card-names {
  align-self: stretch;                 /* Wider than the other lines: the script needs room… */
  max-width: none;                     /* …so the stack's 100% cap does not apply… */
  margin-inline: -6cqw;                /* …and it may use 6% of the card more on each side (still inside the clear area at this height). */
  font-family: var(--font-script);     /* Calligraphy. */
  font-size: 11cqw;                    /* Corinthia is set large (small x-height); sized so the longest line fits. */
  line-height: 0.95;                   /* Two lines nestled like the card. */
  color: var(--ink);                   /* Charcoal ink. */
}
.card-names span { display: block; }   /* "Dominique Del Real" / "& Irwingh Gaxiola" on two lines. */
/* The five-line names (user ruling 2026-11-05): "Dominique / Del Real / & / Irwingh / Gaxiola", one row per
   line of the couple's text (site.js marks the heading .card-names-rows). Each row is short, so the script
   can stay large, but five rows need more height than two: the rows nestle a little closer and the
   ampersand row is smaller, in the card's mauve, like the design's styled ampersand. Sizes are in cqw, so
   the whole stack scales with the card; measured in a real browser at card widths 240–620px. */
.card-names-rows {
  font-size: 9.6cqw;                   /* Large script, a step under the two-line card (five rows must fit the clear area). */
  line-height: 0.94;                   /* Rows nestle like hand lettering; Corinthia's q/g tails (0.42em) and capitals (0.59em) need 0.94 to clear each other. */
}
.card-name-line { display: block; }   /* One name per line. */
.card-amp {
  font-size: 0.68em;                   /* The ampersand row is smaller… */
  line-height: 0.92;                   /* …in a shorter row of its own (0.63 of a name row)… */
  color: var(--rose);                  /* …in the card mauve (large display text, like the monogram's ampersand)… */
  transform: translateY(0.08em);       /* …nudged down to sit optically midway (the glyph rides high in its row); no layout effect. */
}
.card-invite {
  font-family: var(--font-caps);       /* Tracked caps. */
  font-size: max(2.9cqw, 10.5px);      /* Small caps, with a legible floor on phones. */
  letter-spacing: 0.2em;               /* Wide tracking like the card. */
  padding-inline-start: 0.2em;         /* Re-center despite trailing tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--ink);                   /* Charcoal. */
  line-height: 1.85;                   /* Two lines, spaced like the card. */
}
.card-date {
  font-family: var(--font-num);        /* Bold card numerals. */
  font-size: max(4.1cqw, 14px);        /* Fits "January 22nd, 2027 at 3 p.m." on one line, with a legible floor on phones. */
  letter-spacing: 0.04em;              /* A touch of air between the figures. */
  color: var(--rose-deep);             /* Readable mauve: this size is below the large-text size, where the card mauve fails contrast. */
  line-height: 1.25;                   /* Compact; wraps evenly if a longer date is typed. */
}
.card-place {
  font-family: var(--font-caps);       /* Tracked caps. */
  font-size: max(2.9cqw, 10.5px);      /* Same small caps as the invitation line, with the same floor. */
  letter-spacing: 0.2em;               /* Wide tracking like the card. */
  padding-inline-start: 0.2em;         /* Re-center despite trailing tracking. */
  text-transform: uppercase;           /* Caps. */
  line-height: 2.05;                   /* Room for the underline below. */
}
.card-place a {
  color: var(--ink);                   /* Charcoal, like the card's printed address. */
  text-decoration: underline;          /* Underlined, like the card. */
  text-decoration-thickness: 0.12cqw;  /* Hairline that scales with the card. */
  text-underline-offset: 0.45em;       /* Rule sits low, like the card. */
}
.card-place a:hover { color: var(--rose-deep); } /* Mauve on hover — it's a directions link. */
.card-reply {
  margin-top: 2cqw;                    /* A little extra air above the reply line. */
  font-family: var(--font-body);       /* Text serif. */
  font-size: max(2.85cqw, 11px);       /* Matches the card, with a legible floor on phones. */
  color: var(--ink);                   /* Charcoal. */
  line-height: 1.3;                    /* Single line (wraps evenly if a longer one is typed). */
}
/* Small cards (a 320–340px phone): the text cannot shrink below its legible floor, so the lines would wrap
   (a dangling "|" in the place line, a three-line invitation). A slightly wider clear column and a touch less
   tracking keep each line whole. Measured in a real browser at 320px: the place line needs ~183px, the column is then ~190px. */
@container (max-width: 340px) {
  .card-body { left: 17%; right: 17%; }  /* A little wider column (the flowers shrink with the card too). */
  .card-invite, .card-place { letter-spacing: 0.14em; padding-inline-start: 0.14em; } /* Slightly tighter tracking. */
  .card-date { font-size: 13px; }        /* Lower floor so "January 22nd, 2027 at 3 p.m." stays on one line. */
}
/* Very small cards (a 280px folding-phone screen, 240–300px cards): with the five-line names the stack would
   otherwise run past the flowers at the top and bottom. Closer lines, slightly smaller small print and tighter
   tracking keep everything inside the clear area (measured in a real browser at 240–300px, English and Spanish). */
@container (max-width: 300px) {
  .card-body { gap: 2.6cqw; }            /* Closer lines. */
  .card-names-rows { font-size: 9cqw; }  /* The script a touch smaller. */
  .card-invite { font-size: 9.5px; line-height: 1.5; letter-spacing: 0.1em; padding-inline-start: 0.1em; } /* Two lines instead of three. */
  .card-date { font-size: 12px; max-width: 90%; } /* Smallest numerals that stay comfortable to read; a wrapped (Spanish) date stays clear of the leaves at the column's edge. */
  .card-place { font-size: 9.5px; line-height: 1.75; letter-spacing: 0.08em; padding-inline-start: 0.08em; } /* Still room for the underline; tracking just tight enough to keep "RANCHO VIEJO | GOODYEAR" whole and off the leaf tips. */
  .card-reply { margin-top: 0; font-size: 10px; max-width: 86%; } /* No extra air above the last line, and kept off the column's edges, where the bottom flowers' stems curl in. */
}

/* --- HOME: welcome column --- */
.welcome {
  display: grid;                       /* Stacked column. */
  gap: 1.5rem;                         /* Even space between items. */
  justify-items: start;                /* Left-aligned items. */
  width: 100%;                         /* Fill the grid cell… */
  max-width: 30rem;                    /* …up to one shared measure, so rules, notes and lede end together. */
}
@media (max-width: 899px) {
  .welcome { justify-items: center; text-align: center; margin-inline: auto; } /* Phones: centered under the card. */
  .welcome .actions, .welcome .text-links { justify-content: center; } /* Centered buttons and links. */
}
.countdown {
  display: flex;                       /* Number and label side by side… */
  align-items: baseline;               /* …on a shared baseline. */
  flex-wrap: wrap;                     /* Wrap if ever too narrow. */
  gap: 0.2rem 0.75rem;                 /* Space between number and label. */
  padding-block: 1.1rem;               /* Air inside the rules. */
  border-block: 1px solid var(--line); /* Hairlines above and below, like a card rule. */
  width: 100%;                         /* Rules span the column's shared measure. */
}
@media (max-width: 899px) { .countdown { justify-content: center; } } /* Centered on phones. */
@media (max-width: 599px) {
  .welcome .eyebrow-sep { display: none; } /* Phones: no dangling middle dot… */
  .welcome .eyebrow-last { display: block; } /* …the place gets its own line instead. */
}
.countdown-num {
  font-family: var(--font-num);        /* Card numerals. */
  font-size: var(--fs-3xl);            /* Big, bold number (64px). */
  line-height: 1;                      /* Tight. */
  color: var(--rose);                  /* Card mauve (large display text). */
  font-variant-numeric: tabular-nums;  /* Digits don't jitter as they change. */
  letter-spacing: 0.04em;              /* A touch of air between digits. */
}
.countdown-label {
  font-family: var(--font-caps);       /* Small caps label. */
  font-size: var(--fs-sm);             /* 16px label. */
  letter-spacing: var(--track-sm);     /* Small-label tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--ink);                   /* Charcoal. */
}
.countdown-text {
  font-family: var(--font-num);        /* Card numerals face for the day-of / after messages. */
  font-size: var(--fs-xl);             /* Large. */
  color: var(--rose);                  /* Mauve (large display text). */
  line-height: 1.2;                    /* Compact. */
}
.lede { font-size: var(--fs-md); color: var(--ink); max-width: 30rem; } /* The welcome sentence. */
.privacy-note { max-width: 30rem; font-size: var(--fs-sm); color: var(--ink-soft); border-left: 2px solid var(--blush); padding-left: 1rem; text-align: left; } /* Photo/privacy request: quiet but noticeable. */
.privacy-note .label { margin-bottom: 0.15rem; } /* Small caps label above the note. */
.welcome .todo { max-width: 30rem; }   /* Notes keep the same measure. */

/* --- HOME: the essentials --- */
.essentials-grid {
  display: grid;                       /* Grid of essential facts. */
  margin: 2rem 0 0;                    /* Space under the title; reset dl margins. */
  border-top: 1px solid var(--line);   /* Hairline above the row. */
}
.essential {
  padding: 1.4rem 0.25rem;             /* Cell padding. */
  border-bottom: 1px solid var(--line);/* Hairline between stacked cells on phones. */
  text-align: center;                  /* Centered cells. */
  display: grid;                       /* Label, value, link stacked. */
  gap: 0.4rem;                         /* Space between them. */
  align-content: start;                /* Top-aligned contents. */
}
.essential dd { margin: 0; }           /* Reset definition indent. */
.essential .value { font-size: var(--fs-md); line-height: 1.4; } /* The key fact. */
.essential .detail { font-size: var(--fs-sm); color: var(--ink-soft); line-height: 1.45; } /* Supporting line. */
.essential .todo { margin-top: 0.2rem; } /* Notes sit just under the label. */
.essential-link { font-size: var(--fs-sm); } /* Smaller link line. */
.essential-link .link-pair { justify-content: center; } /* The lead-in and the two app links stay centered like the rest of the cell, even when they wrap. */
@media (min-width: 600px) {
  .essentials-grid { grid-template-columns: 1fr 1fr; } /* Two per row on tablets. */
  .essential { padding-inline: 1.25rem; } /* Horizontal cell padding once side by side. */
}
@media (min-width: 900px) {
  .essentials-grid { grid-template-columns: repeat(var(--count, 4), minmax(0, 1fr)); border-bottom: 1px solid var(--line); } /* One row on desktop. */
  .essential { border-bottom: 0; }     /* The row has one bottom rule instead. */
  .essential + .essential { border-left: 1px solid var(--line); } /* Hairlines between cells, not boxes. */
}
.hashtag { text-align: center; margin-top: 2.5rem; } /* Hashtag line under the essentials. */
.hashtag .todo { display: inline-block; } /* Note sized to its text. */
.home-section { margin-top: var(--section-gap); } /* Sections spaced evenly. */

/* --- SCHEDULE --- */
.schedule-grid {
  display: grid;                       /* Timeline + aside. */
  gap: clamp(72px, 9vw, 96px);         /* Space between them (roomier before "Good to know"). */
  margin-top: clamp(32px, 5vw, 56px);  /* Space under the page header. */
}
@media (min-width: 900px) { .schedule-grid { grid-template-columns: minmax(0, 1fr) 300px; align-items: start; } } /* Timeline left, aside right. */
.day-heading {
  font-family: var(--font-caps);       /* Tracked caps. */
  font-size: clamp(1.0625rem, 2.6vw, var(--fs-md)); /* 17px phones → 19px desktop: one line at 360px. */
  letter-spacing: var(--track-sm);     /* Label tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--rose-deep);             /* Readable mauve at this smaller size. */
  padding-bottom: 1rem;                /* Space above the first rule. */
  border-bottom: 1px solid var(--line);/* Hairline under the day. */
}
.events { list-style: none; margin: 0; padding: 0; } /* Plain list of events. */
.event {
  display: grid;                       /* Time column + details. */
  gap: 0.6rem 2rem;                    /* Row/column gaps. */
  padding-block: 1.75rem;              /* Space inside each event. */
  border-bottom: 1px solid var(--line);/* Events separated by hairlines, not boxes. */
}
.event:last-child, .event:has(+ .other-events:last-child) { border-bottom: 0; } /* No rule after the final event. */
@media (min-width: 600px) { .event { grid-template-columns: 11rem minmax(0, 1fr); } } /* Time column left from tablet up. */
.event-time {
  font-family: var(--font-num);        /* Card numerals for times. */
  font-size: 1.3rem;                   /* Prominent, a touch smaller. */
  color: var(--rose-deep);             /* Mauve. */
  line-height: 1.3;                    /* Compact. */
}
.event-time.is-pending {
  font-family: var(--font-body);       /* Plain text for the honest "to follow" line. */
  font-style: italic;                  /* Reads as a note. */
  font-size: var(--fs-sm);             /* Smaller. */
  color: var(--ink-soft);              /* Secondary. */
  padding-top: 0.3rem;                 /* Align with the event name's cap line. */
}
.event-body { display: grid; gap: 0.5rem; } /* Stacked details. */
.event-name {
  font-family: var(--font-caps);       /* Tracked caps. */
  font-size: var(--fs-lg);             /* 24px (large text). */
  letter-spacing: var(--track);        /* Card tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--rose);                  /* Card mauve at large size. */
  line-height: 1.3;                    /* Compact. */
  text-wrap: wrap;                     /* Plain wrapping: balance pushed the chip onto a phantom second line. */
}
.event-venue { font-weight: 500; }     /* Venue name slightly heavier. */
.event-address { color: var(--ink-soft); font-size: var(--fs-sm); } /* Address in secondary text. */
.event-meta { display: grid; gap: 0.6rem; margin: 0.4rem 0 0; } /* Attire / notes list. */
.event-meta dd { margin: 0; }          /* Reset indent. */
.event .todo { max-width: 34rem; }     /* Notes keep a measure. */
.other-events { padding-block: 1.75rem; } /* The "other events" note row. */

.good-to-know {
  background: var(--paper-blush);      /* The one soft blush band on this page. */
  padding: clamp(1.4rem, 3vw, 2rem);   /* Inner padding. */
  border-top: 1px solid var(--blush);  /* A slightly deeper edge on top. */
}
.good-to-know h2 {
  font-family: var(--font-caps);       /* Tracked caps title. */
  font-size: var(--fs-md);             /* 19px — fits one line in the 300px aside. */
  letter-spacing: var(--track-sm);     /* Label tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--rose-deep);             /* Readable mauve on blush. */
}
.facts { list-style: none; margin: 1rem 0 0; padding: 0; display: grid; gap: 1.1rem; } /* Stacked fact list. */
.facts li { font-size: var(--fs-sm); line-height: 1.55; } /* Compact fact text. */
.facts .label { position: relative; padding-left: 1.1rem; } /* Room for the sprig mark. */
.facts .label::before {
  content: "";                         /* Tiny sage leaf mark. */
  position: absolute;                  /* Placed before the label. */
  left: 0;                             /* At the start. */
  top: 0.45em;                         /* Centered on the caps. */
  width: 0.55rem;                      /* Leaf width. */
  height: 0.3rem;                      /* Leaf height. */
  border-radius: 0 100% 0 100%;        /* Leaf shape. */
  background: var(--sage);             /* Leaf green. */
}
.plan-links { display: grid; gap: 0.4rem; margin-top: 1.4rem; padding-top: 1.1rem; border-top: 1px solid var(--blush); font-size: var(--fs-sm); } /* Calendar + map links at the foot of the aside. */

/* --- FAQS --- */
.faq-groups { margin-top: clamp(32px, 5vw, 56px); display: grid; gap: clamp(36px, 5vw, 56px); } /* Space between groups. */
.faq-group { display: grid; gap: 0.75rem; } /* Label above its list on phones. */
@media (min-width: 900px) { .faq-group { grid-template-columns: 220px minmax(0, 1fr); gap: 2.5rem; align-items: start; } } /* Label in a left column on wide screens. */
.faq-label {
  font-family: var(--font-caps);       /* Small caps category label. */
  font-size: 1rem;                     /* A step larger so the group names stand out. */
  font-weight: 700;                    /* Bold. */
  letter-spacing: var(--track-sm);     /* Label tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--rose-deep);             /* Readable mauve. */
  padding-top: 1.15rem;                /* Wide: align with the first question's text. */
}
@media (max-width: 899px) { .faq-label { padding-top: 0; } } /* Phones: label sits directly above its group. */
.faq-list { border-top: 1px solid var(--line); } /* Rule above the first question. */
.faq { border-bottom: 1px solid var(--line); } /* Rule under every question. */
.faq-group:last-child .faq:last-child { border-bottom: 0; } /* No rule under the very last question. */
.faq summary {
  list-style: none;                    /* Hide the default disclosure triangle. */
  cursor: pointer;                     /* Clickable. */
  display: flex;                       /* Question text + marker. */
  align-items: center;                 /* Marker centered on the text. */
  gap: 1rem;                           /* Space before the marker. */
  padding: 1rem 0.25rem;               /* Tap area. */
  font-size: var(--fs-md);             /* Question text size. */
  font-weight: 500;                    /* Medium weight keeps questions above the body-size answers. */
  line-height: 1.45;                   /* Compact. */
  color: var(--ink);                   /* Charcoal. */
}
.faq summary::-webkit-details-marker { display: none; } /* Hide the WebKit triangle too. */
.faq summary:hover { background: var(--paper-blush); } /* Blush hover wash. */
.faq-q { flex: 1; }                    /* Question takes the row. */
.faq summary::after {
  content: "";                         /* Plus/minus marker drawn with borders. */
  flex: none;                          /* Fixed size. */
  width: 0.7rem;                       /* Marker width. */
  height: 0.7rem;                      /* Marker height. */
  background: linear-gradient(var(--rose-deep), var(--rose-deep)) center / 100% 1.5px no-repeat, linear-gradient(var(--rose-deep), var(--rose-deep)) center / 1.5px 100% no-repeat; /* A thin mauve plus. */
  transition: transform 200ms ease;    /* Gentle rotation. */
}
.faq[open] summary::after { background: linear-gradient(var(--rose-deep), var(--rose-deep)) center / 100% 1.5px no-repeat; } /* Open: minus. */
.faq-a { padding: 0 0.25rem 1.25rem; display: grid; gap: 0.75rem; max-width: 65ch; } /* Answer body. */
.faq-a p { font-size: inherit; line-height: 1.65; } /* Answer text at full body size (the page's main reading). */
.faq-a ul { margin: 0; padding-left: 1.2rem; font-size: inherit; } /* Airport list, also at body size. */
.faq-a li + li { margin-top: 0.35rem; } /* Space between list items. */
.gallery-note { margin-top: 2rem; font-style: italic; color: var(--ink-soft); } /* Gentle "inspiration only" note above the pictures. */
.faq-gallery { display: grid; gap: 1.75rem; margin-top: 1.25rem; } /* Inspiration pictures stacked with air between. */
.faq-gallery figure { margin: 0; } /* Reset default figure margins. */
.faq-gallery img { width: 100%; height: auto; border: 0; background: var(--paper); } /* Scales down on phones, capped per image so small files stay tidy. */
.faq-gallery img.framed { height: auto; background: #fff; } /* Same width and shape for every outfit picture; white bars fill the gaps. */
.faq-gallery figcaption { margin: 0 0 0.5rem; } /* Title sits above each picture, like the other sections. */
.faq-contact { margin-top: 2.5rem; text-align: center; } /* Contact line under the groups. */

/* --- RSVP --- */
.rsvp-wrap { max-width: 40rem; margin: clamp(24px, 4vw, 40px) auto 0; } /* A focused, narrower column. */
.rsvp-intro { text-align: center; display: grid; gap: 0.75rem; justify-items: center; } /* Deadline line and preview note. */
.rsvp-deadline { font-style: italic; color: var(--ink); } /* "Kindly respond by …". */
.rsvp-progress {
  list-style: none;                    /* No numbers — words only. */
  margin: 2rem 0 0;                    /* Space above. */
  padding: 0;                          /* Reset. */
  display: flex;                       /* In a row. */
  justify-content: center;             /* Centered. */
  flex-wrap: wrap;                     /* Wrap on tiny screens. */
  gap: 0.25rem 1.25rem;                /* Spacing. */
}
.rsvp-progress li {
  font-family: var(--font-caps);       /* Small caps. */
  font-size: var(--fs-xs);             /* Small. */
  letter-spacing: var(--track-sm);     /* Label tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--ink-soft);              /* Inactive steps in secondary text. */
  padding-bottom: 0.3rem;              /* Room for the active rule. */
  border-bottom: 1px solid transparent;/* Reserve the rule's space. */
}
.rsvp-progress li[aria-current="step"] { color: var(--rose-deep); border-bottom-color: var(--rose); } /* Active step: mauve with a thin rule. */
.rsvp-form {
  margin-top: 1.5rem;                  /* Space under the progress row. */
  border-top: 1px solid var(--line);   /* Hairline above the form. */
  padding-top: 2rem;                   /* Space inside. */
  scroll-margin-top: calc(var(--header-h, 7rem) + 1rem); /* Step scrolls land below the sticky header (height measured by script). */
}
.rsvp-step { display: grid; gap: 1.5rem; } /* Stacked step content. */
.step-title {
  font-family: var(--font-caps);       /* Tracked caps. */
  font-size: var(--fs-lg);             /* 24px (large). */
  letter-spacing: var(--track-sm);     /* Label tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--rose);                  /* Card mauve at large size. */
  line-height: 1.3;                    /* Compact. */
}
.step-title.is-script {
  font-family: var(--font-script);     /* "Hi Maria!" / "Thank you, Maria!" in script. */
  font-size: 3.2rem;                   /* Large for Corinthia. */
  letter-spacing: 0;                   /* No tracking for script. */
  text-transform: none;                /* Natural case. */
  color: var(--ink);                   /* Charcoal. */
  line-height: 1;                      /* Tight. */
}
.guest {
  border: 0;                           /* No fieldset box; hairlines instead. */
  border-top: 1px solid var(--line);   /* Rule above each guest. */
  margin: 0;                           /* Reset. */
  padding: 1.25rem 0 0;                /* Space inside. */
  display: grid;                       /* Stacked. */
  gap: 0.9rem;                         /* Spacing. */
  min-width: 0;                        /* Fieldsets otherwise refuse to shrink. */
}
.guest legend {
  float: left;                         /* Lets the legend sit inside the grid flow. */
  width: 100%;                         /* Full row. */
  padding: 0;                          /* Reset. */
  font-size: var(--fs-md);             /* Guest name. */
  font-weight: 500;                    /* Slightly heavier. */
  color: var(--ink);                   /* Charcoal. */
}
.choices { display: grid; gap: 0.6rem; } /* Stacked on phones. */
@media (min-width: 560px) { .choices { grid-template-columns: 1fr 1fr; } } /* Side by side when there's room. */
.choice {
  display: flex;                       /* Radio + label text. */
  align-items: center;                 /* Centered. */
  gap: 0.7rem;                         /* Space between radio and text. */
  min-height: 52px;                    /* Big tap target. */
  padding: 0.5rem 0.9rem;              /* Inner padding. */
  border: 1px solid var(--line);       /* Soft tile edge. */
  border-radius: 2px;                  /* Square-ish. */
  cursor: pointer;                     /* Whole tile is clickable. */
  font-size: 1.0625rem;                /* Choice text. */
}
.choice:hover { background: var(--paper-blush); } /* Blush hover wash. */
.choice:has(input:checked) { border-color: var(--rose-deep); background: var(--paper-blush); } /* Chosen tile. */
.choice input { accent-color: var(--rose-deep); width: 1.15rem; height: 1.15rem; margin: 0; flex: none; } /* Mauve native radio. */
.guest-extra { display: grid; gap: 0.9rem; } /* The guest's name, once a guest is coming. */
.party-fields { display: grid; gap: 1.2rem; border-top: 1px solid var(--line); padding-top: 1.5rem; } /* Party-level questions. */
.step-actions { display: flex; flex-wrap: wrap; gap: 0.75rem; justify-content: flex-start; border-top: 1px solid var(--line); padding-top: 1.5rem; } /* Button row, left-grouped like the rest of the site. */
.summary + .step-actions { border-top: 0; } /* After the summary list its last hairline is enough (no double rule). */
.summary { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); } /* Thank-you summary list. */
.summary li { padding: 0.9rem 0; border-bottom: 1px solid var(--line); display: grid; gap: 0.15rem; } /* One row per guest. */
.summary .who { font-weight: 500; } /* Guest name. */
.summary .answer { color: var(--rose-deep); font-style: italic; } /* Their answer. */
.summary .extra { color: var(--ink-soft); font-size: var(--fs-sm); } /* The guests' own message, quoted. */
.summary .answer.is-none { color: var(--ink-soft); } /* "No reply": quieter than a real answer. */
.thanks-flower { width: 88px; height: auto; margin-inline: auto; -webkit-mask-image: radial-gradient(closest-side, #000 70%, transparent); mask-image: radial-gradient(closest-side, #000 70%, transparent); } /* Peony accent with softened crop edges. */
.thanks-head { text-align: center; display: grid; gap: 0.75rem; justify-items: center; } /* Centered thank-you heading block. */
.preview-note { font-size: var(--fs-sm); color: var(--ink-soft); font-style: italic; } /* Draft-only honesty line. */

/* --- Page fallback: shown only if the scripts never draw the page ---
   Invisible at first and revealed after 4 seconds, so a normal load never flashes it.
   site.js removes the paragraph as soon as it draws the page. */
.boot-fallback { max-width: 30rem; margin: 2rem auto; text-align: center; color: var(--ink-soft); opacity: 0; animation: boot-fallback-in 0s linear 4s forwards; } /* Hidden, then switched on after 4s. */
@keyframes boot-fallback-in { to { opacity: 1; } } /* The reveal: a zero-length fade, delayed above. */

/* --- RSVP on the hosted site: lookup, party answers, summary, notices ---
   The lookup / party / thank-you steps reuse the classes above (.field, .input,
   .guest, .choice, .summary, .step-actions …). These few rules add what the
   design-only version never needed: notices, disabled controls (admin preview)
   and the closed state. */
.rsvp-notice { max-width: 30rem; font-size: var(--fs-sm); color: var(--ink-soft); border-left: 2px solid var(--blush); padding-left: 1rem; text-align: left; } /* A quiet but noticeable note: RSVPs closed, or a preview reminder. */
.rsvp-notice:focus { outline: 2px solid var(--rose-deep); outline-offset: 4px; } /* The 'someone updated your RSVP' notice takes focus when it appears. */
.rsvp-step .step-actions .btn-quiet { background: transparent; border-color: transparent; text-decoration: underline; } /* The 'look up a different name' control: a quiet text-style button. */
.btn[aria-disabled="true"] { cursor: progress; } /* A busy button stays focusable but ignores clicks (rsvp.js). */
.thanks-head .lede { text-align: center; } /* The line under the party's names. */
.summary-note { font-style: italic; color: var(--ink-soft); } /* The guests' own message, quoted under the answers. */
.rsvp-step .choice span { min-width: 0; overflow-wrap: anywhere; } /* A long label wraps inside its tile instead of widening the page (320px screens). */
.input:disabled, .textarea:disabled, .select:disabled {
  background: var(--paper-blush);      /* Switched-off fields (admin preview) look inactive. */
  color: var(--ink-soft);              /* Dimmed text. */
  border-color: var(--line);           /* Soft edge. */
  cursor: not-allowed;                 /* Tells the pointer it won't work. */
}
.choice:has(input:disabled) { opacity: 0.6; cursor: not-allowed; } /* Switched-off answer tiles. */
.btn[aria-busy="true"] { opacity: 0.6; cursor: progress; } /* A request is on its way. */

/* --- RSVP: the ways in without a name search (personal-links.md section 7.1) ---
   "Please use the personal link we sent you" (no link, search off), "We couldn't find this
   invitation link" (unknown link), "Looking for your invitation…" (the link is being checked),
   and the connection message with "Find my invitation" (the check failed). */
.rsvp-message { padding-block: 0.25rem 0.5rem; } /* The couple's message under the blossom. */
.rsvp-message .lede { max-width: 28rem; }  /* A comfortable measure, centred by .thanks-head. */
.rsvp-loading { padding-block: 1.25rem; text-align: center; font-style: italic; color: var(--ink-soft); } /* Quiet progress line. */
.rsvp-wrap:has([data-rsvp-step="invalid"]) .rsvp-lead { display: none; } /* An unknown link: its message replaces "Please tell us who's coming". */

/* ==========================================================================
   5b. THE RSVP POP-UP (personal links, personal-links.md section 7.2)
   A native <dialog> that rsvp.js opens with showModal() on a family's personal
   link, once the intro has finished. It is a sheet of the card's white paper:
   the card's two top corners of flowers, a script greeting ("Hi Ana and
   Luis!"), the question in tracked caps and the reply-by date in italics, one
   row per person with two large choices, and the buttons in a bar that stays
   within reach while the sheet scrolls. Under 600px it fills the screen; the
   two problem pop-ups (unknown link, no connection) are a small card on every
   screen. It fades and rises in gently (not at all with reduced motion), and
   the page behind never scrolls while it is open.
   ========================================================================== */
html:has(.rsvp-popup[open]) { overflow: hidden; } /* The page behind stays put while the pop-up is open. */
.rsvp-popup {
  --popup-pad: clamp(20px, 6vw, 44px); /* Side padding inside the pop-up (never under the page's 16px gutter). */
  container: rsvp-popup / inline-size; /* Its rows lay out by the pop-up's own width (side-by-side choices only when they fit). */
  width: min(36rem, calc(100% - 2 * var(--gutter))); /* A card-sized sheet, inside the page gutters. */
  max-width: none;                     /* Undo the browser's own cap… */
  max-height: min(54rem, calc(100% - 2 * var(--gutter))); /* …and keep it inside the screen (taller content scrolls inside). */
  margin: auto;                        /* Centred in the screen. */
  padding: 0;                          /* The steps pad themselves (the flowers reach the edges). */
  border: 1px solid var(--line);       /* Hairline edge, like the site's rules. */
  border-radius: 3px;                  /* Square-ish corners, per the design system. */
  background: var(--paper);            /* White card stock. */
  color: var(--ink);                   /* Charcoal ink. */
  box-shadow: 0 1px 2px rgba(64, 61, 62, 0.08), 0 28px 64px -22px rgba(131, 15, 62, 0.42); /* A card lifted off the page, rose-tinted like the invitation's shadow. */
  overflow-x: hidden;                  /* Corner flowers never add sideways scrolling. */
  overflow-y: auto;                    /* A long party scrolls inside the pop-up. */
  overscroll-behavior: contain;        /* Scrolling never chains to the page behind. */
}
.rsvp-popup::backdrop { background: rgba(64, 61, 62, 0.46); } /* A soft charcoal veil over the page. */
.rsvp-popup[open] { animation: popup-in 340ms cubic-bezier(0.2, 0.8, 0.2, 1); } /* Opens with a gentle rise. */
.rsvp-popup[open]::backdrop { animation: popup-veil-in 340ms ease-out; } /* The veil fades in with it. */
@keyframes popup-in {
  from { opacity: 0; transform: translateY(14px) scale(0.985); } /* Slightly low and faint… */
  to { opacity: 1; transform: none; }  /* …settling in place. */
}
@keyframes popup-veil-in {
  from { opacity: 0; }                 /* Clear… */
  to { opacity: 1; }                   /* …to veiled. */
}
.popup-form { margin: 0; }             /* No default form spacing. */
.popup-step {
  display: flex;                       /* Head, question, rows and buttons… */
  flex-direction: column;              /* …stacked… */
  gap: 1.25rem;                        /* …with even air between them. */
}

/* --- Head: the card's top corners and the script greeting (the dialog's accessible name) --- */
.popup-head {
  position: relative;                  /* Anchor for the corners. */
  padding: clamp(58px, 13vw, 76px) var(--popup-pad) 0; /* The greeting starts below the flowers' busiest part. */
  text-align: center;                  /* Centred like the card. */
}
.popup-corner {
  position: absolute;                  /* Laid behind the greeting… */
  top: 0;                              /* …flush with the top edge. */
  width: clamp(104px, 30%, 172px);     /* Small on phones, generous on wide screens. */
  height: auto;                        /* Keep the artwork's proportions. */
  -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent), linear-gradient(var(--edge-fade), #000 58%, transparent); /* Fade the cropped bottom and inner edges (WebKit). */
  mask-image: linear-gradient(to bottom, #000 62%, transparent), linear-gradient(var(--edge-fade), #000 58%, transparent);         /* Fade the cropped bottom and inner edges. */
  -webkit-mask-composite: source-in;   /* Keep only where both fades are opaque (WebKit syntax). */
  mask-composite: intersect;           /* Keep only where both fades are opaque. */
  pointer-events: none;                /* Decoration only. */
}
.popup-corner-left { left: 0; --edge-fade: to right; }   /* Top-left flowers; the inner (right) edge fades. */
.popup-corner-right { right: 0; --edge-fade: to left; }  /* Top-right flowers; the inner (left) edge fades. */
.popup-greeting {
  position: relative;                  /* Above the corners. */
  font-family: var(--font-script);     /* Calligraphy, like the names on the card. */
  font-size: clamp(2.75rem, 10vw, 3.5rem); /* ≥44px so Corinthia stays legible. */
  line-height: 1.05;                   /* Compact when a long party wraps. */
  word-spacing: 0.15em;                /* Corinthia's swash capitals (L, J…) eat a normal space: "and Lydia", not "andLydia". */
  color: var(--ink);                   /* Charcoal ink. */
}
.popup-greeting.is-long { font-size: clamp(2.3rem, 8vw, 2.9rem); } /* A big party's many names: a step smaller (still ≥ 36px script). */

/* --- The pop-up's own language switch: the header's is behind the modal pop-up and cannot be
   reached, so a family whose language was set wrongly switches here (same buttons as the header). --- */
.popup-lang {
  display: flex;                       /* The two words and the divider in a row… */
  justify-content: center;             /* …centred… */
  align-items: center;                 /* …on one line. */
  gap: 0.15rem;                        /* Tight, they read as one control. */
  white-space: nowrap;                 /* Never wraps between the corner flowers. */
  font-family: var(--font-caps);       /* Same tracked caps as the header's switch. */
  font-size: 0.72rem;                  /* Small, quiet. */
  letter-spacing: 0.08em;              /* Light tracking. */
}
.popup-head .popup-lang {
  position: absolute;                  /* Laid over the top edge of the sheet… */
  top: 0.3rem;                         /* …just inside it, above the greeting… */
  left: 50%;                           /* …centred between the corner flowers… */
  transform: translateX(-50%);         /* …exactly. */
  z-index: 1;                          /* Above the flowers. */
}
.popup-lang .lang-btn {
  position: relative;                  /* Anchors the invisible hit extender below. */
  min-width: 44px;                     /* At least 44px wide to tap, though the type stays small. */
  min-height: 44px;                    /* At least 44px tall to tap (the extender below supplies the height). */
}
.popup-lang .lang-btn::after {
  content: "";                         /* An invisible extender, like the card links'. */
  position: absolute;                  /* Laid over the button… */
  inset: -3px 0;                       /* …reaching 3px above and below so the hit area is 44px tall. */
}
.popup-small .popup-lang { margin-top: -1rem; } /* The small card: tucked into its top padding, above the blossom. */

/* --- The question, the reply-by date, and step titles --- */
.popup-intro {
  display: grid;                       /* Stacked lines… */
  gap: 0.35rem;                        /* …close together… */
  justify-items: center;               /* …centred. */
  padding: 0 var(--popup-pad);         /* Inside the side padding. */
  margin-top: -0.35rem;                /* Tucked under the greeting. */
  text-align: center;                  /* Centred like the card. */
}
.popup-subtitle, .popup-step-title {
  font-family: var(--font-caps);       /* Tracked display caps, like the card's small lines. */
  font-size: 0.9375rem;                /* Small caps size. */
  letter-spacing: var(--track);        /* Card tracking. */
  padding-inline-start: var(--track);  /* Re-centre despite trailing tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--rose-deep);             /* Readable mauve (small text). */
  line-height: 1.5;                    /* Airy when it wraps. */
}
.popup-step-title { letter-spacing: var(--track-sm); padding-inline-start: var(--track-sm); } /* "A few more details (optional)" is longer: lighter tracking. */
.popup-deadline { font-size: var(--fs-sm); font-style: italic; color: var(--ink-soft); } /* "Kindly reply by December 11, 2026." in quiet italics. */
.popup-lede {
  max-width: 27rem;                    /* A comfortable measure… */
  margin-inline: auto;                 /* …centred… */
  padding: 0 var(--popup-pad);         /* …inside the side padding. */
  font-size: var(--fs-md);             /* Reading size. */
  line-height: 1.55;                   /* Comfortable rhythm. */
  text-align: center;                  /* Centred like the card. */
  color: var(--ink);                   /* Charcoal. */
}
.popup-intro .popup-lede { padding: 0; } /* Already inside the intro's padding. */

/* --- Rows: one per person, two large choices each --- */
.popup-body-inner {
  display: grid;                       /* Messages, rows, fields… */
  gap: 1.25rem;                        /* …evenly spaced… */
  padding: 0 var(--popup-pad);         /* …inside the side padding. */
}
.popup-people { border-top: 1px solid var(--line); } /* A hairline above the first person. */
.popup-person {
  display: grid;                       /* Name above the choices. */
  gap: 0.7rem;                         /* Close enough to read as one row. */
  min-width: 0;                        /* Fieldsets otherwise refuse to shrink. */
  margin: 0;                           /* Reset. */
  padding: 1.1rem 0 1.2rem;            /* Air above and below. */
  border: 0;                           /* No fieldset box… */
  border-bottom: 1px solid var(--line); /* …a hairline between people instead. */
}
.popup-person-name {
  float: left;                         /* Lets the legend sit inside the grid flow. */
  width: 100%;                         /* Full row. */
  padding: 0;                          /* Reset. */
  font-size: 1.1875rem;                /* The person's name, a little larger than body text. */
  font-weight: 500;                    /* Slightly heavier. */
  text-align: center;                  /* Centred like the card. */
  color: var(--ink);                   /* Charcoal. */
}
.rsvp-popup .popup-choices { grid-template-columns: 1fr; } /* Stacked full-width choices on narrow sheets (the page's own .choices rule is for the section). */
@container rsvp-popup (min-width: 32rem) {
  .rsvp-popup .popup-choices { grid-template-columns: 1fr 1fr; } /* Side by side when the pop-up is wide enough for both labels. */
}
.rsvp-popup .choice { min-height: 56px; padding: 0.55rem 1rem; } /* Big, comfortable tap targets. */
.rsvp-popup .choice span { min-width: 0; overflow-wrap: anywhere; } /* A long label wraps inside its tile (Spanish, 320px screens). */
.rsvp-popup .guest .choices { grid-template-columns: 1fr 1fr; } /* "Yes" / "No" for a guest are short: always side by side. */
.popup-person .field-error, .popup-error { text-align: center; } /* Messages centred under centred rows. */
/* The details step ("Bringing a guest?", the guest's name, the message) is centred like the rest of the sheet:
   one alignment per sheet, under the centred greeting and title (typed text inside the boxes stays left-aligned). */
.rsvp-popup .guest legend,
.rsvp-popup .field label,
.rsvp-popup .field .hint,
.rsvp-popup .field .field-error { text-align: center; } /* Legends, labels, hints and errors centred like the greeting. */
.popup-notice { max-width: none; }     /* The "someone updated your RSVP" note spans the column. */
.popup-already {
  font-family: var(--font-caps);       /* Tracked caps… */
  font-size: var(--fs-xs);             /* …small… */
  letter-spacing: var(--track-sm);     /* …lightly tracked… */
  text-transform: uppercase;           /* …capitals… */
  color: var(--rose-deep);             /* …in the readable mauve… */
  text-align: center;                  /* …centred above the summary… */
  text-wrap: balance;                  /* …and, when it wraps, in even lines (never one word alone). */
}
.rsvp-popup .summary li { justify-items: center; text-align: center; } /* Everyone's answers, centred like the card. */

/* --- The button bar: stays in reach at the bottom while the sheet scrolls --- */
.popup-actions {
  position: sticky;                    /* Pinned to the bottom of the scrolling pop-up… */
  bottom: 0;                           /* …while there is more to scroll. */
  z-index: 1;                          /* Above the rows scrolling beneath it. */
  display: flex;                       /* Buttons in a row… */
  flex-wrap: wrap;                     /* …wrapping when narrow… */
  justify-content: center;             /* …centred. */
  gap: 0.75rem;                        /* Space between buttons. */
  margin-top: auto;                    /* At the bottom of a full-height sheet. */
  padding: 1rem var(--popup-pad) calc(1.1rem + env(safe-area-inset-bottom, 0px)); /* Clear of the home indicator on notched phones. */
  border-top: 1px solid var(--line);   /* Hairline above. */
  background: var(--paper);            /* Rows scroll under white paper, not through it. */
}
.popup-actions .btn { min-width: 10.5rem; } /* Even, generous buttons. */

/* --- The small pop-up: an unknown link, or no connection --- */
.rsvp-popup[data-size="small"] { width: min(27rem, calc(100% - 2 * var(--gutter))); } /* A small card on every screen. */
.popup-small { padding-top: 1.5rem; text-align: center; } /* Air above the blossom. */
.popup-small .popup-error { padding: 0 var(--popup-pad); } /* Inside the side padding. */
.popup-small .popup-actions { position: static; } /* Short: nothing scrolls under it. */
.popup-flower {
  width: 72px;                         /* A small blossom… */
  height: auto;                        /* …in proportion… */
  margin-inline: auto;                 /* …centred… */
  -webkit-mask-image: radial-gradient(closest-side, #000 70%, transparent); /* …with softened crop edges (WebKit). */
  mask-image: radial-gradient(closest-side, #000 70%, transparent);         /* …with softened crop edges. */
}
.popup-title {
  font-family: var(--font-caps);       /* Tracked display caps. */
  font-size: 1.375rem;                 /* Large text, so the card mauve is readable. */
  letter-spacing: var(--track);        /* Card tracking. */
  padding-inline-start: var(--track);  /* Re-centre despite trailing tracking. */
  text-transform: uppercase;           /* Caps. */
  color: var(--rose);                  /* Card mauve (large display text). */
  line-height: 1.3;                    /* Compact. */
}

/* --- Phones: a full-height sheet that slides up, with full-width stacked buttons --- */
@media (max-width: 599px) {
  .rsvp-popup[data-size="sheet"] {
    width: 100%;                       /* Edge to edge… */
    height: 100%;                      /* …top to bottom (older browsers)… */
    height: 100dvh;                    /* …of the visible screen, toolbars included. */
    max-height: none;                  /* No cap. */
    border: 0;                         /* No edge needed. */
    border-radius: 0;                  /* Square, like a screen. */
  }
  .rsvp-popup[data-size="sheet"][open] { animation-name: popup-sheet-in; } /* Slides up instead of rising. */
  .rsvp-popup[data-size="sheet"] .popup-form { display: flex; flex-direction: column; min-height: 100%; } /* The form is at least as tall as the sheet… */
  .rsvp-popup[data-size="sheet"] .popup-body { display: flex; flex-direction: column; flex: 1 0 auto; } /* …its step area takes the rest… */
  .rsvp-popup[data-size="sheet"] .popup-step { flex: 1 0 auto; } /* …and the step fills it, so the buttons sit at the bottom of the screen. */
  .popup-actions { flex-direction: column; } /* The main button above the other (DOM order). */
  .popup-actions .btn { width: 100%; min-height: 52px; } /* Full-width, thumb-sized buttons. */
}
@media (max-width: 599px) and (max-height: 700px) {
  .popup-actions { gap: 0.5rem; padding-block: 0.7rem calc(0.8rem + env(safe-area-inset-bottom, 0px)); } /* Short phones: a slimmer bar leaves more of the screen for the answers. */
  .popup-actions .btn { min-height: 48px; } /* Still a full thumb target. */
}
@keyframes popup-sheet-in {
  from { opacity: 0.4; transform: translateY(32px); } /* Low and faint… */
  to { opacity: 1; transform: none; }  /* …in place. */
}
@media (prefers-reduced-motion: reduce) {
  .rsvp-popup, .rsvp-popup::backdrop { animation: none !important; } /* Opens and closes without any motion. */
}

/* ==========================================================================
   6. UTILITIES
   Small helpers used across pages.
   ========================================================================== */
.vh {
  position: absolute !important;       /* Visually hidden but read by screen readers. */
  width: 1px;                          /* Tiny box. */
  height: 1px;                         /* Tiny box. */
  margin: -1px;                        /* Pulled out of flow. */
  padding: 0;                          /* No padding. */
  overflow: hidden;                    /* Clip contents. */
  clip: rect(0 0 0 0);                 /* Fully clipped. */
  white-space: nowrap;                 /* No wrapping. */
  border: 0;                           /* No border. */
}
.center { text-align: center; }        /* Centered text block. */
.nowrap { white-space: nowrap; }       /* Keep short phrases together. */
.noscript-note { max-width: 32rem; margin: 3rem auto; padding-inline: var(--gutter); text-align: center; color: var(--ink-soft); } /* The only text shown when scripts are switched off. */

/* ==========================================================================
   7. MOTION
   One gentle page-switch fade (opacity .35 → 1, 8px rise, 320ms). Content is
   complete at rest — nothing waits invisible. Reduced-motion users get none.
   ========================================================================== */
@keyframes page-in {
  from { opacity: 0.35; transform: translateY(8px); } /* Start slightly faded and lowered… */
  to { opacity: 1; transform: none; }  /* …settle fully visible in place. */
}
.page.is-entering { animation: page-in 320ms ease-out; } /* Applied by the router on page switches. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;        /* No page-switch animation. */
    transition: none !important;       /* No hover transitions. */
    scroll-behavior: auto !important;  /* Instant scrolling. */
  }
}

/* ==========================================================================
   8. PHONE LAYOUT (≤ 699px) — the app-like mobile version.
   The same page and the same content, re-arranged for one thumb: a
   compact sticky header that keeps only the "I & D" monogram, a fixed bottom
   tab bar (Home · Schedule · FAQs · RSVP) with small line icons, full-width
   stacked buttons, outlined half-width link buttons, and a scrollable row of
   FAQ category chips. Everything phone-only is hidden by default here and
   switched on inside the one max-width: 699px block, so tablets and desktops
   (≥ 700px) render exactly as before.
   ========================================================================== */

/* --- Phone-only pieces: hidden unless the phone block below shows them --- */
.tab-bar { display: none; }            /* The bottom tab bar exists only on phones. */
.faq-chips { display: none; }          /* The FAQ category chips exist only on phones. */
.label-phone { display: none; }        /* Short phone button labels stay out of the wide layouts. */
.label-extra { display: none; }        /* So does their phone-only hidden suffix (wide layouts read the full label). */

@media (max-width: 699px) {
  /* --- Compact header: the monogram alone, ~52px tall, still sticky --- */
  .site-header {
    display: flex;                     /* Lets the monogram center vertically… */
    align-items: center;               /* …in the middle of the bar… */
    justify-content: center;           /* …and horizontally. */
    min-height: 52px;                  /* Compact phone header height. */
    padding-block: 0;                  /* The min-height alone sets the size. */
  }
  .site-header nav { display: none; }  /* The top nav row gives way to the bottom tab bar on phones. */
  .draft-toggle { min-height: 48px; }  /* Preview banner's "Show guest view" button: a full 48px thumb target. */
  .monogram {
    font-size: 2rem;                   /* Slightly smaller mark on phones. */
    line-height: 48px;                 /* One 48px line: the mark sits centered in it, and all 48px of the 52px header is the tap target */
                                       /*   (a line height, not flexbox, so the spaces in "I & D" are kept). */
    padding-block: 0;                  /* The line height alone sets the size. */
  }

  /* --- Bottom tab bar: fixed, white, hairline top edge, soft upward shadow --- */
  .tab-bar {
    display: block;                    /* Shown on phones only. */
    position: fixed;                   /* Pinned to the bottom of the screen… */
    left: 0;                           /* …from the left edge… */
    right: 0;                          /* …to the right edge… */
    bottom: 0;                         /* …resting on the bottom edge. */
    z-index: 40;                       /* Above page content, the header (20) and the side bands (30). */
    background: var(--paper);          /* White card stock, like the header. */
    border-top: 1px solid var(--line); /* Hairline top border. */
    box-shadow: 0 -8px 20px -14px rgba(64, 61, 62, 0.22); /* A very soft upward shadow. */
    padding-bottom: env(safe-area-inset-bottom, 0px); /* Clears the home indicator on notched phones. */
    padding-inline: env(safe-area-inset-left, 0px) env(safe-area-inset-right, 0px); /* Clears the notch in landscape. */
    transition: transform 200ms ease;  /* Slides smoothly away while typing (none under reduced motion). */
  }
  .site.is-typing .tab-bar {
    transform: translateY(calc(100% + 24px)); /* While a field has focus: fully out of view, shadow included. */
  }
  .tab-list {
    list-style: none;                  /* No bullets. */
    margin: 0;                         /* Reset list margins. */
    padding: 0;                        /* Reset list padding. */
    display: grid;                     /* Four equal tabs… */
    grid-template-columns: repeat(4, minmax(0, 1fr)); /* …sharing the width evenly. */
    height: 64px;                      /* The bar's height above the safe-area padding. */
  }
  .tab-link {
    position: relative;                /* Anchor for the active indicator line. */
    display: flex;                     /* Icon above label… */
    flex-direction: column;            /* …stacked vertically… */
    align-items: center;               /* …centered horizontally… */
    justify-content: center;           /* …and vertically. */
    gap: 5px;                          /* Space between icon and label. */
    height: 100%;                      /* The whole tab is the tap target (64px ≥ 48px). */
    color: var(--ink-soft);            /* Inactive tabs in the secondary ink. */
    text-decoration: none;             /* A tab, not a text link. */
    -webkit-tap-highlight-color: transparent; /* No grey flash: the tab has its own :active wash. */
  }
  .tab-icon {
    width: 22px;                       /* 22px line icon… */
    height: 22px;                      /* …square. */
    fill: none;                        /* Line drawings, no fills. */
    stroke: currentColor;              /* Icons take the tab's text color (active/inactive). */
    stroke-width: 1.5;                 /* Fine line, like the card's hairlines. */
    stroke-linecap: round;             /* Soft line ends. */
    stroke-linejoin: round;            /* Soft corners. */
    flex: none;                        /* Never squashed. */
  }
  .tab-label {
    font-family: var(--font-caps);     /* Gilda Display caps, like the rest of the navigation. */
    font-size: 11px;                   /* Small tab label. */
    line-height: 1;                    /* Tight, so icon + label sit as one unit. */
    letter-spacing: 0.12em;            /* Light tracking. */
    padding-inline-start: 0.12em;      /* Re-centers the label despite its trailing tracking. */
    text-transform: uppercase;         /* Caps. */
  }
  .tab-label .nocase { text-transform: none; } /* Keeps the lowercase "s" of "FAQs". */
  @media (max-width: 340px) {
    .tab-label { font-size: 10px; letter-spacing: 0.04em; padding-inline-start: 0.04em; } /* Narrowest phones: lighter tracking and type keep the Spanish labels apart (about 8px of air each side). */
  }
  .tab-link[aria-current="page"] { color: var(--rose-deep); } /* Active tab in the readable mauve. */
  .tab-link[aria-current="page"]::before {
    content: "";                       /* Decorative indicator line. */
    position: absolute;                /* Laid along… */
    top: -1px;                         /* …the top edge of the tab, over the bar's hairline… */
    left: 24%;                         /* …centered, a little narrower… */
    right: 24%;                        /* …than the tab itself. */
    height: 2px;                       /* 2px line. */
    background: var(--rose);           /* Card mauve (ornament use). */
  }
  .tab-link:active { background: var(--paper-blush); } /* Blush wash while pressed. */
  .tab-link:focus-visible {
    outline: 2px solid var(--rose-deep); /* Visible keyboard focus ring… */
    outline-offset: -5px;              /* …drawn inside the tab so the screen edge never clips it. */
  }

  /* --- Nothing hides behind the bar: the footer ends above it --- */
  .site-footer { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px) + 16px); } /* Bar height + safe area + air. */

  /* --- Buttons: no grey tap flash, and a pressed state instead of sticky hover --- */
  .btn { -webkit-tap-highlight-color: transparent; } /* Buttons have their own :active states below. */
  .btn-primary:active { background: var(--rose-deeper); border-color: var(--rose-deeper); } /* Pressed: deeper mauve. */
  .btn-secondary:active { background: var(--paper-blush); } /* Pressed: blush wash. */

  /* --- Outlined link buttons (Home calendar/directions, Schedule maps, "Good to know" links) --- */
  .link-buttons {
    display: grid;                     /* Two half-width buttons… */
    grid-template-columns: 1fr 1fr;    /* …side by side. */
    gap: 0.75rem;                      /* Same spacing as the button stack. */
    align-items: stretch;              /* Paired buttons share one height (the text row aligns baselines). */
    width: 100%;                       /* Span the column. */
  }
  .link-buttons .dot { display: none; } /* The middle dot separator is replaced by the gap. */
  .link-buttons .break { display: none; } /* The grid already puts each pair on its own row. */
  .link-buttons a, .plan-links a {
    display: flex;                     /* Centers the label in the box. */
    align-items: center;               /* Vertical centering. */
    justify-content: center;           /* Horizontal centering. */
    min-height: 48px;                  /* Comfortable tap target. */
    padding: 0.6rem 0.4rem;            /* Slim side padding: half-width buttons at 360px still fit one line. */
    font-family: var(--font-caps);     /* Tracked display caps, like the other buttons. */
    font-size: 12px;                   /* Same size as the FAQ chips; "Add to calendar" fits at 360px. */
    letter-spacing: 0.14em;            /* Same tracking as the FAQ chips. */
    text-transform: uppercase;         /* Caps. */
    text-align: center;                /* A wrapped label stays centered. */
    line-height: 1.2;                  /* Tight label leading. */
    text-decoration: none;             /* Buttons, not underlined links. */
    color: var(--rose-deep);           /* Outlined mauve, like the secondary button. */
    background: var(--paper);          /* White fill (also on the blush "Good to know" band). */
    border: 1px solid var(--rose-deep);/* Mauve outline. */
    border-radius: 2px;                /* Square-ish corners. */
    -webkit-tap-highlight-color: transparent; /* Own :active wash instead of the grey flash. */
  }
  .link-buttons a:active, .plan-links a:active { background: var(--paper-blush); } /* Pressed: blush wash. */
  @media (max-width: 379px) {
    .link-buttons a { letter-spacing: 0.08em; } /* Smallest phones: lighter tracking keeps side space even in the half-width pair. */
  }
  .label-phone { display: inline; }    /* Phones show the short button label, which starts the accessible name… */
  .label-full { display: none; }       /* …and the wide-screen wording drops out of the name (WCAG 2.5.3 label in name)… */
  .label-extra {                       /* …while a hidden suffix keeps any detail the short label leaves out ("— Google Calendar"). */
    display: inline;                   /* Present on phones only (display: none on wider screens). */
    position: absolute;                /* Out of the layout. */
    width: 1px;                        /* Tiny box. */
    height: 1px;                       /* Tiny box. */
    margin: -1px;                      /* Pulled out of flow. */
    overflow: hidden;                  /* Clip contents. */
    clip: rect(0 0 0 0);               /* Fully clipped. */
    white-space: nowrap;               /* No wrapping. */
  }

  /* --- HOME: full-width stacked buttons, link buttons below --- */
  .essential-link .link-pair { justify-content: center; align-items: center; } /* The pair is centered in the cell and its links keep 48px tap boxes. */
  .link-pair .dot { display: none; } /* Phones: the gap between the 48px tap boxes separates the two apps, so no dot can dangle at a wrap. */
  .link-pair .link-apps { flex-wrap: wrap; align-items: center; justify-content: inherit; column-gap: 1.25rem; } /* Phones: a clear gap keeps the two apps apart without a dot, and they may wrap cleanly on the narrowest screens. */
  .essential-link a {
    display: inline-flex;              /* A box that can be taller than its one line of text… */
    align-items: center;               /* …with the underlined label centered vertically… */
    justify-content: center;           /* …and horizontally… */
    min-height: 48px;                  /* …48px tall, a full thumb target… */
    min-width: 48px;                   /* …and never narrower than 48px ("RSVP"). */
    padding-inline: 0.5rem;            /* A little extra hit area either side of the words. */
  }
  .card-place a { position: relative; } /* Anchor for the invisible hit extender below (the card artwork layout is untouched). */
  .card-place a::after {
    content: "";                       /* Invisible box… */
    position: absolute;                /* …laid over the address link… */
    inset: -8px -6px;                  /* …reaching 8px above/below and 6px either side: a ≥48px-tall tap area. */
  }
  .welcome .actions {
    flex-direction: column;            /* RSVP above "See the schedule" (DOM order)… */
    width: 100%;                       /* …both spanning the column. */
  }
  .welcome .actions .btn { width: 100%; min-height: 52px; } /* Full-width, thumb-sized buttons. */

  /* --- SCHEDULE: tighter events, map buttons, full-width plan links --- */
  .schedule-grid { margin-top: 1.75rem; } /* A little less space under the page header. */
  .event { gap: 0.4rem; padding-block: 1.4rem; } /* Tighter event rows on a small screen. */
  .event-name { font-size: 1.25rem; letter-spacing: 0.16em; } /* Phones: event names a step smaller than the section title. */
  .event-time.is-pending { padding-top: 0; } /* The "to add" block needs no cap-line alignment when stacked. */
  .event-body { gap: 0.45rem; }         /* Slightly tighter details. */
  .event-body .link-buttons { margin-top: 0.35rem; } /* Map buttons sit just clear of the address. */
  .plan-links { gap: 0.6rem; }          /* Space between the stacked full-width buttons. */

  /* --- FAQS: category chips that scroll inside their own row --- */
  .faq-chips {
    display: flex;                     /* One row of chips… */
    gap: 0.5rem;                       /* …with small gaps… */
    overflow-x: auto;                  /* …that scrolls sideways inside itself (never the page). */
    margin: 1.25rem calc(var(--gutter) * -1) 0; /* Bleeds to the screen edges like the card corners above. */
    padding: 4px var(--gutter);        /* Keeps the first/last chip on the gutter; room for focus rings. */
    scroll-padding-inline: var(--gutter); /* Keyboard-scrolled chips stop on the gutter too. */
    overscroll-behavior-x: contain;    /* A sideways fling never drags the page or triggers "back". */
    scrollbar-width: none;             /* No scrollbar strip (Firefox). */
  }
  /* Soft 28px edge fades hint there are more chips — only on an edge that really has more (JS sets the classes). */
  .faq-chips.has-more-end {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent); /* Right fade only (WebKit). */
    mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent);         /* Right fade only. */
  }
  .faq-chips.has-more-start {
    -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 28px), transparent);  /* Left fade only (WebKit). */
    mask-image: linear-gradient(to left, #000 calc(100% - 28px), transparent);          /* Left fade only. */
  }
  .faq-chips.has-more-start.has-more-end {
    -webkit-mask-image: linear-gradient(to right, transparent, #000 28px, #000 calc(100% - 28px), transparent); /* Both edges (WebKit). */
    mask-image: linear-gradient(to right, transparent, #000 28px, #000 calc(100% - 28px), transparent);         /* Both edges. */
  }
  .faq-chips::-webkit-scrollbar { display: none; } /* No scrollbar strip (WebKit). */
  .faq-chip {
    flex: none;                        /* Chips keep their natural width. */
    min-height: 40px;                  /* 40px tall pills. */
    padding: 0 0.95rem;                /* Side padding around the label. */
    font-family: var(--font-caps);     /* Tracked display caps. */
    font-size: 12px;                   /* Small caps label. */
    letter-spacing: 0.14em;            /* Label tracking. */
    text-transform: uppercase;         /* Caps. */
    white-space: nowrap;               /* One line per chip. */
    color: var(--rose-deep);           /* Readable mauve. */
    background: var(--paper);          /* White fill. */
    border: 1px solid var(--rose-deep);/* Outlined, square-ish pill. */
    border-radius: 2px;                /* Square-ish corners, per the design system. */
    cursor: pointer;                   /* It's a button. */
    -webkit-tap-highlight-color: transparent; /* Own :active wash instead of the grey flash. */
  }
  .faq-chip { position: relative; }   /* Anchor for the hit extender below. */
  .faq-chip::after {
    content: "";                       /* Invisible box… */
    position: absolute;                /* …laid over the chip… */
    inset: -5px 0;                     /* …4px past the outline top and bottom (inset counts from inside the 1px border): 48px tall, within the row's 4px padding so its clip never cuts it. */
  }
  .faq-chip:active { background: var(--paper-blush); } /* Pressed: blush wash. */
  .faq-chip:focus-visible { outline-offset: 2px; } /* Ring stays inside the row's padding. */
  .faq-groups { margin-top: 1.75rem; }  /* Groups start a little closer under the chips. */
  .faq-label { scroll-margin-top: calc(var(--header-h, 53px) + 1rem); } /* Chip jumps land clear of the sticky header. */
  .faq summary { min-height: 56px; }   /* Every question row is a generous tap target. */
  .faq .link-pair { align-items: center; } /* Lead-in and links share a centre line next to the 48px tap boxes. */
  .faq .text-links a {
    display: inline-flex;              /* A box that can be taller than its one line of text ("Get directions" under an answer)… */
    align-items: center;               /* …with the underlined label centered vertically, so it looks unchanged… */
    min-height: 48px;                  /* …and 48px tall, a full thumb target like the Home link buttons. */
  }

  /* --- RSVP: step buttons full width and stacked --- */
  .step-actions { flex-direction: column; } /* Back above Send RSVP (DOM order). */
  .rsvp-step .btn { width: 100%; min-height: 52px; } /* Full-width, thumb-sized step buttons. */
}

/* Small phones: each event shows its name first, then the bold time, then the details. */
@media (max-width: 599px) {
  .event-body { display: contents; }                    /* Let the name and details join the event's own stack… */
  .event-body > .event-name { order: 1; }               /* …name first, */
  .event-time { order: 2; }                             /* …then the bold time, */
  .event-body > :not(.event-name) { order: 3; }         /* …then venue, address, buttons and notes. */
}

/* --- Language switch (English | Español), top right of the header --- */
.lang-switch {
  position: absolute;                  /* Pinned to the header's right edge. */
  top: 0.75rem;                        /* Level with the monogram. */
  right: var(--gutter);                /* Same side gutter as the page. */
  display: flex;                       /* The two words and the divider in a row. */
  align-items: center;                 /* Divider centered on the words. */
  gap: 0.15rem;                        /* Tight, they read as one control. */
  font-family: var(--font-caps);       /* Same tracked caps as the nav. */
  font-size: 0.72rem;                  /* Small, quiet. */
  letter-spacing: 0.08em;              /* Light tracking. */
}
.lang-btn {
  appearance: none;                    /* Plain text buttons. */
  background: none;                    /* No fill. */
  border: 0;                           /* No box. */
  border-bottom: 1.5px solid transparent; /* Space for the active underline. */
  padding: 0.55rem 0.3rem;             /* Comfortable tap area. */
  font: inherit;                       /* Inherit the caps font. */
  letter-spacing: inherit;             /* …and tracking. */
  text-transform: uppercase;           /* Caps like the nav. */
  color: var(--ink-soft);              /* Quiet when inactive. */
  cursor: pointer;                     /* Clickable. */
}
.lang-btn:hover { color: var(--rose-deep); }               /* Mauve on hover. */
.lang-btn[aria-pressed="true"] { color: var(--rose-deep); border-bottom-color: var(--rose-deep); } /* The language showing. */
.lang-sep { color: var(--line); }      /* Soft divider. */
.lang-short { display: none; }          /* Short "EN | ES" only on small phones. */
@media (max-width: 420px) { .lang-full { display: none; } .lang-short { display: inline; } } /* Keeps the switch clear of the monogram. */
@media (max-width: 699px) { .lang-switch { top: 50%; transform: translateY(-50%); right: 0.6rem; font-size: 0.68rem; } } /* Phones: centered in the 52px header. */
