@charset "UTF-8";

@font-face {
  font-family: "CeremonyBuri";
  src: url("../fonts/ceremony-buri-regular.4930dc40b0.woff2") format("woff2");
  /* preloaded from the document head, so a short block beats a visible swap */
  font-style: normal;
  font-weight: 400;
  font-display: block;
}

@font-face {
  font-family: "CeremonyBuri";
  src: url("../fonts/ceremony-buri-semibold.201e8ee778.woff2") format("woff2");
  font-style: normal;
  font-weight: 600;
  font-display: block;
}

@font-face {
  font-family: "CeremonySans";
  src: url("../fonts/ceremony-sans-variable.2cc39d717c.woff2") format("woff2-variations");
  font-style: normal;
  font-weight: 45 920;
  font-display: swap;
}

:root {
  --canvas: #e6e0d4;
  --paper: #fbf8f1;
  --cream: #f5eee1;
  --soft-gray: #f5eee1;
  --ink: #2a2521;
  --ink-soft: #57504a;
  --muted: #6f665f;
  --indigo: #3b5170;
  --indigo-soft: #e4e9f0;
  --coral: #a95343;
  --coral-soft: #f1ddd6;
  --rose: #b0596b;
  --rose-ink: #9c4a5d;
  --rose-soft: #f6e3e7;
  --gold: #b6975c;
  --gold-soft: #e6d9bd;
  --sage: #7f957f;
  --blue-gray: #6f819c;
  --line: #e3dbcc;
  --white: #fff;
  --display-ko: "CeremonyBuri", AppleMyungjo, "Nanum Myeongjo", Batang, serif;
  --body: "CeremonySans", Pretendard, -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", sans-serif;
  --ease-paper: cubic-bezier(.2, .75, .25, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
}

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

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

body {
  margin: 0;
  min-width: 320px;
  min-height: 100%;
  overflow-x: hidden;
  color: var(--ink);
  background: var(--canvas);
  font-family: var(--body);
  font-size: 15px;
  line-height: 1.75;
  font-synthesis: none;
  word-break: keep-all;
  overflow-wrap: break-word;
  -webkit-font-smoothing: antialiased;
}

button,
input,
textarea {
  color: inherit;
  font: inherit;
}

button,
summary,
a {
  -webkit-tap-highlight-color: transparent;
}

button {
  border: 0;
  cursor: pointer;
}

a {
  color: inherit;
}

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

svg {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.65;
}

:focus-visible {
  outline: 3px solid #b85f4e;
  outline-offset: 3px;
}

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

.skip-link {
  position: fixed;
  z-index: 2000;
  top: 10px;
  left: 10px;
  padding: 10px 14px;
  border-radius: 3px;
  color: var(--white);
  background: var(--ink);
  transform: translateY(-150%);
  transition: transform .2s ease;
}

.skip-link:focus {
  transform: translateY(0);
}

/* An author `display` beats the UA rule for [hidden], which silently leaves
   toggled-off blocks on screen. Keep the attribute authoritative. */
[hidden] {
  display: none !important;
}

.page-stage {
  min-height: 100vh;
  min-height: 100svh;
}

main:focus {
  outline: 0;
}

.invitation-shell {
  width: 100%;
  max-width: 440px;
  margin: 0 auto;
  background: var(--paper);
}

.content-column {
  min-width: 0;
  background: var(--paper);
}

.eyebrow {
  margin: 0 0 17px;
  color: var(--coral);
  font-family: var(--display-ko);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .16em;
  line-height: 1.2;
}

/* Watercolor cover — full-width on mobile, fixed at left on desktop. */
.hero {
  position: relative;
  width: 100%;
  height: auto;
  min-height: 0;
  aspect-ratio: 941 / 1672;
  container-type: inline-size;
  overflow: hidden;
  color: var(--ink);
  background: var(--paper);
}

.hero__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  animation: watercolor-arrive 1.35s var(--ease-paper) both;
}

.hero__copy {
  position: absolute;
  top: 23cqw;
  right: 22px;
  left: 22px;
  text-align: center;
}

.hero__caption {
  margin: 0 0 10px;
  color: var(--coral);
  font-family: var(--display-ko);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: .18em;
  line-height: 1.2;
  /* The letter-spacing is trailing space on the last glyph; pull it back so the
     word stays optically centred over the names. */
  text-indent: .18em;
}

.hero h1 {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 10px;
  margin: 0;
  font-family: var(--display-ko);
  font-size: clamp(24px, 7.4vw, 32px);
  font-weight: 400;
  letter-spacing: .08em;
  line-height: 1.2;
}

.hero h1 i {
  color: var(--muted);
  font-size: .38em;
  font-style: normal;
  letter-spacing: .02em;
}

.hero__event {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin-top: 8px;
  color: var(--ink-soft);
  font-family: var(--body);
  font-size: 11px;
  letter-spacing: .025em;
  line-height: 1.6;
}

.hero__event span {
  font-family: var(--body);
  letter-spacing: .03em;
}

.scroll-cue {
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 1px;
  height: 34px;
  overflow: hidden;
  background: rgba(220, 128, 109, .2);
}

.scroll-cue span {
  display: block;
  width: 1px;
  height: 16px;
  background: var(--coral);
  animation: scroll-line 1.8s ease-in-out infinite;
}

@keyframes watercolor-arrive {
  from { opacity: .55; transform: scale(1.015); }
  to { opacity: 1; transform: scale(1); }
}

@keyframes scroll-line {
  from { transform: translateY(-18px); }
  65%, to { transform: translateY(38px); }
}

.paper-section {
  position: relative;
  padding: 56px 28px;
  background-color: var(--paper);
  background-image: repeating-linear-gradient(0deg, transparent 0 4px, rgba(100, 72, 55, .009) 4px 5px);
}

.section-heading {
  margin-bottom: 26px;
  text-align: center;
}

.section-heading h2 {
  margin: 0;
  font-family: var(--display-ko);
  font-size: 25px;
  font-weight: 400;
  letter-spacing: -.015em;
  line-height: 1.45;
}

.section-heading > p:last-child:not(.eyebrow),
.section-disclosure > .section-heading > p {
  margin: 8px 0 0;
  color: var(--muted);
  font-size: 13px;
}



/* Invitation text */
.greeting {
  padding-top: 66px;
  padding-bottom: 58px;
  background-color: var(--cream);
  text-align: center;
}

.greeting__text {
  margin: 0;
  color: var(--ink-soft);
  font-family: var(--display-ko);
  font-size: 15px;
  line-height: 2.28;
}

.greeting__names {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  margin: 43px 0 0;
  color: var(--muted);
  font-size: 12px;
}

.greeting__names span {
  min-width: 190px;
}

.greeting__names small {
  display: block;
  margin-bottom: 1px;
  color: var(--muted);
  font-size: 11px;
  letter-spacing: .06em;
}

.greeting__names strong {
  margin-left: 5px;
  color: var(--ink);
  font-family: var(--display-ko);
  font-size: 17px;
  font-weight: 600;
}

.greeting__names i {
  width: 52px;
  height: 1px;
  margin: 3px 0;
  background: rgba(220, 128, 109, .36);
}

/* Family information follows the source invitation's inline disclosure. */
.family-section {
  padding: 0 24px 22px;
  border-top: 1px solid #ececeb;
  border-bottom: 1px solid #e4e5e4;
  background: var(--cream);
}

.family-disclosure summary {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-height: 54px;
  cursor: pointer;
  color: var(--ink-soft);
  font-size: 12px;
  list-style: none;
}

.family-disclosure summary::-webkit-details-marker,
.transport-list summary::-webkit-details-marker,
.account-groups summary::-webkit-details-marker {
  display: none;
}

.family-disclosure summary i {
  width: 8px;
  height: 8px;
  border-right: 1px solid var(--muted);
  border-bottom: 1px solid var(--muted);
  transform: translateY(-2px) rotate(45deg);
  transition: transform .2s ease;
}

.family-disclosure[open] summary i {
  transform: translateY(2px) rotate(225deg);
}

.family-columns {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  padding-top: 3px;
}

.contact-family {
  min-width: 0;
  padding: 17px 14px 13px;
  border: 1px solid #e3e5e3;
  background: var(--white);
}

.contact-family h3 {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0 0 13px;
  padding-bottom: 10px;
  border-bottom: 1px solid #ececeb;
  font-size: 12px;
  font-weight: 650;
}

.contact-family p {
  display: flex;
  justify-content: space-between;
  gap: 5px;
  margin: 0;
  padding: 8px 0;
  color: var(--muted);
  font-size: 11px;
}

.contact-family p strong {
  color: var(--ink);
  font-weight: 600;
}






/* Venue */
.location-section {
  padding-right: 30px;
  padding-left: 30px;
}

.venue-copy {
  text-align: center;
}

.venue-copy h3 {
  margin: 0 0 10px;
  font-family: var(--display-ko);
  font-size: 20px;
  font-weight: 600;
}

.venue-copy h3 span {
  display: block;
  margin-top: 10px;
  color: var(--muted);
  font-family: inherit;
  font-size: 20px;
  font-weight: inherit;
}

.venue-copy p {
  margin: 0;
  color: var(--muted);
  font-size: 13px;
}

.venue-copy .venue-tel {
  margin-top: 8px;
  font-size: 12px;
  letter-spacing: .01em;
}

.map-embed {
  position: relative;
  margin: 33px -30px 0;
  overflow: hidden;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: #f0eee9;
}

.map-embed iframe {
  display: block;
  width: 100%;
  height: 248px;
  border: 0;
}

.map-actions {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  margin: 0 -28px 22px;
  border-bottom: 1px solid var(--line);
  background: var(--white);
}

.map-actions > * {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  min-height: 51px;
  padding: 5px;
  border-right: 1px solid var(--line);
  color: var(--ink-soft);
  background: transparent;
  font-size: 12px;
  text-decoration: none;
}

.map-actions span {
  font-weight: 600;
}

.map-actions small {
  color: var(--muted);
  font-size: 10px;
}

.map-actions > *:last-child {
  border-right: 0;
}

.venue-actions {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin-bottom: 24px;
}

.venue-actions > * {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 46px;
  border: 1px solid var(--line);
  border-radius: 2px;
  color: var(--ink-soft);
  background: var(--paper);
  font-size: 12px;
  text-decoration: none;
}

.venue-actions svg {
  width: 16px;
  height: 16px;
}

.transport-list,
.account-groups {
  border-top: 1px solid var(--line);
}

.transport-list details,
.account-groups details {
  border-bottom: 1px solid var(--line);
}

.transport-list summary,
.account-groups summary {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 59px;
  padding: 8px 32px 8px 4px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 650;
  list-style: none;
}

.transport-list summary::after,
.account-groups summary::after {
  position: absolute;
  top: 50%;
  right: 8px;
  width: 8px;
  height: 8px;
  border-right: 1px solid var(--muted);
  border-bottom: 1px solid var(--muted);
  content: "";
  transform: translateY(-70%) rotate(45deg);
  transition: transform .2s ease;
}

.transport-list details[open] summary::after,
.account-groups details[open] summary::after {
  transform: translateY(-20%) rotate(225deg);
}

.transport-list details > p {
  margin: -2px 0 0;
  padding: 0 4px 20px;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.75;
}

.transport-list details > p strong {
  color: var(--ink-soft);
}

.transport-list details > p small {
  color: var(--muted);
  font-size: 10px;
}

/* Accounts */
.account-section {
  background: var(--cream);
}

.account-groups summary {
  gap: 9px;
}

.account-list {
  padding-bottom: 14px;
}

.account-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  margin-bottom: 7px;
  padding: 13px 12px 13px 15px;
  border: 1px solid #e4ddd1;
  background: rgba(255, 255, 255, .72);
}

.account-row p {
  min-width: 0;
  margin: 0;
  line-height: 1.45;
}

.account-row p span,
.account-row p strong {
  display: block;
}

.account-row p span {
  margin-bottom: 3px;
  color: var(--muted);
  font-size: 11px;
}

.account-row p strong {
  font-size: 13px;
  font-weight: 600;
}

.account-row button {
  min-width: 48px;
  min-height: 44px;
  padding: 0 9px;
  border: 1px solid #d9cec2;
  border-radius: 2px;
  color: var(--ink-soft);
  background: var(--white);
  font-size: 12px;
}

/* Footer */
.footer {
  padding: 48px 28px calc(96px + env(safe-area-inset-bottom));
  color: var(--ink-soft);
  background: var(--paper);
  text-align: center;
}

.footer__thanks {
  margin: 0;
  font-family: var(--display-ko);
  font-size: 15px;
  line-height: 2;
}

.footer__closing-name {
  margin: 24px 0 0;
  color: var(--ink);
  font-family: var(--display-ko);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .04em;
}

/* Mobile utility mirrors the source's two final actions. */
.floating-utility {
  position: fixed;
  z-index: 700;
  right: max(12px, calc((100vw - 440px) / 2 + 12px));
  bottom: calc(12px + env(safe-area-inset-bottom));
  left: max(12px, calc((100vw - 440px) / 2 + 12px));
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  max-width: 416px;
  margin: 0 auto;
  padding: 5px;
  border: 1px solid rgba(226, 217, 207, .9);
  border-radius: 3px;
  background: rgba(255, 253, 246, .94);
  box-shadow: 0 8px 28px rgba(68, 52, 40, .14);
  opacity: 0;
  transform: translateY(20px);
  transition: opacity .3s ease, transform .3s ease;
  pointer-events: none;
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}

.floating-utility.is-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.floating-utility button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 45px;
  border-right: 1px solid var(--line);
  color: var(--ink);
  background: transparent;
  font-size: 12px;
  font-weight: 600;
}

.floating-utility button:last-child {
  border-right: 0;
}

.floating-utility svg {
  width: 16px;
  height: 16px;
}

.toast {
  position: fixed;
  z-index: 3000;
  right: 22px;
  bottom: calc(80px + env(safe-area-inset-bottom));
  left: 22px;
  max-width: 360px;
  margin: 0 auto;
  padding: 12px 17px;
  border-radius: 3px;
  color: var(--white);
  background: rgba(55, 49, 44, .94);
  box-shadow: 0 7px 24px rgba(45, 34, 27, .2);
  font-size: 12px;
  text-align: center;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity .22s ease, transform .22s ease;
  pointer-events: none;
}

.toast.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.js .reveal {
  opacity: 0;
  filter: blur(6px);
  transition: opacity .9s ease, filter .9s var(--ease-out);
}

.js .reveal.is-visible {
  opacity: 1;
  filter: blur(0);
}

/* Opening: the cover settles in once on load. The global reduced-motion rule
   above already collapses this to an instant paint. */
@keyframes cover-copy-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

.js .hero__copy > * {
  animation: cover-copy-rise .95s var(--ease-paper) both;
}

.js .hero__caption { animation-delay: .35s; }
.js .hero h1 { animation-delay: .55s; }
.js .hero__event { animation-delay: .75s; }

/* Ceremony month: open paper, fine rules and a single wedding-day seal. */
.calendar {
  max-width: 320px;
  margin: 28px auto 0;
  padding: 18px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  font-family: var(--display-ko);
}

.calendar__row--head,
.calendar__grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 6px 0;
}

.calendar__row--head {
  margin-bottom: 12px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  text-align: center;
}

.calendar__cell {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 36px;
  color: var(--ink-soft);
  font-size: 16px;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.calendar .is-sunday { color: var(--coral); }
.calendar .is-saturday { color: var(--indigo); }

.calendar__cell.is-ceremony {
  position: relative;
  width: 32px;
  height: 32px;
  margin: 2px auto;
  border-radius: 50%;
  background: var(--coral);
  color: var(--white);
  font-weight: 600;
}

.calendar__cell.is-ceremony::after {
  position: absolute;
  inset: -3px;
  border: 1px solid var(--coral-soft);
  border-radius: 50%;
  content: "";
}

.countdown {
  display: flex;
  flex-direction: row-reverse;
  align-items: baseline;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  margin: 22px 0 0;
  text-align: center;
}

.countdown strong {
  color: var(--coral);
  font-family: var(--display-ko);
  font-size: 21px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
  line-height: 1.4;
}

.countdown span {
  color: var(--muted);
  font-family: var(--display-ko);
  font-size: 13px;
  font-weight: 400;
}

/* Shared form controls for RSVP and the guestbook */
.rsvp-form,
.guestbook-form {
  display: grid;
  gap: 16px;
  margin-top: 20px;
  text-align: left;
}

.rsvp-form fieldset {
  margin: 0;
  padding: 0;
  border: 0;
}

.rsvp-form legend,
.field > label {
  display: block;
  margin-bottom: 8px;
  padding: 0;
  color: var(--ink-soft);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .02em;
}

.field > label small,
.field__hint {
  color: var(--muted);
  font-size: 11px;
  font-weight: 400;
}

.field__hint {
  display: block;
  margin-top: 6px;
}

.choice-row {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

.choice-row--three {
  grid-template-columns: repeat(3, 1fr);
}

.choice-row label {
  position: relative;
  display: block;
}

.choice-row input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.choice-row span {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 45px;
  padding: 0 8px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: var(--white);
  color: var(--ink-soft);
  font-size: 13px;
  cursor: pointer;
  transition: border-color .18s ease, background .18s ease, color .18s ease;
}

.choice-row input:checked + span {
  border-color: var(--coral);
  background: var(--coral-soft);
  color: var(--coral);
  font-weight: 600;
}

.choice-row input:focus-visible + span {
  outline: 2px solid var(--coral);
  outline-offset: 2px;
}

.field input,
.field textarea {
  display: block;
  width: 100%;
  min-height: 45px;
  padding: 12px 13px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: var(--white);
  color: var(--ink);
  font-family: var(--body);
  font-size: 14px;
}

.field textarea {
  resize: vertical;
  line-height: 1.6;
}

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

.form-note {
  margin: 0;
  color: var(--muted);
  font-size: 11px;
}

.primary-button {
  min-height: 48px;
  border: 0;
  border-radius: 3px;
  background: var(--coral);
  color: var(--white);
  font-family: var(--body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: .04em;
}

.primary-button:disabled {
  background: var(--muted);
  cursor: progress;
}

.ghost-button {
  width: 100%;
  min-height: 45px;
  margin-top: 14px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: var(--white);
  color: var(--ink-soft);
  font-family: var(--body);
  font-size: 13px;
}

.form-status {
  margin: 0;
  min-height: 17px;
  font-size: 12px;
}

.form-status[data-tone="ok"] { color: var(--sage); }
.form-status[data-tone="error"] { color: var(--coral); }
.form-status[data-tone="pending"] { color: var(--muted); }

/* Guestbook entries */
.guestbook-list {
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
  text-align: left;
}

.guestbook-entry {
  position: relative;
  padding: 17px 0;
  border-bottom: 1px solid var(--line);
}

.guestbook-entry__head {
  display: flex;
  align-items: baseline;
  gap: 9px;
  margin-bottom: 7px;
}

.guestbook-entry__head strong {
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
}

.guestbook-entry__head span {
  color: var(--muted);
  font-size: 11px;
}

.guestbook-entry p {
  margin: 0;
  padding-right: 44px;
  color: var(--ink-soft);
  font-size: 13px;
  line-height: 1.75;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.guestbook-entry__delete {
  position: absolute;
  top: 13px;
  right: 0;
  min-width: 44px;
  min-height: 32px;
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: 11px;
}

.guestbook-empty {
  padding: 22px 0;
  color: var(--muted);
  font-size: 12px;
  text-align: center;
}

@media (min-width: 520px) and (max-width: 959px) {
  .page-stage {
    padding: 30px 0 48px;
  }

  .invitation-shell {
    box-shadow: 0 22px 65px rgba(58, 45, 35, .14);
  }
}

/* Desktop keeps the single phone-width column centred. Korean mobile
   invitations are read on a phone first and simply centre the same
   composition when the link is opened on a computer, so the cover and the
   details stay in one continuous scroll at every width. The floating
   utility and toast already centre themselves against the 440px column,
   so they need no desktop override. */
@media (min-width: 960px) {
  body {
    background-color: var(--canvas);
    background-image:
      linear-gradient(90deg, rgba(255, 255, 255, .15) 1px, transparent 1px),
      linear-gradient(rgba(255, 255, 255, .12) 1px, transparent 1px);
    background-size: 42px 42px;
  }

  .page-stage {
    padding: 42px 0 72px;
  }

  .invitation-shell {
    box-shadow: 0 24px 80px rgba(58, 45, 35, .16);
  }
}

@media (max-width: 359px) {
  .hero__copy {
    top: 20cqw;
  }

  .hero__caption {
    margin-bottom: 7px;
    font-size: 13px;
    letter-spacing: .14em;
    text-indent: .14em;
  }

  .hero__event {
    margin-top: 5px;
    line-height: 1.4;
  }

  .paper-section {
    padding-right: 23px;
    padding-left: 23px;
  }

  .family-section {
    padding-right: 18px;
    padding-left: 18px;
  }

  .location-section .map-embed,
  .location-section .map-actions {
    margin-right: -23px;
    margin-left: -23px;
  }

  .account-row {
    padding-left: 11px;
  }

  .account-row p strong {
    font-size: 12px;
  }

  .contact-family {
    padding-right: 10px;
    padding-left: 10px;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }

  .js .reveal {
    opacity: 1;
    filter: none;
  }
}

/* Inline validation replaces the browser's own bubble, which covers the next
   field on a phone. */
.field.is-invalid input,
.field.is-invalid textarea {
  border-color: var(--coral);
  box-shadow: 0 0 0 2px var(--coral-soft);
}

fieldset.is-invalid .choice-row span {
  border-color: var(--coral);
}

.form-status[data-tone="error"] {
  font-weight: 600;
}

/* After a successful RSVP the form gives way to a confirmation card, so a
   guest is never left wondering whether it went through. */
.rsvp-done {
  display: grid;
  gap: 8px;
  margin-top: 20px;
  padding: 24px 20px;
  border: 1px solid var(--coral-soft);
  border-radius: 3px;
  background: var(--white);
  text-align: center;
}

.rsvp-done strong {
  color: var(--coral);
  font-family: var(--display-ko);
  font-size: 17px;
  font-weight: 600;
}

.rsvp-done p {
  margin: 0;
  color: var(--ink-soft);
  font-size: 13px;
  line-height: 1.7;
}

.rsvp-done button {
  margin-top: 6px;
  min-height: 44px;
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: 12px;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ------------------------------------------------------------------ */
/* Emphasis, motion and finish. Indigo from the groom's hanbok carries
   every action and every strong statement; a single gold thread rule
   marks structure; rouge stays reserved for the ceremony day, the bride's
   side and the cover caption. One orchestrated moment on load, then
   motion only answers what the guest does.                             */
/* ------------------------------------------------------------------ */

/* Cover: names carry the page */
.hero h1 {
  gap: 12px;
  font-size: clamp(27px, 8.6cqw, 36px);
  letter-spacing: .1em;
}

.hero h1 i {
  font-size: .36em;
}

.hero__event {
  margin-top: 10px;
  color: var(--ink);
  font-size: 12px;
  letter-spacing: .04em;
}

.hero__event time {
  font-weight: 600;
}

@keyframes hero-drift {
  from { transform: scale(1); }
  to   { transform: scale(1.035) translateY(-.6%); }
}

.js .hero__image {
  transform-origin: 50% 35%;
  animation:
    watercolor-arrive 1.35s var(--ease-paper) both,
    hero-drift 16s 1.4s ease-in-out infinite alternate;
}

/* Section titles: a short gold thread draws in beneath each title once
   the section is on screen. */
.section-heading {
  margin-bottom: 24px;
}

.section-heading h2 {
  position: relative;
  padding-bottom: 16px;
  color: var(--ink);
  letter-spacing: .04em;
}

.section-heading h2::after {
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 30px;
  height: 1px;
  background: var(--gold);
  transform: translateX(-50%) scaleX(0);
  transform-origin: center;
  transition: transform .8s .35s var(--ease-out);
  content: "";
}

.reveal.is-visible .section-heading h2::after,
html:not(.js) .section-heading h2::after {
  transform: translateX(-50%) scaleX(1);
}

.section-heading > p:last-child:not(.eyebrow),
.section-disclosure > .section-heading > p {
  margin-top: 12px;
}

.eyebrow {
  margin-bottom: 12px;
  color: var(--indigo);
  letter-spacing: .12em;
}

/* Invitation text: the couple's names are the emphasis, not the labels */
.greeting__names strong {
  color: var(--ink);
  font-size: 19px;
}

/* Family cards: quiet, no heavy chrome */



/* Disclosures unfold instead of snapping */
@keyframes unfold {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

details[open] > :not(summary) {
  animation: unfold .36s var(--ease-out) both;
}

.family-disclosure summary,
.transport-list summary,


.transport-list summary::after,
.family-disclosure summary i {
  transition: transform .3s var(--ease-out);
}

/* Venue: the real map, toned to the paper, framed like a plate */
.venue-copy h3 {
  color: var(--ink);
  font-size: 22px;
}

.venue-copy h3 span {
  color: var(--ink-soft);
}

.map-embed {
  position: relative;
  overflow: hidden;
  border: 0;
  border-radius: 2px;
  background: var(--cream);
  /* Hairlines as shadows so the map keeps its full-bleed width on a phone. */
  box-shadow: inset 0 0 0 1px var(--line), 0 0 0 1px var(--gold-soft);
}

.map-embed iframe {
  display: block;
  filter: grayscale(.38) sepia(.26) saturate(.72) brightness(1.03) contrast(.96);
  transition: filter .5s ease;
}

.map-embed:hover iframe,
.map-embed:focus-within iframe {
  filter: grayscale(.1) sepia(.08) saturate(.95);
}

/* The anchor is the pin's tip: the rotated 18px square's lowest corner sits
   22px below the marker's top edge, so the marker is lifted by exactly that.
   The label then hangs just under the tip instead of pushing the pin up. */
.map-embed__marker {
  position: absolute;
  top: 50%;
  left: 50%;
  display: grid;
  justify-items: center;
  transform: translate(-50%, -22px);
  pointer-events: none;
  will-change: left, top;
}

.map-embed__marker--parking {
  transform: translate(-50%, -27px);
}

.map-embed__marker span {
  margin-top: 6px;
}

.map-embed__marker i {
  width: 18px;
  height: 18px;
  border: 3px solid var(--paper);
  border-radius: 50% 50% 50% 0;
  background: var(--indigo);
  box-shadow: 0 6px 14px rgba(42, 37, 33, .28);
  transform: rotate(-45deg);
}

.map-embed__marker i::after {
  position: absolute;
  bottom: -14px;
  left: 50%;
  width: 14px;
  height: 5px;
  border-radius: 50%;
  background: rgba(42, 37, 33, .22);
  transform: translateX(-50%) rotate(45deg);
  filter: blur(1.5px);
  content: "";
}

.map-embed__marker span {
  padding: 5px 10px;
  border: 1px solid var(--gold-soft);
  border-radius: 2px;
  background: rgba(251, 248, 241, .96);
  color: var(--ink);
  font-family: var(--display-ko);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .06em;
  white-space: nowrap;
  box-shadow: 0 3px 10px rgba(42, 37, 33, .12);
}

.map-caption {
  display: none;
  margin: 10px 0 18px;
  color: var(--muted);
  font-size: 12px;
  letter-spacing: .02em;
  text-align: center;
}

.map-actions {
  margin-top: 0;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--white);
}

.map-actions > * {
  color: var(--ink-soft);
  transition: background .2s ease;
}

.map-actions > *:hover,
.map-actions > *:focus-visible {
  background: var(--indigo-soft);
}

.map-actions small {
  color: var(--muted);
}

.venue-actions a,
.venue-actions button {
  color: var(--indigo);
  border-color: var(--line);
}

.venue-actions svg {
  stroke: currentColor;
}

/* Accounts */
.account-row p strong {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
}

.account-row button,
[data-copy] {
  transition: background .2s ease, color .2s ease, border-color .2s ease;
}

.account-row button {
  color: var(--indigo);
}

.account-row button.is-copied,
.venue-actions button.is-copied {
  border-color: var(--indigo);
  background: var(--indigo);
  color: var(--white);
}

/* Forms */
.choice-row input:checked + span {
  border-color: var(--indigo);
  background: var(--indigo-soft);
  color: var(--indigo);
}

.choice-row input:focus-visible + span,
.field input:focus-visible,
.field textarea:focus-visible {
  border-color: var(--indigo);
  outline-color: var(--indigo);
}

.choice-row span {
  transition: border-color .18s ease, background .18s ease, color .18s ease, transform .12s ease;
}

.choice-row span:active {
  transform: scale(.985);
}

.primary-button {
  background: var(--indigo);
  transition: background .2s ease, transform .12s ease;
}

.primary-button:hover {
  background: #33475f;
}

.primary-button:active {
  transform: scale(.99);
}

.rsvp-done {
  border-color: var(--gold-soft);
  animation: unfold .5s var(--ease-out) both;
}

.rsvp-done strong {
  color: var(--indigo);
}

.form-status[data-tone="ok"] { color: var(--sage); }

.field.is-invalid input,
.field.is-invalid textarea {
  border-color: var(--coral);
  box-shadow: 0 0 0 2px var(--coral-soft);
}

/* Guestbook */
.guestbook-entry__head strong {
  color: var(--ink);
}

.guestbook-entry {
  animation: unfold .4s var(--ease-out) both;
}

.guestbook-entry__delete {
  color: var(--muted);
}

.guestbook-entry__delete:hover {
  color: var(--indigo);
}

/* Utility bar */
.floating-utility button {
  color: var(--indigo);
}

.floating-utility svg {
  stroke: currentColor;
}

/* Footer */
.footer__closing-name {
  color: var(--ink);
  letter-spacing: .1em;
}

/* Which side: one segmented switch instead of colour-coded dots. The thumb
   slides to the chosen side; only that side's accounts are shown. */
.side-toggle {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  margin: 0 auto 18px;
  padding: 4px;
  max-width: 260px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--white);
  box-shadow: inset 0 1px 2px rgba(42, 37, 33, .05);
}

.side-toggle button {
  position: relative;
  z-index: 1;
  min-height: 40px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font-family: var(--display-ko);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: .06em;
  transition: color .25s ease;
}

.side-toggle button[aria-selected="true"] {
  color: var(--white);
}

.side-toggle button:focus-visible {
  outline: 2px solid var(--indigo);
  outline-offset: 3px;
}

.side-toggle__thumb {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 4px;
  width: calc(50% - 4px);
  border-radius: 999px;
  background: var(--indigo);
  box-shadow: 0 4px 12px rgba(59, 81, 112, .28);
  transition: transform .32s var(--ease-out);
}

.side-toggle[data-side="bride"] .side-toggle__thumb {
  transform: translateX(100%);
}

.account-groups .account-list {
  animation: unfold .36s var(--ease-out) both;
}

.contact-family h3 {
  display: block;
  text-align: center;
  color: var(--ink);
  font-family: var(--display-ko);
  letter-spacing: .06em;
}

.contact-family h3::after {
  display: block;
  width: 22px;
  height: 1px;
  margin: 8px auto 0;
  background: var(--gold);
  content: "";
}

/* ------------------------------------------------------------------ */
/* Material: paper grain, light and warm shadow.                        */
/* ------------------------------------------------------------------ */

/* A faint mulberry-fibre grain over the whole card. The noise is an inline
   SVG so nothing is fetched; multiply keeps it in the paper, not on top. */
.invitation-shell {
  position: relative;
  isolation: isolate;
}

.invitation-shell::before {
  position: absolute;
  z-index: 2;
  inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='260' height='260'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .35 0 0 0 0 .3 0 0 0 0 .22 0 0 0 .55 0'/></filter><rect width='100%25' height='100%25' filter='url(%23g)'/></svg>");
  background-size: 260px 260px;
  opacity: .11;
  mix-blend-mode: multiply;
  pointer-events: none;
  content: "";
}

/* Light falls from the upper left across every section, and the cover's
   edges fall off softly into the paper instead of ending on a hard line. */
.paper-section,
.footer {
  position: relative;
  background-image:
    radial-gradient(120% 60% at 18% 0%, rgba(255, 255, 255, .55), transparent 60%),
    linear-gradient(180deg, rgba(120, 96, 60, .025), transparent 40%, rgba(120, 96, 60, .03));
}

.hero::after {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(130% 90% at 50% 40%, transparent 55%, rgba(120, 96, 60, .14) 100%),
    linear-gradient(180deg, transparent 84%, var(--paper) 100%);
  pointer-events: none;
  content: "";
}

.hero__copy {
  z-index: 1;
}

/* Gold thread: fades at both ends like a real stitch */
.section-heading h2::after,
.contact-family h3::after {
  background: linear-gradient(90deg, transparent, var(--gold) 30%, var(--gold) 70%, transparent);
}

/* Depth: warm ink shadows, never neutral grey */
.account-row,
.contact-family,
.rsvp-done,
.map-actions,
.side-toggle {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, .7) inset,
    0 1px 2px rgba(74, 58, 36, .06),
    0 10px 24px -14px rgba(74, 58, 36, .22);
}

.map-embed {
  box-shadow:
    inset 0 0 0 1px var(--line),
    inset 0 0 40px rgba(74, 58, 36, .08),
    0 0 0 1px var(--gold-soft),
    0 16px 34px -20px rgba(74, 58, 36, .35);
}

.map-embed::after {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: radial-gradient(110% 80% at 50% 50%, transparent 60%, rgba(74, 58, 36, .12));
  pointer-events: none;
  content: "";
}

.map-embed__marker {
  z-index: 2;
}

/* Indigo controls catch a little light on the top edge */
.primary-button,
.side-toggle__thumb,
.account-row button.is-copied {
  background-image: linear-gradient(180deg, rgba(255, 255, 255, .12), transparent 55%);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .18) inset, 0 8px 18px -10px rgba(59, 81, 112, .55);
}

.choice-row input:checked + span {
  box-shadow: 0 1px 0 rgba(255, 255, 255, .6) inset, 0 6px 14px -10px rgba(59, 81, 112, .5);
}

.floating-utility {
  border-color: rgba(227, 219, 204, .95);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .8) inset, 0 12px 30px -12px rgba(74, 58, 36, .3);
}

.toast {
  background: rgba(42, 37, 33, .94);
}

@media (prefers-reduced-motion: reduce) {
  .js .hero__image { animation: none; }
}

/* Parents are named the customary way: "A · B의 아들 C". The relation reads
   quieter than the names on either side of it. */
.greeting__names small {
  letter-spacing: .02em;
}

.greeting__names small em {
  margin: 0;
  color: var(--muted);
  font-style: normal;
  letter-spacing: inherit;
}

/* Two points on one map: the venue and the overflow car park, joined by the
   shuttle route. Marker positions are projected by app.js from the
   coordinates on the section, so they stay exact at any column width. */
.map-embed__marker {
  transition: opacity .4s ease;
}

.map-embed__marker--parking i {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border: 2px solid var(--indigo);
  border-radius: 50% 50% 50% 0;
  background: var(--paper);
  color: var(--indigo);
  font-family: var(--body);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  transform: rotate(-45deg);
}

.map-embed__marker--parking i > * { transform: rotate(45deg); }

.map-embed__marker--parking span {
  font-family: var(--body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .02em;
}

.map-embed__route {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
}

.map-embed__route polyline {
  fill: none;
  stroke: var(--gold);
  stroke-width: 2.5;
  stroke-dasharray: 5 6;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  filter: drop-shadow(0 1px 0 rgba(255, 255, 255, .8));
}

@keyframes shuttle-run {
  to { stroke-dashoffset: -22; }
}

.reveal.is-visible .map-embed__route polyline {
  animation: shuttle-run 2.4s linear infinite;
}

.map-legend {
  display: grid;
  gap: 7px;
  margin: 12px 0 18px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: var(--white);
  list-style: none;
  color: var(--ink-soft);
  font-size: 12px;
  line-height: 1.5;
}

.map-legend li {
  display: flex;
  align-items: center;
  gap: 9px;
}

.map-legend i {
  flex: none;
  display: grid;
  place-items: center;
  width: 16px;
  height: 16px;
  font-style: normal;
}

.map-legend__venue {
  width: 12px;
  height: 12px;
  margin: 0 2px;
  border: 2px solid var(--paper);
  border-radius: 50% 50% 50% 0;
  background: var(--indigo);
  transform: rotate(-45deg);
}

.map-legend__parking {
  border: 1.5px solid var(--indigo);
  border-radius: 50%;
  color: var(--indigo);
  font-family: var(--body);
  font-size: 10px;
  font-weight: 700;
}

.map-legend__shuttle {
  width: 18px;
  height: 0;
  border-top: 2.5px dashed var(--gold);
}

/* Labels open away from the nearest frame edge: the venue sits at the
   left of the frame so its label runs right; the car park at the right so
   its label runs left. The marker box itself is only the pin, so the
   projected point stays exactly under the tip. */
.map-embed__marker span {
  position: absolute;
  top: 100%;
  left: 50%;
  margin-top: 4px;
  transform: translateX(-50%);
}

.map-embed__marker--venue span {
  left: -4px;
  transform: none;
}

.map-embed__marker--parking span {
  right: -4px;
  left: auto;
  transform: none;
}

/* The venue is the subject of the map: a larger, darker pin with the
   display-face label; the overflow car park is clearly secondary. */
.map-embed__marker--venue i {
  width: 22px;
  height: 22px;
  border-width: 3px;
  background: var(--indigo);
  box-shadow: 0 0 0 3px rgba(59, 81, 112, .18), 0 8px 18px rgba(42, 37, 33, .32);
}

.map-embed__marker--venue {
  transform: translate(-50%, -27px);
}

.map-embed__marker--venue span {
  padding: 6px 12px;
  font-size: 13px;
}

.map-embed__marker--parking {
  opacity: .92;
}

.map-embed__marker--parking i {
  width: 18px;
  height: 18px;
  border-width: 1.5px;
  font-size: 10px;
  box-shadow: 0 4px 10px rgba(42, 37, 33, .18);
}

.map-embed__marker--parking {
  transform: translate(-50%, -22px);
}

.map-embed__marker--parking span {
  padding: 4px 8px;
  border-color: var(--line);
  color: var(--ink-soft);
  font-size: 11px;
  font-weight: 500;
  box-shadow: 0 2px 6px rgba(42, 37, 33, .1);
}

.map-legend strong {
  color: var(--ink);
  font-weight: 600;
}

.transport-list details > p strong {
  color: var(--ink);
}

/* Map loading: paper and a quiet note until Google's frame has painted,
   then the frame, markers and route fade in together. */
.map-embed::before {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: grid;
  place-items: center;
  color: var(--muted);
  font-size: 12px;
  letter-spacing: .04em;
  content: "지도를 불러오는 중";
}

.map-embed iframe,
.map-embed__marker,
.map-embed__route {
  opacity: 0;
  transition: opacity .6s ease;
}

.map-embed[data-loaded="true"] iframe,
.map-embed[data-loaded="true"] .map-embed__marker,
.map-embed[data-loaded="true"] .map-embed__route {
  opacity: 1;
}

.map-embed[data-loaded="true"] .map-embed__marker--parking {
  opacity: .92;
}

/* Head count: a stepper is quicker on a phone than the number keypad */
.stepper {
  display: grid;
  grid-template-columns: 48px 1fr 48px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: var(--white);
  overflow: hidden;
}

.stepper button {
  min-height: 45px;
  border: 0;
  background: var(--cream);
  color: var(--indigo);
  font-size: 20px;
  font-weight: 500;
  line-height: 1;
  transition: background .15s ease;
}

.stepper button:hover { background: var(--indigo-soft); }
.stepper button:active { background: var(--indigo-soft); }
.stepper button:focus-visible { outline: 2px solid var(--indigo); outline-offset: -2px; }

.stepper input {
  min-height: 45px;
  border: 0;
  border-right: 1px solid var(--line);
  border-left: 1px solid var(--line);
  border-radius: 0;
  text-align: center;
  font-variant-numeric: tabular-nums;
  -moz-appearance: textfield;
}

.stepper input::-webkit-outer-spin-button,
.stepper input::-webkit-inner-spin-button {
  margin: 0;
  -webkit-appearance: none;
}

.stepper input:focus-visible {
  outline-offset: -2px;
}

/* Guestbook delete: an inline confirmation row instead of a browser prompt */
.guestbook-entry__confirm {
  display: grid;
  /* minmax(0, …): a text input's intrinsic width would otherwise refuse to
     shrink and push the buttons past the edge of a phone screen. */
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: 6px;
  margin-top: 10px;
  animation: unfold .3s var(--ease-out) both;
}

.guestbook-entry__confirm input {
  width: 100%;
  min-width: 0;
  min-height: 40px;
  padding: 0 11px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: var(--white);
  font-family: var(--body);
  font-size: 13px;
}

.guestbook-entry__confirm input:focus-visible {
  border-color: var(--indigo);
  outline: 2px solid var(--indigo);
  outline-offset: 1px;
}

.guestbook-entry__confirm button {
  min-height: 40px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 3px;
  background: var(--white);
  color: var(--ink-soft);
  font-size: 12px;
}

.guestbook-entry__confirm button[data-confirm] {
  border-color: var(--indigo);
  background: var(--indigo);
  color: var(--white);
  font-weight: 600;
}

.guestbook-entry__confirm .form-status {
  grid-column: 1 / -1;
}

/* Alignment pass */

/* Legend: every glyph lives in the same 18px box, so the three lines of
   text start on one vertical line. */
.map-legend li {
  align-items: flex-start;
}

.map-legend i {
  position: relative;
  width: 18px;
  height: 18px;
  margin: 0;
  border: 0;
  border-radius: 0;
  background: none;
  transform: none;
  font-size: 0;
}

.map-legend__venue::before {
  position: absolute;
  top: 2px;
  left: 3px;
  width: 11px;
  height: 11px;
  border: 1.5px solid var(--paper);
  border-radius: 50% 50% 50% 0;
  background: var(--indigo);
  transform: rotate(-45deg);
  content: "";
}

.map-legend__parking::before {
  position: absolute;
  inset: 1px;
  display: grid;
  place-items: center;
  border: 1.5px solid var(--indigo);
  border-radius: 50%;
  color: var(--indigo);
  font-family: var(--body);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  content: "P";
}

.map-legend__shuttle::before {
  position: absolute;
  top: 8px;
  right: 0;
  left: 0;
  border-top: 2.5px dashed var(--gold);
  content: "";
}

.map-legend li > span {
  line-height: 18px;
}

/* Side switch: the serif face carries a tall ascent, so the label is
   nudged down to sit on the pill's optical centre. */
.side-toggle button {
  padding-top: 3px;
  line-height: 1;
}

/* Closing line: the middle dot keeps normal spacing while the names keep
   their tracking. */
.footer__closing-name span {
  margin: 0 .35em;
  letter-spacing: 0;
}

/* A taller frame shows the whole approach: station, venue block and the
   overflow car park with the road between them. */
.map-embed iframe {
  height: 430px;
}

@media (min-width: 520px) {
  .map-embed iframe {
    height: 460px;
  }
}

/* The shuttle line follows the road (route points on the section), drawn
   over the frame in frame pixels. */
.map-embed__route polyline {
  stroke-width: 3;
  stroke-dasharray: 6 7;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 1.5px rgba(255, 255, 255, .9)) drop-shadow(0 1px 1px rgba(74, 58, 36, .25));
}

/* The frame is a locked plate by default: our markers and route can only be
   right while the map inside has not moved. A guest who wants to pan or
   zoom switches it live, which hides the overlay until it is put back. */
.map-embed iframe {
  pointer-events: none;
}

.map-embed.is-live iframe {
  pointer-events: auto;
}

.map-embed.is-live .map-embed__marker,
.map-embed.is-live .map-embed__route {
  opacity: 0;
  pointer-events: none;
}

.map-embed__toggle {
  position: absolute;
  bottom: 12px;
  left: 12px;
  z-index: 3;
  min-height: 40px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(251, 248, 241, .96);
  color: var(--indigo);
  font-family: var(--body);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .02em;
  box-shadow: 0 4px 12px rgba(74, 58, 36, .18);
  transition: background .2s ease, color .2s ease;
}

.map-embed__toggle[aria-pressed="true"] {
  border-color: var(--indigo);
  background: var(--indigo);
  color: var(--white);
}

.map-embed__toggle:focus-visible {
  outline: 2px solid var(--indigo);
  outline-offset: 2px;
}

.map-embed__note {
  position: absolute;
  top: 12px;
  left: 50%;
  z-index: 3;
  margin: 0;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(42, 37, 33, .82);
  color: var(--white);
  max-width: calc(100% - 24px);
  font-size: 11px;
  text-align: center;
  transform: translateX(-50%);
  pointer-events: none;
  animation: unfold .3s var(--ease-out) both;
}

/* ------------------------------------------------------------------ */
/* Map: Leaflet on OpenStreetMap tiles. The pins and the shuttle route are
   layers of the map itself, so they pan and zoom with it.               */
/* ------------------------------------------------------------------ */
.map-embed__canvas {
  height: 430px;
  background: var(--cream);
  font-family: var(--body);
}

@media (min-width: 520px) {
  .map-embed__canvas {
    height: 460px;
  }
}

.map-embed .leaflet-container {
  background: var(--cream);
  font-family: var(--body);
}

/* Tiles take the paper tone; the marker and route panes stay crisp. */
.map-embed .leaflet-tile-pane {
  filter: grayscale(.38) sepia(.26) saturate(.72) brightness(1.03) contrast(.96);
  transition: filter .5s ease;
}

.map-embed:hover .leaflet-tile-pane,
.map-embed:focus-within .leaflet-tile-pane {
  filter: grayscale(.1) sepia(.08) saturate(.95);
}

/* Vignette sits above the tiles and below the markers. */
.map-embed::after {
  z-index: 450;
}

.map-embed::before {
  z-index: 0;
}

.map-embed[data-loaded="true"]::before {
  display: none;
}

/* Marker icons are empty boxes at the point; the pin hangs from them. */
.map-embed .map-pin {
  background: none;
  border: 0;
}

.map-embed .map-pin .map-embed__marker {
  top: 0;
  left: 0;
  opacity: 1;
}

.map-embed .leaflet-marker-pane {
  z-index: 600;
}

/* Shuttle route as a map path */
.map-embed path.shuttle-route {
  fill: none;
  stroke: var(--gold);
  stroke-width: 3;
  stroke-dasharray: 6 7;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 1.5px rgba(255, 255, 255, .9)) drop-shadow(0 1px 1px rgba(74, 58, 36, .25));
}

.reveal.is-visible .map-embed path.shuttle-route {
  animation: shuttle-run 2.4s linear infinite;
}

/* Controls */
.map-embed__controls {
  position: absolute;
  bottom: 12px;
  left: 12px;
  z-index: 1000;
  display: flex;
  gap: 6px;
}

.map-embed__controls button {
  min-width: 40px;
  min-height: 40px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(251, 248, 241, .96);
  color: var(--indigo);
  font-family: var(--body);
  font-size: 12px;
  font-weight: 600;
  box-shadow: 0 4px 12px rgba(74, 58, 36, .18);
  transition: background .2s ease;
}

.map-embed__controls button[data-map-zoom] {
  padding: 0;
  font-size: 18px;
  font-weight: 500;
}

.map-embed__controls button:hover {
  background: var(--indigo-soft);
}

.map-embed__controls button:focus-visible {
  outline: 2px solid var(--indigo);
  outline-offset: 2px;
}

.map-embed .leaflet-control-attribution {
  padding: 2px 6px;
  background: rgba(251, 248, 241, .85);
  color: var(--muted);
  font-size: 10px;
}

.map-embed .leaflet-control-attribution a {
  color: var(--ink-soft);
}

.map-embed__fallback {
  margin: 0;
  padding: 24px;
  color: var(--muted);
  font-size: 12px;
  text-align: center;
}

.map-actions {
  grid-template-columns: repeat(4, 1fr);
}

.map-actions small {
  white-space: nowrap;
}

/* Retire the frame-era toggle */
.map-embed__toggle,
.map-embed__note {
  display: none;
}

/* Legend: icon | name | description, so the descriptions share one left edge */
.map-legend li {
  display: grid;
  grid-template-columns: 18px 6.4em minmax(0, 1fr);
  align-items: start;
  column-gap: 9px;
}

.map-legend strong,
.map-legend li > span {
  line-height: 18px;
}

/* Bride's side takes a rose tone wherever the two sides are chosen */
.side-toggle[data-side="bride"] .side-toggle__thumb {
  background: var(--rose);
  background-image: linear-gradient(180deg, rgba(255, 255, 255, .12), transparent 55%);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .18) inset, 0 8px 18px -10px rgba(176, 89, 107, .55);
}

.choice-row label[data-side="bride"] input:checked + span {
  border-color: var(--rose);
  background: var(--rose-soft);
  color: var(--rose-ink);
  box-shadow: 0 1px 0 rgba(255, 255, 255, .6) inset, 0 6px 14px -10px rgba(176, 89, 107, .5);
}

.choice-row label[data-side="bride"] input:focus-visible + span {
  border-color: var(--rose);
  outline-color: var(--rose);
}

/* RSVP and guestbook start folded; their headings remain the toggle. */
.section-disclosure > summary {
  margin-bottom: 0;
  cursor: pointer;
  list-style: none;
}

.section-disclosure > summary::-webkit-details-marker {
  display: none;
}

.section-disclosure[open] > summary {
  margin-bottom: 28px;
}

.section-disclosure__hint {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  color: var(--muted);
  font-size: 12px;
}

.section-disclosure__hint i {
  width: 6px;
  height: 6px;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
}

.section-disclosure[open] .section-disclosure__hint i {
  transform: translateY(2px) rotate(225deg);
}

.section-disclosure .when-open,
.section-disclosure[open] .when-closed {
  display: none;
}

.section-disclosure[open] .when-open {
  display: inline;
}

/* Date and weekday/time share one display face and centered heading. */
#dateTitle {
  font-size: 25px;
  letter-spacing: .015em;
}

#dateTitle time > span {
  display: block;
  white-space: nowrap;
}

#dateTitle .date-section__time {
  margin-top: 10px;
  font-size: 22px;
}

.map-embed__marker--venue small {
  display: block;
  margin-top: 3px;
  color: var(--ink-soft);
  font-family: var(--body);
  font-size: 12px;
  font-weight: 600;
}

/* 피로연·전세버스 rows: label above value, centred like the rest of the paper
   column. Only the /after-party edition renders these. */
.info-list {
  max-width: 300px;
  margin: 0 auto;
  text-align: center;
}

.info-list > div {
  padding: 18px 0;
  border-top: 1px solid var(--line);
}

.info-list > div:last-child {
  border-bottom: 1px solid var(--line);
}

.info-list dt {
  margin-bottom: 9px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 650;
  letter-spacing: .06em;
}

.info-list dd {
  margin: 0;
  color: var(--ink);
  font-family: var(--display-ko);
  font-size: 17px;
  line-height: 1.6;
  /* Korean wraps between words, never mid-word. */
  word-break: keep-all;
}

.info-list dd small {
  display: block;
  margin-top: 5px;
  color: var(--muted);
  font-family: var(--body);
  font-size: 12px;
  line-height: 1.6;
}

@media (max-width: 359px) {
  .info-list dd {
    font-size: 16px;
  }
}
