/* ============================================================
   義信 & 姵璇 — Wedding Invitation
   Layout: every section is one "card" of identical width, and the
   whole type scale is derived from that width (--col), so the
   proportions match the printed cards in Style/ at any viewport.
   ============================================================ */

/* ---------- Self-hosted webfonts ----------
   All faces are subset to the exact characters this page uses
   (118 CJK + 59 Latin), so the full set weighs ~236 KB instead of 80 MB+.
   Rebuild with the pipeline documented in instruction.md if copy changes. */

/* Abhaya Libre — English serif */
@font-face {
  font-family: 'Abhaya Libre';
  src: url('assets/fonts/AbhayaLibre-Regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Abhaya Libre';
  src: url('assets/fonts/AbhayaLibre-Medium.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Abhaya Libre';
  src: url('assets/fonts/AbhayaLibre-SemiBold.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Abhaya Libre';
  src: url('assets/fonts/AbhayaLibre-Bold.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}

/* LINE Seed Sans — English sans */
@font-face {
  font-family: 'LINE Seed Sans';
  src: url('assets/fonts/LINESeedSans-Thin.woff2') format('woff2');
  font-weight: 300; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'LINE Seed Sans';
  src: url('assets/fonts/LINESeedSans-Regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'LINE Seed Sans';
  src: url('assets/fonts/LINESeedSans-Bold.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}

/* 源樣明體 GenYoMin TW — Chinese serif */
@font-face {
  font-family: 'GenYoMin TW';
  src: url('assets/fonts/GenYoMinTW-Regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'GenYoMin TW';
  src: url('assets/fonts/GenYoMinTW-Medium.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}

/* 台北黑體 Taipei Sans TC — Chinese sans */
@font-face {
  font-family: 'Taipei Sans TC';
  src: url('assets/fonts/TaipeiSans-Regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Taipei Sans TC';
  src: url('assets/fonts/TaipeiSans-Bold.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}

:root {
  --paper:      #F7F4EF;
  --paper-warm: #FBF9F5;
  --ink:        #1B1740;  /* navy — English display type */
  --ink-black:  #1A1A1A;  /* near-black — Chinese content */
  --ink-soft:   #3A3556;
  --muted:      #7C7689;
  --rule:       #DCD6CB;
  --rose:       #B24A4A;

  /* CJK stacks list the Latin face second: the CJK subsets carry no
     Latin glyphs, so digits and roman text fall through to it. */
  --display:  'Abhaya Libre', Georgia, 'Times New Roman', serif;
  --sans-en:  'LINE Seed Sans', 'Helvetica Neue', Arial, sans-serif;
  --serif-tc: 'GenYoMin TW', 'Abhaya Libre', Georgia, serif;
  --sans-tc:  'Taipei Sans TC', 'LINE Seed Sans', 'Helvetica Neue', Arial, sans-serif;
  --script:   'Abhaya Libre', Georgia, serif;

  --gutter: clamp(1.25rem, 5vw, 2rem);

  /* The card column. Every section is exactly this wide, and every
     type size below is a fraction of it — that is what keeps the
     proportions identical from 390px to desktop. */
  --col: min(100vw - 2 * var(--gutter), 34rem);

  /* Type scale, measured off the printed cards as a % of card width.
     max() adds a legibility floor so small text stays readable on
     phones, where a pure ratio would fall below ~9px. */
  --fs-title:    max(2.5rem,   calc(var(--col) * 0.110));  /* OUR WEDDING DAY */
  --fs-month:    max(1.375rem, calc(var(--col) * 0.052));  /* 09              */
  --fs-heading:  max(1rem,     calc(var(--col) * 0.0425)); /* 時間 / 建議穿著  */
  --fs-body-tc:  max(1rem,     calc(var(--col) * 0.0413)); /* 證婚儀式 / 穿著   */
  --fs-savedate: max(1.25rem,  calc(var(--col) * 0.0410)); /* SAVE the DATE   */
  --fs-poem:     max(0.9375rem,calc(var(--col) * 0.0367)); /* 邀請詩          */
  --fs-names-tc: max(0.9375rem,calc(var(--col) * 0.0327)); /* 呂義信          */
  --fs-info:     max(0.875rem, calc(var(--col) * 0.0295)); /* 時間/地點/地址   */
  --fs-names-en: max(0.75rem,  calc(var(--col) * 0.0254)); /* RICHARD LYU     */
  --fs-cal:      max(0.6875rem,calc(var(--col) * 0.0227)); /* SUN / 13        */
  --fs-date-sm:  max(0.6875rem,calc(var(--col) * 0.0210)); /* 2026.09.19      */

  /* One vertical rhythm for every section. */
  --section-y: calc(var(--col) * 0.16);
  --block-y:   calc(var(--col) * 0.09);

  /* One knob for the info list + message section, which sit a notch
     smaller than the card-derived scale. Tune this single value. */
  --fs-sm: 0.82;
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background-color: var(--paper);
  /* Subtle fibrous paper grain, inlined so the page stays self-contained */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)' opacity='0.045'/%3E%3C/svg%3E");
  color: var(--ink);
  font-family: var(--sans-tc);
  font-weight: 400;
  line-height: 1.9;
  overflow-x: hidden;
}

img { display: block; max-width: 100%; height: auto; }
figure { margin: 0; }
a { color: inherit; }

/* Every section is the same card column, centred. */
.cover,
.portrait,
.invitation,
.date-card,
.message,
.countdown,
.footer {
  width: var(--col);
  margin-inline: auto;
  text-align: center;
}

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

/* ---------- Scroll animations ---------- */

.fade-in, .slide-left, .slide-right {
  opacity: 0;
  transition: opacity 1.1s ease, transform 1.1s cubic-bezier(0.22, 1, 0.36, 1);
}
.fade-in     { transform: translateY(24px); }
.slide-left  { transform: translateX(-28px); }
.slide-right { transform: translateX(28px); }

.fade-in.visible, .slide-left.visible, .slide-right.visible {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .fade-in, .slide-left, .slide-right {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ============================================================
   Section 1 — Cover
   ============================================================ */

.cover {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.cover-title {
  margin: 0;
  font-family: var(--display);
  font-weight: 400;
  font-size: var(--fs-title);
  line-height: 1.06;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink);
}

.cover-title span { display: block; }

.cover-names {
  margin: calc(var(--col) * 0.075) 0 0;
  font-family: var(--serif-tc);
  font-size: var(--fs-savedate);
  font-weight: 400;
  letter-spacing: 0.2em;
  text-indent: 0.2em;   /* offset the trailing letter-space, keeps it centred */
  color: var(--ink);
}

.cover-meta { margin-top: calc(var(--col) * 0.1); }

.cover-date {
  margin: 0 0 0.9em;
  font-family: var(--sans-en);
  font-size: var(--fs-date-sm);
  font-weight: 400;
  letter-spacing: 0.22em;
  color: var(--ink-soft);
}

.cover-venue {
  margin: 0;
  font-family: var(--display);
  font-size: calc(var(--fs-savedate) * 0.8);
  font-weight: 500;
  letter-spacing: 0.02em;
}

.scroll-indicator {
  position: absolute;
  left: 50%;
  bottom: calc(var(--col) * 0.06);
  transform: translateX(-50%);
  transition: opacity 0.6s ease;
}

.scroll-line {
  display: block;
  width: 1px;
  height: calc(var(--col) * 0.1);
  background: linear-gradient(to bottom, transparent, var(--muted));
  animation: scrollPulse 2.6s ease-in-out infinite;
  transform-origin: top;
}

@keyframes scrollPulse {
  0%, 100% { transform: scaleY(0.35); opacity: 0.35; }
  50%      { transform: scaleY(1);    opacity: 1; }
}

/* ============================================================
   Section 2 — Portrait  (card 002)
   ============================================================ */

.portrait { padding-bottom: var(--section-y); }

.portrait-photo {
  position: relative;
  overflow: hidden;
}

/* 2:3 is the photo's native ratio — nothing is cropped, so heads
   can never be cut off at any viewport width. */
.portrait-photo img {
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  object-position: center;
  animation: kenBurns 22s ease-out both;
}

@keyframes kenBurns {
  from { transform: scale(1.06); }
  to   { transform: scale(1); }
}

.portrait-caption {
  position: absolute;
  inset: auto 0 0 0;
  padding: calc(var(--col) * 0.18) calc(var(--col) * 0.06) calc(var(--col) * 0.06);
  color: #fff;
  background: linear-gradient(to top, rgba(20, 18, 32, 0.66), transparent);
}

.portrait-names {
  margin: 0 0 0.5em;
  font-family: var(--sans-en);
  font-size: var(--fs-names-en);
  font-weight: 300;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  white-space: nowrap;
}

.portrait-quote {
  margin: 1.2em 0 0;
  font-family: var(--display);
  font-size: calc(var(--fs-date-sm) * 1.05);
  font-weight: 400;
  line-height: 1.8;
  color: rgba(255, 255, 255, 0.9);
}

/* ============================================================
   Section 3 — Invitation / Save the Date  (card 004)
   ============================================================ */

.invitation { padding-bottom: var(--section-y); }

.invitation-head { margin-bottom: var(--block-y); }

.arc-text {
  display: block;
  width: 100%;
  margin: 0 auto;
  overflow: visible;
}

.arc-text text {
  fill: var(--ink);
  font-family: var(--display);
  font-size: 36px;
  font-weight: 500;
  letter-spacing: 0.14em;
}

.invitation-date {
  margin: 0.4em 0 0;
  font-family: var(--display);
  font-size: var(--fs-date-sm);
  letter-spacing: 0.14em;
  color: var(--ink-soft);
}

.framed-photo {
  padding: calc(var(--col) * 0.022);
  background: var(--paper-warm);
  box-shadow: 0 1px 0 rgba(27, 23, 64, 0.06),
              0 18px 40px -28px rgba(27, 23, 64, 0.45);
}

/* Native ratios again — no cropping anywhere. */
.framed-photo img {
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: cover;
}

/* IMG_4395 is 3396x2331, not exactly 3:2 — use its true ratio so
   this photo is uncropped too. */
.framed-photo--wide img { aspect-ratio: 3396 / 2331; }

.save-the-date {
  margin: var(--block-y) 0 0;
  font-family: var(--display);
  font-size: var(--fs-savedate);
  font-weight: 400;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.save-the-date em {
  font-style: italic;
  font-size: 0.9em;
  text-transform: lowercase;
  padding: 0 0.15em;
}

/* ============================================================
   Section 4 — Couple & Calendar  (card 003)
   ============================================================ */

.date-card { padding-bottom: var(--section-y); }

.calendar-month {
  margin: 0 0 calc(var(--col) * 0.07);
  font-family: var(--display);
  font-size: var(--fs-month);
  font-weight: 400;
  letter-spacing: 0.04em;
}

/* Narrower than the card column so the seven columns sit close together
   instead of being spread across the full width. */
.calendar-week,
.calendar-days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  align-items: center;
  width: calc(var(--col) * 0.62);
  margin-inline: auto;
  column-gap: 0;
}

.calendar-week span,
.calendar-days span {
  font-family: var(--display);
  font-size: var(--fs-cal);
  letter-spacing: 0.06em;
  color: var(--ink-soft);
}

.calendar-days {
  margin-top: calc(var(--col) * 0.018);
  row-gap: calc(var(--col) * 0.008);
}

/* Uniform square cells keep the five rows evenly spaced and let the
   highlighted date sit flush with the plain ones. */
.calendar-days span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  justify-self: center;
  width: calc(var(--col) * 0.055);
  height: calc(var(--col) * 0.055);
  line-height: 1;
}

.calendar-highlight {
  position: relative;
  z-index: 0;
  color: #fff !important;
  font-weight: 500;
}

.calendar-highlight::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath fill='%23B24A4A' d='M50 92C14 64 2 45 2 28 2 11 15 2 27 2c11 0 19 7 23 16 4-9 12-16 23-16 12 0 25 9 25 26 0 17-12 36-48 64z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* --- Couple names --- */

.couple {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--col) * 0.03);
  margin: var(--block-y) 0;
}

.couple-side { flex: 1; }

.couple-zh {
  margin: 0 0 0.4em;
  font-family: var(--sans-tc);
  font-size: var(--fs-names-tc);
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--ink-black);
}

.couple-role {
  margin-right: 0.6em;
  color: var(--ink-black);
}

.couple-en {
  margin: 0;
  font-family: var(--sans-en);
  font-size: var(--fs-names-en);
  font-weight: 300;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}

.couple-heart {
  flex: none;
  font-size: var(--fs-names-en);
  color: var(--ink);
}

/* --- Photo & info --- */

.bleed-photo img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  object-position: center 40%;
}

/* Shrink to the widest row and centre that block, so the label/value
   columns stay aligned instead of each line centring on its own. */
.info-list {
  width: fit-content;
  max-width: 100%;
  margin: var(--block-y) auto 0;
  text-align: left;
}

.info-row {
  display: flex;
  gap: calc(var(--col) * 0.04);
  padding: 0.85em 0;
  border-bottom: 1px solid var(--rule);
}

.info-row:last-child { border-bottom: 0; }

.info-row dt {
  flex: none;
  font-family: var(--sans-tc);
  font-weight: 700;
  font-size: calc(var(--fs-info) * var(--fs-sm));
  letter-spacing: 0.22em;
  color: var(--ink-black);
}

.info-row dd {
  margin: 0;
  font-family: var(--sans-tc);
  font-size: calc(var(--fs-info) * var(--fs-sm));
  font-weight: 400;
  line-height: 1.8;
  letter-spacing: 0.06em;
  color: var(--ink-black);
}

.map-link {
  display: table;   /* own line, but underline hugs the text */
  margin-top: 0.6em;
  padding-bottom: 0.2em;
  font-size: 0.92em;
  letter-spacing: 0.1em;
  text-decoration: none;
  color: var(--ink);
  border-bottom: 1px solid var(--ink);
  transition: opacity 0.3s ease;
}

.map-link:hover { opacity: 0.55; }

/* ============================================================
   Section 5 — Message, Schedule, Dress Code  (card 005)
   ============================================================ */

.message { padding-bottom: var(--section-y); }

.script-title {
  margin: 0 0 var(--block-y);
  font-family: var(--script);
  font-size: calc(var(--fs-title) * 0.62 * var(--fs-sm));
  font-weight: 400;
  line-height: 1.25;
  color: var(--ink-black);
}

.message-text {
  margin: 0;
  font-family: var(--serif-tc);
  font-size: calc(var(--fs-poem) * var(--fs-sm));
  font-weight: 400;
  line-height: 2.15;
  letter-spacing: 0.08em;
  color: var(--ink-black);
}

.heart-divider {
  display: block;
  margin: var(--block-y) 0;
  font-size: calc(var(--fs-info) * var(--fs-sm));
  color: var(--rose);
}

/* Only used inside .message (時 間 / 建 議 穿 著). */
.block-title {
  margin: 0 0 calc(var(--col) * 0.06);
  font-family: var(--sans-tc);
  font-size: calc(var(--fs-heading) * var(--fs-sm));
  font-weight: 700;
  letter-spacing: 0.28em;
  text-indent: 0.28em;
  color: var(--ink-black);
}

.schedule { margin-bottom: var(--block-y); }

.schedule-row {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: calc(var(--col) * 0.06);
  padding: 0.4em 0;
}

.schedule-time {
  min-width: 4.5em;
  text-align: right;
  font-family: var(--display);
  font-size: calc(var(--fs-body-tc) * 1.05 * var(--fs-sm));
  letter-spacing: 0.04em;
}

.schedule-label {
  min-width: 5em;
  text-align: left;
  font-family: var(--serif-tc);
  font-size: calc(var(--fs-body-tc) * var(--fs-sm));
  letter-spacing: 0.12em;
  color: var(--ink-black);
}

.dress-code { margin-top: var(--block-y); }

.dress-list {
  display: inline-block;
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: left;
}

.dress-list li {
  font-family: var(--serif-tc);
  font-size: calc(var(--fs-body-tc) * var(--fs-sm));
  line-height: 2.15;
  letter-spacing: 0.1em;
  color: var(--ink-black);
}

.dress-list li::before {
  content: "・";
  margin-right: 0.15em;
}

.swatches {
  display: flex;
  justify-content: center;
  gap: calc(var(--col) * 0.035);
  margin: var(--block-y) 0 0;
  padding: 0;
  list-style: none;
}

.swatches li {
  width: calc(var(--col) * 0.088);
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--swatch);
}

/* ============================================================
   Section 6 — Countdown
   ============================================================ */

.countdown { padding-bottom: var(--section-y); }

.countdown-caption {
  margin: 0 0 calc(var(--col) * 0.07);
  font-family: var(--display);
  font-style: italic;
  font-size: var(--fs-date-sm);
  letter-spacing: 0.1em;
  color: var(--muted);
}

.countdown-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: calc(var(--col) * 0.02);
}

.countdown-box {
  padding: 0 calc(var(--col) * 0.01);
  border-left: 1px solid var(--rule);
}

.countdown-box:first-child { border-left: 0; }

.countdown-number {
  display: block;
  font-family: var(--display);
  font-size: var(--fs-month);
  font-weight: 400;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

.countdown-number.pop { animation: numberPop 0.4s ease; }

@keyframes numberPop {
  0%   { transform: translateY(0.18em); opacity: 0.3; }
  100% { transform: translateY(0);      opacity: 1; }
}

.countdown-label {
  display: block;
  margin-top: 0.5em;
  font-size: calc(var(--fs-cal) * 0.9);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}

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

.footer {
  padding: var(--block-y) 0 var(--section-y);
  border-top: 1px solid var(--rule);
}

.footer-names {
  margin: 0 0 0.5em;
  font-family: var(--script);
  font-size: var(--fs-savedate);
}

.footer-names-tc {
  margin: 0;
  font-family: var(--serif-tc);
  font-size: var(--fs-date-sm);
  letter-spacing: 0.2em;
  text-indent: 0.2em;   /* offset the trailing letter-space, keeps it centred */
  color: var(--muted);
}
