/* Built from site/assets/css/ by tools/build-css.js — edit those, not this. */

/* ═══ 01-base.css ═══ */
/* ══════════════════════════════════════════════════════════════
   Shared defaults. Every style sets its own look on top: Postcard
   below, the paper styles in paper-themes.css.
   ══════════════════════════════════════════════════════════════ */
:root{
  --ink:#ffffff;
  --muted:#f0f0f0;
  --accent:#7ecb9a;
  --accent2:#a8d8c0;
  --namesFont:"Alex Brush",cursive;
  --btnShadow:0 12px 36px rgba(0,0,0,.30);
}

/* ═══ 02-postcard.css ═══ */
/* ══════════════════════════════════════════════════════════════
   THEME: Postcard
   bg:#f3eadc (dot texture)  paper:#fffaf0  ink:#1f1812
   accent:#b83568  accent-deep:#7c1e3c
   ══════════════════════════════════════════════════════════════ */
body[data-theme="postcard"]{
  /* Single, evenly-tinted cream (pinkish — same hue as the old radial
     wash in the top-left corner). Was two-tone: plain cream + a soft
     pink radial that made the top corners look different from the rest
     of the page. Now flat across all sections. Dot texture preserved. */
  background:#f0e1d6;
  background-image:
    radial-gradient(circle at 1px 1px,rgba(31,24,18,.05) 1px,transparent 0);
  background-size:5px 5px;
}

/* Hero */
body[data-theme="postcard"] .slide[data-slide="0"]{ position:relative;overflow:hidden; }
body[data-theme="postcard"] .slide[data-slide="0"]::after{
  content:'';position:absolute;inset:0;
  background:radial-gradient(ellipse at center,transparent 30%,rgba(0,0,0,.45) 100%),
             linear-gradient(180deg,rgba(0,0,0,.2) 0%,transparent 40%,rgba(0,0,0,.65) 100%);
  pointer-events:none;z-index:0;
}
body[data-theme="postcard"] .slide[data-slide="0"] .card{ position:relative;z-index:1; }

/* Names */
body[data-theme="postcard"] .namesScript{ font-style:italic;font-weight:300;letter-spacing:-.02em; }
body[data-theme="postcard"] .amp{ color:#e8c9c0; }

/* All content cards — paper with border (no shadow per design). */
body[data-theme="postcard"] .card:not(.cardHero){
  background:#fffaf0;
  border:1px solid rgba(31,24,18,.16);
  box-shadow:none;
  backdrop-filter:none;max-width:min(720px,92vw);
}

/* RSVP card specifically — dashed inner border. Background stays
   transparent so the body's dotted texture (the one behind the letter
   slide + polaroid strips) shows through and the RSVP page reads as
   the same paper, not a flat solid block. */
body[data-theme="postcard"] .slide[data-slide="rsvp"]{ background:transparent; }
body[data-theme="postcard"] .slide[data-slide="rsvp"] .card{ position:relative; }
body[data-theme="postcard"] .slide[data-slide="rsvp"] .card::before{
  content:'';position:absolute;inset:12px;
  border:1px dashed rgba(31,24,18,.32);pointer-events:none;z-index:0;
}
body[data-theme="postcard"] .slide[data-slide="rsvp"] .card .content{ position:relative;z-index:1; }

/* Section text */
body[data-theme="postcard"] .sectionTitle{
  font-family:"Cormorant Garamond",Georgia,serif;font-style:italic;font-weight:300;
  font-size:clamp(40px,6vw,80px);color:#1f1812;text-shadow:none;letter-spacing:-.01em;line-height:1;
}
body[data-theme="postcard"] .body{
  font-family:"Cormorant Garamond",Georgia,serif;font-size:18px;font-weight:400;
  line-height:1.65;color:#3a2e22;text-shadow:none;
}
body[data-theme="postcard"] .divider{ background:rgba(31,24,18,.16); }

/* Form labels */
body[data-theme="postcard"] #rsvpForm label{
  font-size:10.5px;letter-spacing:.28em;text-transform:uppercase;color:#7c6852;
}
body[data-theme="postcard"] select{
  background:rgba(255,250,240,.9);color:#1f1812;border:1px solid rgba(31,24,18,.18);
}

/* Name inputs */
body[data-theme="postcard"] input:not([readonly]):not(.prefsDietInput):not([type="radio"]){
  font-family:"Cormorant Garamond",Georgia,serif;font-size:18px;
  background:transparent;border:0;border-bottom:1px solid rgba(31,24,18,.18);
  border-radius:0;padding:10px 0;color:#1f1812;outline:none;
}
body[data-theme="postcard"] input:not([readonly]):not(.prefsDietInput):not([type="radio"])::placeholder{ color:#7c6852;opacity:.6; }
body[data-theme="postcard"] input:not([readonly]):not(.prefsDietInput):not([type="radio"]):focus{ border-bottom-color:#b83568; }

/* Guest cards — paper-2 bg with dashed border */
body[data-theme="postcard"] .nameList{ gap:18px;margin-bottom:8px; }
body[data-theme="postcard"] .nameItem{
  background:#fbf3e1;
  border:1px dashed rgba(31,24,18,.32);
  border-radius:4px;
  padding:22px 22px 14px;
  grid-template-columns:1fr auto;
}
body[data-theme="postcard"] .nameItem:first-child{ padding-top:22px; }
body[data-theme="postcard"] .nameItem:last-child{
  border-bottom:1px dashed rgba(31,24,18,.32);padding-bottom:14px;
}
body[data-theme="postcard"] .nameItem:hover{ border-color:#b83568; }
body[data-theme="postcard"] .nameItem input[readonly]{
  background:transparent;color:#1f1812;border-bottom:1px solid rgba(31,24,18,.18);
  font-family:"Cormorant Garamond",Georgia,serif;font-size:18px;
  /* The base .nameItem input[readonly] rule (line 3181) sets
     font-weight:700 for non-themed contexts. Override to a lighter
     weight so postcard readonly names read as classical
     handwriting rather than a bold UI label. */
  font-weight:300;
  font-style:italic;
}
/* Match the section's "we can't wait to celebrate with you!" heading
   font on the editable name inputs too — Cormorant Garamond italic
   reads as a classical handwritten letter rather than a UI form
   field. Applies to both EN and FR. */
body[data-theme="postcard"] .nameItem input[data-name-input="1"]{
  font-family:"Cormorant Garamond",Georgia,serif;
  font-style:italic;
  font-weight:300;
  font-size:20px;
  letter-spacing:.005em;
  color:#1f1812;
}
body[data-theme="postcard"] .nameItem input[data-name-input="1"]::placeholder{
  font-style:italic;
  opacity:.5;
}

/* Attending choices */
body[data-theme="postcard"] .attendingChoice{
  border:2px solid rgba(31,24,18,.45);background:rgba(255,250,240,.95);
  color:#1f1812;font-size:26px;font-weight:600;letter-spacing:-.01em;
}
body[data-theme="postcard"] .attendingChoice:hover{ border-color:#7c1e3c; background:#fffaf0; }
body[data-theme="postcard"] .attendingChoiceEm{
  color:#1f1812;font-weight:700;font-size:11.5px;letter-spacing:.3em;opacity:1;
}
/* Selected = accent-deep deep claret */
body[data-theme="postcard"] .attendingChoice:has(input:checked){
  background:#7c1e3c;border-color:#7c1e3c;color:#fff7e8;
}
body[data-theme="postcard"] .attendingChoice:has(input:checked) .attendingChoiceEm{
  color:rgba(255,247,232,.75);
}

/* Meal picks */
body[data-theme="postcard"] .mealPickRow{ grid-template-columns:repeat(3,1fr); }
body[data-theme="postcard"] .mealPick{
  border:1px solid rgba(31,24,18,.18);background:#fffaf0;color:#3a2e22;
}
body[data-theme="postcard"] .mealPick:hover{ border-color:#3a2e22;color:#1f1812; }
body[data-theme="postcard"] .mealPick .mealLabel{
  font-family:"Cormorant Garamond",Georgia,serif;font-style:italic;font-size:18px;color:#1f1812;
  text-transform:none;letter-spacing:0;
}

body[data-theme="postcard"] .mealPick:has(input:checked){ background:#7c1e3c;border-color:#7c1e3c;color:#fff7e8; }
body[data-theme="postcard"] .mealPick:has(input:checked) .mealLabel{ color:#fff7e8; }

body[data-theme="postcard"] .mealPick:has(input:checked) svg{ opacity:1;color:#fff7e8; }

/* Dietary call-out — paper bg + claret rail to stand out from meal picks */
body[data-theme="postcard"] .prefsField{
  background:rgba(184,53,104,.06);
  border:1px solid rgba(31,24,18,.16);
  border-left:3px solid #7c1e3c;
}
body[data-theme="postcard"] .prefsFieldLabel{
  font-family:"Outfit","Inter",sans-serif;
  color:#7c1e3c;
  font-weight:600;
  letter-spacing:.22em;
}
body[data-theme="postcard"] .nameItemPrefs .prefsDietInput{
  background:#fffaf0;
  border:1px solid rgba(31,24,18,.16);
  border-radius:3px;
  color:#1f1812;
  padding:10px 12px;
}
body[data-theme="postcard"] .nameItemPrefs .prefsDietInput::placeholder{ color:#7c6852;opacity:.7; }
body[data-theme="postcard"] .nameItemPrefs .prefsDietInput:focus{
  border-color:#b83568;background:#fff;
}

/* Add-guest button */
body[data-theme="postcard"] .nameActions{
  display:flex;align-items:center;justify-content:center;gap:8px;
  margin-top:20px;width:100%;background:transparent;
  border:1px dashed rgba(31,24,18,.32);border-radius:3px;padding:16px;
  font-family:"Outfit","Inter",sans-serif;font-size:11px;
  letter-spacing:.3em;text-transform:uppercase;color:#b83568;cursor:pointer;
  transition:border-color 220ms,background 220ms;
}
body[data-theme="postcard"] .nameActions:hover{
  border-color:#b83568;background:rgba(124,30,60,.04);
}
body[data-theme="postcard"] .nameActions .btnIcon{
  background:transparent;border:none;color:inherit;
  width:auto;height:auto;border-radius:0;padding:0;font-size:16px;
}
body[data-theme="postcard"] .nameActions .helper{
  font-family:"Outfit","Inter",sans-serif;font-size:11px;
  letter-spacing:.3em;text-transform:uppercase;color:inherit;
}

/* Submit button */
body[data-theme="postcard"] .rsvpFormActions{
  display:flex;flex-direction:column;align-items:center;margin-top:28px;
}
body[data-theme="postcard"] .btnPrimary{
  width:auto;padding:18px 44px;border-radius:60px;font-weight:400;
  background:#7c1e3c;box-shadow:none;
  font-family:"Outfit","Inter",sans-serif;font-size:11px;
  letter-spacing:.3em;text-transform:uppercase;
}
body[data-theme="postcard"] .btnPrimary:hover{ background:#b83568;transform:translateY(-1px); }
body[data-theme="postcard"] .btnPrimary:disabled{ opacity:.45;cursor:not-allowed;transform:none; }

body[data-theme="postcard"] .btnSecondary{
  background:transparent;border:1px solid rgba(31,24,18,.22);color:#3a2e22;
  border-radius:60px;font-size:11px;letter-spacing:.2em;
}
body[data-theme="postcard"] .btnSecondary:hover{ background:rgba(31,24,18,.05); }
body[data-theme="postcard"] .btnIcon{ background:transparent;border:none;color:#1f1812; }

body[data-theme="postcard"] .attendeeCount{
  font-family:"Outfit","Inter",sans-serif;font-size:10.5px;
  letter-spacing:.3em;text-transform:uppercase;color:#7c6852;
  text-align:center;margin-top:10px;
}

/* Confirmed state */
body[data-theme="postcard"] .rsvpConfirmedBadge.yes{ background:#7c1e3c; }
body[data-theme="postcard"] .rsvpConfirmedName{
  background:rgba(31,24,18,.05);border:1px solid rgba(31,24,18,.12);
  border-radius:4px;color:#1f1812;
  /* Match the editable name-input typography (Cormorant Garamond
     italic light, 20px) so the confirmation view feels like a
     continuation of the form rather than a different surface. */
  font-family:"Cormorant Garamond",Georgia,serif;
  font-style:italic;
  font-weight:300;
  font-size:20px;
  letter-spacing:.005em;
}
body[data-theme="postcard"] .rsvpPersonTag.menu{ background:#e8c9c0;color:#5a1c36; }
body[data-theme="postcard"] .rsvpPersonTag.diet{ background:#d4e8d0;color:#2a5a38; }
body[data-theme="postcard"] .err{ color:#b83568; }

/* ─── POSTCARD: scrapbook DOM (envelope, polaroid, letter, ticket, tag) ─── */
body[data-theme="postcard"]{
  --pc-bg:#f3eadc; --pc-bg2:#ece1ce; --pc-paper:#fffaf0; --pc-paper2:#fbf3e1;
  --pc-ink:#1f1812; --pc-ink2:#3a2e22; --pc-muted:#7c6852;
  --pc-accent:#b83568; --pc-accent-deep:#7c1e3c;
  --pc-line:rgba(31,24,18,.18); --pc-line-soft:rgba(31,24,18,.08); --pc-line-dashed:rgba(31,24,18,.32);
  --pc-serif:"Cormorant Garamond","EB Garamond",Georgia,serif;
  --pc-sans:"Outfit","Inter",ui-sans-serif,system-ui,sans-serif;
  --pc-script:"Pinyon Script","Snell Roundhand",cursive;
  --pc-mono:"JetBrains Mono",ui-monospace,"SF Mono",Menlo,monospace;
}

/* Suppress old postcard hero overlay + photo strip styles */
body[data-theme="postcard"] .slide[data-slide="0"]::after{ display:none; }
body[data-theme="postcard"] .slide[data-slide="0"]{ overflow:visible;background:transparent; }
body[data-theme="postcard"] .photoStrip{ background:transparent;height:auto;min-height:0; }

/* Shared text primitives */

body[data-theme="postcard"] .pcMonoMini{
  font-family:var(--pc-mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--pc-muted);
}
body[data-theme="postcard"] .pcScript{
  font-family:var(--pc-script);font-weight:400;color:var(--pc-accent);line-height:.95;
}
body[data-theme="postcard"] .pcScriptMd{
  font-family:var(--pc-script);font-size:38px;color:var(--pc-accent);line-height:1.08;
  /* Balance line breaks so multi-word titles like "With Joyful Hearts" wrap
     evenly across lines instead of leaving a single orphan word. */
  text-wrap:balance;
  display:inline-block;
  max-width:100%;
}
body[data-theme="postcard"] .pcScriptLg{ font-family:var(--pc-script);font-size:56px;color:var(--pc-accent);line-height:1; }
body[data-theme="postcard"] .pcScriptMini{ font-family:var(--pc-script);font-size:24px;color:var(--pc-accent);line-height:1; }
body[data-theme="postcard"] .pcEyebrow{
  font-family:var(--pc-mono);font-size:11px;letter-spacing:.32em;text-transform:uppercase;color:var(--pc-muted);
  display:inline-flex;align-items:center;gap:8px;
}
body[data-theme="postcard"] .pcEyebrow::before{
  content:"";display:inline-block;width:18px;height:1px;background:currentColor;opacity:.5;
}
body[data-theme="postcard"] .pcH2{
  font-family:var(--pc-serif);font-style:italic;font-weight:300;color:var(--pc-ink);
  font-size:clamp(42px,6vw,88px);line-height:1;letter-spacing:-.02em;margin:14px 0 0;text-wrap:balance;
}
body[data-theme="postcard"] .pcH2 em.pcScript{ font-size:1.15em;display:inline-block; }

/* Postmark */
body[data-theme="postcard"] .pcPostmark{
  position:relative;border:1.6px solid var(--pc-accent-deep);border-radius:50%;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  color:var(--pc-accent-deep);background:rgba(124,30,60,.03);
  font-family:var(--pc-serif);font-style:italic;text-align:center;flex-shrink:0;
}
body[data-theme="postcard"] .pcPostmark::before,
body[data-theme="postcard"] .pcPostmark::after{
  content:"";position:absolute;left:10%;right:10%;height:1px;background:var(--pc-accent-deep);opacity:.7;
}
body[data-theme="postcard"] .pcPostmark::before{ top:30%; }
body[data-theme="postcard"] .pcPostmark::after{ bottom:30%; }
body[data-theme="postcard"] .pcPm1, body[data-theme="postcard"] .pcPm3{
  font-family:var(--pc-sans);font-style:normal;font-size:9px;letter-spacing:.22em;text-transform:uppercase;
}
body[data-theme="postcard"] .pcPm2{
  font-family:var(--pc-serif);font-style:italic;line-height:1.05;margin:3px 0;
  display:flex;flex-direction:column;align-items:center;gap:1px;
  text-align:center;
}
body[data-theme="postcard"] .pcPm2 .pcPmDateLine{ font-size:11px; }
body[data-theme="postcard"] .pcPm2 .pcPmYearLine{ font-size:10px;opacity:.85; }

/* Stamp — perforated edge only, NOT throughout the body.
   We use background-images that draw small notches/half-circles along each
   border, leaving the interior fully solid so the landmark stays readable. */
body[data-theme="postcard"] .pcStamp{
  position:relative;aspect-ratio:3/4;background:var(--pc-paper);padding:8px;flex-shrink:0;
  box-shadow:0 4px 12px -4px rgba(0,0,0,.25);
  /* Edge perforations: 4 radial-gradient strips, one per edge, painted as
     tiny notches in the page-bg colour so they look like punched holes. */
  background-image:
    radial-gradient(circle 3.5px at 6px 0,  var(--pc-bg) 99%, transparent 100%),
    radial-gradient(circle 3.5px at 6px 100%, var(--pc-bg) 99%, transparent 100%),
    radial-gradient(circle 3.5px at 0 6px,  var(--pc-bg) 99%, transparent 100%),
    radial-gradient(circle 3.5px at 100% 6px, var(--pc-bg) 99%, transparent 100%);
  background-position:0 0, 0 100%, 0 0, 100% 0;
  background-size:12px 8px, 12px 8px, 8px 12px, 8px 12px;
  background-repeat:repeat-x, repeat-x, repeat-y, repeat-y;
  background-color:var(--pc-paper);
}
body[data-theme="postcard"] .pcStampInner{
  border:1.5px solid var(--pc-accent-deep);height:100%;padding:8px 6px;
  display:flex;flex-direction:column;align-items:center;text-align:center;color:var(--pc-accent-deep);
}
body[data-theme="postcard"] .pcStampPortrait{
  /* Portrait stamp — photo box sized so the three text rows (initials,
     date, city·country) always have room below it. flex:0 0 auto +
     overflow:hidden guarantees it can't grow past its computed height
     even when iOS Safari pads the inner flex item. */
  width:84%;aspect-ratio:1/1;margin:4px auto 6px;
  flex:0 0 auto;overflow:hidden;
  border:1.5px solid currentColor;background:rgba(184,53,104,.06);padding:3px;
}
body[data-theme="postcard"] .pcStampPortrait svg{ display:block;width:100%;height:100%; }
/* Stamp text — bumped weight + size + darker ink for legibility while keeping
   the deep-claret stamp aesthetic. */
body[data-theme="postcard"] .pcStampRow1{
  font-family:var(--pc-serif);font-style:italic;font-weight:600;font-size:15px;
  line-height:1.05;color:#1f1812;letter-spacing:-.005em;
}
body[data-theme="postcard"] .pcStampRow1 span{
  font-family:var(--pc-script);font-style:normal;font-weight:400;color:var(--pc-accent-deep);
}
body[data-theme="postcard"] .pcStampRow2{
  font-family:var(--pc-serif);font-style:italic;font-weight:500;font-size:12.5px;
  margin-top:4px;color:#3a2e22;
}
body[data-theme="postcard"] .pcStampValue{
  margin-top:auto;font-family:var(--pc-sans);font-weight:600;font-size:8.5px;
  letter-spacing:.16em;color:#1f1812;
  display:flex;flex-direction:column;align-items:center;gap:2px;
  text-align:center;
}
body[data-theme="postcard"] .pcStampValueCity,
body[data-theme="postcard"] .pcStampValueCountry{
  white-space:nowrap;max-width:100%;
  overflow:hidden;text-overflow:ellipsis;
  line-height:1.1;
}
body[data-theme="postcard"] .pcStampValueCountry{ opacity:.85; }

/* Envelope hero card */
body[data-theme="postcard"] .pcCardHero{
  background:transparent;border:none;box-shadow:none;backdrop-filter:none;
  padding:0;max-width:1280px;width:100%;
}
body[data-theme="postcard"] .pcPaper{
  position:relative;background:var(--pc-paper);border:1px solid var(--pc-line);border-radius:2px;
  padding:clamp(36px,6vw,80px) clamp(28px,6vw,80px) clamp(60px,10vh,100px);
  box-shadow:0 1px 0 rgba(255,247,232,.7) inset,
             0 30px 60px -28px rgba(31,24,18,.35),
             0 4px 14px -6px rgba(31,24,18,.2);
  background-image:radial-gradient(circle at 1px 1px,rgba(31,24,18,.04) 1px,transparent 0);
  background-size:4px 4px;
}
body[data-theme="postcard"] .pcPerfTop,
body[data-theme="postcard"] .pcPerfBottom{
  position:absolute;left:12px;right:12px;height:1px;border-top:1px dashed var(--pc-line-dashed);
}
body[data-theme="postcard"] .pcPerfTop{ top:14px; }
body[data-theme="postcard"] .pcPerfBottom{ bottom:14px; }

body[data-theme="postcard"] .pcEnvelopeGrid{
  display:grid;grid-template-columns:1.4fr auto;gap:clamp(32px,5vw,64px);
  grid-template-areas:
    "address stamp"
    "via     .";
  align-items:start;margin-bottom:clamp(40px,7vh,72px);
}
body[data-theme="postcard"] .pcEnvelopeGrid .pcAddress{ grid-area:address; }
body[data-theme="postcard"] .pcEnvelopeGrid .pcStamps {
  grid-area:stamp;
  /* Drop the stamp down a touch so it clears the centered
     "wedding invitation" label at the top. Same rotation/orientation
     handled inside .pcStamp via its own transform — only the vertical
     offset moves. */
  margin-top:28px;
}
body[data-theme="postcard"] .pcEnvelopeGrid .pcVia   { grid-area:via;justify-self:start;margin-top:18px; }
body[data-theme="postcard"] .pcAddressLabel{
  font-family:var(--pc-mono);font-size:10px;letter-spacing:.32em;text-transform:uppercase;
  color:var(--pc-muted);margin-bottom:12px;
}
body[data-theme="postcard"] .pcAddressName{
  display:flex;align-items:baseline;gap:16px;margin-bottom:26px;flex-wrap:wrap;
}
body[data-theme="postcard"] .pcAddressName .pcScript{
  font-family:var(--pc-script);font-size:clamp(32px,3.6vw,46px);color:var(--pc-accent);line-height:.9;
}

body[data-theme="postcard"] .pcAddressLines{
  display:flex;flex-direction:column;gap:14px;margin-bottom:28px;
}
/* Desktop: shorten the dashed rules so they don't stretch all the way
   across the wide address column. Mobile keeps full width (the column
   spans the whole paper already). When the household shares a surname
   and we render the single-line layout, the 50% cap is dropped so the
   combined name (e.g. "Jad & Karell EL-Asmar") doesn't truncate on
   narrow-desktop widths (880px–1237px). */
@media (min-width:681px){
  body[data-theme="postcard"] .pcAddressLines{ max-width:50%; }
  body[data-theme="postcard"] .pcAddressLines.pcAddressLines-shared{ max-width:none; }
}
/* Each handwritten line sits on its own dashed address rule.
   The dashed border stays edge-to-edge while the text itself is padded
   from the left so the script doesn't sit flush with the line start. */
body[data-theme="postcard"] .pcAddressLines .pcAddrHandwritten{
  padding:0 0 6px clamp(10px,1.6vw,22px);
  border-bottom:1px dashed var(--pc-line-dashed);
}

/* Defensive: never render an empty handwritten line, and cap visible
   lines at 3 (name / & / name). All three keep their dashed underline. */
body[data-theme="postcard"] .pcAddressLines .pcAddrHandwritten:empty{
  display:none;
}
body[data-theme="postcard"] .pcAddressLines .pcAddrHandwritten:nth-child(n+4){
  display:none;
}
/* "Blank" rule used when the household shares a surname → only the
   middle line carries the combined name, top + bottom rules stay
   visible but carry no text. The &nbsp; in the markup keeps the box
   from collapsing to zero height (which the :empty rule would hide). */
body[data-theme="postcard"] .pcAddressLines .pcAddrHandwritten-blank{
  color:transparent;
  user-select:none;
}

/* Handwritten recipient name — Birthstone (flowing romantic script)
   in dark ink. Each name on its own line with "&" trailing line 1. */
body[data-theme="postcard"] .pcAddrHandwritten{
  font-family:"Birthstone","Pinyon Script",cursive;
  font-size:clamp(32px,4.1vw,52px);
  line-height:1.2;
  color:#1a1410;
  letter-spacing:.005em;
  margin:0;
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
  /* Slight rotation makes it look hand-inked, not typeset */
  transform:rotate(-0.6deg);
  transform-origin:left center;
}
/* Ampersand line — left-aligned like the names, slightly smaller */

body[data-theme="postcard"] .pcVia{
  display:inline-flex;align-items:baseline;gap:10px;padding:6px 12px;
  border:1px solid var(--pc-line);border-radius:30px;background:rgba(184,53,104,.04);
}
/* Desktop sizes for the VIA · air mail · par avion pill — one size
   bigger than the .pcMonoMini / .pcScriptMini defaults so the
   airmail line reads well on a wide postcard envelope. Scoped to
   .pcVia so other uses of the mini classes (RSVP cue, etc.) are
   untouched. */
body[data-theme="postcard"] .pcVia .pcMonoMini   { font-size:12px;letter-spacing:.20em; }
body[data-theme="postcard"] .pcVia .pcScriptMini { font-size:28px; }
body[data-theme="postcard"] .pcStamps{
  display:flex;flex-direction:column;align-items:flex-end;gap:18px;
}

body[data-theme="postcard"] .pcCornerTl,
body[data-theme="postcard"] .pcCornerTr,
body[data-theme="postcard"] .pcCornerBr {
  position:absolute;font-family:var(--pc-mono);font-size:10px;
  letter-spacing:.22em;text-transform:uppercase;color:var(--pc-muted);
}
body[data-theme="postcard"] .pcCornerTl{ top:28px;left:30px; }
body[data-theme="postcard"] .pcCornerTr{ top:28px;right:30px; }
/* "N° 1" marker — smaller and pushed all the way to the left edge
   of the postcard so it reads as a tiny stamp number rather than
   competing with the centered "wedding invitation" label. */
body[data-theme="postcard"] .pcCornerTl.pcCornerTl--smaller{
  left:12px;
  font-size:8px;
  letter-spacing:.18em;
}
/* When the №01 marker is removed and the wedding-invitation label
   needs to be centered. Only applies above the mobile breakpoint —
   on phones the mobile media query (line 1925) already drops the
   absolute positioning and stacks the label as a centered block,
   which doesn't need (or want) the desktop's 42% width cap. */
@media (min-width: 521px) {
  body[data-theme="postcard"] .pcCornerTr.pcCornerTr--centered{
    top:28px;
    left:50%;
    right:auto;
    transform:translateX(-50%);
    max-width:42%;
    text-align:center;
    white-space:nowrap;
    pointer-events:none;
  }
}

body[data-theme="postcard"] .pcCornerBr{
  bottom:28px;right:30px;font-family:var(--pc-serif);font-style:italic;font-weight:700;font-size:18px;
  letter-spacing:.02em;text-transform:none;color:var(--pc-ink);
}

body[data-theme="postcard"] .pcGreeting{
  text-align:center;padding:clamp(32px,5vh,48px) 0 0;border-top:1px dashed var(--pc-line-dashed);
}
body[data-theme="postcard"] .pcGreetingEyebrow{
  font-family:var(--pc-mono);font-size:clamp(22px,3vw,34px);font-weight:600;
  letter-spacing:.32em;text-transform:uppercase;color:var(--pc-muted);
  margin-bottom:clamp(32px,5vh,48px);
  /* Keep the eyebrow on a single line. The FR string "vous êtes
     invités !" is longer than the EN "you are invited!" and the
     wide letter-spacing makes it wrap on narrower viewports — squeeze
     the tracking down on small widths so it stays one row. */
  white-space:nowrap;
}
@media (max-width:680px){
  body[data-theme="postcard"] .pcGreetingEyebrow{
    letter-spacing:.18em;
    font-size:clamp(15px,4vw,22px);
    /* The longer copy ("you are invited to the wedding of" / "vous
       êtes invités au mariage de") doesn't fit on one row on phones,
       so allow wrapping with tight line-height so the two rows read
       as one stacked phrase. */
    white-space:normal;
    line-height:1.25;
    padding:0 12px;
  }
}
@media (max-width:380px){
  body[data-theme="postcard"] .pcGreetingEyebrow{
    letter-spacing:.10em;
    font-size:clamp(13px,3.6vw,18px);
  }
}
body[data-theme="postcard"] .pcGreetingNames{
  /* Same script font as the Classic theme's couple name — flowing
     handwritten feel that reads naturally as the centrepiece of the
     "You are invited!" block. Larger clamp because script glyphs
     visually weigh less than serif italic at the same px size. */
  font-family:"Alex Brush",cursive;font-style:normal;font-weight:400;
  font-size:clamp(80px,14.4vw,190px);line-height:.92;letter-spacing:.005em;margin:0;color:var(--pc-ink);
  display:inline-flex;align-items:baseline;gap:.18em;flex-wrap:wrap;justify-content:center;
}
body[data-theme="postcard"] .pcGreetingNames .pcAmp{
  font-family:"Alex Brush",cursive;font-style:normal;color:var(--pc-accent);font-size:.85em;
  transform:translateY(.04em);margin:0 -.04em;
}
/* Long-form variant — fires only when either name carries a surname.
   First-names-only invitations keep the default oversized clamp; the
   moment we add a surname we drop the cap so the two-word names fit
   the card without dominating the page. */
body[data-theme="postcard"] .pcGreetingNames-long{
  font-size:clamp(52px,9vw,112px);
  letter-spacing:0;
}
body[data-theme="postcard"] .pcGreetingMeta{
  margin-top:32px;display:inline-flex;align-items:center;flex-wrap:wrap;justify-content:center;
  gap:20px;font-family:var(--pc-serif);font-style:italic;font-weight:400;
  font-size:clamp(28px,4vw,48px);letter-spacing:0;text-transform:none;line-height:1.15;color:var(--pc-ink2);
}
/* Parents line ("— children of … and … —") — sits between the couple
   names and the "are getting married · date" subline. Each family is
   wrapped in its own span so mobile can break the line per family
   without splitting any single family name across two rows. */
body[data-theme="postcard"] .pcGreetingParents{
  margin:22px auto 0;
  font-family:var(--pc-serif);font-style:italic;font-weight:400;
  font-size:clamp(20px,2.2vw,30px);
  color:var(--pc-ink2);
  letter-spacing:.005em;
  line-height:1.35;
  max-width:780px;
  text-wrap:balance;
  padding:0 24px;
  display:flex;flex-wrap:wrap;justify-content:center;align-items:baseline;
  gap:.4em;
}
@media (max-width:680px){
  body[data-theme="postcard"] .pcGreetingParents{
    flex-direction:column;
    gap:6px;
    align-items:center;
    text-wrap:initial;
    padding:0 16px;
    font-size:clamp(17px,4.4vw,22px);
  }
  /* Center the connective words and family names each on their own line */
  body[data-theme="postcard"] .pcGreetingParents > span{
    text-align:center;
    display:block;
  }
}
body[data-theme="postcard"] .pcGreetingDate{
  color:var(--pc-accent);font-weight:700;
}

body[data-theme="postcard"] .pcCountdown{
  /* Block-level flex so the pills always start on their own row, even
     on wide monitors where a shorter meta line (notably the French
     "se marieront · 25 décembre 2025") would otherwise leave enough
     horizontal room for the countdown to ride alongside it. */
  margin-top:28px;display:flex;gap:14px;flex-wrap:wrap;justify-content:center;
}
body[data-theme="postcard"] .pcCdPill{
  display:flex;flex-direction:column;align-items:center;gap:4px;
  padding:10px 16px;background:var(--pc-paper2);border:1px dashed var(--pc-line-dashed);border-radius:4px;min-width:62px;
}
body[data-theme="postcard"] .pcCdPill .v{
  font-family:var(--pc-serif);font-style:italic;font-weight:700;font-size:28px;line-height:1;color:var(--pc-ink);
}
body[data-theme="postcard"] .pcCdPill .l{
  font-family:var(--pc-mono);font-size:9px;font-weight:700;letter-spacing:.22em;text-transform:uppercase;color:var(--pc-muted);
}
body[data-theme="postcard"] .pcRsvpCue{
  margin-top:32px;display:flex;justify-content:center;
}
body[data-theme="postcard"] .pcRsvpCue .pcMonoMini{
  padding:6px 14px;border:1px dashed var(--pc-line-dashed);border-radius:30px;font-weight:700;
}

/* Letter card */
body[data-theme="postcard"] .pcCardLetter{
  background:transparent !important;border:none !important;box-shadow:none !important;backdrop-filter:none !important;
  padding:0;display:flex;justify-content:center;
}
body[data-theme="postcard"] .pcLetterPaper{
  position:relative;background:var(--pc-paper2);width:100%;max-width:680px;
  padding:clamp(32px,5vw,64px) clamp(28px,5vw,64px) clamp(40px,6vh,72px);
  border:1px solid var(--pc-line);
  box-shadow:none;
}
body[data-theme="postcard"] .pcLetterRules{
  position:absolute;top:16px;left:36px;bottom:16px;width:1px;background:rgba(184,53,104,.35);
}

body[data-theme="postcard"] .pcLetterSalut{ margin-bottom:22px;padding-left:16px; }
body[data-theme="postcard"] .pcLetterBody{
  font-family:var(--pc-serif);font-size:18px;line-height:30px;color:var(--pc-ink);padding-left:16px;
  /* One empty ruled row at the bottom of the body so the line under
     the last sentence ("…in the making.") continues for one more
     blank row — like a notebook page still ruled after the writing
     stops. */
  padding-bottom:30px;
  /* Ruled lines anchored to the body element so each rule sits at the
     baseline of the row above it — letters rest ON the line, like a
     notebook page. Stripe at y=23 in each 30px cycle matches the
     Cormorant Garamond baseline at this font-size / line-height. */
  background-image:repeating-linear-gradient(
    180deg,
    transparent 0,
    transparent 23px,
    rgba(124,30,60,.22) 23px,
    rgba(124,30,60,.22) 24px,
    transparent 24px,
    transparent 30px
  );
  background-position:0 0;
}
body[data-theme="postcard"] .pcLetterBody p{
  /* Inter-paragraph margin set to exactly one line-height so the rule
     under the blank row stays continuous — gives the letter the look
     of writing on a continuous lined sheet. */
  margin:0 0 30px;
  /* "pretty" keeps the last line from being a single orphan word and softens
     uneven line breaks throughout — reads more like handwritten prose. */
  text-wrap:pretty;
  hyphens:none;
}
body[data-theme="postcard"] .pcLetterBody p:last-child{ margin-bottom:0; }
body[data-theme="postcard"] .pcLetterClose{
  margin-top:28px;padding-left:16px;font-family:var(--pc-serif);font-style:italic;font-size:17px;color:var(--pc-ink2);
}
body[data-theme="postcard"] .pcLetterClose .pcScriptLg{
  margin-top:18px;display:inline-block;color:var(--pc-accent);
  /* Keep the couple signature ("Karell & Jad") on a single line and
     never overflow the letter card. Capped at the same 38px the title
     (.pcScriptMd) uses so the signature is never visually heavier
     than the heading above it — on narrower paper it still scales
     down so it never overflows. The bottom margin is negative so the
     descenders sit flush with the next ruled line on the paper. */
  white-space:nowrap;
  max-width:100%;
  font-size:clamp(28px, 6.4vw, 38px);
  line-height:1;
}
body[data-theme="postcard"] .pcLetterFoot{ margin-top:32px;padding-left:16px; }
/* P.S. — overrides the .pcMonoMini caps/mono style so the line reads
   as a handwritten afterthought in the same serif as the rest of the
   letter. Other uses of .pcMonoMini (e.g. RSVP cue pill) keep the
   uppercase mono look. */
body[data-theme="postcard"] .pcLetterFoot .pcMonoMini{
  font-family:var(--pc-serif),Georgia,serif;
  font-style:italic;
  font-weight:400;
  font-size:15px;
  letter-spacing:.01em;
  text-transform:none;
  color:var(--pc-ink2);
}

/* Formal hosting letter — activates when both parent fields are set.
   Centered serif layout reads as a traditional wedding invitation. */

body[data-theme="postcard"] .pcHeart{
  position:absolute;bottom:28px;right:36px;color:var(--pc-accent);opacity:.6;
}

/* Venue card */
body[data-theme="postcard"] .pcCardVenue{
  background:var(--pc-paper);border:1px solid var(--pc-line);
  box-shadow:none;
  backdrop-filter:none;padding:clamp(36px,5vw,64px) clamp(28px,5vw,56px);
  position:relative;
}
body[data-theme="postcard"] .pcVenueHead{ text-align:center;margin-bottom:32px; }
body[data-theme="postcard"] .pcVenueHead .pcEyebrow{ margin-bottom:14px; }
body[data-theme="postcard"] .pcVenueBody{
  font-family:var(--pc-serif);font-size:16px;line-height:1.6;color:var(--pc-ink2);
}
body[data-theme="postcard"] .pcCardVenue > .pcPostmark{
  position:absolute;top:18px;right:18px;
}

/* Dress code tag */
body[data-theme="postcard"] .pcCardDress{
  background:transparent !important;border:none !important;box-shadow:none !important;backdrop-filter:none !important;
  padding:0;display:flex;justify-content:center;
}
body[data-theme="postcard"] .pcDressTag{
  position:relative;background:var(--pc-paper2);width:100%;max-width:560px;
  padding:56px 44px 40px;border:1px solid var(--pc-line);border-radius:12px 12px 4px 4px;
  box-shadow:none;
  text-align:center;transform:rotate(-1.2deg);
}
body[data-theme="postcard"] .pcDressTag::before{
  content:"";position:absolute;top:12px;left:12px;right:12px;bottom:12px;
  border:1px dashed var(--pc-line-dashed);pointer-events:none;
}
body[data-theme="postcard"] .pcTagEyelet{
  position:absolute;top:-14px;left:50%;transform:translateX(-50%);
  width:36px;height:36px;background:var(--pc-paper2);border:1px solid var(--pc-line);border-radius:50%;
}
body[data-theme="postcard"] .pcTagEyeletHole{
  position:absolute;top:-2px;left:50%;transform:translateX(-50%);
  width:12px;height:12px;background:var(--pc-bg);border:1px solid var(--pc-line);border-radius:50%;
}
body[data-theme="postcard"] .pcDressTagStamp{
  display:inline-block;margin-bottom:18px;padding:5px 12px;
  border:1px solid var(--pc-accent-deep);font-family:var(--pc-mono);font-size:10px;letter-spacing:.32em;
  text-transform:uppercase;color:var(--pc-accent-deep);transform:rotate(-2deg);
}
body[data-theme="postcard"] .pcDressTitle{
  font-family:var(--pc-serif);font-style:italic;font-weight:300;
  font-size:clamp(36px,4.5vw,56px);line-height:1;letter-spacing:-.02em;margin:0 0 18px;
}
body[data-theme="postcard"] .pcDressDesc{
  font-family:var(--pc-serif);font-size:17px;line-height:1.55;color:var(--pc-ink2);
  margin:0 auto 26px;max-width:420px;text-wrap:pretty;
}
body[data-theme="postcard"] .pcDressSwatches{ display:inline-flex;gap:12px; }
body[data-theme="postcard"] .pcDsw{ width:38px;height:56px;border-radius:60px; }

/* Polaroid SCATTER (replaces photoStrip in vertical layout) — fanned stack of 4
   polaroids per section: 2 fronts (with captions) overlap 2 backs. Photos
   rotate through the available pool so consecutive sections show different mixes. */
body[data-theme="postcard"] .pcPolaroidStrip{
  display:flex;justify-content:center;align-items:center;
  /* Padding mirrors the slide pattern (40px top, 20px bottom) so the
     gap between a polaroid strip and the next/previous slide is the
     same 60px (20 + 40) you see between the hero and the letter — the
     postcard reads as one continuous flow, no over-large gaps under
     the photos before the next section. */
  padding:40px 24px 20px;background:transparent;
  min-height:clamp(310px,40vh,450px);
}
/* Scatter is the last strip — add a smaller bottom cushion so there's
   a little "page" to scroll past the photos at the end of the invite. */
body[data-theme="postcard"] .pcPolaroidStrip:has(.pcScatter){
  padding-bottom: clamp(60px, 11vh, 120px);
}
body[data-theme="postcard"] .pcScatter{
  position:relative;
  width:min(1100px,96vw);
  display:flex;justify-content:center;align-items:center;
  perspective:1200px;
}
body[data-theme="postcard"] .pcPolaroid{
  position:relative;
  background:var(--pc-paper);
  padding:18px 18px 36px;
  width:min(440px,50vw);
  /* Frame height is content-driven (photo window + padding). The window
     itself carries the aspect-ratio (see .pcPolaroidImg) so the crop is
     deterministic across engines — deriving the window height from a
     %/calc of an aspect-ratio parent rendered differently on Blink
     (Android/Chrome) vs WebKit (iOS), shifting the crop. */
  box-shadow:0 1px 0 rgba(255,255,255,.7) inset,
             0 28px 56px -20px rgba(31,24,18,.45),
             0 8px 20px -10px rgba(31,24,18,.25);
  /* base transform uses CSS vars so hover can add scale without resetting
     rotation/translate (which would yank the polaroid out from under the cursor) */
  --pc-rot:0deg;
  --pc-ty:0px;
  --pc-scale:1;
  transform:rotate(var(--pc-rot)) translateY(var(--pc-ty)) scale(var(--pc-scale));
  /* margin is in the transition list so the auto-shuffle pair-swap
     glides horizontally instead of snapping (each position class sets
     a different margin-right to control the overlap). */
  transition:transform 1080ms cubic-bezier(.22,.61,.36,1),
             margin 1080ms cubic-bezier(.22,.61,.36,1),
             box-shadow 1080ms ease,
             z-index 0s;
  flex-shrink:0;
}
body[data-theme="postcard"] .pcPolaroidImg{
  position:relative;
  width:100%;aspect-ratio:4/5;height:auto;
  overflow:hidden;
  filter:contrast(1.02) saturate(1.02);
}
/* Real <img> child — uses object-fit so the crop is consistent across
   every browser engine (background-image had Samsung Chromium quirks). */
body[data-theme="postcard"] .pcPolaroidImg > .pcPolaroidImg-photo{
  position:absolute;inset:0;
  width:100%;height:100%;
  object-fit:cover;
  object-position:center 30%;
  display:block;
  user-select:none;
  -webkit-user-drag:none;
}
/* Cross-fade overlay used by the shuffle transition — sits on top of the
   polaroid's own photo and fades in over ~1.1s for a smooth swap instead
   of a blank-then-pop. Now rendered as <img> + object-fit so the crop
   matches the host photo exactly across browsers. */
/* Shuffle overlay — three transition styles selectable per slot:
   --fade  (default cross-fade, kept identical to prior behavior)
   --slide (new photo slides up from below while fading in)
   --zoom  (new photo zooms in from 1.12 → 1 while fading in)
   Base rules cover position; modifiers vary the transition. */
.pcPolaroidImgFade{
  position:absolute;inset:0;
  width:100%;height:100%;
  object-fit:cover;
  object-position:center 30%;
  display:block;
  filter:contrast(1.02) saturate(1.02);
  pointer-events:none;
  will-change:opacity, transform;
}
/* --fade (default) */
.pcPolaroidImgFade,
.pcPolaroidImgFade--fade{
  opacity:0;
  transform:none;
  transition:opacity 1100ms cubic-bezier(.4,.0,.2,1);
}
.pcPolaroidImgFade.show,
.pcPolaroidImgFade--fade.show{ opacity:1; }

/* --slide: new photo slides up from below */
.pcPolaroidImgFade--slide{
  opacity:0;
  transform:translateY(18%);
  transition:opacity 900ms cubic-bezier(.4,.0,.2,1),
             transform 900ms cubic-bezier(.4,.0,.2,1);
}
.pcPolaroidImgFade--slide.show{
  opacity:1;
  transform:translateY(0);
}

/* --zoom: new photo zooms in while fading */
.pcPolaroidImgFade--zoom{
  opacity:0;
  transform:scale(1.12);
  transition:opacity 1000ms cubic-bezier(.4,.0,.2,1),
             transform 1000ms cubic-bezier(.4,.0,.2,1);
}
.pcPolaroidImgFade--zoom.show{
  opacity:1;
  transform:scale(1);
}

body[data-theme="postcard"] .pcTape{
  position:absolute;top:-10px;left:50%;transform:translateX(-50%) rotate(-3deg);
  width:60px;height:18px;background:rgba(220,195,140,.55);
  border-left:1px dashed rgba(124,80,30,.25);border-right:1px dashed rgba(124,80,30,.25);
}
/* Red pushpin/thumbtack alternative to .pcTape — matches the classic
   plastic-headed thumbtack: round flat top cap, narrow cylindrical
   neck, wide flared skirt at the bottom, and a short chrome pin
   protruding underneath. Drawn as a single inline-SVG background-image
   so all 4 plastic tiers + the metal shaft scale crisply at any size.
   Rotated −16° around the cap (transform-origin) so the head stays
   anchored near the polaroid's top-centre and the shaft tilts to the
   left, like a tack pressed in by hand. */
body[data-theme="postcard"] .pcPin{
  position:absolute;top:-18px;left:50%;
  width:34px;height:42px;
  transform:translateX(-50%) rotate(-16deg);
  transform-origin:50% 13px;
  z-index:3;
  pointer-events:none;
  /* Wide flat red disc (map-pin / office-pin style) + short brass needle. */
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 60'><ellipse cx='24' cy='23' rx='20' ry='7' fill='%23a01010'/><ellipse cx='24' cy='20' rx='20' ry='7' fill='%23e51a1a'/><polygon points='22.4,26 25.6,26 24.9,50 23.1,50' fill='%23b88a2a'/><polygon points='23.1,50 24.9,50 24,55' fill='%2386601c'/></svg>");
  background-position:center;
  background-size:contain;
  background-repeat:no-repeat;
  filter:drop-shadow(2px 3px 2px rgba(0,0,0,.35));
}
/* Wax-seal fastener — third option alongside .pcTape and .pcPin.
   Uses transparent-background PNGs so only the wax renders on the
   polaroid. Each modifier class points at a different catalog PNG —
   keep filenames in sync with validWaxStyle() in lambda/handlers_client.go
   and the dashboard picker. */
body[data-theme="postcard"] .pcWax{
  position:absolute;top:-22px;left:50%;
  width:64px;height:64px;
  transform:translateX(-50%) rotate(-4deg);
  z-index:3;
  pointer-events:none;
  background-image:url("/assets/wax-seal.png");
  background-position:center;
  background-size:contain;
  background-repeat:no-repeat;
  filter:drop-shadow(2px 4px 3px rgba(0,0,0,.4));
}
body[data-theme="postcard"] .pcWax-classic   { background-image:url("/assets/wax-seal.png"); }
body[data-theme="postcard"] .pcWax-rose      { background-image:url("/assets/wax-seal-rose.png"); }
body[data-theme="postcard"] .pcWax-rose-red  { background-image:url("/assets/wax-seal-rose-red.png"); }
body[data-theme="postcard"] .pcWax-rose-gold { background-image:url("/assets/wax-seal-rose-gold.png"); }
body[data-theme="postcard"] .pcWax-rose-deep { background-image:url("/assets/wax-seal-rose-deep.png"); }

/* Scatter — fronts hide ~80% of the back polaroids (only a sliver pokes out).
   Four patterns (a/b/c/d) cycle across sections so each one feels distinct.
   Left and right pairs are intentionally asymmetric (different Y, rotation,
   and slice widths) so it reads as a tossed pile instead of a mirrored layout.
   Per-position transform values are stored as CSS variables so hover can
   smoothly add scale without resetting them (no more jitter). */

/* Pattern A — gentle fan, back-right drops lower */
body[data-theme="postcard"] .pcScatter-a .pcPolaroidPos-bl{
  --pc-rot:-9deg;  --pc-ty:26px;
  margin-right:calc(-1 * min(360px, 42.6vw)); z-index:1;
}
body[data-theme="postcard"] .pcScatter-a .pcPolaroidPos-fl{
  --pc-rot:-3deg;  --pc-ty:0px;
  margin-right:-28px; z-index:3;
}
body[data-theme="postcard"] .pcScatter-a .pcPolaroidPos-fr{
  --pc-rot:5deg;   --pc-ty:18px;
  margin-right:calc(-1 * min(344px, 40.8vw)); z-index:3;
}
body[data-theme="postcard"] .pcScatter-a .pcPolaroidPos-br{
  --pc-rot:11deg;  --pc-ty:38px;
  margin-right:0; z-index:1;
}

/* Pattern B — tighter overlap, back-left drops lower (opposite weight from A) */
body[data-theme="postcard"] .pcScatter-b .pcPolaroidPos-bl{
  --pc-rot:-12deg; --pc-ty:40px;
  margin-right:calc(-1 * min(380px, 45vw)); z-index:1;
}
body[data-theme="postcard"] .pcScatter-b .pcPolaroidPos-fl{
  --pc-rot:3deg;   --pc-ty:14px;
  margin-right:-16px; z-index:3;
}
body[data-theme="postcard"] .pcScatter-b .pcPolaroidPos-fr{
  --pc-rot:-4deg;  --pc-ty:0px;
  margin-right:calc(-1 * min(368px, 43.6vw)); z-index:3;
}
body[data-theme="postcard"] .pcScatter-b .pcPolaroidPos-br{
  --pc-rot:8deg;   --pc-ty:28px;
  margin-right:0; z-index:1;
}

/* Pattern C — dramatic angles, big drop on back-right, tight middle pair */
body[data-theme="postcard"] .pcScatter-c .pcPolaroidPos-bl{
  --pc-rot:-16deg; --pc-ty:50px;
  margin-right:calc(-1 * min(370px, 43.8vw)); z-index:1;
}
body[data-theme="postcard"] .pcScatter-c .pcPolaroidPos-fl{
  --pc-rot:5deg;   --pc-ty:24px;
  margin-right:-40px; z-index:3;
}
body[data-theme="postcard"] .pcScatter-c .pcPolaroidPos-fr{
  --pc-rot:-2deg;  --pc-ty:0px;
  margin-right:calc(-1 * min(356px, 42vw)); z-index:3;
}
body[data-theme="postcard"] .pcScatter-c .pcPolaroidPos-br{
  --pc-rot:14deg;  --pc-ty:36px;
  margin-right:0; z-index:1;
}

/* Pattern D — subtle, almost level, slight lean right */
body[data-theme="postcard"] .pcScatter-d .pcPolaroidPos-bl{
  --pc-rot:-5deg;  --pc-ty:20px;
  margin-right:calc(-1 * min(356px, 42vw)); z-index:1;
}
body[data-theme="postcard"] .pcScatter-d .pcPolaroidPos-fl{
  --pc-rot:2deg;   --pc-ty:6px;
  margin-right:-24px; z-index:3;
}
body[data-theme="postcard"] .pcScatter-d .pcPolaroidPos-fr{
  --pc-rot:-6deg;  --pc-ty:0px;
  margin-right:calc(-1 * min(364px, 43vw)); z-index:3;
}
body[data-theme="postcard"] .pcScatter-d .pcPolaroidPos-br{
  --pc-rot:6deg;   --pc-ty:32px;
  margin-right:0; z-index:1;
}

/* Smooth hover lift: only --pc-scale changes, so rotation + Y stay anchored.
   The polaroid grows in place from its centre, the cursor stays inside it,
   and z-index promotion brings it above the rest. No jitter. */
body[data-theme="postcard"] .pcScatter .pcPolaroid:hover,
body[data-theme="postcard"] .pcScatter .pcPolaroid.pcPolaroidFocus{
  --pc-scale:1.1;
  z-index:20;
  box-shadow:0 1px 0 rgba(255,255,255,.7) inset,
             0 24px 48px -14px rgba(31,24,18,.5),
             0 8px 20px -8px rgba(31,24,18,.3);
}

/* Mobile — keep the SAME overlapping scatter as desktop, but loosen the
   negative margins so the four polaroids spread out a bit on phones
   (the desktop overlap, when scaled to 50vw polaroids, leaves almost
   nothing visible of the back-row pair). Rotation + translateY from each
   pattern still apply, so the scatter still feels random. */
@media (max-width:680px){
  /* Keep most of the overlap from desktop (so the scatter doesn't go wide
     past the card edges on the sides) but loosen it just enough that the
     back-row polaroids are visible. */
  body[data-theme="postcard"] .pcScatter .pcPolaroidPos-bl{
    margin-right: calc(-1 * min(280px, 36vw));
  }
  body[data-theme="postcard"] .pcScatter .pcPolaroidPos-fl{
    margin-right: -14px;
  }
  body[data-theme="postcard"] .pcScatter .pcPolaroidPos-fr{
    margin-right: calc(-1 * min(270px, 35vw));
  }
  body[data-theme="postcard"] .pcScatter .pcPolaroidPos-br{
    margin-right: 0;
  }
  /* Push the back-row polaroids further down so a finger-sized portion
     sticks out below the front pair and is easy to tap. Overrides the
     per-pattern --pc-ty values from the desktop A/B/C/D rules. */
  body[data-theme="postcard"] .pcScatter .pcPolaroidPos-bl{ --pc-ty: 90px; }
  body[data-theme="postcard"] .pcScatter .pcPolaroidPos-br{ --pc-ty: 96px; }
  /* Push the whole scatter down a bit so it sits lower on the slide. */
  body[data-theme="postcard"] .pcScatter{
    margin-top: clamp(28px, 8vh, 72px);
  }
}

/* Hide old hero countdown when postcard transforms inject its own */
body[data-theme="postcard"] .pcCardHero .countdownWrap{ display:none; }

/* Address line text (when venue address fields are set) */

/* Itinerary tickets (postcard) */
body[data-theme="postcard"] .pcCardItinerary{
  background:transparent !important;border:none !important;box-shadow:none !important;backdrop-filter:none !important;
  /* Override the global .card width cap (960px) so the itinerary row
     can fill the full slide width regardless of viewport. */
  padding:0;
  max-width:none !important;
  width:100%;
}
body[data-theme="postcard"] .pcItHead{ text-align:center;margin-bottom:48px; }
body[data-theme="postcard"] .pcItHead .pcEyebrow{ margin-bottom:14px; }
body[data-theme="postcard"] .pcTickets{
  /* Desktop: all tickets on one row, each sharing an equal fraction
     of the FULL slide width. No max cap, no scroll, no wrap. */
  display:grid;
  grid-auto-flow:column;
  grid-auto-columns:1fr;
  align-items:stretch;
  gap:clamp(14px,1.8vw,28px);
  width:100%;
  margin:0 auto;
}
body[data-theme="postcard"] .pcTicket{
  background:var(--pc-paper);display:grid;grid-template-columns:96px 16px 1fr;align-items:stretch;
  box-shadow:none;
  position:relative;overflow:hidden;
  min-width:0;
}
body[data-theme="postcard"] .pcTicket::before,
body[data-theme="postcard"] .pcTicket::after{
  content:"";position:absolute;width:14px;height:14px;background:var(--pc-bg);border-radius:50%;
  left:calc(96px + 8px);transform:translateX(-50%);
}
body[data-theme="postcard"] .pcTicket::before{ top:-7px; }
body[data-theme="postcard"] .pcTicket::after{ bottom:-7px; }
body[data-theme="postcard"] .pcTicketStub{
  background:var(--pc-accent-deep);color:var(--pc-paper);padding:22px 14px;
  display:flex;flex-direction:column;justify-content:space-between;align-items:flex-start;text-align:left;
  min-width:0;
}
body[data-theme="postcard"] .pcTicketNum{
  font-family:var(--pc-mono);font-size:10px;letter-spacing:.26em;text-transform:uppercase;opacity:.85;
}
body[data-theme="postcard"] .pcTicketStubTime{
  font-family:var(--pc-serif);font-style:italic;font-weight:300;font-size:22px;line-height:1;letter-spacing:-.01em;
  /* Center the time horizontally within the dark ticket stub —
     overrides the stub's flex-start cross-axis alignment and forces
     the text itself to be centered too. Mobile inherits the same
     rule so the layout stays consistent across viewports. */
  align-self:center;
  text-align:center;
  width:100%;
}
body[data-theme="postcard"] .pcTicketPerf{ border-left:1px dashed var(--pc-line-dashed);margin:12px 0; }
body[data-theme="postcard"] .pcTicketBody{
  padding:22px 20px 20px;
  display:flex;flex-direction:column;gap:5px;
  min-width:0;
}

body[data-theme="postcard"] .pcTicketName{
  font-family:var(--pc-serif);font-style:italic;font-weight:300;font-size:clamp(22px,1.9vw,28px);
  color:var(--pc-ink);line-height:1.15;letter-spacing:-.01em;margin-top:2px;
  overflow-wrap:break-word;
}
body[data-theme="postcard"] .pcTicketDesc{
  font-family:var(--pc-serif);font-size:14px;color:var(--pc-ink2);line-height:1.5;margin-top:4px;text-wrap:pretty;
  overflow-wrap:break-word;
}
body[data-theme="postcard"] .pcTicketLoc{
  /* Address line is the longest text in the body — switch from
     inline-flex pill (which forced narrow wrapping) to a block-level
     box that fills the body column width, with no overflow-wrap so
     words only break at spaces (no per-letter splits like CATHEDR /
     ALE). Sentence-case text-transform reads better at this size. */
  display:flex;align-items:flex-start;gap:6px;margin-top:8px;
  max-width:100%;
  font-family:var(--pc-mono);font-size:11px;letter-spacing:.04em;text-transform:none;
  color:var(--pc-accent-deep);text-decoration:none;
  padding:6px 10px;border:1px dashed var(--pc-line-dashed);border-radius:4px;
  overflow-wrap:normal;
  word-break:keep-all;
  line-height:1.4;
  transition:background .15s;
}
body[data-theme="postcard"] .pcTicketLoc:hover{ background:rgba(124,30,60,.05); }
body[data-theme="postcard"] .pcTicketLocPin{ font-size:13px; }
@media (max-width:520px){
  body[data-theme="postcard"] .pcTickets{
    grid-template-columns:1fr;
    grid-auto-flow:row;
    grid-auto-columns:auto;
    overflow-x:visible;
    scroll-snap-type:none;
  }
  body[data-theme="postcard"] .pcTicket{ grid-template-columns:90px 16px 1fr; }
  body[data-theme="postcard"] .pcTicket::before,
  body[data-theme="postcard"] .pcTicket::after{ left:calc(90px + 8px); }
}

/* Itinerary list (non-postcard themes) */
.itinList{ display:flex;flex-direction:column;gap:14px;margin-top:18px; }
.itinRow{
  display:grid;grid-template-columns:110px 1fr;gap:14px;align-items:baseline;
  padding:14px 0;border-bottom:1px solid rgba(255,255,255,.12);
}
.itinRow:last-child{ border-bottom:none; }
.itinRowTime{
  font-family:Georgia,serif;font-style:italic;font-weight:300;font-size:20px;opacity:.9;
}
.itinRowName{ font-family:inherit;font-size:17px;font-weight:600; }
.itinRowDesc{ font-size:14px;opacity:.75;margin-top:3px;line-height:1.45; }
/* Address link under an itinerary item — taps open Google Maps. Styled
   like a soft pill so it doesn't look like body text. */
.itinRowLoc{
  display:inline-flex;align-items:center;gap:6px;
  margin-top:8px;padding:5px 10px;
  font-size:13px;color:inherit;text-decoration:none;
  background:rgba(31,24,18,.05);border:1px solid rgba(31,24,18,.08);
  border-radius:999px;line-height:1.2;
  transition:background-color 120ms ease, border-color 120ms ease;
}
.itinRowLoc:hover{ background:rgba(184,53,104,.1);border-color:rgba(184,53,104,.3); }
.itinRowLocPin{ font-size:13px;line-height:1; }
/* Classical writing for the address text — Cormorant Garamond italic
   matches the postcard theme's letter body and reads like a
   handwritten note rather than UI copy. Applies in EN and FR. */
.itinRowLocText{
  font-family:"Cormorant Garamond", Georgia, "Times New Roman", serif;
  font-style:italic;
  font-weight:500;
  font-size:14px;
  letter-spacing:.005em;
}

/* Responsive */
@media (max-width:880px){
  body[data-theme="postcard"] .pcEnvelopeGrid{
    grid-template-columns:1fr;
    grid-template-areas:
      "address"
      "stamp"
      "via";
  }
  body[data-theme="postcard"] .pcStamps{ flex-direction:row;align-items:center;align-self:flex-start; }
  body[data-theme="postcard"] .pcGreetingNames{ font-size:clamp(54px,13.5vw,108px); }
  body[data-theme="postcard"] .pcGreetingNames-long{ font-size:clamp(36px,9vw,68px); }
}
/* Phone layout — like a real postcard: stamp pinned top-right with the
   "Via Air Mail" pill directly underneath, address block sitting lower
   on the left. */
@media (max-width:680px){
  body[data-theme="postcard"] .pcEnvelopeGrid{
    grid-template-columns:minmax(0,1fr) auto;
    grid-template-areas:
      ".       stamp"
      ".       via"
      "address address";
    gap:14px clamp(16px,4vw,28px);
    align-items:start;
  }
  body[data-theme="postcard"] .pcEnvelopeGrid .pcAddress{
    grid-area:address;margin-top:2px;min-width:0;
  }
  body[data-theme="postcard"] .pcEnvelopeGrid .pcStamps{
    grid-area:stamp;justify-self:end;align-self:start;
    flex-direction:column;align-items:flex-end;
    /* Lowered to clear the centered "wedding invitation" label on
       mobile too (used to be -6px, pulling the stamp up). */
    margin-top:10px;
  }
  body[data-theme="postcard"] .pcEnvelopeGrid .pcVia{
    grid-area:via;justify-self:end;margin-top:6px;
    /* Shrink the airmail pill on mobile so it doesn't compete with
       the stamp visually — tighter padding/gap and smaller inner
       text sizes for both the VIA label and the script line. */
    padding:4px 9px;gap:6px;
  }
  body[data-theme="postcard"] .pcEnvelopeGrid .pcVia .pcMonoMini{
    font-size:10px;letter-spacing:.16em;
  }
  body[data-theme="postcard"] .pcEnvelopeGrid .pcVia .pcScriptMini{
    font-size:18px;
  }
  /* The inline width on .pcStamp (200px for desktop landscape) is too
     wide for narrow viewports. Cap smaller so the stamp doesn't dominate
     the page on phones. */
  body[data-theme="postcard"] .pcStamp{ width:118px !important; }
  /* Pull the entire envelope hero up — lower top padding lets the
     "To / Dearest" label start higher on the left and the stamp sit
     higher on the right. */
  body[data-theme="postcard"] .pcPaper{
    padding-top: 26px !important;
  }
  body[data-theme="postcard"] .pcEnvelopeGrid{
    /* No extra margin under the envelope grid: the .pcGreeting block
       below already supplies symmetric padding above YOU ARE INVITED.
       Adding margin here was making the top gap roughly 2x the bottom. */
    margin-bottom: 0;
  }
  /* Keep the hero card from overflowing horizontally so it stays centered
     in the slide rather than getting pushed flush to one side. */
  body[data-theme="postcard"] .pcCardHero,
  body[data-theme="postcard"] .pcPaper{ max-width:100%;overflow:hidden; }
}
@media (max-width:520px){
  body[data-theme="postcard"] .pcPaper{ padding:24px 24px 80px; }
  body[data-theme="postcard"] .pcCornerTr {
    position:static;display:block;text-align:center;margin:4px 0;
  }
  /* №01 stays anchored to the LEFT on mobile — used to be centered
     with the other corner labels, but that lost the "corner mark"
     feel; left-align keeps it reading like a stamp number. */
  body[data-theme="postcard"] .pcCornerTl{
    position:static;display:block;text-align:left;margin:4px 0;
  }
  /* Keep the "J & K" mark pinned to the bottom-right of the postcard on
     mobile too. The default mobile stack-and-center rule pushed it below
     the RSVP cue, where it read like body content rather than a corner
     mark. */
  body[data-theme="postcard"] .pcCornerBr{
    position:absolute;bottom:22px;right:22px;
    text-align:right;margin:0;
  }
}

/* Hero */

/* Countdown pills: deep navy with inner silver glow */

/* Content card: deep navy frosted glass with silver glow frame */

/* Section titles: Cinzel, silver, tracked, star prefix */

/* Body: Cormorant Garamond, cool silver-white */

/* Divider: silver lines ✦ centre */

/* Nav: pill buttons */

*{box-sizing:border-box;}

html,body{height:100%;}

body{
  margin:0;
  color:var(--ink);
  font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,Arial;
  overflow:hidden;
}

/* ═══ 03-landing.css ═══ */
/* The landing page (no invitation in the address). */

/* ── Landing page ──────────────────────────────────────── */

#landingPage{
  position:fixed;
  inset:0;
  z-index:10;
  background:#fff;
  overflow-y:auto;
  display:none; /* JS sets to block when no ?event= param */
  font-family:"Inter",system-ui,sans-serif;
  color:#0f1b2d;
  /* Mirror the dashboard's design tokens so the marketing page reads
     as the same product the moment a visitor signs in. Kept inline on
     #landingPage rather than :root so they don't leak into the
     invitation render that lives in the same file. */
  --lAccent:      #3d72e0;
  --lAccentDeep:  #2458c8;
  --lAccentSoft:  #ddeaff;
  --lAccentBg:    #f0f5ff;
  --lText:        #0f1b2d;
  --lSub:         #3a5070;
  --lMuted:       #6a8aa8;
  --lBorder:      #ccd9f0;
  --lSurface:     #f6f8fd;
  --lSurfaceAlt:  #ffffff;
}

/* ── Nav ── */
/* Maintenance banner — sits above the nav on the landing page. */
.lMaintenanceBar{
  background:#f59e0b;
  color:#1a1a1a;
  text-align:center;
  font-size:13px;
  font-weight:700;
  line-height:1.4;
  padding:9px 18px;
  letter-spacing:.04em;
  box-shadow:0 2px 10px rgba(0,0,0,.18);
}
/* Maintenance toggle (driven by /assets/maintenance.js → <html>.maintenance).
   .maintOnly = shown only while paused; .maintHide = hidden while paused.
   Flip MAINTENANCE_MODE to false to bring the Log In CTAs back. */
html:not(.maintenance) .maintOnly{ display:none !important; }
html.maintenance .maintHide{ display:none !important; }
.lNav{
  position:sticky;
  top:0;
  z-index:100;
  background:rgba(255,255,255,.92);
  backdrop-filter:blur(12px);
  border-bottom:1px solid #ebebeb;
}
.lNavInner{
  max-width:1120px;
  margin:0 auto;
  padding:0 24px;
  height:60px;
  display:flex;
  align-items:center;
  justify-content:space-between;
}
.lBrand{
  font-size:15px;
  font-weight:800;
  letter-spacing:-.01em;
  color:#111;
  display:flex;
  align-items:center;
  gap:7px;
}
.lBrandDot{
  width:8px;height:8px;
  border-radius:50%;
  background:var(--lAccent);
  display:inline-block;
}
.lBrandLight{ color:#fff; }
.lBrandLight .lBrandDot{ background:var(--lAccentSoft); }
.lNavLinks{
  display:flex;
  align-items:center;
  gap:12px;
}
.lNavSignIn{
  font-size:14px;
  font-weight:600;
  color:#444;
  text-decoration:none;
}
.lNavSignIn:hover{ color:#111; }
.lNavCta{
  font-size:14px;
  font-weight:700;
  background:var(--lAccent);
  color:#fff;
  padding:9px 18px;
  border-radius:8px;
  text-decoration:none;
  transition:background .15s;
}
.lNavCta:hover{ background:var(--lAccentDeep); }

/* ── Buttons ── */
.lBtnPrimary{
  display:inline-block;
  background:var(--lAccent);
  color:#fff;
  font-size:16px;
  font-weight:700;
  padding:14px 28px;
  border-radius:10px;
  text-decoration:none;
  transition:background .15s,transform .1s,box-shadow .15s;
  box-shadow:0 4px 14px rgba(61,114,224,.18);
}
.lBtnPrimary:hover{ background:var(--lAccentDeep); transform:translateY(-1px); box-shadow:0 6px 18px rgba(61,114,224,.28); }
.lBtnGhost{
  display:inline-block;
  background:transparent;
  color:var(--lText);
  font-size:16px;
  font-weight:600;
  padding:14px 28px;
  border-radius:10px;
  border:2px solid var(--lBorder);
  text-decoration:none;
  transition:border-color .15s,background-color .15s;
}
.lBtnGhost:hover{ border-color:var(--lAccent); background:var(--lAccentBg); }
.lBtnLg{ font-size:18px; padding:16px 36px; }

/* ── Hero ── */
.lHero{
  background:#fff;
  padding:80px 24px 60px;
}
.lHeroInner{
  max-width:1120px;
  margin:0 auto;
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:60px;
  align-items:center;
}
.lHeroText{ max-width:540px; }
.lBadge{
  display:inline-block;
  font-size:12px;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--lAccent);
  background:var(--lAccentBg);
  border:1px solid var(--lAccentSoft);
  padding:5px 12px;
  border-radius:999px;
  margin-bottom:20px;
}
.lHeroTitle{
  font-family:"Cormorant Garamond","Playfair Display",Georgia,serif;
  font-size:clamp(40px,5vw,64px);
  font-weight:700;
  line-height:1.06;
  letter-spacing:-.01em;
  color:var(--lText);
  margin:0 0 18px;
}
.lHeroTitle em{
  font-family:"Alex Brush",cursive;
  font-style:normal;
  font-weight:400;
  color:var(--lAccent);
  font-size:1.15em;
  line-height:.9;
  display:inline-block;
  vertical-align:-.08em;
  padding:0 .05em;
}
.lHeroSub{
  font-size:18px;
  line-height:1.65;
  color:#555;
  margin:0 0 28px;
}
.lHeroActions{
  display:flex;
  flex-wrap:wrap;
  gap:12px;
  margin-bottom:18px;
}
.lHeroNote{
  font-size:13px;
  color:#888;
  margin:0;
}
.lHeroMaint{
  font-size:13.5px;
  font-weight:600;
  color:#b06a00;
  background:rgba(255,176,32,.12);
  border:1px solid rgba(255,176,32,.35);
  border-radius:8px;
  padding:8px 12px;
  margin:0 0 12px;
}

/* ── Phone mockup ── */
.lHeroVisual{
  display:flex;
  justify-content:center;
}
.lPhoneMock{
  width:220px;
  height:440px;
  background:#111;
  border-radius:36px;
  padding:10px;
  box-shadow:0 40px 100px rgba(0,0,0,.22), 0 0 0 1px rgba(255,255,255,.06);
  position:relative;
}
.lPhoneScreen{
  width:100%;
  height:100%;
  border-radius:28px;
  overflow:hidden;
  background:linear-gradient(160deg,#0a1810 0%,#1a3020 100%);
  display:flex;
  align-items:center;
  justify-content:center;
}
.lPhoneInvite{
  text-align:center;
  padding:24px 16px;
  color:#fff;
}
.lPhoneLabel{
  font-size:11px;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:rgba(126,203,154,.7);
  margin:0 0 12px;
}
.lPhoneNames{
  font-family:"Alex Brush",cursive;
  font-size:42px;
  line-height:1.15;
  color:#fff;
  margin-bottom:14px;
}
.lPhoneAmp{
  font-family:"Cormorant Garamond",serif;
  font-style:italic;
  font-size:22px;
  color:rgba(126,203,154,.8);
}
.lPhoneDate{
  font-size:11px;
  letter-spacing:.06em;
  color:rgba(255,255,255,.5);
  margin-bottom:20px;
}
.lPhoneRsvpBtn{
  background:rgba(126,203,154,.18);
  border:1px solid rgba(126,203,154,.4);
  border-radius:999px;
  font-size:11px;
  font-weight:600;
  color:rgba(126,203,154,.95);
  padding:8px 14px;
  letter-spacing:.03em;
}

/* ── Types strip ── */
.lTypesStrip{
  background:var(--lSurface);
  border-top:1px solid var(--lBorder);
  border-bottom:1px solid var(--lBorder);
  padding:18px 24px;
  text-align:center;
  font-size:14px;
  font-weight:600;
  color:var(--lSub);
  letter-spacing:.04em;
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  align-items:center;
  gap:12px;
}
.lDot{ color:var(--lMuted); }

/* ── Generic section ── */
.lSection{
  padding:80px 24px;
  background:var(--lSurfaceAlt);
}
.lSectionAlt{
  background:var(--lSurface);
}
.lSectionInner{
  max-width:960px;
  margin:0 auto;
  text-align:center;
}
.lSectionLabel{
  display:inline-block;
  font-size:12px;
  font-weight:700;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--lAccent);
  margin-bottom:14px;
}
.lSectionTitle{
  font-family:"Cormorant Garamond","Playfair Display",Georgia,serif;
  font-size:clamp(30px,3.8vw,46px);
  font-weight:700;
  letter-spacing:-.01em;
  color:var(--lText);
  margin:0 0 48px;
  line-height:1.15;
}

/* ── Steps ── */
.lSteps{
  display:flex;
  align-items:flex-start;
  gap:0;
  justify-content:center;
  flex-wrap:wrap;
}
.lStep{
  flex:1;
  min-width:200px;
  max-width:280px;
  text-align:center;
  padding:0 20px;
}
.lStepNum{
  width:48px;
  height:48px;
  border-radius:50%;
  background:var(--lAccent);
  color:#fff;
  font-size:20px;
  font-weight:800;
  display:flex;
  align-items:center;
  justify-content:center;
  margin:0 auto 16px;
  box-shadow:0 4px 14px rgba(61,114,224,.22);
}
.lStep h3{
  font-size:17px;
  font-weight:700;
  color:var(--lText);
  margin:0 0 8px;
}
.lStep p{
  font-size:14px;
  line-height:1.65;
  color:var(--lSub);
  margin:0;
}
.lStepArrow{
  font-size:22px;
  color:var(--lAccent);
  opacity:.45;
  flex-shrink:0;
  padding-top:12px;
  align-self:flex-start;
  margin-top:10px;
}

/* ── Feature grid ── */
.lFeatGrid{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:24px;
  text-align:left;
}
.lFeat{
  background:var(--lSurfaceAlt);
  border:1px solid var(--lBorder);
  border-radius:16px;
  padding:28px 24px;
  transition:box-shadow .2s,transform .2s,border-color .2s;
}
.lFeat:hover{
  box-shadow:0 12px 36px rgba(61,114,224,.12);
  transform:translateY(-2px);
  border-color:var(--lAccentSoft);
}
.lFeatIcon{
  font-size:28px;
  margin-bottom:12px;
  filter:saturate(1.15);
}
.lFeat h3{
  font-size:16px;
  font-weight:700;
  color:var(--lText);
  margin:0 0 8px;
}
.lFeat p{
  font-size:14px;
  line-height:1.65;
  color:var(--lSub);
  margin:0;
}

/* ── Pricing section ── */
.lPricingSubtitle{
  text-align:center;
  color:var(--lSub);
  font-size:16px;
  margin:-12px 0 40px;
}
.lPricingGrid{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:24px;
  align-items:start;
}
@media(max-width:820px){ .lPricingGrid{ grid-template-columns:1fr; max-width:380px; margin:0 auto; } }
.lPricingGrid2{ grid-template-columns:minmax(0,1fr) minmax(0,1.2fr); align-items:stretch; }
@media(max-width:820px){ .lPricingGrid2{ grid-template-columns:1fr; max-width:460px; } }
.lAddonList{ list-style:none; margin:14px 0 0; padding:0; display:flex; flex-direction:column; }
.lAddonList li{ display:flex; justify-content:space-between; align-items:flex-start; gap:14px; padding:12px 0; border-top:1px solid var(--lBorder); }
.lAddonList li div{ display:flex; flex-direction:column; gap:3px; }
.lAddonList strong{ color:var(--lText); }
.lAddonList span{ font-size:13.5px; line-height:1.45; color:var(--lMuted); }
.lAddonList b{ font-size:18px; color:var(--lText); }
.lCapNote{ margin:16px 0 0; padding:12px 14px; border-radius:10px; background:var(--lAccentBg); font-size:14px; color:var(--lText); }
.lPricingFine{ margin:20px auto 0; max-width:640px; text-align:center; font-size:13.5px; color:var(--lMuted); }
.lPricingCard{
  background:var(--lSurfaceAlt);
  border:1.5px solid var(--lBorder);
  border-radius:16px;
  padding:32px 28px;
  position:relative;
  display:flex;
  flex-direction:column;
  gap:0;
}
.lPricingCardFeatured{
  border-color:var(--lAccent);
  box-shadow:0 12px 40px rgba(61,114,224,.20);
  transform:scale(1.03);
}
.lPricingBadge{
  position:absolute;
  top:-13px;
  left:50%;
  transform:translateX(-50%);
  background:var(--lAccent);
  color:#fff;
  font-size:11px;
  font-weight:700;
  letter-spacing:.08em;
  text-transform:uppercase;
  padding:4px 14px;
  border-radius:20px;
  box-shadow:0 4px 12px rgba(61,114,224,.28);
}
.lPricingTier{
  font-size:13px;
  font-weight:700;
  text-transform:uppercase;
  letter-spacing:.14em;
  color:var(--lMuted);
  margin-bottom:12px;
}
.lPricingCardFeatured .lPricingTier{ color:var(--lAccent); }
.lPricingPrice{
  margin-bottom:24px;
}
.lPricingAmount{
  font-family:"Cormorant Garamond","Playfair Display",Georgia,serif;
  font-size:54px;
  font-weight:700;
  color:var(--lText);
  letter-spacing:-.02em;
  line-height:1;
}
.lPricingPer{
  font-size:14px;
  color:var(--lMuted);
}
.lPricingFeatures{
  list-style:none;
  padding:0;
  margin:0 0 28px;
  display:flex;
  flex-direction:column;
  gap:9px;
  font-size:14px;
  color:#444;
  flex:1;
}
.lPricingFeatures li{ color:var(--lText); }
/* Upgrade features — what this tier adds over the one below. Shiny
   gold→orange gradient text so the value of stepping up really pops. */
.lPricingCta{
  display:block;
  text-align:center;
  padding:12px 20px;
  border-radius:10px;
  font-size:14px;
  font-weight:700;
  text-decoration:none;
  background:var(--lAccent);
  color:#fff;
  transition:background .14s,box-shadow .14s;
  box-shadow:0 4px 14px rgba(61,114,224,.18);
}
.lPricingCta:hover{ background:var(--lAccentDeep); box-shadow:0 6px 18px rgba(61,114,224,.28); }

/* ── Collaboration section (Admin / Editor / Viewer) ── */
.lCollabGrid{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:20px;
  text-align:left;
}
@media(max-width:820px){ .lCollabGrid{ grid-template-columns:1fr; } }
.lCollabCard{
  background:var(--lSurfaceAlt);
  border:1.5px solid var(--lBorder);
  border-radius:14px;
  padding:24px 22px;
  display:flex;
  flex-direction:column;
  gap:10px;
  transition:border-color .2s,box-shadow .2s;
}
.lCollabCard:hover{ border-color:var(--lAccentSoft); box-shadow:0 10px 30px rgba(61,114,224,.10); }
.lCollabHead{
  display:flex;
  align-items:center;
  gap:10px;
}
.lCollabBadge{
  padding:3px 10px;
  border-radius:999px;
  font-size:10px;
  font-weight:700;
  letter-spacing:.12em;
  text-transform:uppercase;
}
.lCollabBadge-admin  { background:rgba(124, 30, 60, .12); color:#7c1e3c; border:1px solid rgba(124, 30, 60, .25); }
.lCollabBadge-editor { background:rgba(36, 99, 130, .12); color:#1f4e6a; border:1px solid rgba(36, 99, 130, .25); }
.lCollabBadge-viewer { background:rgba(120, 113, 108, .12); color:#57534e; border:1px solid rgba(120, 113, 108, .25); }
.lCollabCard h3{
  font-family:"Cormorant Garamond",Georgia,serif;
  font-size:22px;
  font-weight:700;
  color:var(--lText);
  margin:4px 0 0;
  line-height:1.2;
}
.lCollabCard p{
  font-size:13.5px;
  line-height:1.55;
  color:var(--lSub);
  margin:0;
}
.lCollabSummary{
  margin-top:28px;
  font-size:13px;
  color:var(--lMuted);
  font-style:italic;
}

/* ── CTA section ── */
.lCtaSection{
  background:linear-gradient(135deg,#0f1b2d 0%,#1f3057 50%,#0f1b2d 100%);
  padding:80px 24px;
  text-align:center;
  position:relative;
  overflow:hidden;
}
.lCtaSection::before{
  content:"";
  position:absolute;
  inset:0;
  background:radial-gradient(circle at 30% 40%,rgba(61,114,224,.22),transparent 55%);
  pointer-events:none;
}
.lCtaInner{
  position:relative;
  max-width:600px;
  margin:0 auto;
}
.lCtaSection h2{
  font-family:"Cormorant Garamond","Playfair Display",Georgia,serif;
  font-size:clamp(32px,4vw,46px);
  font-weight:700;
  color:#fff;
  margin:0 0 12px;
  letter-spacing:-.01em;
}
.lCtaSection p{
  font-size:17px;
  color:rgba(255,255,255,.72);
  margin:0 0 28px;
}
.lCtaSection .lBtnPrimary{
  background:#fff;
  color:var(--lAccentDeep);
  box-shadow:0 8px 28px rgba(255,255,255,.25);
}
.lCtaSection .lBtnPrimary:hover{
  background:var(--lAccentBg);
  box-shadow:0 10px 32px rgba(255,255,255,.32);
}
.lCtaNote{
  font-size:13px;
  color:rgba(255,255,255,.5);
  margin-top:14px;
}

/* ── Footer ── */
.lFooter{
  background:#0a1322;
  border-top:1px solid rgba(255,255,255,.06);
  padding:48px 24px;
  text-align:center;
  color:rgba(255,255,255,.55);
}
.lFooterInner{
  max-width:600px;
  margin:0 auto;
}
.lFooter p{
  font-size:14px;
  margin:8px 0 0;
}
.lFooterSmall{
  font-size:12px;
  margin-top:16px;
  color:rgba(255,255,255,.3);
}

/* ── Responsive ── */
@media(max-width:800px){
  .lHeroInner{ grid-template-columns:1fr; gap:40px; }
  .lHeroText{ max-width:100%; }
  .lHeroVisual{ display:none; }
  .lFeatGrid{ grid-template-columns:repeat(2,1fr); }
  .lStepArrow{ display:none; }
  .lSteps{ gap:24px; }
}
@media(max-width:520px){
  .lFeatGrid{ grid-template-columns:1fr; }
  .lHero{ padding:48px 20px 40px; }
  .lSection{ padding:56px 20px; }
}

/* One tab per kind of event on sale (landing-pricing.js); hidden while there's only one. */
.lPricingTypes{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;margin:0 0 28px}
.lPricingTypes button{padding:8px 16px;border:1.5px solid rgba(0,0,0,.14);border-radius:999px;background:transparent;color:inherit;font:inherit;font-size:14px;cursor:pointer}
.lPricingTypes button.active{border-color:currentColor;font-weight:700}

/* ═══ 04-invite.css ═══ */
/* The invitation page itself: slides, the RSVP form, the thank-you. */

/* ── Invite page ───────────────────────────────────────── */

#invitePage{
  display:none; /* shown by JS */
}

/* ---------------- Slider ---------------- */

.slider{
  position:relative;
  z-index:1;

  height:100vh;

  overflow-x:auto;
  overflow-y:hidden;

  display:flex;

  scroll-snap-type:x mandatory;

  -webkit-overflow-scrolling:touch;

  scroll-behavior:auto;

  touch-action:pan-x pan-y;

  overscroll-behavior-x:contain;
}

.slider::-webkit-scrollbar{height:0;}
.slider{scrollbar-width:none;}

.slide{
  flex:0 0 100vw;
  height:100vh;
  max-width:100vw;

  scroll-snap-align:start;

  display:flex;
  align-items:center;
  justify-content:center;

  padding:28px;

  overflow-y:auto;
  /* Belt-and-braces — body already has overflow:hidden but per-slide
     overflow:auto can leak horizontal panning on touch devices when an
     inner element is wider than the slide's content box. */
  overflow-x:hidden;
  -webkit-overflow-scrolling:touch;
}

/* ---------------- Remove boxes ---------------- */

.card{
  /* Width must fit inside the slide's content box (slide has 28px padding
     on each side → 56px). Using calc(100vw - 56px) avoids the old bug
     where 96vw was wider than the available content area on phones,
     making the whole card scroll horizontally. */
  width:min(960px, calc(100vw - 56px));

  background:transparent;
  border:none;
  box-shadow:none;

  backdrop-filter:none;
}

/* Readability boost — applies only to themes that DON'T already style the RSVP:
   Classic (no data-theme), Golden, Modern, Midnight. Garden Romance and Postcard
   keep their own treatments. */

/* Frosted-glass attending choice + meal pick on Classic-family themes only */

/* ---------------- Hero ---------------- */

.heroText{
  text-align:center;
}

.namesScript{
  font-family:var(--namesFont,"Alex Brush",cursive);

  font-size:clamp(60px,9vw,110px);

  line-height:.95;

  margin:0;

  color:white;

  text-shadow:
    0 6px 20px rgba(0,0,0,.5),
    0 12px 40px rgba(0,0,0,.6);
}

.amp{
  font-family:"Cormorant Garamond",serif;

  font-size:clamp(32px,5vw,48px);

  margin:6px 0;

  color:white;

  text-shadow:0 12px 40px rgba(0,0,0,.6);
}

.subline{
  margin:8px 0 0;

  font-weight:900;

  letter-spacing:.05em;

  text-transform:uppercase;

  font-size:14px;

  text-shadow:0 6px 18px rgba(0,0,0,.6);
}

/* ---------------- Countdown ---------------- */

.countdownWrap{
  margin:24px auto 0;

  display:flex;
  gap:10px;

  flex-wrap:wrap;

  justify-content:center;
}

.pill{
  background:rgba(0,0,0,.45);

  backdrop-filter:blur(10px);

  border-radius:999px;

  padding:10px 14px;

  display:flex;
  gap:10px;

  min-width:110px;

  justify-content:center;

  font-weight:800;
}

.pill .v{font-size:18px;}
.pill .l{font-size:12px;opacity:.8;text-transform:uppercase;}

/* ---------------- Content ---------------- */

.content{
  padding:20px;
  text-align:center;
}

.sectionTitle{
  font-family:"Cormorant Garamond",serif;

  font-size:36px;

  margin-bottom:10px;

  text-shadow:0 8px 30px rgba(0,0,0,.65);
}

.body{
  font-size:17px;

  line-height:1.7;

  color:#f3f3f3;

  text-shadow:0 6px 22px rgba(0,0,0,.7);
}

.divider{
  height:1px;
  background:rgba(255,255,255,.4);
  margin:20px auto;
  width:120px;
}

/* ---------------- RSVP form ---------------- */

label{
  display:block;
  margin:14px 0 8px;
  font-weight:900;
}

select,input{
  width:100%;

  padding:12px 12px;

  border-radius:12px;

  border:none;

  background:rgba(255,255,255,.9);

  color:#111;

  font-size:16px;
}

/* Attending choice buttons */
.attendingChoices{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:12px;
  margin-bottom:8px;
}
.attendingChoice{
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  padding:22px 16px;
  margin:0;
  border:1px solid rgba(255,255,255,.35);
  background:transparent;
  border-radius:2px;
  font-family:"Cormorant Garamond",Georgia,serif;
  font-style:italic;
  font-weight:300;
  font-size:22px;
  color:rgba(255,255,255,.85);
  cursor:pointer;
  text-align:center;
  transition:all 220ms ease;
  user-select:none;
  width:auto;
}
.attendingChoice:hover{ border-color:rgba(255,255,255,.7); }
.attendingChoice input{ display:none; }
.attendingChoiceEm{
  display:block;
  font-family:Inter,system-ui,sans-serif;
  font-style:normal;
  font-size:10px;
  letter-spacing:.3em;
  text-transform:uppercase;
  color:rgba(255,255,255,.4);
  margin-top:6px;
}
.attendingChoice:has(input:checked){
  background:rgba(255,255,255,.92);
  border-color:rgba(255,255,255,.92);
  color:#111;
}
.attendingChoice:has(input:checked) .attendingChoiceEm{ color:rgba(0,0,0,.45); }

/* Readonly name display */
.nameItem input[readonly]{
  background:transparent;
  color:rgba(255,255,255,.92);
  font-weight:700;
  font-size:17px;
  padding:6px 0;
  border-bottom:1px solid rgba(255,255,255,.2);
  border-radius:0;
  cursor:default;
}

/* Meal choice cards */
.mealPickRow{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(90px,1fr));
  gap:10px;
}
.mealPick{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:6px;
  padding:18px 10px 14px;
  margin:0;
  border:1px solid rgba(255,255,255,.35);
  background:transparent;
  border-radius:3px;
  color:rgba(255,255,255,.7);
  cursor:pointer;
  text-align:center;
  transition:all 220ms ease;
  user-select:none;
  width:auto;
}
.mealPick:hover{ border-color:rgba(255,255,255,.7); color:rgba(255,255,255,.92); }
.mealPick input{ display:none; }
.mealPick svg{ width:32px;height:32px;opacity:.85;margin-bottom:2px; }
/* Per-option SVG drawing — wraps the icon SVG that the owner picked
   from the catalog in the dashboard. Same sizing as the legacy svg
   selector so the look is unchanged. */

.mealPick .mealLabel{
  font-family:"Cormorant Garamond",Georgia,serif;
  font-style:italic;
  font-weight:400;
  font-size:18px;
  color:rgba(255,255,255,.9);
  line-height:1;
  text-transform:none;
  letter-spacing:0;
}

.mealPick:has(input:checked){
  background:rgba(255,255,255,.92);
  border-color:rgba(255,255,255,.92);
  color:#111;
}
.mealPick:has(input:checked) .mealLabel{ color:#111; }

.mealPick:has(input:checked) svg{ opacity:1; }
@media(max-width:520px){
  .mealPickRow{ grid-template-columns:1fr;gap:8px; }
  .mealPick{ flex-direction:row;justify-content:flex-start;gap:14px;padding:12px 14px; }
  .mealPick svg{ width:24px;height:24px;margin:0; }
  .mealPick .mealLabel{ font-size:17px; }
}

.btnPrimary{

  margin-top:18px;

  width:100%;

  padding:12px 16px;

  border-radius:12px;

  border:0;

  cursor:pointer;

  font-weight:900;

  background:linear-gradient(135deg,var(--accent),var(--accent2));

  color:white;

  box-shadow:var(--btnShadow);
}

.spinner{
  display:none;
  margin-top:12px;
}

.err{
  margin-top:10px;
  margin-bottom:80px;
  color:#ffb3c4;
  font-weight:900;
}

/* ---------------- RSVP confirmed state ---------------- */

.btnSecondary{
  margin-top:12px;
  width:100%;
  padding:11px 16px;
  border-radius:12px;
  border:1.5px solid rgba(255,255,255,.25);
  cursor:pointer;
  font-weight:700;
  background:rgba(255,255,255,.08);
  color:white;
  font-size:14px;
}
.btnSecondary:hover{ background:rgba(255,255,255,.15); }

.rsvpConfirmed{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:14px;
  padding:8px 0;
  text-align:center;
}

.rsvpConfirmedBadge{
  display:inline-block;
  padding:8px 20px;
  border-radius:999px;
  font-weight:800;
  font-size:15px;
  letter-spacing:.02em;
}
.rsvpConfirmedBadge.yes{ background:#4caf72; color:#fff; border:none; }
.rsvpConfirmedBadge.no { background:#e05555; color:#fff; border:none; }

.rsvpConfirmedNames{
  display:flex;
  flex-direction:column;
  gap:6px;
  width:100%;
}
.rsvpConfirmedName{
  padding:10px 14px;
  background:rgba(255,255,255,.9);
  border-radius:10px;
  font-size:14px;
  color:#111;
}

.rsvpModifyBtn{ margin-top:4px; }

.rsvpFormActions{
  display:flex;
  flex-direction:column;
  gap:0;
}

/* ---------------- name inputs ---------------- */

/* Dynamic prompt above the RSVP name list — text depends on
   inviteeData.isFamily + expectedGuests.length (see app-rsvp.js
   initRsvp). Always reflects what the form actually allows
   ("add anyone" vs "+1" vs "fixed roster"). */
.rsvpInvitePrompt{
  margin: 6px 0 12px;
  padding: 10px 14px;
  border-radius: 8px;
  /* Wine palette to match the rest of the invite — text in the
     deep wine accent, soft pink-wine wash for the background, and
     a darker wine left-border for the pill edge. */
  background: rgba(124, 30, 60, .08);
  border-left: 3px solid #7c1e3c;
  color: #5a1430;
  font-size: 15px;
  line-height: 1.5;
  font-weight: 500;
}
.rsvpInvitePrompt:empty{ display:none; }

.nameList{
  display:flex;
  flex-direction:column;
  gap:0;
}

.nameItem{
  display:grid;
  grid-template-columns:1fr 42px;
  gap:10px;
  padding:16px 0;
  border-bottom:1px solid rgba(255,255,255,.12);
}
.nameItem:first-child{ padding-top:0; }
.nameItem:last-child{ border-bottom:none; padding-bottom:0; }

.nameItemPrefs{
  grid-column:1/-1;
  display:flex;
  flex-direction:column;
  gap:10px;
  margin-top:2px;
}

/* 👶 Baby / 🧒 Kid toggles — their own full-width line under the name row.
   Baby swaps the meal picker for the high-chair selector (.chairPickRow);
   Kid swaps it for the kids menu (.kidsMenuRow). */
.nameItemKinds{
  grid-column:1/-1;
  display:flex;
  flex-wrap:wrap;
  gap:6px 20px;
  margin-top:2px;
}
.nameItemKind{
  display:inline-flex;
  align-items:center;
  gap:8px;
  font-size:13px;
  opacity:.82;
  cursor:pointer;
  user-select:none;
  width:fit-content;
}
.nameItemKind input{ width:16px;height:16px;cursor:pointer;accent-color:#b83568; }
.nameItemKind:has(input:checked){ opacity:1;font-weight:600; }
.chairPickRow,
.kidsMenuRow{ display:flex;flex-direction:column;gap:8px; }

.nameItemErr{
  grid-column:1/-1;
  margin-top:6px;
  font-size:13px;
  font-weight:700;
  color:#b83568;
}
.nameItem--invalid input[data-name-input="1"]{
  border-color:#b83568;
  box-shadow:0 0 0 2px rgba(184,53,104,0.15);
}

/* Add-guest button base reset (themes override) */
.nameActions{
  display:flex;align-items:center;justify-content:center;gap:10px;
  width:100%;margin-top:14px;padding:14px 16px;
  background:transparent;border:1px dashed rgba(255,255,255,.18);
  border-radius:10px;color:inherit;cursor:pointer;
  font:inherit;text-align:center;
  transition:border-color 200ms,background 200ms;
}
.nameActions:hover{ border-color:rgba(255,255,255,.4); background:rgba(255,255,255,.04); }
.nameActions:disabled{ opacity:.45;cursor:not-allowed; }

.btnIcon{
  width:42px;
  height:42px;

  border-radius:12px;

  border:none;

  background:white;

  font-weight:900;

  cursor:pointer;
}

/* ---------------- Nav buttons ---------------- */

/* ---------------- Success overlay ---------------- */

.overlay{
  position:fixed;
  inset:0;

  display:none;

  align-items:center;
  justify-content:center;

  background:rgba(0,0,0,.6);

  z-index:9999;
}

.overlay .box{

  width:min(520px,92vw);

  background:white;

  border-radius:18px;

  padding:24px;

  text-align:center;

  color:#222;
}

input,
select,
textarea{
  font-size:16px;
}

/* ═══ 05-vertical.css ═══ */
/* ══════════════════════════════════════════════════════════════
   LAYOUT: Vertical (every style)
   Natural top-to-bottom scroll; photo strips between sections
   ══════════════════════════════════════════════════════════════ */

body.layout-vertical {
  overflow-y: auto;
}

body.layout-vertical .slider {
  display: block;
  height: auto;
  overflow: visible;
  scroll-snap-type: none;
}

body.layout-vertical .slide {
  flex: none;
  width: 100%;
  height: auto;
  min-height: auto;
  scroll-snap-align: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* Halved from the previous 80/40 (gap 120px) → 40/20 (gap 60px) so
     the postcard reads as one continuous sequence rather than discrete
     blocks separated by huge gutters. Hero override below matches. */
  padding: 40px 24px 20px;
}

/* Hero stays full viewport height */
body.layout-vertical .slide[data-slide="0"] {
  min-height: 100vh;
  padding: 20px 24px;
}

/* Hint becomes a scroll prompt */
body.layout-vertical .hint {
  font-size: 13px;
  letter-spacing: .1em;
  opacity: .7;
  animation: hintBounce 2.2s ease-in-out infinite;
}

@keyframes hintBounce {
  0%, 100% { transform: translateY(0); }
  50%       { transform: translateY(5px); }
}

/* Cards sit over the fixed photo bg — theme CSS provides frosted glass */
body.layout-vertical .card:not(.cardHero) {
  max-width: min(680px, 90vw);
  margin: 0 auto;
}

/* Full-width photo strip between sections */
.photoStrip {
  width: 100%;
  height: 50vh;
  background-size: cover;
  background-position: center;
}

/* Modern accent: thin blue line between photo and content */

/* Mobile: stack photo above content */

/* Per-slide overlay — Midnight applies its own gradient via theme CSS */

/* Lift card above photo and overlay */

/* ── Per-person RSVP preferences (menu + dietary) ────────────────────────── */

.rsvpPersonTag{
  display:inline-block;
  font-size:11px;
  padding:1px 7px;
  border-radius:20px;
  font-weight:600;
  margin-left:4px;
  vertical-align:middle;
}
.rsvpPersonTag.menu{ background:#e8e8e8; color:#333; }
.rsvpPersonTag.diet{ background:#d4f0dc; color:#2a7a45; }
.rsvpPersonTag.baby{ background:#dbeafe; color:#1e40af; }
.rsvpPersonTag.kid{ background:#fef3c7; color:#92400e; }
body[data-theme="postcard"] .rsvpPersonTag.baby { background:#cfe0f5; color:#1e40af; }

/* Dietary text field — call-out style so it doesn't disappear under the meal pick */
.prefsField{
  display:flex;
  flex-direction:column;
  gap:8px;
  margin-top:14px;
  padding:14px 16px;
  background:rgba(255,255,255,.06);
  border:1px solid rgba(255,255,255,.12);
  border-left:3px solid rgba(255,255,255,.45);
  border-radius:6px;
}
.prefsFieldLabel{
  font-size:11.5px;
  letter-spacing:.24em;
  text-transform:uppercase;
  color:rgba(255,255,255,.82);
  font-weight:700;
  display:flex;
  align-items:center;
  gap:8px;
}
.prefsFieldLabel::before{
  content:"";
  display:inline-block;
  width:14px;
  height:14px;
  background:currentColor;
  -webkit-mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 2v9'/><path d='M5 2v9'/><path d='M13 2v9'/><path d='M9 11v11'/><path d='M5 11h8'/><path d='M17 22V8a4 4 0 0 1 4-4v18'/></svg>") center/contain no-repeat;
          mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 2v9'/><path d='M5 2v9'/><path d='M13 2v9'/><path d='M9 11v11'/><path d='M5 11h8'/><path d='M17 22V8a4 4 0 0 1 4-4v18'/></svg>") center/contain no-repeat;
  opacity:.85;
  flex-shrink:0;
}
.nameItemPrefs .prefsDietInput{
  font-family:"Cormorant Garamond",Georgia,serif;
  font-size:17px;
  background:rgba(0,0,0,.18);
  border:1px solid rgba(255,255,255,.22);
  border-radius:4px;
  padding:10px 12px;
  color:#fff;
  width:100%;
  outline:none;
  transition:border-color 200ms ease,background 200ms ease;
}
.nameItemPrefs .prefsDietInput::placeholder{ color:rgba(255,255,255,.45); }
.nameItemPrefs .prefsDietInput:focus{
  border-color:rgba(255,255,255,.6);
  background:rgba(0,0,0,.25);
}

/* ═══ 06-postcard-phone.css ═══ */
/* ════════════════════════════════════════════════════════════════════════
   MOBILE READABILITY — Postcard
   Default sizes are tuned for desktop. On phones (≤680px / ≤520px) bump
   absolute font sizes that were illegible (10–11px small caps, postmark
   text, ticket labels, swatch labels, etc.).
   ════════════════════════════════════════════════════════════════════════ */

@media (max-width: 680px) {

  /* Tighter slide gutter on phones — 28px each side was too generous
     and combined with .card width was pushing things off-screen. */
  .slide { padding: 16px; }
  .card  { width: min(960px, calc(100vw - 32px)); }

  /* Polaroid scatter and big single polaroids — shrink to viewport
     scale so the photo strip never extends past the card width. The
     desktop pattern uses min(440px,50vw) per polaroid + negative
     margins as wide as 45vw which crosses 100vw on small phones. */
  body[data-theme="postcard"] .pcScatter      { width: min(1100px, calc(100vw - 32px)); }
  body[data-theme="postcard"] .pcPolaroid     { width: min(280px, 44vw); }
  body[data-theme="postcard"] .pcPolaroid-big { width: min(320px, 70vw); }
  body[data-theme="postcard"] .pcPolaroidStrip{
    width: 100%; max-width: 100%; overflow: hidden;
    /* Halved again — minimal vertical padding so polaroid strips
       sit immediately under the slide above on mobile. */
    padding: 6px 16px;
    min-height: 0;
  }
  /* Mobile slide padding halved too — page-to-page transitions are
     tighter and the postcard reads as one continuous flow. */
  
  body[data-theme="postcard"] .pcPolaroidStrip-left,
  body[data-theme="postcard"] .pcPolaroidStrip-right{
    padding: 20px 16px;
    min-height: 0;
  }
  body[data-theme="postcard"] .pcStripInner   {
    flex-direction: column; gap: 14px;
    width: 100%; max-width: 100%;
  }
  body[data-theme="postcard"] .pcStripInner-noText { align-items: center; }

  /* RSVP form — keep inputs, name list, and buttons inside the card */
  #rsvpForm,
  #rsvpForm select,
  #rsvpForm input,
  #rsvpForm textarea,
  #rsvpForm .nameList,
  #rsvpForm button { max-width: 100%; box-sizing: border-box; }
  #rsvpForm select,
  #rsvpForm input { width: 100%; }

  /* Stack the action buttons ABOVE the name input on phones, right-aligned.
     Long names get the full row width and the "Can't attend" pill + ✕
     button sit out of the way on a separate level (top-right). Drop the
     grid entirely so theme overrides can't reintroduce the squeeze. */
  .nameItem,
  body[data-theme="postcard"]       .nameItem {
    display: flex !important;
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }
  .nameItem input[data-name-input="1"] { width: 100%; min-width: 0; order: 2; }
  .nameItemActions {
    width: 100%;
    justify-content: flex-end;
    flex-wrap: wrap;
    order: 1;
  }
  .nameItemKinds { order: 2; }
  .nameItemPrefs { order: 3; }

  /* Meal pills — drop the postcard theme's hard-coded 3-column grid on
     phones so cards like "STEAK" can't overflow the card width. Single
     column reads cleaner and keeps each label fully visible. */
  body[data-theme="postcard"]       .mealPickRow { grid-template-columns: 1fr; }

  /* ── Garden Romance ── */
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  

  /* ── Postcard ── */
  body[data-theme="postcard"] .pcEyebrow,
  body[data-theme="postcard"] .pcMonoMini,
  body[data-theme="postcard"] .pcCornerTl,
  body[data-theme="postcard"] .pcCornerTr,
  body[data-theme="postcard"] .pcCornerBr {
    font-size: 12px;
    letter-spacing: .24em;
  }
  body[data-theme="postcard"] .pcAddressLabel { font-size: 12px; letter-spacing: .28em; }
  
  
  /* Mobile-scoped echo of the address-line guard so it wins regardless
     of where in the cascade the mobile overrides fall. */
  body[data-theme="postcard"] .pcAddressLines .pcAddrHandwritten:empty,
  body[data-theme="postcard"] .pcAddressLines .pcAddrHandwritten:nth-child(n+4) {
    display: none !important;
  }
  /* Also kill any stray .pcAddrLine that might be injected. */
  
  /* The dashed border-top on .pcGreeting works as a divider in the
     desktop side-by-side envelope layout, but on mobile (where the
     greeting stacks directly under the address) it reads as a stray
     4th line below the last name. Drop it on phones. */
  body[data-theme="postcard"] .pcGreeting { border-top: none; }
  /* Eyebrow + meta stay bumped on phones too (clamp() handles desktop) */
  body[data-theme="postcard"] .pcGreetingEyebrow {
    letter-spacing: .28em; margin-bottom: 26px;
  }
  body[data-theme="postcard"] .pcGreetingMeta { gap: 16px; margin-top: 26px; }
  body[data-theme="postcard"] .pcCountdown { gap: 10px; margin-top: 22px; }
  body[data-theme="postcard"] .pcCdPill    { padding: 8px 12px; min-width: 56px; }
  body[data-theme="postcard"] .pcCdPill .v { font-size: 24px; }
  body[data-theme="postcard"] .pcCdPill .l { font-size: 10.5px; letter-spacing: .2em; }
  body[data-theme="postcard"] .pcH2 { font-size: clamp(36px, 9vw, 64px); }
  body[data-theme="postcard"] .pcLetterBody {
    font-size: 17px; line-height: 28px;
  }
  body[data-theme="postcard"] .pcLetterClose { font-size: 16px; }
  
  body[data-theme="postcard"] .pcLetterSalut .pcScriptMd { font-size: 34px; }
  body[data-theme="postcard"] .pcVenueBody    { font-size: 16px; line-height: 1.65; }
  body[data-theme="postcard"] .pcTicketNum {
    font-size: 11.5px; letter-spacing: .22em;
  }
  body[data-theme="postcard"] .pcTicketStubTime { font-size: 24px; }
  body[data-theme="postcard"] .pcTicketName     { font-size: clamp(22px, 5.5vw, 28px); }
  body[data-theme="postcard"] .pcTicketDesc     { font-size: 15px; line-height: 1.55; }
  body[data-theme="postcard"] .pcDressTitle     { font-size: clamp(32px, 8vw, 44px); }
  /* RSVP slide title — the longer FR string "Serez-vous des nôtres ?"
     wraps to two rows at the default 40px clamp minimum. Shrink the
     mobile floor and nowrap so the title always reads as a single
     line on phones. */
  body[data-theme="postcard"] .slide[data-slide="rsvp"] .sectionTitle{
    font-size: clamp(24px, 7vw, 40px);
    white-space: nowrap;
  }
  body[data-theme="postcard"] .pcDressDesc      { font-size: 16px; line-height: 1.6; }
  body[data-theme="postcard"] .pcDressTagStamp  { font-size: 11.5px; letter-spacing: .28em; }
  body[data-theme="postcard"] .pcDsw            { width: 32px; height: 46px; }

  /* Postmark — small circular stamp text was 9-10px; bump for legibility */
  body[data-theme="postcard"] .pcPm1,
  body[data-theme="postcard"] .pcPm3 {
    font-size: 10.5px; letter-spacing: .2em;
  }
  body[data-theme="postcard"] .pcPm2 .pcPmDateLine { font-size: 12.5px; }
  body[data-theme="postcard"] .pcPm2 .pcPmYearLine { font-size: 11px; }
  /* Stamp rectangle text — Samsung Browser/Android renders fine, but iOS
     Safari's italic-serif metrics push date/value text past the inline
     width. Tighten letter-spacing and use ellipsis on overflow. Do NOT
     overflow:hidden on .pcStampInner — that clipped the text rows when
     the portrait box took most of the vertical space. */
  body[data-theme="postcard"] .pcStampRow1  { font-size: 12.5px; }
  body[data-theme="postcard"] .pcStampRow2  {
    font-size: 11px; letter-spacing: -.01em;
    white-space: nowrap; max-width: 100%;
    overflow: hidden; text-overflow: ellipsis;
  }
  body[data-theme="postcard"] .pcStampValue { font-size: 8px; letter-spacing: .04em; }
  
  body[data-theme="postcard"] .pcRsvpCue .pcMonoMini { font-size: 11.5px; }

  /* Letter slide — "FROM J & K" was wrapping mid-text and overlapping
     "Saturday, …" on the right. Stack the top row vertically on phones so
     they can't collide. */
  
  

  /* Heart was half-hidden behind the RSVP badge on phones. Shrink it and
     tuck it into the true bottom-right corner, below the badge, so it
     reads as a full heart instead of a partial sliver. */
  body[data-theme="postcard"] .pcLetterPaper { padding-bottom: clamp(40px, 7vh, 64px); }
  body[data-theme="postcard"] .pcHeart {
    width: 32px; height: 30px;
    bottom: 12px; right: 16px;
    opacity: .55;
  }
  /* Drop the signature ~2mm further on phones so its baseline lands on the
     next ruled line of the letter paper. */
  body[data-theme="postcard"] .pcLetterClose .pcScriptLg { margin-top: 26px; }
}

/* Smaller phones (≤480px) — squeeze a bit more padding, keep text readable */
@media (max-width: 480px) {
  
  body[data-theme="postcard"] .pcCardLetter,
  body[data-theme="postcard"] .pcCardVenue,
  body[data-theme="postcard"] .pcCardDress {
    padding-left: clamp(16px, 4vw, 28px);
    padding-right: clamp(16px, 4vw, 28px);
  }
  /* The RSVP card — make padding tighter so the form has more room */
  body[data-theme="postcard"]       .slide[data-slide="rsvp"] .card {
    padding: 20px 16px;
  }
  /* Form labels on RSVP */
  body[data-theme="postcard"]       #rsvpForm label {
    font-size: 11.5px; letter-spacing: .24em;
  }
  body[data-theme="postcard"]       .attendingChoice {
    font-size: 22px; padding: 18px 12px;
  }
  body[data-theme="postcard"]       .mealPick .mealLabel { font-size: 17px; }
  
  body[data-theme="postcard"]       .btnPrimary {
    font-size: 12px; padding: 16px 32px; letter-spacing: .26em;
  }
  body[data-theme="postcard"]       .prefsFieldLabel { font-size: 12px; letter-spacing: .22em; }
  body[data-theme="postcard"]       .nameItemPrefs .prefsDietInput { font-size: 16px; }
  body[data-theme="postcard"]       .nameActions { font-size: 12px; letter-spacing: .26em; padding: 14px; }
}

/* ── Postcard — single BIG polaroid in split layout (mimics Garden Romance) ── */

/* Hide all polaroid captions (user request — applies to scatter + big alike) */

body[data-theme="postcard"] .pcPolaroidStrip-left,
body[data-theme="postcard"] .pcPolaroidStrip-right {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: clamp(48px, 10vh, 120px) clamp(20px, 5vw, 64px);
  min-height: auto;
}
body[data-theme="postcard"] .pcStripInner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(32px, 5vw, 80px);
  align-items: center;
  max-width: 1280px;
  width: 100%;
}
body[data-theme="postcard"] .pcPolaroidStrip-right .pcStripInner {
  direction: rtl;
}
body[data-theme="postcard"] .pcPolaroidStrip-right .pcStripInner > * {
  direction: ltr;
}
body[data-theme="postcard"] .pcStripPhoto {
  display: flex;
  justify-content: center;
}
body[data-theme="postcard"] .pcPolaroid-big {
  position: relative;
  background: var(--pc-paper, #fffaf0);
  padding: 14px 14px 56px;
  width: min(520px, 92vw);
  /* Height is content-driven — the photo window (.pcPolaroidImg) carries
     the 3/4 aspect-ratio so the crop is identical on every browser. */
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.7) inset,
    0 28px 56px -20px rgba(31, 24, 18, 0.4),
    0 8px 20px -8px rgba(31, 24, 18, 0.22);
  --pc-rot: -2deg;
  --pc-scale: 1;
  transform: rotate(var(--pc-rot)) scale(var(--pc-scale));
  margin: 0;
  flex-shrink: 0;
  transition: transform 720ms cubic-bezier(0.22, 0.61, 0.36, 1),
              box-shadow 720ms ease;
}
body[data-theme="postcard"] .pcPolaroidStrip-right .pcPolaroid-big { --pc-rot: 2deg; }
body[data-theme="postcard"] .pcPolaroid-big:hover { --pc-scale: 1.04; }
body[data-theme="postcard"] .pcPolaroid-big .pcPolaroidImg {
  width: 100%;
  aspect-ratio: 3 / 4;
  height: auto;
  overflow: hidden;
  filter: contrast(1.02) saturate(1.02);
}
body[data-theme="postcard"] .pcStripText {
  max-width: 460px;
}
body[data-theme="postcard"] .pcPolaroidStrip-right .pcStripText { margin-left: auto; }
body[data-theme="postcard"] .pcStripEyebrow {
  font-family: var(--pc-sans, "Outfit", "Inter", sans-serif);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--pc-muted, #7c6852);
  margin-bottom: 18px;
}
body[data-theme="postcard"] .pcStripScript {
  font-family: var(--pc-script, "Pinyon Script", cursive);
  font-size: clamp(40px, 5vw, 72px);
  color: var(--pc-accent, #b83568);
  line-height: 1;
  margin-bottom: 24px;
}
body[data-theme="postcard"] .pcStripRule {
  width: 56px;
  height: 1px;
  background: var(--pc-line, rgba(31,24,18,0.18));
  margin-bottom: 18px;
}
body[data-theme="postcard"] .pcStripMono {
  font-family: var(--pc-serif, "Cormorant Garamond", serif);
  font-style: italic;
  font-weight: 400;
  font-size: 20px;
  letter-spacing: 0.04em;
  color: var(--pc-ink2, #3a2e22);
}

/* Mobile: stack the split layout vertically */
@media (max-width: 720px) {
  body[data-theme="postcard"] .pcStripInner {
    grid-template-columns: 1fr;
    gap: 28px;
  }
  body[data-theme="postcard"] .pcPolaroidStrip-right .pcStripInner { direction: ltr; }
  body[data-theme="postcard"] .pcPolaroidStrip-right .pcStripText { margin-left: 0; }
}

/* ═══ 07-rsvp-people.css ═══ */
/* The RSVP form's per-guest actions: can't attend, remove. */

/* ── RSVP per-person actions: "Can't attend" toggle + remove (×) ────────── */
.nameItemActions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* Remove pill — used for extra guests the user added (NOT invite-link
   invitees). Red fill so it reads as a destructive action. */
.nameRemoveBtn {
  /* Wine palette matches the rest of the invite (heading, P.S.,
     RSVP pill, name-prompt) instead of the alarm-red default that
     read as a destructive UI button against the warm paper. */
  background: rgba(124, 30, 60, 0.08);
  border: 1px solid #7c1e3c;
  color: #7c1e3c;
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  padding: 5px 12px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
  white-space: nowrap;
}
.nameRemoveBtn:hover {
  background: #7c1e3c;
  border-color: #7c1e3c;
  color: #fff;
}

/* When a person is skipped, dim the name + strike-through, hide preferences */
.nameItem-skipping input[data-name-input="1"] {
  color: #94a3b8 !important; /* over the style's own input colour */
  text-decoration: line-through;
  text-decoration-color: rgba(148, 163, 184, 0.75);
}
.nameItem-skipping .nameItemPrefs { display: none !important; }
.nameItem-skipping .btnIcon { opacity: 0.55; }

/* The nameItem layout in themed forms needs to make room for the actions */
body[data-theme="postcard"]       .nameItem {
  grid-template-columns: 1fr auto;
}

/* Stamp portrait can be either an SVG (default) or a user-uploaded photo.
   The "transform" toggle applies a vintage monochrome ink look that better
   suits a postage-stamp aesthetic. */
body[data-theme="postcard"] .pcStampPhoto {
  width: 100%; height: 100%;
  background-position: center;
  background-repeat: no-repeat;
  /* Default fit (also applied when no modifier matches) — fills entirely
     and crops edges so the stamp square is always full. */
  background-size: cover;
}
/* Three explicit fit modes selectable from the dashboard. Mirrors the
   .stampPhotoPreview-fitMode-* classes in dashboard.css so what an admin
   previews matches the live invitation. */
body[data-theme="postcard"] .pcStampPhoto-fill    { background-size: cover; }
body[data-theme="postcard"] .pcStampPhoto-fit     { background-size: contain; }
body[data-theme="postcard"] .pcStampPhoto-stretch { background-size: 100% 100%; }
body[data-theme="postcard"] .pcStampPhoto-transform {
  filter: grayscale(1) contrast(1.25) sepia(0.5) brightness(0.94);
  mix-blend-mode: multiply;
}

/* RSVP deadline badge inside the postcard letter — more prominent */
body[data-theme="postcard"] .pcRsvpBadge {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  margin-top: 14px;
  padding: 10px 18px;
  background: var(--pc-accent-deep, #7c1e3c);
  color: #fffaf0;
  border-radius: 4px;
  box-shadow: 0 4px 14px -6px rgba(124, 30, 60, 0.45);
}
body[data-theme="postcard"] .pcRsvpBadgeDate {
  align-self: stretch;
  text-align: center;
}
body[data-theme="postcard"] .pcRsvpBadgeLabel {
  font-family: var(--pc-mono, monospace);
  font-size: 10px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  font-weight: 700;
  opacity: 0.85;
  margin-bottom: 2px;
}
body[data-theme="postcard"] .pcRsvpBadgeDate {
  font-family: var(--pc-serif, "Cormorant Garamond", serif);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(20px, 2.4vw, 28px);
  line-height: 1.1;
  letter-spacing: 0.01em;
}
/* Wrapper used when the badge is appended to the RSVP slide (below the
   form). Centers the badge and gives it breathing room — the letter-slide
   version stays left-aligned via .pcLetterFoot's layout. */
body[data-theme="postcard"] .pcRsvpBadgeWrap {
  display: flex;
  justify-content: center;
  margin-top: 28px;
}

/* ═══ 08-edit-pins.css ═══ */
/* The dashboard's Preview & Edit pins (?edit=1). */

/* ────────── Inline edit pins (?edit=1) ──────────
   Decorates editable elements with a hover affordance + ✎ pin. The
   host stays styled by its theme; the pin floats over a corner, always
   shown — a small preview, or a phone with no hover, gives no other hint
   that a piece can be changed — and grows on hover/focus. */
.editPinHost {
  position: relative;
  outline-offset: 4px;
  transition: outline-color 120ms ease, background-color 120ms ease;
}
/* Inline hosts (spans like #name1 / #brideParents / #letterPs) need
   an inline-block so the absolutely-positioned pin can anchor to a
   measurable box. */
span.editPinHost {
  display: inline-block;
}
.editPinHost:hover {
  outline: 1.5px dashed rgba(124, 30, 60, 0.55);
  background: rgba(124, 30, 60, 0.04);
  cursor: pointer;
}
.editPin {
  appearance: none;
  position: absolute;
  top: -10px;
  right: -10px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: none;
  background: #7c1e3c;
  color: #fff;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 4px 14px -4px rgba(124, 30, 60, 0.55);
  opacity: 0.9;
  pointer-events: auto;
  transform: scale(0.85);
  transition: opacity 140ms ease, transform 140ms ease;
  z-index: 5;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* Too small to wear its pin without hiding its words: on hover only. */
.editPinHost--small > .editPin { opacity: 0; pointer-events: none; }
.editPinHost:hover > .editPin,
.editPinHost:focus-within > .editPin,
.editPin:focus,
.editPin:hover {
  opacity: 1;
  pointer-events: auto;
  transform: scale(1);
}
/* Polaroid pin sits in the top-right corner of the polaroid, tucked
   inside the visible bounds (small positive insets so it can't be
   clipped by the iframe edge on phone view). The polaroid rotates,
   so the pin tilts with it but stays anchored to the corner. */
/* Polaroid pin — rendered at document root with position:fixed and
   placed by JS so it tracks the polaroid but is clamped to the
   iframe viewport. Can never be clipped by parent overflow or by
   the polaroid extending past the iframe edge. */
.editPin--polaroid {
  position: fixed;
  top: 0;
  left: 0;
  right: auto;
  bottom: auto;
  opacity: 1;
  pointer-events: auto;
  transform: scale(1);
  background: #7c1e3c;
  color: #fff;
  border: 2px solid #fff;
  width: 36px;
  height: 36px;
  font-size: 16px;
  z-index: 999;
  box-shadow: 0 4px 14px -2px rgba(124, 30, 60, 0.75), 0 0 0 1px rgba(0, 0, 0, 0.15);
}
.editPin--polaroid:hover,
.editPin--polaroid:focus {
  transform: scale(1.1);
  box-shadow: 0 6px 18px -2px rgba(124, 30, 60, 0.9);
}

/* Popover anchored over the edited element. Fixed-position so scroll
   doesn't disconnect it from the host. z-index above the polaroid
   action bar so it never gets covered. */
.editPopover {
  position: fixed;
  z-index: 1100;
  width: min(360px, 92vw);
  background: #fffaf2;
  color: #1f1812;
  border: 1px solid rgba(31, 24, 18, 0.22);
  border-radius: 10px;
  box-shadow: 0 24px 60px -16px rgba(0, 0, 0, 0.4);
  padding: 12px;
  font-family: system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
}
.editPopoverHead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.editPopoverField {
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #7c6852;
  font-weight: 700;
}
.editPopoverClose {
  appearance: none;
  background: transparent;
  border: none;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  color: #7c6852;
}
.editPopoverInput {
  width: 100%;
  box-sizing: border-box;
  font-family: inherit;
  font-size: 14px;
  padding: 8px 10px;
  border: 1px solid rgba(31, 24, 18, 0.18);
  border-radius: 6px;
  background: #fff;
  color: #1f1812;
  resize: vertical;
}
.editPopoverInput:focus {
  outline: none;
  border-color: #7c1e3c;
  box-shadow: 0 0 0 3px rgba(124, 30, 60, 0.16);
}
.editPopoverActions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 10px;
}
.editPopoverCancel,
.editPopoverSave {
  appearance: none;
  font-size: 12.5px;
  font-weight: 600;
  padding: 6px 14px;
  border-radius: 6px;
  cursor: pointer;
  border: 1px solid rgba(31, 24, 18, 0.18);
}
.editPopoverCancel {
  background: transparent;
  color: #7c6852;
}
.editPopoverSave {
  background: #7c1e3c;
  color: #fff;
  border-color: #7c1e3c;
}

/* "+ Add another slide" — appears only in edit mode at the bottom of
   the last extra slide so the owner can append a new one without
   leaving the preview. */
.editAddExtraSlideBtn {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: 18px auto 0;
  padding: 8px 18px;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: #7c1e3c;
  background: rgba(124, 30, 60, 0.06);
  border: 1.5px dashed #7c1e3c;
  border-radius: 999px;
  cursor: pointer;
  position: relative;
  z-index: 4;
}
.editAddExtraSlideBtn:hover {
  background: rgba(124, 30, 60, 0.12);
}

/* Unified polaroid pin — one ✎ per polaroid that opens a popover
   covering photo + fastener + wax in a single dialog. Same wine
   accent as the text-edit pin so the visual language stays
   consistent across the entire preview. */
.editPolaroidHost {
  position: relative;
}
.editPolaroidHost:hover {
  outline: 1.5px dashed rgba(124, 30, 60, 0.55);
  outline-offset: 4px;
  cursor: pointer;
}
.editPin--polaroid {
  top: -10px;
  right: -10px;
}
.editPolaroidHost:hover > .editPin--polaroid,
.editPolaroidHost:focus-within > .editPin--polaroid,
.editPin--polaroid:focus,
.editPin--polaroid:hover {
  opacity: 1;
  pointer-events: auto;
  transform: scale(1);
}

/* Stacked section labels inside the unified polaroid popover. */
.editPopoverSectionLbl {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #7c6852;
  margin: 6px 0 6px;
}
.editPopoverSectionHint {
  font-weight: 500;
  font-style: italic;
  letter-spacing: 0;
  text-transform: none;
  color: #9a8775;
}

/* Slot picker + pool grid inside the unified popover. The picker
   grid (Auto/Shuffle/pool photos, single-select) mirrors the
   dashboard's .polaroidThumbGrid; the pool grid (all uploads,
   multi-select with ✓ badges) mirrors .polaroidPoolGrid. The whole
   popover scrolls vertically when content exceeds the viewport. */
.editPolaroidPopover {
  width: min(440px, 96vw);
  max-height: calc(100vh - 24px);
  overflow-y: auto;
  /* Prevent scroll chaining — when the owner reaches the top or
     bottom of the popover, the iframe page underneath should NOT
     start scrolling as a result. */
  overscroll-behavior: contain;
}
.editPolaroidPickerGrid,
.editPolaroidPoolGrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(68px, 1fr));
  gap: 6px;
  max-height: 220px;
  overflow-y: auto;
  /* Same scroll containment for the inner grids — the photo lists
     can be long and the wheel/touch scroll should stay inside them
     instead of bubbling out to scroll the popover, then the page. */
  overscroll-behavior: contain;
  padding: 6px;
  border: 1px dashed rgba(31, 24, 18, 0.18);
  border-radius: 8px;
  background: rgba(124, 30, 60, 0.04);
  margin-bottom: 12px;
}
.editPolaroidPoolGrid {
  background: rgba(31, 24, 18, 0.04);
  border-left: 2px solid rgba(124, 30, 60, 0.45);
}
.editPolaroidPoolThumb {
  appearance: none;
  background: #fff;
  border: 1.5px solid rgba(31, 24, 18, 0.18);
  border-radius: 6px;
  padding: 0;
  width: 100%;
  aspect-ratio: 1 / 1;
  cursor: pointer;
  overflow: hidden;
  position: relative;
  transition: border-color 120ms, transform 120ms;
}
.editPolaroidPoolThumb:hover { transform: translateY(-1px); }
.editPolaroidPoolThumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.editPolaroidPoolCheck {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  border: 1.5px solid rgba(31, 24, 18, 0.25);
  color: transparent;
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color 120ms, color 120ms, border-color 120ms;
}
.editPolaroidPoolThumb.selected { border-color: #7c1e3c; }
.editPolaroidPoolThumb.selected .editPolaroidPoolCheck {
  background: #7c1e3c;
  border-color: #7c1e3c;
  color: #fff;
}
.editPolaroidPoolThumb-deny {
  animation: editPoolShake 420ms ease;
}
@keyframes editPoolShake {
  0%, 100% { transform: translate(0); }
  20%      { transform: translate(-4px, 0); }
  40%      { transform: translate(4px, 0); }
  60%      { transform: translate(-3px, 0); }
  80%      { transform: translate(3px, 0); }
}
.editPolaroidThumb {
  appearance: none;
  background: #fff;
  border: 1.5px solid rgba(31, 24, 18, 0.18);
  border-radius: 6px;
  padding: 0;
  width: 100%;
  aspect-ratio: 1 / 1;
  cursor: pointer;
  overflow: hidden;
  position: relative;
  transition: border-color 120ms, transform 120ms;
  display: flex;
  align-items: center;
  justify-content: center;
}
.editPolaroidThumb:hover { transform: translateY(-1px); }
.editPolaroidThumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.editPolaroidThumb-auto,
.editPolaroidThumb-shuffle {
  background: linear-gradient(135deg, #fdfdfb, #ece5d7);
}
.editPolaroidThumbLbl {
  font-family: "Cormorant Garamond", Georgia, serif;
  font-style: italic;
  font-size: 13px;
  color: #7c6852;
}
.editPolaroidThumb.selected {
  border-color: #7c1e3c;
  box-shadow: 0 6px 18px rgba(124, 30, 60, 0.18);
}
.editPolaroidPhotoEmpty {
  grid-column: 1 / -1;
  font-size: 12px;
  color: #7c6852;
  font-style: italic;
  text-align: center;
  padding: 16px 8px;
}

/* Fastener popover — Tape / Pin / Wax / None pills, plus a wax
   catalog that toggles on only when Wax is selected so the picker
   stays compact for the other three options. */

.editFastenerPills {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
  margin-bottom: 10px;
}
.editFastenerPill {
  appearance: none;
  background: #fff;
  color: #1f1812;
  border: 1.5px solid rgba(31, 24, 18, 0.18);
  border-radius: 999px;
  padding: 6px 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.05em;
  cursor: pointer;
}
.editFastenerPill:hover { border-color: #7c1e3c; }
.editFastenerPill.selected {
  background: #7c1e3c;
  color: #fff;
  border-color: #7c1e3c;
}
.editFastenerWaxCatalog {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(64px, 1fr));
  gap: 8px;
  margin-bottom: 10px;
  padding: 10px;
  border: 1px dashed rgba(31, 24, 18, 0.18);
  border-left: 2px solid #7c1e3c;
  border-radius: 8px;
  background: rgba(124, 30, 60, 0.04);
}
.editFastenerWaxBtn {
  appearance: none;
  background: #fff;
  border: 1.5px solid rgba(31, 24, 18, 0.18);
  border-radius: 8px;
  padding: 6px 4px 4px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.editFastenerWaxBtn img {
  width: 38px;
  height: 38px;
  object-fit: contain;
}
.editFastenerWaxBtn span {
  font-size: 10px;
  font-weight: 600;
  color: #7c6852;
  text-align: center;
}
.editFastenerWaxBtn.selected {
  border-color: #7c1e3c;
  background: rgba(124, 30, 60, 0.08);
}
.editFastenerWaxBtn.selected span { color: #7c1e3c; }
.editFastenerWaxCatalog[hidden] { display: none !important; }


/* A save's answer, when the invitation is open in a tab of its own. */
#editNote {
  position: fixed;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%);
  z-index: 1001;
  max-width: calc(100vw - 32px);
  box-sizing: border-box;
  padding: 10px 16px;
  border-radius: 999px;
  background: #1f1812;
  color: #fff;
  font: 600 14px/1.35 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  box-shadow: 0 10px 30px -8px rgba(0, 0, 0, 0.45);
}
#editNote[hidden] { display: none; }
#editNote.editNote--error { background: #9b2335; border-radius: 14px; }

/* ═══ 09-dietary.css ═══ */
/* The RSVP form's dietary chips. */

/* ── RSVP dietary chips ──────────────────────────────────────────────────────
   Reuse the .mealPick component so the fixed dietary options inherit each
   theme's pill + selected-state styling; these rules only make them compact
   pills (colors stay themed). The "Other…" free-text field reuses .prefsDietInput. */
.prefsDietChips{ display:flex; flex-wrap:wrap; gap:8px; margin-top:4px; }
body .prefsDietChips .prefsDietChip{
  flex-direction:row; align-items:center; justify-content:center;
  gap:0; width:auto; padding:8px 15px; border-radius:999px;
}
body .prefsDietChips .prefsDietChip .mealLabel{ font-size:15px; line-height:1.15; }
.prefsDietOtherInput, .prefsDietDetailInput{ margin-top:10px; }
@media(max-width:520px){
  body .prefsDietChips{ gap:7px; }
  body .prefsDietChips .prefsDietChip{ padding:7px 13px; }
  body .prefsDietChips .prefsDietChip .mealLabel{ font-size:14px; }
}

/* ═══ 10-save-the-date.css ═══ */
/* ══════════════════════════════════════════════════════════════
   The save the date (app-savedate.js): one card, in the colours
   and fonts of the style the couple picked — a paper style's
   --pp-*, Postcard's --pc-* otherwise.
   ══════════════════════════════════════════════════════════════ */
body.mode-savedate{
  --s-bg:var(--pp-bg,#f3eadc); --s-paper:var(--pp-paper,#fffaf0); --s-ink:var(--pp-ink,#1f1812);
  --s-sub:var(--pp-sub,#7c6852); --s-line:var(--pp-line,rgba(31,24,18,.18)); --s-accent:var(--pp-accent,#7c1e3c);
  --s-accent-ink:var(--pp-accent-ink,#fffaf0); --s-hi:var(--pp-hi,#b83568);
  --s-display:var(--pp-display,"Cormorant Garamond",Georgia,serif); --s-body:var(--pp-body,"Cormorant Garamond",Georgia,serif);
  --s-script:var(--pp-script,"Pinyon Script",cursive); --s-caps:var(--pp-caps,"Outfit","Inter",system-ui,sans-serif);
  --s-radius:var(--pp-btn-radius,999px);
  margin:0; min-height:100vh; background:var(--s-bg); color:var(--s-ink); font-family:var(--s-body);
}
/* Black Tie's page is black around a cream card. */
body.mode-savedate[data-theme="blacktie"] .stdFoot{ color:#b8b0a0; }

.std{ min-height:100vh; box-sizing:border-box; padding:28px 16px 24px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:16px; }
.stdCard{
  width:100%; max-width:460px; box-sizing:border-box; background:var(--s-paper); border:1px solid var(--s-line);
  padding:30px 26px 28px; text-align:center; box-shadow:0 18px 50px rgba(0,0,0,.10);
  display:flex; flex-direction:column; align-items:center;
}
.stdFor{ margin:0 0 18px; font-family:var(--s-caps); font-size:12px; letter-spacing:.16em; text-transform:uppercase; color:var(--s-sub); }
.stdPhoto{ margin:0 0 22px; width:100%; aspect-ratio:4/5; max-height:52vh; overflow:hidden; background:var(--s-line); }
.stdPhoto img{ width:100%; height:100%; object-fit:cover; display:block; }
.stdKicker{ margin:0; font-family:var(--s-caps); font-size:13px; font-weight:600; letter-spacing:.32em; text-transform:uppercase; color:var(--s-hi); }
.stdNames{ margin:10px 0 0; font-family:var(--s-script); font-weight:400; font-size:clamp(40px,12vw,56px); line-height:1.1; color:var(--s-ink); }
.stdAmp{ font-family:var(--s-display); font-style:italic; font-size:.6em; color:var(--s-hi); padding:0 .1em; }
.stdLead{ margin:6px 0 0; font-family:var(--s-display); font-style:italic; font-size:19px; color:var(--s-sub); }
.stdRule{ width:56px; height:1px; background:var(--s-hi); opacity:.55; margin:22px 0; }
.stdDate{ margin:0; display:flex; flex-direction:column; align-items:center; gap:2px; }
.stdDow, .stdYear{ font-family:var(--s-caps); font-size:13px; letter-spacing:.24em; text-transform:uppercase; color:var(--s-sub); }
.stdDayBig{ font-family:var(--s-display); font-size:clamp(32px,9vw,42px); line-height:1.15; color:var(--s-ink); }
.stdDateLine{ margin:0; font-family:var(--s-display); font-size:28px; line-height:1.25; color:var(--s-ink); }
.stdPlace{ margin:12px 0 0; font-family:var(--s-display); font-size:20px; color:var(--s-ink); }
.stdNote{ margin:18px 0 0; max-width:34ch; text-wrap:balance; font-size:17px; line-height:1.55; color:var(--s-ink); }
.stdFollow{ margin:22px 0 0; font-family:var(--s-display); font-style:italic; font-size:18px; color:var(--s-sub); }
.stdCal{ position:relative; margin-top:22px; }
.stdCalBtn{
  min-height:46px; padding:12px 24px; border:0; border-radius:var(--s-radius); background:var(--s-accent); color:var(--s-accent-ink);
  font-family:var(--s-caps); font-size:14px; font-weight:600; letter-spacing:.08em; cursor:pointer;
}
.stdCalMenu{
  position:absolute; left:50%; top:calc(100% + 8px); transform:translateX(-50%); z-index:5; min-width:230px;
  background:var(--s-paper); border:1px solid var(--s-line); box-shadow:0 14px 34px rgba(0,0,0,.16); display:flex; flex-direction:column; text-align:left;
}
.stdCalMenu[hidden]{ display:none; }
.stdCalMenu a{ padding:13px 16px; min-height:44px; box-sizing:border-box; font-family:var(--s-caps); font-size:14px; color:var(--s-ink); text-decoration:none; }
.stdCalMenu a + a{ border-top:1px solid var(--s-line); }
.stdCalMenu a:hover{ background:var(--s-bg); }
.stdCount{ margin:16px 0 0; font-family:var(--s-caps); font-size:12px; letter-spacing:.18em; text-transform:uppercase; color:var(--s-sub); }
.stdFoot{ margin:0; font-family:var(--s-caps); font-size:11px; letter-spacing:.12em; color:var(--s-sub); }
/* Just the photo: the picture as it was made, uncropped, and their words. */
.stdJustPhoto{ justify-content:flex-start; padding-top:24px; }
.stdOnlyPhoto{ display:block; max-width:min(100%,560px); max-height:82vh; height:auto; box-shadow:0 18px 50px rgba(0,0,0,.12); }
.stdOnlyNote{ margin:4px 0 0; max-width:36ch; text-align:center; text-wrap:balance; font-size:18px; line-height:1.55; color:var(--s-ink); }
.stdNoPhoto{ margin:30vh 0 0; font-family:var(--s-caps); font-size:13px; letter-spacing:.16em; text-transform:uppercase; color:var(--s-sub); }
@media (max-width:420px){ .stdCard{ padding:22px 18px 24px; } }
