/* =========================================================================
   Rossa & Augustine — round 4
   Chunk 1/6 — tokens, reset, base type, utilities

   Round 4 DAY palette: paper gold + sunlit wisteria on warm cream paper,
   with soft-sky bands for countdown and colophon. Corona kingdom by day:
   nothing emits light, everything is lit. Sage recedes to a supporting
   botanical tint inside artwork only. Every text/background pair below was
   measured; ratios are recorded in DAY-NOTES.md.
   ========================================================================= */

:root{
  /* Wisteria takes the structural accent role sage used to hold.
     The token names stay put so the whole sheet does not have to churn. */
  --sage:#6b53a0;        /* wisteria in sun     5.62:1 on cream */
  --sage-deep:#4f3d7a;   /* lilac shade         8.31:1 on cream */
  --sage-soft:#ece5f7;   /* lilac wash — SURFACE tint, never text */
  --sage-line:#c3b2dd;   /* lilac hairline, decorative only */
  --cream:#f6f3ec;
  --cream-2:#efe9dd;
  --ink:#332f3a;         /* ink, warmed toward violet 11.78:1 on cream */
  --ink-soft:#514761;    /*                      7.82:1 on cream */
  --white:#fffdf9;
  --line:#ded5cb;
  --accent:#8c5a0f;      /* paper gold, text-safe    5.29:1 on cream */
  --accent-glow:#e8c98a; /* sunlit gold, light-only (never text) */
  --lantern:#7a5410;     /* paper gold on sky        5.35:1 on --dusk */

  /* Soft daylight sky — the midday band. Countdown + colophon.
     Token names retained so the sheet does not churn. */
  --dusk:#dbe6f2;
  --dusk-2:#e8eef5;

  /* Checked pairs; see DAY-NOTES.md. */
  --on-sage:#fffdf9;     /* 9.06:1 on --sage-deep */
  --on-deep:#332f3a;     /* 11.18:1 on --dusk-2   */

  --serif:'Cormorant Garamond','Apple Garamond',Garamond,'Times New Roman',serif;
  --script:'Parisienne','Snell Roundhand','Apple Chancery',cursive;
  /* Korean: soft, warm, handwriting-adjacent myeongjo first. The first three
     are not yet self-hosted — naming them here means dropping the woff2 files
     in later needs no CSS change. macOS today lands on Apple Myungjo /
     AppleMyungjo, then Apple SD Gothic Neo. Noto Serif KR is demoted to a
     late fallback: it is the stiff institutional face the couple disliked. */
  --kr:'Nanum Myeongjo','Gowun Batang','KoPub Batang','AppleMyungjo','Apple Myungjo',
       'Apple SD Gothic Neo','Malgun Gothic','Noto Serif KR',serif;

  --ease:cubic-bezier(.22,.61,.36,1);
  --reveal:.9s;
  --ui:.35s;

  --gut:6vw;
  --sec:clamp(70px,11vw,140px);
  --card-pad:clamp(28px,5vw,56px);
  --measure:64ch;

  /* Daylight shadows: cast, not emitted. Cooler and shallower than the
     night sheet's bloom-adjacent drops. */
  --shadow-card:0 10px 28px rgba(79,61,122,.10);
  --shadow-lift:0 4px 14px rgba(79,61,122,.20);
  --shadow-deep:0 20px 54px rgba(79,61,122,.20);
}

*,*::before,*::after{box-sizing:border-box}
html,body,h1,h2,h3,h4,p,ul,ol,li,figure,blockquote,fieldset,legend{margin:0;padding:0}
ul,ol{list-style:none}
html{-webkit-text-size-adjust:100%}
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}

body{
  font-family:var(--serif);
  font-size:18px;
  line-height:1.6;
  color:var(--ink);
  background:var(--cream);
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
body.is-loading{opacity:1}
body.is-locked{overflow:hidden}

img,svg{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
input,select,textarea{font:inherit;color:inherit}

/* ── Korean typography ───────────────────────────────────────────────────
   Round 4. The complaint was "딱딱한 느낌" — stiff. Four levers, no webfont:
   1. family order  — soft myeongjo first (see --kr)
   2. weight 300    — lighter stroke than the default 400 Noto Serif KR
   3. leading 1.9   — Hangul syllable blocks want far more air than Latin
   4. keep-all      — no mid-word breaks, which is what made it read as blocky
   Plus a ~4% optical reduction so Hangul does not out-size Cormorant. */
html[lang="ko"] body,
html[lang="ko"] .script,
[lang="ko"]{
  font-family:var(--kr);
  font-weight:400;
  font-size:1.02em;
  line-height:1.9;
  letter-spacing:.005em;
  word-break:keep-all;
  overflow-wrap:break-word;
  font-optical-sizing:auto;
}
html[lang="ko"] body{font-size:18.5px}
html[lang="ko"] p,
html[lang="ko"] li,
html[lang="ko"] dd{line-height:1.92;word-break:keep-all}
/* Headings keep-all too, but tighter leading so they do not fall apart. */
html[lang="ko"] h1,
html[lang="ko"] h2,
html[lang="ko"] h3,
html[lang="ko"] .section__title,
html[lang="ko"] .plate__title{
  font-weight:400;line-height:1.45;letter-spacing:0;word-break:keep-all;
}
html[lang="ko"] strong,
html[lang="ko"] b{font-weight:700}
html[lang="ko"] .no-kr{font-family:var(--serif);font-weight:400;font-size:1em;line-height:1.6}
/* The script face has no Hangul; Korean display type falls back to the
   Korean serif — lighter and looser, never tofu. */
html[lang="ko"] .script{letter-spacing:.015em;font-weight:400;line-height:1.5}

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

.skip-link{
  position:absolute;left:12px;top:-100px;z-index:200;
  background:var(--white);color:var(--ink);
  padding:.7em 1.2em;border-radius:100px;border:1.5px solid var(--sage);
  box-shadow:var(--shadow-card);transition:top var(--ui) var(--ease);
}
.skip-link:focus{top:12px}

:focus-visible{
  outline:2.5px solid var(--sage-deep);
  outline-offset:3px;
  border-radius:4px;
}
.on-dark :focus-visible,
.envelope :focus-visible,
.menu :focus-visible,
.colophon :focus-visible{outline-color:var(--sage-deep)}

.noscript{padding:14vh var(--gut);text-align:center;max-width:36em;margin:0 auto}
.noscript p{margin-bottom:1em}

/* Shown when the content payload fails to load. Same shape as .noscript:
   this is the other way a guest can end up with nothing to read. */
.loaderr{padding:14vh var(--gut);text-align:center;max-width:36em;margin:0 auto}
.loaderr__title{font-size:clamp(1.5rem,4vw,2rem);font-weight:400;line-height:1.3;color:var(--ink)}
.loaderr__body{margin:1em 0 1.8em;color:var(--ink-soft);line-height:1.75}

/* =========================================================================
   Chunk 2/6 — buttons, rules, reveal, envelope intro
   ========================================================================= */

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.5em;
  font-family:inherit;font-size:1rem;letter-spacing:.06em;
  padding:.85em 1.8em;border-radius:100px;white-space:normal;text-align:center;
  min-height:48px;cursor:pointer;
  transition:background var(--ui) var(--ease),color var(--ui) var(--ease),
             transform var(--ui) var(--ease),box-shadow var(--ui) var(--ease);
}
.btn--solid{background:var(--sage-deep);color:var(--on-sage);box-shadow:var(--shadow-lift)}
.btn--solid:hover{background:#3f2f63;transform:translateY(-2px);box-shadow:0 8px 20px rgba(79,61,122,.26)}
.btn--outline{border:1.5px solid var(--ink);color:var(--ink)}
.btn--outline:hover{background:var(--ink);color:var(--cream)}
.btn--soft{background:var(--cream-2);color:var(--ink);border:1px solid var(--line)}
.btn--soft:hover{background:var(--sage-deep);color:var(--on-sage);border-color:var(--sage-deep)}
.btn--ghost{color:var(--ink-soft);text-decoration:underline;text-underline-offset:.3em;padding:.6em 1em}
.btn--ghost:hover{color:var(--ink)}
.btn[disabled]{opacity:.55;cursor:not-allowed;transform:none;box-shadow:none}
.btn--wide{width:100%}

.eyebrow{
  font-size:.8rem;letter-spacing:.28em;text-transform:uppercase;
  color:var(--sage-deep);font-family:var(--serif);
}
html[lang="ko"] .eyebrow{letter-spacing:.18em;font-size:.78rem}

.rule{height:1px;background:var(--line);border:0}
.rule--short{width:64px;margin:0 auto}

/* Reveal — genuinely off under reduced motion (see chunk 6). */
[data-reveal]{opacity:0;transform:translateY(28px);
  transition:opacity var(--reveal) var(--ease),transform var(--reveal) var(--ease)}
[data-reveal].in{opacity:1;transform:none}

/* ── Envelope intro ─────────────────────────────────────────────────────
   old3 opened with a modal gate. Kept as an opening *moment*, but it is a
   real dialog: focus-trapped, Escape-closable, dismissed state remembered,
   and the page beneath is inert only while it is open.                    */
.envelope{position:fixed;inset:0;z-index:150;display:grid;place-items:center;padding:24px}
.envelope[hidden]{display:none}
.envelope__scrim{position:absolute;inset:0;background:rgba(79,61,122,.28);backdrop-filter:blur(6px)}
.envelope__card{
  position:relative;z-index:1;
  width:min(440px,100%);max-height:calc(100dvh - 48px);overflow:auto;
  background:var(--white);border-radius:20px;
  padding:clamp(32px,6vw,48px) clamp(24px,5vw,40px);
  text-align:center;box-shadow:var(--shadow-deep);
  animation:env-in .7s var(--ease) both;
}
@keyframes env-in{from{opacity:0;transform:scale(.94) translateY(18px)}to{opacity:1;transform:none}}
.envelope__rule{height:1px;background:var(--line);margin:0 auto;width:56px}
.envelope .eyebrow{margin:1.4em 0 .8em}
.envelope__monogram{
  margin:0 auto 1.1em;color:var(--sage-deep);
}
.mono{display:block;line-height:0}
.mono__svg{display:block;width:100%;height:auto;color:inherit}
.envelope__monogram .mono__svg{width:58px;margin:0 auto}
.envelope__title{font-family:var(--script);font-size:clamp(1.5rem,6.6vw,2.9rem);
  font-weight:400;line-height:1.3;margin-bottom:.25em;
  white-space:nowrap;font-synthesis:none;font-kerning:normal;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  padding-bottom:.1em}
html[lang="ko"] .envelope__title{white-space:nowrap;line-height:1.4;
  -webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}
.envelope__date{font-size:.85rem;letter-spacing:.24em;text-transform:uppercase;
  color:var(--ink-soft);margin-bottom:1.2em}
html[lang="ko"] .envelope__date{letter-spacing:.1em;text-transform:none}
.envelope__body{color:var(--ink-soft);margin-bottom:1.5em;line-height:1.75}
/* Language is chosen here, before the invitation opens: the guest picks a
   language rather than discovering a switch later. Same control, same
   storage key as the header switch. */
.envelope__langlabel{font-size:.72rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink-soft);margin-bottom:.7em}
html[lang="ko"] .envelope__langlabel{letter-spacing:.08em;text-transform:none;font-size:.85rem}
.langswitch--env{display:inline-flex;margin-bottom:1.6em}
.langswitch--env button{padding:.6em 1.25em;font-size:.85rem;min-height:44px}
.envelope__enter{width:100%;margin-bottom:1.6em}

/* =========================================================================
   Chunk 3/6 — chrome, menu, hero, section frame
   ========================================================================= */

.chrome{position:fixed;top:0;left:0;right:0;z-index:60;transition:background var(--ui),box-shadow var(--ui)}
.chrome.is-scrolled{background:rgba(246,243,236,.94);backdrop-filter:blur(10px);
  box-shadow:0 1px 0 var(--line)}
.chrome__bar{display:flex;align-items:center;justify-content:space-between;
  gap:12px;padding:14px var(--gut);max-width:1440px;margin:0 auto}
.chrome__mark{display:inline-flex;align-items:baseline;gap:.7em;min-height:44px;padding:.2em 0}
.chrome__mark-glyph{display:inline-block;width:30px;color:var(--sage-deep)}
.chrome__mark-glyph .mono__svg{width:30px}
.chrome__mark-text{font-size:.72rem;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-soft)}
html[lang="ko"] .chrome__mark-text{letter-spacing:.08em;text-transform:none}
.chrome__tools{display:flex;align-items:center;gap:10px}

.langswitch{display:inline-flex;border:1px solid var(--line);border-radius:100px;
  background:var(--white);overflow:hidden}
.langswitch button{padding:.5em .95em;font-size:.78rem;letter-spacing:.1em;
  color:var(--ink-soft);min-height:40px;transition:background var(--ui),color var(--ui)}
.langswitch button[aria-pressed="true"]{background:var(--sage-deep);color:var(--on-sage)}
.langswitch button:not([aria-pressed="true"]):hover{background:var(--cream-2);color:var(--ink)}

.chrome__menu{display:inline-flex;align-items:center;gap:.6em;
  border:1px solid var(--line);background:var(--white);border-radius:100px;
  padding:.5em 1.05em;min-height:40px;font-size:.78rem;letter-spacing:.18em;text-transform:uppercase}
html[lang="ko"] .chrome__menu{letter-spacing:.06em;text-transform:none}
.chrome__menu-bars{display:inline-flex;flex-direction:column;gap:4px;width:16px}
.chrome__menu-bars i{display:block;height:1.5px;background:var(--ink);
  transition:transform var(--ui) var(--ease),opacity var(--ui) var(--ease)}
.chrome__menu[aria-expanded="true"] .chrome__menu-bars i:first-child{transform:translateY(2.75px) rotate(45deg)}
.chrome__menu[aria-expanded="true"] .chrome__menu-bars i:last-child{transform:translateY(-2.75px) rotate(-45deg)}

/* Full-bleed menu, old3's script-set link stack — but as a real nav list. */
.menu{position:fixed;inset:0;z-index:70;background:var(--cream);
  display:grid;place-items:safe center;padding:80px 6vw 40px;overflow:auto;
  /* `place-items:center` alone is the bug: when the link stack is taller than
     the viewport, a centred grid item overflows in BOTH directions and the
     overflow above the container is unreachable — the scroll range starts at
     the container's top edge, so the first menu links are simply cut off.
     `safe` degrades to start-alignment exactly in that case, which is the
     whole fix. `-webkit-overflow-scrolling` keeps the scroll usable on iOS.
     `100dvh` rather than relying on `inset:0` alone: on mobile the collapsing
     URL bar changes the visual viewport mid-scroll, which is why this showed
     up only when the page was already scrolled. */
  height:100dvh;max-height:100dvh;-webkit-overflow-scrolling:touch}
.menu[hidden]{display:none}
.menu__inner{text-align:center;max-width:520px;width:100%}
.menu__flourish{color:var(--sage);margin:0 auto .8em;width:64px}
.menu__list{display:flex;flex-direction:column;gap:.35em;margin-bottom:2.2em}
.menu__list a{display:inline-block;font-family:var(--script);
  font-size:clamp(1.9rem,7vw,2.6rem);line-height:1.35;padding:.1em .4em;
  transition:color var(--ui) var(--ease)}
.menu__list a:hover{color:var(--sage-deep)}
html[lang="ko"] .menu__list a{font-size:clamp(1.5rem,5.5vw,1.9rem)}
.menu__foot{font-style:italic;font-size:.9rem;letter-spacing:.14em;color:var(--ink-soft)}
html[lang="ko"] .menu__foot{letter-spacing:.04em;font-style:normal}

/* ── Hero ─────────────────────────────────────────────────────────────── */
.hero{position:relative;min-height:100svh;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;
  padding:130px var(--gut) 96px;overflow:hidden;color:var(--ink)}
.hero__art{position:absolute;inset:0;z-index:0}
.hero__art svg{width:100%;height:100%;object-fit:cover}
.hero__veil{position:absolute;inset:0;z-index:1;
  background:linear-gradient(180deg,rgba(255,253,249,.62),rgba(255,253,249,.80))}
.hero__center{position:relative;z-index:2;display:flex;flex-direction:column;
  align-items:center;max-width:780px;width:100%}
.hero__monogram{width:82px;height:82px;border:1.5px solid var(--sage-line);
  border-radius:50%;display:grid;place-items:center;margin-bottom:1.3em;
  color:var(--sage-deep);padding:15px;
  box-shadow:var(--shadow-lift);background:rgba(255,253,249,.55)}
.hero__monogram .mono__svg{width:100%}
.hero__eyebrow{font-size:.82rem;letter-spacing:.34em;text-transform:uppercase;
  color:var(--sage-deep);opacity:1;margin-bottom:.7em}
html[lang="ko"] .hero__eyebrow{letter-spacing:.16em;text-transform:none}
.hero__title{font-family:var(--script);font-weight:400;line-height:1.18;
  font-size:clamp(1.6rem,7.4vw,7.5rem);text-shadow:none;
  white-space:nowrap;overflow-wrap:normal;text-wrap:nowrap;
  /* Parisienne is a thin connected script: synthesised bold/italic and
     subpixel hinting are what make it look broken at large sizes. */
  font-synthesis:none;font-kerning:normal;
  text-rendering:optimizeLegibility;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  padding-bottom:.12em}
.hero__title .amp{font-size:.62em;opacity:.9;font-family:var(--serif);font-style:italic}
html[lang="ko"] .hero__title{font-size:clamp(1.5rem,6.2vw,5rem);line-height:1.34;white-space:nowrap;-webkit-font-smoothing:auto;-moz-osx-font-smoothing:auto}
.hero__date{margin-top:.7em;font-size:.92rem;letter-spacing:.26em;text-transform:uppercase;opacity:1;color:var(--ink-soft)}
html[lang="ko"] .hero__date{letter-spacing:.1em;text-transform:none;font-size:1.05rem}
.hero__tag{margin-top:1.1em;max-width:34ch;font-size:1.12rem;line-height:1.65;opacity:1;color:var(--ink-soft)}
.hero__cta{display:flex;flex-wrap:wrap;gap:.8em;justify-content:center;margin-top:1.9em}
.hero__cta .btn--outline{border-color:var(--ink);color:var(--ink);background:rgba(255,253,249,.55)}
.hero__cta .btn--outline:hover{background:var(--ink);color:var(--cream)}
.hero__scroll{margin-top:2.4em;font-size:.8rem;letter-spacing:.2em;text-transform:uppercase;
  opacity:1;color:var(--ink-soft);display:inline-flex;flex-direction:column;align-items:center;gap:.35em}
html[lang="ko"] .hero__scroll{letter-spacing:.06em;text-transform:none}
.hero__scroll i{font-style:normal;font-size:1.2rem;animation:bob 1.8s var(--ease) infinite}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(6px)}}

/* ── The arrival plate (FACT-06). Tier A only. ──────────────────────────
   Not a schedule row, not a footnote: a card in the hero, repeated at the
   head of the schedule, on the ceremony item, on the venue, and after
   submit. Given the accent tan so it reads as the one urgent thing. */
.plate{
  position:relative;z-index:2;width:min(560px,100%);margin:2.4em auto 0;
  background:var(--white);color:var(--ink);text-align:left;
  border-radius:16px;padding:clamp(20px,4vw,28px) clamp(20px,4vw,30px);
  border:1px solid var(--line);border-left:4px solid var(--accent);
  box-shadow:var(--shadow-card);
}
.plate__label{font-size:.72rem;letter-spacing:.24em;text-transform:uppercase;
  color:var(--accent);margin-bottom:.7em;display:flex;align-items:center;gap:.6em}
html[lang="ko"] .plate__label{letter-spacing:.08em;text-transform:none}
.plate__label::before{content:"";width:22px;height:1px;background:var(--accent);flex:none}
.plate__title{font-size:clamp(1.25rem,3.6vw,1.55rem);line-height:1.35;margin-bottom:.45em;font-weight:500}
.plate__body{color:var(--ink-soft);font-size:1rem;line-height:1.7}
.plate--inline{margin:1.6em 0 0}
.plate--quiet{border-left-color:var(--sage);background:var(--cream-2);box-shadow:none}
.plate--quiet .plate__label{color:var(--sage-deep)}
.plate--quiet .plate__label::before{background:var(--sage-deep)}

/* ── Section frame ─────────────────────────────────────────────────────── */
.section{padding:var(--sec) var(--gut);position:relative}
.section--alt{background:var(--cream-2)}
.section--sage{background:var(--sage-soft);color:var(--ink)}
.section--sage .eyebrow{color:var(--sage-deep)}
.section__head{max-width:720px;margin:0 auto clamp(40px,6vw,72px);text-align:center}
.section__head .eyebrow{display:block;margin-bottom:.9em}
.section__title{font-weight:400;font-size:clamp(2rem,4vw,2.9rem);line-height:1.25;
  overflow-wrap:break-word}
.section__lead{margin-top:1em;color:var(--ink-soft);font-size:1.06rem;line-height:1.75;
  max-width:52ch;margin-left:auto;margin-right:auto}
.section--sage .section__lead{color:var(--ink-soft);opacity:1}
.section__mark{display:block;width:1px;height:52px;background:var(--line);margin:0 auto 2.2em}
.section--sage .section__mark{background:var(--sage-line)}
.wrap{max-width:1040px;margin:0 auto}
.wrap--narrow{max-width:760px;margin:0 auto}

/* =========================================================================
   Chunk 4/6 — countdown, schedule, venues, travel, FAQ, plates, footer
   ========================================================================= */

/* ── Countdown ─── Round 4 DAY: the open-sky band. ────────────────
   Cream paper still owns the page; this and the colophon are the two
   wide-sky moments, which is where the Corona-by-day image lives. */
.countdown{text-align:center;position:relative;overflow:hidden;
  background:radial-gradient(120% 90% at 50% 108%,#fdfaf2 0%,var(--dusk-2) 42%,var(--dusk) 100%);
  color:var(--on-deep)}
.countdown__sky{position:absolute;inset:0;z-index:0;pointer-events:none}
.countdown__sky svg{width:100%;height:100%}
.countdown > *:not(.countdown__sky){position:relative;z-index:1}
.countdown .eyebrow{color:var(--lantern)}
.countdown .section__title{color:var(--on-deep)}
.countdown__grid{display:flex;flex-wrap:wrap;justify-content:center;
  gap:clamp(14px,4vw,44px);margin-top:.4em}
.cd{min-width:72px;display:flex;flex-direction:column;align-items:center;gap:.5em}
.cd__num{font-size:clamp(2.4rem,7vw,3.4rem);line-height:1;font-weight:500;
  font-variant-numeric:tabular-nums;font-family:var(--serif);color:var(--lantern);
  text-shadow:none}
.cd__lab{font-size:.7rem;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-soft)}
html[lang="ko"] .cd__lab{letter-spacing:.06em;text-transform:none;font-size:.8rem}
.countdown__note{margin-top:2.2em;font-style:italic;color:var(--ink-soft);font-size:.98rem}
html[lang="ko"] .countdown__note{font-style:normal}
.countdown__done{margin-top:1.6em;font-size:1.15rem;color:var(--lantern)}

/* ── Schedule — old3's two-column event blocks, alternating side ───────── */
.sched__intro{max-width:60ch;margin:0 auto clamp(32px,5vw,56px)}
.event{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(28px,5vw,64px);
  align-items:center;padding:clamp(36px,6vw,64px) 0}
.event + .event{border-top:1px solid var(--line)}
.event--rev .event__info{order:2}
.event__index{font-size:.72rem;letter-spacing:.26em;text-transform:uppercase;
  color:var(--sage-deep);margin-bottom:.9em;display:flex;align-items:center;gap:.7em}
html[lang="ko"] .event__index{letter-spacing:.08em;text-transform:none}
.event__index::after{content:"";height:1px;flex:1;background:var(--line)}
.event__title{font-size:clamp(1.7rem,4vw,2.3rem);font-weight:400;margin-bottom:.5em;line-height:1.25}
.event__time{font-size:1.18rem;line-height:1.6;margin-bottom:.6em;color:var(--ink)}
.event__venue{color:var(--ink-soft);font-size:1.02rem;margin-bottom:.7em;line-height:1.6}
.event__desc{color:var(--ink-soft);line-height:1.75;max-width:46ch}
.event__actions{display:flex;flex-wrap:wrap;gap:.7em;margin-top:1.4em}
.event__actions .btn{font-size:.88rem;padding:.7em 1.3em}

/* Framed art plate — the printed-invitation crop old3 gave its maps. */
.frame{position:relative;border-radius:16px;overflow:hidden;background:var(--cream-2);
  box-shadow:var(--shadow-card);border:1px solid var(--line)}
.frame svg{width:100%;height:auto;display:block}
/* A real photograph in a slot. The aspect box above already reserves the
   space, so the image only has to fill it: no layout shift when it decodes,
   and no change to any surrounding rule. object-position is set per slot
   inline so a crop can be nudged without touching this file. */
.frame--photo picture,.frame--photo img{display:block;width:100%;height:100%}
.frame--photo img{object-fit:cover}
.frame--16x9{aspect-ratio:16/9}
.frame--4x5{aspect-ratio:4/5}
.frame--1x1{aspect-ratio:1/1}
.frame--4x3{aspect-ratio:4/3}
.frame--3x4{aspect-ratio:3/4}
.frame > svg{position:absolute;inset:0;width:100%;height:100%}
.frame__cap{position:absolute;left:0;right:0;bottom:0;padding:14px 16px;
  font-size:.74rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink);background:linear-gradient(180deg,rgba(255,253,249,0),rgba(255,253,249,.88))}
html[lang="ko"] .frame__cap{letter-spacing:.04em;text-transform:none;font-size:.8rem}

/* ── Venues ────────────────────────────────────────────────────────────── */
.venues{display:grid;gap:clamp(28px,5vw,44px);grid-template-columns:1fr}
.venue{background:var(--white);border:1px solid var(--line);border-radius:20px;
  overflow:hidden;box-shadow:var(--shadow-card);display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.1fr)}
.venue__media{position:relative;min-height:100%}
.venue__media .frame{border:0;border-radius:0;box-shadow:none;height:100%}
.venue__body{padding:var(--card-pad)}
.venue__name{font-size:clamp(1.45rem,3.4vw,1.9rem);font-weight:400;line-height:1.3;margin-bottom:.2em}
.venue__room{color:var(--accent);font-style:italic;margin-bottom:.5em}
html[lang="ko"] .venue__room{font-style:normal}
.venue__addr{color:var(--ink-soft);font-size:.98rem;margin-bottom:1.3em;line-height:1.6}
.venue__facts{display:flex;flex-direction:column;gap:1em;margin-bottom:1.4em}
.venue__facts li{position:relative;padding-left:1.4em;color:var(--ink-soft);line-height:1.7;font-size:1rem}
.venue__facts li::before{content:"";position:absolute;left:0;top:.72em;
  width:7px;height:7px;border:1px solid var(--sage);border-radius:50%}

/* ── Travel ────────────────────────────────────────────────────────────── */
.tips{display:grid;gap:0;max-width:820px;margin:0 auto;border-top:1px solid var(--line)}
.tip{display:grid;grid-template-columns:52px 1fr;gap:18px;align-items:start;
  padding:26px 4px;border-bottom:1px solid var(--line)}
.tip__icon{width:44px;height:44px;border:1px solid var(--sage-line);border-radius:50%;
  display:grid;place-items:center;color:var(--sage-deep)}
.tip__icon svg{width:20px;height:20px}
.tip p{line-height:1.75;color:var(--ink-soft)}

/* ── FAQ ───────────────────────────────────────────────────────────────── */
.faq{max-width:820px;margin:0 auto;border-top:1px solid var(--line)}
.faq__item{border-bottom:1px solid var(--line)}
.faq__q{width:100%;display:flex;align-items:flex-start;justify-content:space-between;
  gap:20px;text-align:left;padding:24px 4px;font-size:1.12rem;line-height:1.5;min-height:56px}
.faq__q:hover{color:var(--sage-deep)}
.faq__sign{flex:none;width:22px;height:22px;position:relative;margin-top:.3em}
.faq__sign::before,.faq__sign::after{content:"";position:absolute;background:var(--sage-deep);
  transition:transform var(--ui) var(--ease),opacity var(--ui) var(--ease)}
.faq__sign::before{left:0;right:0;top:10px;height:1.5px}
.faq__sign::after{top:0;bottom:0;left:10px;width:1.5px}
.faq__q[aria-expanded="true"] .faq__sign::after{transform:scaleY(0)}
.faq__a{padding:0 4px 26px;color:var(--ink-soft);line-height:1.8;max-width:60ch}
.faq__a[hidden]{display:none}

/* ── Colophon ──────────────────────────────────────────────────────────── */
.colophon{background:radial-gradient(120% 130% at 50% -20%,#fdfaf2 0%,var(--dusk-2) 45%,var(--dusk) 100%);
  color:var(--on-deep);text-align:center;
  padding:clamp(56px,9vw,86px) var(--gut)}
.colophon__mono{width:66px;height:66px;border:1px solid var(--sage-line);border-radius:50%;
  display:grid;place-items:center;padding:13px;color:var(--sage-deep);
  box-shadow:var(--shadow-lift)}
.colophon__mono{margin:0 auto 1.4em}
.colophon__mono .mono__svg{width:100%}
.colophon__names{font-family:var(--script);font-size:clamp(2.1rem,7vw,2.8rem);line-height:1.2;margin-bottom:.25em}
.colophon__date{letter-spacing:.3em;font-size:.82rem;text-transform:uppercase;opacity:1;color:var(--ink-soft);margin-bottom:1.4em}
html[lang="ko"] .colophon__date{letter-spacing:.08em;text-transform:none;font-size:.95rem}
.colophon__contact{font-size:.95rem;opacity:1;color:var(--ink-soft);line-height:1.8;overflow-wrap:anywhere}
/* WCAG 2.2 AA (2.5.8) wants a 24x24 hit area; this link measured 121x18.
   Vertical padding on an INLINE element grows the border box — which is what
   is hit, and what getBoundingClientRect reports — without growing the line
   box, so nothing moves on screen. The 1.8 line-height above already leaves
   more room than the padding takes, so consecutive lines do not overlap. */
.colophon__contact a{text-decoration:underline;text-underline-offset:.3em;
  padding-block:.25em}
.colophon__note{margin-top:1.6em;font-size:.78rem;opacity:1;color:var(--ink-soft);line-height:1.7;max-width:44ch;margin-inline:auto}
/* Handing the device to the next household. Set below the colophon note and
   separated by a rule: findable by someone who is looking for it, quiet for
   someone who is not. Sized as a normal control, not a tiny legal link — the
   guest most likely to need it is the one least able to hit a 20px target. */
.colophon__switch{margin-top:2.2em;padding-top:1.6em;border-top:1px solid var(--sage-line)}
.colophon__switch-intro{font-size:.82rem;color:var(--ink-soft);line-height:1.7;
  max-width:34ch;margin:0 auto .7em}
.colophon__switch-btn{font-size:.9rem;min-height:44px}

/* =========================================================================
   Chunk 5/6 — RSVP card, fields, steppers, review, confirmation
   ========================================================================= */

.rsvp__card{max-width:660px;margin:0 auto;background:var(--white);
  border:1px solid var(--line);border-radius:24px;padding:var(--card-pad);
  box-shadow:0 16px 40px rgba(79,61,122,.10)}
.rsvp__steps{display:flex;align-items:center;justify-content:center;gap:8px;margin-bottom:1.8em}
.rsvp__steps li{width:26px;height:3px;border-radius:2px;background:var(--line)}
.rsvp__steps li[aria-current="step"]{background:var(--sage-deep);width:38px}
.rsvp__steps li.is-done{background:var(--sage-line)}
.rsvp__stephead{text-align:center;margin-bottom:1.6em}
.rsvp__stephead h3{font-size:clamp(1.5rem,4vw,2rem);font-weight:400;line-height:1.3}
.rsvp__stephead p{margin-top:.7em;color:var(--ink-soft);line-height:1.75}
.rsvp__form{display:flex;flex-direction:column;gap:1.4em}
.rsvp__nav{display:flex;flex-wrap:wrap;gap:.7em;justify-content:space-between;margin-top:.6em}
.rsvp__nav .btn{flex:1 1 auto;min-width:44%}

.field{display:flex;flex-direction:column;gap:.5em}
.field__label{font-size:.92rem;letter-spacing:.04em;color:var(--ink)}
.field__help{font-size:.86rem;color:var(--ink-soft);line-height:1.6}
.field input,.field textarea,.field select{
  font-family:inherit;font-size:1.05rem;padding:.8em .95em;min-height:48px;
  border:1.5px solid var(--line);border-radius:10px;background:var(--cream);
  color:var(--ink);width:100%;
  transition:border-color var(--ui),box-shadow var(--ui)}
.field textarea{min-height:110px;resize:vertical;line-height:1.6}
.field input:focus,.field textarea:focus,.field select:focus{
  outline:none;border-color:var(--sage-deep);box-shadow:0 0 0 3px rgba(79,61,122,.20)}
.field input[aria-invalid="true"],.field textarea[aria-invalid="true"]{border-color:#96442f}
/* Eight single-character boxes, grouped 4 – 4.

   No letter-spacing: one character per box means it would only push that
   character off centre. The padding is horizontal-zero for the same reason —
   at 320px the row is eight boxes, seven gaps and a separator, and the box
   padding is the first thing that overflows. Width comes from `flex:1 1 0`
   with `min-width:0`, so the boxes divide whatever the row actually has
   rather than each insisting on a `ch` measure the row cannot afford.

   `min-height` is untouched at 48px: the boxes get narrower on a small screen
   and never shorter, so the touch target stays inside WCAG 2.2 AA. */
.field--code input{font-size:1.15rem;letter-spacing:0;text-transform:uppercase;
  text-align:center;padding-left:0;padding-right:0}
.field__groups{display:flex;align-items:center;gap:.28em}
.field--code .field__group{flex:1 1 0;min-width:0}
.field__sep{flex:none;color:var(--ink-soft);font-size:1.15rem;line-height:1}
/* The narrowest supported viewport. 320 − the page gutter − the card padding
   leaves roughly 250px for eight boxes, seven gaps and a separator, so the gap
   tightens and the glyph steps down rather than the row scrolling.

   The gap is what pays for the box width, and the box width is a WCAG 2.2 AA
   target: at a .16em gap the boxes measured 23.4px across, which is under the
   24×24 minimum — close enough to look fine and still be a failure. The
   padding here is bought back from the gap, not from the box. */
@media (max-width:359px){
  .field__groups{gap:.06em}
  .field--code input{font-size:1rem}
  .field__sep{font-size:1rem}
  /* Belt and braces: never let the flex basis take a box under the AA
     minimum, whatever the surrounding padding turns out to be. */
  .field--code .field__group{min-width:24px}
}
.err{color:#8a3d2a;font-size:.9rem;line-height:1.6}
.err[hidden]{display:none}

.choices{display:flex;flex-direction:column;gap:.8em}
.choice{display:flex;align-items:flex-start;gap:.8em;padding:1em 1.1em;
  border:1.5px solid var(--line);border-radius:14px;background:var(--cream);
  cursor:pointer;line-height:1.6;transition:border-color var(--ui),background var(--ui)}
.choice:hover{border-color:var(--sage-line)}
.choice input{margin-top:.28em;width:20px;height:20px;flex:none;accent-color:var(--sage-deep)}
.choice:has(input:checked){border-color:var(--sage-deep);background:var(--white)}
.choice__t{display:block}
.choice__s{display:block;font-size:.88rem;color:var(--ink-soft);margin-top:.2em}

.steppers{display:flex;flex-direction:column;gap:.9em}
.stepper{display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:.9em 1em;border:1px solid var(--line);border-radius:14px;background:var(--cream)}
.stepper__text{min-width:0}
.stepper__name{font-size:1.05rem}
.stepper__hint{display:block;font-size:.84rem;color:var(--ink-soft);line-height:1.55;margin-top:.15em}
.stepper__ctrl{display:flex;align-items:center;gap:6px;flex:none}
.stepper__btn{width:44px;height:44px;border-radius:50%;border:1.5px solid var(--sage-deep);
  color:var(--sage-deep);display:grid;place-items:center;font-size:1.3rem;line-height:1;
  transition:background var(--ui),color var(--ui)}
.stepper__btn:hover:not([disabled]){background:var(--sage-deep);color:var(--on-sage)}
.stepper__btn[disabled]{opacity:.35;cursor:not-allowed}
.stepper__val{min-width:2.2ch;text-align:center;font-size:1.25rem;font-variant-numeric:tabular-nums}

.review{display:flex;flex-direction:column;gap:0;border-top:1px solid var(--line);margin-bottom:1.6em}
.review__row{display:grid;grid-template-columns:minmax(90px,.5fr) 1fr auto;gap:12px;
  align-items:start;padding:16px 2px;border-bottom:1px solid var(--line)}
.review__k{font-size:.78rem;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft);padding-top:.2em}
html[lang="ko"] .review__k{letter-spacing:.04em;text-transform:none;font-size:.88rem}
.review__v{line-height:1.7;overflow-wrap:anywhere}
.review__v ul li + li{margin-top:.25em}
/* Shown wherever a reply that has already been sent could be sent again. */
.rsvp__already{margin-bottom:1.2em;padding:.9em 1.1em;border-radius:10px;
  background:var(--cream-2);color:var(--ink);line-height:1.7;font-size:.94rem}

.done{text-align:center}
.done__seal{width:78px;height:78px;margin:0 auto 1.3em}
.done h3{font-size:clamp(1.6rem,4.4vw,2.1rem);font-weight:400;margin-bottom:.5em;line-height:1.3}
.done p{color:var(--ink-soft);line-height:1.8}
.done__downloads{margin-top:1.8em;padding-top:1.6em;border-top:1px solid var(--line)}
.done__downloads h4{font-size:1.05rem;font-weight:500;margin-bottom:.9em}
.done__downloads .btn{margin:.25em}

/* =========================================================================
   Chunk 6/6 — gallery/portrait, responsive, reduced motion, print
   ========================================================================= */

.portrait{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  gap:clamp(28px,6vw,72px);align-items:center;max-width:960px;margin:0 auto}
.portrait__words p{margin-bottom:1em;line-height:1.85;color:var(--ink-soft);font-size:1.08rem}
.portrait__words p:last-child{margin-bottom:0}
.portrait__quote{margin-top:1.6em;padding-left:1.5em;border-left:2px solid var(--sage)}
.portrait__quote p{font-family:var(--script);font-size:1.85rem;line-height:1.35;
  color:var(--sage-deep);margin-bottom:.3em}
html[lang="ko"] .portrait__quote p{font-size:1.3rem;line-height:1.6}
.portrait__quote span{font-size:.92rem;letter-spacing:.1em;color:var(--ink-soft)}

.gallery{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;max-width:1040px;margin:0 auto}
.gallery .frame{border-color:var(--sage-line);background:var(--white)}

/* ── Responsive ────────────────────────────────────────────────────────── */
@media (max-width:900px){
  .event,.venue,.portrait{grid-template-columns:1fr}
  .event--rev .event__info{order:0}
  .venue__media{min-height:0}
  .venue__media .frame{aspect-ratio:16/9}
  .portrait__quote{margin-top:1.4em}
  .gallery{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:560px){
  :root{--gut:7vw}
  .chrome__mark-text{display:none}
  .hero{padding-top:120px}
  .cd{min-width:60px}
  .countdown__grid{gap:16px}
  .rsvp__nav .btn{min-width:100%}
  .review__row{grid-template-columns:1fr;gap:4px}
  .gallery{grid-template-columns:1fr}
  .menu__list a{font-size:clamp(1.7rem,8vw,2.2rem)}
}
@media (max-width:360px){
  body{font-size:17px}
  .cd__num{font-size:2rem}
  .cd{min-width:52px}
  .langswitch button{padding:.5em .7em}
}
@media (min-width:1200px){
  .section{padding-inline:max(var(--gut),calc((100vw - 1240px)/2))}
}

/* ── Reduced motion: genuinely off, not merely faster ──────────────────── */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    scroll-behavior:auto !important;
  }
  [data-reveal]{opacity:1 !important;transform:none !important;transition:none !important}
  .envelope__card{animation:none !important}
  .hero__scroll i{animation:none !important}
  .btn:hover{transform:none !important}
}

/* ── Print: the invitation, on paper ───────────────────────────────────── */
@media print{
  .chrome,.menu,.envelope,.hero__scroll,.rsvp__card,.skip-link{display:none !important}
  body{background:#fff;color:#000;font-size:12pt}
  .section{padding:18pt 0;break-inside:avoid}
  .hero{min-height:auto;color:#000;padding:0 0 18pt}
  .hero__art,.hero__veil{display:none}
  .colophon{background:none;color:#000}
}

/* hero slot fill (SPEC-13 hero-primary, 4:5 source, bleed crop) */
.hero__art > svg{width:100%;height:100%}
.done__seal svg{border-radius:50%}
.gallery .frame__cap{color:var(--ink)}

/* Chrome sits over the sunlit hero until the page scrolls: ink either way,
   no light-on-dark swap needed. Checked both ways for AA. */
.chrome:not(.is-scrolled) .chrome__mark-glyph,
.chrome:not(.is-scrolled) .chrome__mark-text{color:var(--ink-soft);text-shadow:none}
.chrome:not(.is-scrolled) .langswitch,
.chrome:not(.is-scrolled) .chrome__menu{background:rgba(255,253,249,.94);border-color:rgba(255,253,249,.5)}
