/* ============================================================
   wedding-oldhouse｜老宅囍事（阿嬤家辦喜事）
   概念：1970 年代台灣老宅——牆上一本撕日曆、一扇鐵花窗、一片磨石子地。
   跟中式喜氣劃清界線：那一套是宮廷紅金、朱門、囍印；這一套是庶民日常的懷舊、親切、有點好笑。
   - 開場：撕日曆。最上面那一頁是「今天」，往上撕掉，底下那一頁就是婚期・宜嫁娶，
     那一頁飛到 Hero 落定（一鏡到底）
   - Hero：日曆紙版式（超大日期、農曆、星期、宜嫁娶）＋鐵花窗後的婚紗照（窗後燈亮）
   - Gallery 原生版式「鐵窗花」（ironwin）：每張照片上方一格不同紋樣的漆鐵楣窗，照片本身絕不疊窗花
   - 終章「焊一朵窗花」：按住不放，在窗心焊出一朵花，花心是賓客的名字
   動態語彙：線條「焊」出來（描邊＋焊點一閃）、日曆紙翻動、磨石子反光掃過一次。
   色彩與間距 token 覆寫自 /shared/base.css。

   ── 這一套的六條體系規則，改這份檔案前先讀 ──
   ① 靜就是貴：把鐵花窗、日曆、磨石子全拿掉，版面仍是一張留白、單一強調色、襯線標題的喜帖。
      概念物件只出現在 Hero、相簿、終章與開場；內容區裡只有一根「焊條」小標線。
   ② 單一強調色＝老宅墨綠（--accent），對紙與對 RSVP 那片地都 ≥4.5，所以文字也直接用它
      （--accent-tx 與它同值，留著是給共用元件與自由取色引擎讀）。新增配色要兩個一起給。
   ③ 印的跟寫的分得出來：日曆上印的字＝思源宋體＋Old Standard TT；
      用鉛筆寫上去的字（冠名、日曆背面、彈珠）＝芫荽體（--font-pencil）＋鉛筆灰（--pencil）。
   ④ 磨石子只是紙底的質感：石子點密度極低、只在 html 背景上，絕不壓在字的底下搶對比。
   ⑤ 會一直動的東西只有焊點火花與磨石子反光，而且都只在捲進畫面時跑一次（.is-live／.is-sheen）。
      絕不 scroll-scrub，絕不多色。
   ⑥ 互動絕不擋內容：窗格、宜嫁娶都是 ≥44px 的 <button>，其餘裝飾 pointer-events:none；
      不點、不撕，喜帖照樣完整可讀（PRODUCT 原則 1：長輩零摩擦）。
   ============================================================ */

:root {
  --paper:        #ece7dd;              /* 磨石子米灰（紙底） */
  --paper-raise:  #fbf8f1;              /* 日曆紙／卡片／輸入框 */
  --ink:          #2a2823;              /* 鉛字墨（正文／標題） */
  --ink-soft:     #5c5850;              /* 次要文字（對紙 5.9／對 --sand 5.0） */
  --accent:       #2f5a46;              /* 老宅墨綠（唯一強調色：日曆大字、鐵花窗、小標） */
  --accent-tx:    #2f5a46;              /* 當文字用（同值：墨綠本身對紙就 ≥4.5） */
  --accent-ink:   #f4f1e9;              /* 強調色底上的文字色 */
  --hairline:     rgba(42, 40, 35, .15);
  --ink-rgb:      42, 40, 35;
  --sand:         #e1dbcf;              /* RSVP：比較深的那一片磨石子地 */
  --scratch-a:    #d3d6d0;              /* 刮刮樂塗層＝一片霧面玻璃的冷銀灰 */
  --scratch-b:    #b4b9b1;
  --pencil:       #47464d;
  /* 漆鐵：強調色壓深一點（鐵件的漆色比字的強調色沉），三層材質都從它推 */
  --iron:         color-mix(in srgb, var(--accent) 82%, #15140f);
  --iron-dark:    color-mix(in srgb, var(--accent) 45%, #0c0b08);              /* 鉛筆灰（寫上去的字；對日曆紙 9.0） */
  --font-pencil:  "Iansui", "Kaiti TC", "BiauKai", "DFKai-SB", serif;
  --font-serif-latin: "Old Standard TT", "Libre Baskerville", Georgia, serif;
  --font-body-tc: var(--font-serif-tc);
  --sheet-w:      min(100%, 21rem);

  --radius: .9rem;
  --section-y: clamp(4.5rem, 13vw, 7.5rem);
  --shadow-soft: 0 22px 48px -30px rgba(var(--ink-rgb), .42);

  /* 磨石子：十層各一顆石子、週期 149–379px 兩兩互質（看不出重複的格子，密度極低），
     顏色是低彩度的墨綠／磚紅／黃土／墨＋幾顆白石英，透明度都很低。 */
  --terrazzo:
    radial-gradient(circle at 18% 23%, rgba(47, 90, 70, .22) 0 1.4px, transparent 2.0px),
    radial-gradient(circle at 71% 61%, rgba(42, 40, 35, .13) 0 1.7px, transparent 2.3px),
    radial-gradient(circle at 44% 88%, rgba(255, 255, 255, .75) 0 1.9px, transparent 2.5px),
    radial-gradient(circle at 83% 17%, rgba(150, 80, 55, .18) 0 1.1px, transparent 1.7px),
    radial-gradient(circle at 29% 66%, rgba(176, 134, 70, .2) 0 1.5px, transparent 2.1px),
    radial-gradient(circle at 57% 34%, rgba(42, 40, 35, .1) 0 1px, transparent 1.6px),
    radial-gradient(circle at 9% 79%, rgba(255, 255, 255, .6) 0 1.3px, transparent 1.9px),
    radial-gradient(circle at 64% 9%, rgba(47, 90, 70, .15) 0 2px, transparent 2.6px),
    radial-gradient(circle at 36% 47%, rgba(176, 134, 70, .14) 0 0.9px, transparent 1.5px),
    radial-gradient(circle at 92% 72%, rgba(42, 40, 35, .11) 0 1.3px, transparent 1.9px);
  --terrazzo-size: 173px 191px, 229px 211px, 283px 263px, 197px 241px, 313px 277px, 149px 167px, 349px 331px, 257px 307px, 379px 353px, 223px 199px;
}

/* ---------- 配色變體：復古紅（config.theme = "brick"）----------
   只覆寫色彩 token、版式一律不動（DESIGN.md §7）。預設墨綠是冷調，這組走暖：老房子漆成紅色的鐵門。
   Hero 窗花紋樣隨配色換一款（梅花），由 render.js 的 HERO_MOTIF 決定。 */
html[data-wk-theme="brick"] {
  --accent:     #933628;
  --accent-tx:  #933628;
  --accent-ink: #fbf4f0;
  --sand:       #e6dad1;
  --scratch-a:  #d8c6b9;
  --scratch-b:  #c4ad9d;
}

/* ---------- 配色變體：花磚藍（config.theme = "tile"）----------
   冷調，像老浴室的花磚；窗花換菱花。 */
html[data-wk-theme="tile"] {
  --accent:     #2c5a7c;
  --accent-tx:  #2c5a7c;
  --accent-ink: #f2f6f9;
  --sand:       #dcdedb;
  --scratch-a:  #c3cacd;
  --scratch-b:  #aab4b8;
}

/* ---------- 配色變體：琥珀（config.theme = "amber"）----------
   暖調，像老燈泡底下的木頭窗框；窗花換日出。 */
html[data-wk-theme="amber"] {
  --accent:     #7d5010;
  --accent-tx:  #7d5010;
  --accent-ink: #fdf8ef;
  --sand:       #e6ddcb;
  --scratch-a:  #dccdb0;
  --scratch-b:  #c9b58f;
}

/* 主按鈕：實色墨綠底。ghost 鈕是一圈鉛字墨的細框 */
.btn:not(.btn-ghost) { background: var(--accent-tx); color: var(--accent-ink); }
.btn-ghost { box-shadow: inset 0 0 0 1.5px rgba(var(--ink-rgb), .3); color: var(--ink); }
.btn-ghost:hover { box-shadow: inset 0 0 0 1.5px var(--ink); }
.btn { border-radius: .5rem; letter-spacing: .12em; }

/* 底色放 html、body 透明（body 有底色會蓋掉負 z-index 的裝飾層）。磨石子只在這一層。 */
html {
  background: var(--terrazzo), var(--paper);
  background-size: var(--terrazzo-size), auto;
}
body {
  font-family: var(--wk-f-body, var(--font-body-tc));
  font-weight: 400;
  font-size: var(--text-body);
  line-height: 1.85;
  letter-spacing: .02em;
  background: transparent;
  color: var(--ink);
  overflow-x: hidden;
}

/* ---------- 動態語彙：淡入（位移小） ---------- */
.reveal {
  transform: translateY(14px);
  transition: opacity .9s var(--ease-out), transform .9s var(--ease-out);
}

/* ═══════════════════════════════════════════════════════════
   通用：標頭系統（全站置中）
   ═══════════════════════════════════════════════════════════ */
main > .section, .footer { position: relative; }
main > .section > .container,
main > .section > .container-wide { text-align: center; }
.section-title {
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(clamp(1.5rem, 5.6vw, 2rem) * var(--wk-fs-heading, 1));
  font-weight: 600;
  letter-spacing: .12em;
  text-indent: .12em;
  text-align: center;
  line-height: 1.5;
}
.label-en {
  font-family: var(--wk-f-latin, var(--font-serif-latin));
  font-size: calc(.86rem * var(--wk-fs-latin, 1));
  font-style: italic;
  color: var(--accent-tx);
  text-align: center;
  letter-spacing: .14em;
  margin-bottom: clamp(.35rem, 1.4vw, .55rem);
  line-height: 1.4;
}
/* 焊條：一根細鐵條，兩端各一顆焊點。捲進畫面時鐵條從中間往兩邊「焊」出來、焊點閃一下。
   預設 CSS＝完成態；前置隱藏態只寫在 html.fx 底下。 */
.bar-rule {
  position: relative;
  display: block;
  width: 5.6rem;
  height: 10px;
  margin: clamp(.8rem, 3vw, 1.1rem) auto 0;
  background: linear-gradient(var(--accent), var(--accent)) center / 100% 1.5px no-repeat;
}
.bar-rule::before,
.bar-rule::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 7px; height: 7px;
  margin-top: -3.5px;
  border-radius: 50%;
  background: var(--accent);
}
.bar-rule::before { left: -3px; }
.bar-rule::after  { right: -3px; }
html.fx .bar-rule.reveal { opacity: 1; transform: none; transition: background-size .7s var(--ease-out) .1s; background-size: 0 1.5px; }
html.fx .bar-rule.reveal::before,
html.fx .bar-rule.reveal::after { opacity: 0; scale: 0; }
html.fx .bar-rule.reveal.is-in { background-size: 100% 1.5px; }
html.fx .bar-rule.reveal.is-in::before,
html.fx .bar-rule.reveal.is-in::after { animation: oh-bead .55s cubic-bezier(.3, 1.6, .5, 1) .62s both; }
@keyframes oh-bead {
  0%   { opacity: 0; scale: 0; box-shadow: 0 0 0 0 rgba(255, 236, 196, 0); }
  45%  { opacity: 1; scale: 1.5; box-shadow: 0 0 0 5px rgba(255, 236, 196, .7); }
  100% { opacity: 1; scale: 1; box-shadow: 0 0 0 0 rgba(255, 236, 196, 0); }
}
.dot-sep::before { content: "\00B7"; margin-inline: .6em; opacity: .55; }

/* ═══════════════════════════════════════════════════════════
   日曆紙（Hero 與開場底下那一頁共用同一副骨架）
   ═══════════════════════════════════════════════════════════ */
.cal-sheet {
  position: relative;
  width: var(--sheet-w);
  background: var(--paper-raise);
  color: var(--ink);
  text-align: center;
  box-shadow: 0 1px 0 rgba(var(--ink-rgb), .08), 0 24px 46px -30px rgba(var(--ink-rgb), .5);
}
/* 頂端色帶：年／民國年／月。底下一排撕線（虛點） */
.cal-bind {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5rem;
  height: 2.1rem;
  padding: 0 .95rem;
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: .74rem;
  font-weight: 600;
  letter-spacing: .2em;
  white-space: nowrap;
}
.cal-bind::after {
  content: "";
  position: absolute;
  left: .4rem; right: .4rem; bottom: -6px;
  border-top: 1.5px dotted rgba(var(--ink-rgb), .3);
}
.cal-bind span:empty { display: none; }
.cal-body {
  display: grid;
  grid-template-columns: 2.6rem minmax(0, 1fr) 2.6rem;
  align-items: center;
  padding: 1.25rem .7rem .15rem;
}
.cal-lunar {
  justify-self: center;
  writing-mode: vertical-rl;
  font-size: .95rem;
  letter-spacing: .32em;
  color: var(--ink-soft);
  white-space: nowrap;
}
.cal-day {
  font-family: var(--wk-f-latin, var(--font-serif-latin));
  font-size: calc(clamp(6.6rem, 33vw, 8.8rem) * var(--wk-fs-latin, 1));
  font-weight: 700;
  line-height: .86;
  letter-spacing: -.03em;
  color: var(--accent);
  font-variant-numeric: lining-nums;
}
.cal-day:empty::before { content: "\00a0"; }
.cal-daywrap { position: relative; display: grid; place-items: center; }
/* 鉛筆圈：一鏡到底落定（或 Hero 翻下來）之後，有人拿鉛筆把日期圈起來。預設 CSS＝已經圈好 */
.cal-circle {
  position: absolute;
  left: 50%; top: 52%;
  width: 128%;
  aspect-ratio: 200 / 130;
  translate: -50% -50%;
  overflow: visible;
  pointer-events: none;
}
.cal-circle path {
  fill: none;
  stroke: var(--pencil);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: .78;
  stroke-dasharray: 1;
}
.cal-daywrap:has(.cal-day:empty) .cal-circle { display: none; }
html.fx .cal-circle path { stroke-dashoffset: 1; }
html.fx:not(.has-intro) .cal-circle path { animation: oh-circle .95s cubic-bezier(.5, .05, .3, 1) .35s both; }
html.fx:not(.has-intro):not(.wk-oh-landed) .cal-circle path { animation-delay: .95s; }
@keyframes oh-circle { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
/* 宜嫁娶：日曆右邊那一格小框（Hero 這一顆是按鈕＝彩蛋，翻到背面）。
   按鈕本體是 44px 寬的透明觸控區，看得到的框畫在裡面那個 span 上 */
.cal-yi {
  position: relative;
  justify-self: center;
  display: grid;
  place-items: center;
  min-width: 44px;
  min-height: 5.4rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent);
  font: inherit;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: .98rem;
  font-weight: 700;
  letter-spacing: .3em;
  line-height: 1.2;
}
.cal-yi:not(.cal-yi--today) > span {
  writing-mode: vertical-rl;
  padding: .55rem .28rem;
  border: 1.5px solid var(--accent);
  border-radius: 2px;
  transition: background .3s ease;
}
button.cal-yi { cursor: pointer; }
@media (hover: hover) { button.cal-yi:not(:disabled):hover > span { background: color-mix(in srgb, var(--accent) 8%, transparent); } }
button.cal-yi:disabled { cursor: default; }
button.cal-yi:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.cal-yi--today {
  display: block;
  writing-mode: vertical-rl;
  min-width: 0;
  border: 0;
  padding: 0;
  font-size: .94rem;
  color: var(--ink);
  font-weight: 400;
  color: var(--ink-soft);
  letter-spacing: .22em;
  line-height: 1.6;
}
.cal-yi--today b { color: var(--accent); font-weight: 700; margin-block-end: .25em; }
.cal-week {
  margin: .55rem 1.1rem 0;
  padding-bottom: .85rem;
  border-bottom: 1px solid var(--hairline);
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: .5em;
  text-indent: .5em;
}
.cal-week em {
  margin-left: .5em;
  font-family: var(--wk-f-latin, var(--font-serif-latin));
  font-size: .84rem;
  font-weight: 400;
  font-style: italic;
  letter-spacing: .12em;
  color: var(--ink-soft);
}
.cal-names {
  width: 100%;
  overflow: hidden;
  padding: 1.05rem .9rem 0;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(clamp(1.55rem, 6.6vw, 2rem) * var(--wk-fs-heading, 1));
  font-weight: 600;
  letter-spacing: .14em;
  line-height: 1.4;
  white-space: nowrap;
}
.cal-amp {
  margin: 0 .28em;
  font-family: var(--wk-f-latin, var(--font-serif-latin));
  font-size: .72em;
  font-style: italic;
  font-weight: 400;
  color: var(--accent);
  letter-spacing: 0;
}
.hero-names-en {
  margin-top: .2rem;
  font-family: var(--wk-f-latin, var(--font-serif-latin));
  font-size: calc(.92rem * var(--wk-fs-latin, 1));
  font-style: italic;
  color: var(--ink-soft);
  letter-spacing: .08em;
  white-space: pre;
}
.hero-names-en:empty { display: none; }
.cal-line {
  padding: .45rem 1rem 1.25rem;
  font-size: .9rem;
  letter-spacing: .12em;
  color: var(--ink-soft);
  line-height: 1.7;
}
.hero-note { display: block; font-size: .84rem; margin-top: .1rem; }
.hero-note:empty { display: none; }
/* 冠名：日曆空白處用鉛筆寫上去的一行 */
.cal-memo {
  margin: -.55rem 1.1rem 0;
  padding-bottom: 1rem;
  text-align: right;
  font-family: var(--font-pencil);
  font-size: 1.18rem;
  color: var(--pencil);
  letter-spacing: .04em;
  line-height: 1.3;
  transform: rotate(-3deg);
  transform-origin: 100% 50%;
}
.cal-memo[hidden] { display: none; }

/* 日曆背面（彩蛋①）：翻頁＝紙先壓扁到 0、換面、再張開（render.js 掛 .is-turning／.is-back） */
.hero-sheet { transition: transform .25s cubic-bezier(.2, .8, .3, 1); }
.hero-sheet.is-turning { transform: scaleX(0); transition: transform .22s cubic-bezier(.6, 0, .9, .4); }
.cal-back {
  position: absolute;
  inset: 0;
  display: none;
  padding: 1.6rem 1.4rem;
  text-align: left;
  cursor: pointer;
  background:
    repeating-linear-gradient(to bottom, transparent 0 calc(2.05rem - 1px), rgba(var(--ink-rgb), .06) calc(2.05rem - 1px) 2.05rem),
    var(--paper-raise);
  background-position: 0 calc(1.6rem + 1.2rem + 1rem + .35rem);
}
.hero-sheet.is-back .cal-face { visibility: hidden; }
.hero-sheet.is-back .cal-back { display: block; }
.cal-back-head {
  font-size: .76rem;
  letter-spacing: .3em;
  color: var(--ink-soft);
}
.cal-back-text {
  margin-top: 1rem;
  font-family: var(--font-pencil);
  font-size: 1.32rem;
  line-height: 2.05rem;
  color: var(--pencil);
  white-space: pre-line;
  transform: rotate(-1.2deg);
}

/* ═══════════════════════════════════════════════════════════
   ① Hero
   ═══════════════════════════════════════════════════════════ */
.hero {
  position: relative;
  padding: clamp(2.2rem, 8vw, 3.4rem) var(--gutter) clamp(3.4rem, 10vw, 5rem);
  text-align: center;
}
.hero-content {
  max-width: 40rem;
  margin-inline: auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
}
.hero-greeting {
  max-width: 22em;
  margin-bottom: clamp(1rem, 4vw, 1.4rem);
  font-size: .98rem;
  letter-spacing: .12em;
  color: var(--ink-soft);
  text-wrap: balance;
}
.hero-greeting:empty { display: none; }
.hero-sheet-wrap { width: var(--sheet-w); display: grid; justify-items: center; }
/* 釘子：日曆掛在牆上的那一根 */
.hero-sheet-wrap::before {
  content: "";
  width: 9px; height: 9px;
  margin-bottom: -4px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, rgba(255, 255, 255, .7) 0 18%, transparent 30%), var(--ink);
  position: relative;
  z-index: 1;
}
.hero-sheet { width: 100%; }

/* ══ 鐵窗花：楣窗＋完整的照片（Hero 與原生相簿共用） ══
   窗＝一圈白漆木框（--paper-raise）；上面一格楣窗（霧面玻璃＋漆鐵窗花），下面是完整的婚紗照。
   窗花絕不疊在照片上（2026-10-31 Jacob 打回疊在照片上的第一版）。 */
.win-head {
  position: relative;
  display: block;
  /* content-box：比例算在玻璃本身，不含底下那道 8px 的木框——否則窗花會被縮小、兩側留出一條浮著的玻璃邊 */
  box-sizing: content-box;
  aspect-ratio: 240 / 72;
  border-bottom: 8px solid var(--paper-raise);
  overflow: hidden;
  /* 霧面玻璃：磨砂顆粒＋兩道斜的反光＋上冷下暖的一點漸層；窗框內緣一圈凹進去的陰影 */
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .5 0'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='.9'/%3E%3C/svg%3E"),
    linear-gradient(112deg, transparent 28%, rgba(255, 255, 255, .6) 36%, transparent 45%, transparent 60%, rgba(255, 255, 255, .35) 64%, transparent 70%),
    /* 背光：光從左上來（跟牆上的窗影、鐵條投影同一個方向），玻璃左上亮、右下沉 */
    radial-gradient(120% 160% at 12% 0%, rgba(255, 252, 240, .85), transparent 60%),
    linear-gradient(160deg, #eef0ea, #d3d8cd 75%, #cfcdc1);
  box-shadow: inset 0 3px 5px -2px rgba(20, 25, 20, .35), inset 3px 0 5px -3px rgba(20, 25, 20, .22);
}
.transom {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
  /* 鐵條落在玻璃上的影子（光從左上來＝影子往右下） */
  filter: drop-shadow(2px 3px 1.8px rgba(18, 22, 18, .42));
}
/* 骨架（外框）比裝飾（紋樣）粗一倍半：先有框、再焊花 */
.transom path { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.tr-under path { stroke: var(--iron-dark); stroke-width: 3.2; }
.tr-under .tr-frame { stroke-width: 6.6; }
.tr-paint path { stroke: var(--iron); stroke-width: 2.8; }
.tr-paint .tr-frame { stroke-width: 6; }
.tr-shine path { stroke: rgba(255, 255, 255, .5); stroke-width: .8; }
.tr-shine .tr-frame { stroke-width: 1.3; }
.tr-under .tr-bold { stroke-width: 5; }
.tr-paint .tr-bold { stroke-width: 4.4; }
.tr-shine .tr-bold { stroke-width: 1.1; }
/* 琥珀：鐵件漆成老銅色（偏紅銅、高光暖），不是咖啡色 */
html[data-wk-theme="amber"] { --iron: #7a4626; --iron-dark: #3d2113; }
html[data-wk-theme="amber"] .tr-shine path { stroke: rgba(255, 222, 180, .62); }
html[data-wk-theme="brick"] { --iron: #6a2d23; --iron-dark: #321410; }
html[data-wk-theme="brick"] .tr-shine path { stroke: rgba(255, 226, 214, .34); }
.tr-rivets circle { fill: var(--iron); }
.tr-rivets .tr-rivet-sh { fill: var(--iron-dark); }
.tr-rivets .tr-rivet-hi { fill: rgba(255, 255, 255, .7); }
/* 焊上去：捲進畫面時鐵條一根一根畫出來、鉚釘最後一顆一顆點上（前置隱藏態只在 html.fx 底下） */
html.fx .reveal .transom :is(.tr-under, .tr-paint, .tr-shine) path:not(.tr-frame) { stroke-dasharray: 1; transition: stroke-dashoffset 1.2s cubic-bezier(.45, 0, .25, 1) .15s; }
/* 外框與玻璃從第一格就在（任何時刻都不會看到一扇空窗或半個框），只有裡面的紋樣焊進來 */
html.fx .reveal:not(.is-in) .transom :is(.tr-under, .tr-paint, .tr-shine) path:not(.tr-frame) { stroke-dashoffset: 1; }
html.fx .reveal:not(.is-in) .transom .tr-rivets g { opacity: 0; }
.tr-rivets g { transform-box: fill-box; transform-origin: center; }
html.fx:not(.has-intro) .reveal.is-in .transom .tr-rivets g { animation: oh-rivet .5s ease-out calc(.9s + .04s * min(var(--k, 0), 12)) both; }
@keyframes oh-rivet {
  0%   { opacity: 0; transform: scale(0); }
  45%  { opacity: 1; transform: scale(1.5); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes oh-weld {
  0%   { opacity: 0; transform: scale(0); }
  40%  { opacity: 1; transform: scale(2); filter: brightness(2.4); }
  100% { opacity: 1; transform: scale(1); }
}
/* Hero 那扇窗：開場期間它在牆後面——焊線等開場收掉才開始 */
html.fx.has-intro .hero-frame .transom :is(.tr-under, .tr-paint, .tr-shine) path:not(.tr-frame) { stroke-dashoffset: 1; }
/* 鉚釘也等開場收掉才點上（不然飛行中會看到一排浮著的圓珠、紋樣還沒焊） */
html.fx.has-intro .hero-frame .transom .tr-rivets g { opacity: 0; }

.hero-frame {
  position: relative;
  width: min(84%, 18.5rem);
  margin: clamp(2.6rem, 9vw, 3.4rem) 0 0;
  padding: 9px;
  background: var(--paper-raise);
  box-shadow: 0 0 0 1px rgba(var(--ink-rgb), .12), 0 30px 54px -30px rgba(var(--ink-rgb), .55);
}
.hero-frame::after {        /* 窗台 */
  content: "";
  position: absolute;
  left: -14px; right: -14px; bottom: -11px;
  height: 11px;
  background: var(--paper-raise);
  box-shadow: 0 1px 0 rgba(var(--ink-rgb), .14), 0 12px 18px -12px rgba(var(--ink-rgb), .45);
  pointer-events: none;
}
.hero-photo {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  object-position: center 30%;
}
/* 牆上的光影：同一扇窗的影子，斜斜落在窗的左後方（午後的光從右上來），淡、軟、不碰照片 */
.win-shadow {
  position: absolute;
  left: -34%; top: 10%;
  width: 100%;
  aspect-ratio: 240 / 392;
  z-index: -1;
  pointer-events: none;
  overflow: visible;
  transform: skewX(-16deg) rotate(-3deg);
  transform-origin: 100% 0;
  filter: blur(3.5px);
  opacity: .44;
}
.win-shadow path { fill: none; stroke: rgba(var(--ink-rgb), .22); stroke-width: 6; stroke-linejoin: round; stroke-linecap: round; }
.hero-content { isolation: isolate; }
/* 手機上窗影只剩左緣一小塊、讀起來像髒污——只在桌機的大牆面出現 */
@media (max-width: 1023px) { .win-shadow { display: none; } }
html.fx .hero-frame.reveal:not(.is-in) .win-shadow { opacity: 0; }
.hero-frame.reveal .win-shadow { transition: opacity 1.6s ease .6s; }
/* 窗燈（彩蛋②）：點楣窗的一格，那一格玻璃後面的燈亮起來（暖光透過霧玻璃） */
.win-hits { position: absolute; inset: 0; }
.win-hit {
  position: absolute;
  top: 0;
  width: calc(100% / 3);
  height: 100%;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.win-hit::before {
  content: "";
  position: absolute;
  inset: -15% -25%;
  background: radial-gradient(closest-side, rgba(255, 242, 210, .85), rgba(255, 222, 160, .45) 55%, transparent);
  opacity: 0;
  transition: opacity .45s ease;
  z-index: -1;
}
.win-hits { z-index: 0; isolation: isolate; }
.win-head .transom { z-index: 1; }
.win-hit.is-on::before { opacity: 1; }
.win-hit:focus-visible { outline: 2px solid var(--accent); outline-offset: -4px; }
.win-note {
  min-height: 1.8rem;
  margin-top: 2.1rem;
  font-family: var(--font-pencil);
  font-size: 1.28rem;
  color: var(--pencil);
  opacity: 0;
  transition: opacity .5s ease;
}
.win-note.is-on { opacity: 1; animation: oh-pop .5s cubic-bezier(.3, 1.4, .5, 1); }

/* 倒數：四張小小的撕日曆 */
.countdown {
  display: flex;
  gap: clamp(.55rem, 2.6vw, .8rem);
  justify-content: center;
  margin-top: clamp(1.4rem, 5vw, 2rem);
}
.cd-cell {
  display: grid;
  justify-items: center;
  width: clamp(3.7rem, 17vw, 4.3rem);
  padding: .55rem 0 .6rem;
  background: var(--paper-raise);
  border-top: 5px solid var(--accent);
  box-shadow: 0 1px 0 rgba(var(--ink-rgb), .1), 0 10px 18px -14px rgba(var(--ink-rgb), .5);
}
.cd-cell strong {
  font-family: var(--wk-f-latin, var(--font-serif-latin));
  font-size: calc(1.55rem * var(--wk-fs-latin, 1));
  font-weight: 700;
  line-height: 1.15;
  color: var(--accent);
  font-variant-numeric: tabular-nums lining-nums;
}
.cd-cell span { font-size: .78rem; color: var(--ink-soft); line-height: 1.3; letter-spacing: .1em; }

/* 沒有一鏡到底（跳過、off、量不到）：開場一收，Hero 那一頁從釘子上「翻下來」。
   落定的路徑不演這一段（那一頁本來就在原位了）。has-intro 拿掉的那一刻才開始比對＝不用 JS。 */
html.fx:not(.has-intro):not(.wk-oh-landed) .hero-sheet-wrap {
  transform-origin: 50% 0;
  animation: oh-sheet-in .85s cubic-bezier(.2, .9, .3, 1.15) both;
}
@keyframes oh-sheet-in {
  0%   { opacity: 0; transform: perspective(900px) rotateX(-70deg); }
  60%  { opacity: 1; }
  100% { opacity: 1; transform: none; }
}
/* 飛行中畫面上只准有一頁：開場那一頁飛過來時，Hero 這一頁先藏起來（版面還在、land() 照量），
   done(false) 拿掉 has-intro 的同一幀交棒 */
html.has-intro.wk-oh-landed .hero-sheet { visibility: hidden; }

/* ═══════════════════════════════════════════════════════════
   開場：撕日曆
   ═══════════════════════════════════════════════════════════ */
.intro { display: none; }
html.has-intro .intro {
  --oh-d: 0s;
  display: block;
  position: fixed;
  inset: 0;
  z-index: 80;
  overflow: hidden;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  cursor: pointer;
}
html.has-intro .intro-play { --oh-d: .4s; }
.intro-stage { position: absolute; inset: 0; }
.intro-wall {
  position: absolute;
  inset: 0;
  background: var(--terrazzo), var(--paper);
  background-size: var(--terrazzo-size), auto;
}
/* 一盞從上面照下來的燈（牆的上半截亮一點） */
.intro-wall::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(70% 45% at 50% 22%, rgba(255, 252, 244, .7), transparent 75%);
}
.pad {
  position: absolute;
  left: 50%;
  top: 46%;
  width: min(calc(100vw - 2.5rem), 21rem);
  transform: translate(-50%, -50%);
}
.pad .cal-sheet { width: 100%; }
/* 釘子＋疊在底下的那一疊紙（厚度） */
.pad-nail {
  position: absolute;
  left: 50%;
  top: -14px;
  width: 11px; height: 11px;
  margin-left: -5.5px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, rgba(255, 255, 255, .7) 0 18%, transparent 30%), var(--ink);
  z-index: 3;
}
.pad-edge {
  position: absolute;
  left: 3px; right: 3px; bottom: -7px;
  height: 7px;
  background: repeating-linear-gradient(to bottom, var(--paper-raise) 0 1.2px, rgba(var(--ink-rgb), .16) 1.2px 2px);
  box-shadow: 0 10px 16px -10px rgba(var(--ink-rgb), .5);
}
.pad-today {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  z-index: 2;
  transform-origin: 50% 0;
  transform: perspective(1100px) rotateX(calc(var(--wk-open, 0) * 32deg)) translateY(calc(var(--wk-open, 0) * -3%));
  will-change: transform;
}
.pad-today .cal-body { flex: 1; }
.cal-today {
  padding: .6rem 0 1.3rem;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: .4em;
  text-indent: .4em;
  color: var(--accent);
}
/* 撕線：今天那一頁最上緣的一排小孔 */
.pad-perf {
  position: absolute;
  left: 0; right: 0; top: 2.1rem;
  height: 0;
  border-top: 2px dotted rgba(var(--ink-rgb), .28);
}
/* 掀起來時底部那一截的陰影（越掀越深） */
.pad-curl {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(to top, rgba(var(--ink-rgb), .22), transparent 40%);
  opacity: calc(var(--wk-open, 0) * 1.6);
}
.pad-next { position: relative; z-index: 1; }
/* 底下那一頁被今天那一頁蓋著時暗一點，越掀越亮 */
.pad-next::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(var(--ink-rgb), .14);
  opacity: calc(1 - var(--wk-open, 0) * 1.4);
  pointer-events: none;
}
/* 撕剩的紙根：撕下去之後留在頂端的一截鋸齒（撕之前看不到） */
/* 撕剩的紙根＝今天那一頁的色帶＋一截鋸齒紙（撕之前看不到；色帶由開場 script 在撕的那一刻複製進來） */
.pad-stub {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: calc(2.1rem + 9px);
  z-index: 3;
  background: var(--paper-raise);
  clip-path: polygon(0 0, 100% 0, 100% calc(2.1rem + 4px), 96% calc(2.1rem + 9px), 92% calc(2.1rem + 3px), 87% calc(2.1rem + 8px), 82% calc(2.1rem + 2px), 77% calc(2.1rem + 9px), 71% calc(2.1rem + 4px), 66% calc(2.1rem + 8px), 60% calc(2.1rem + 2px), 55% calc(2.1rem + 9px), 49% calc(2.1rem + 4px), 44% calc(2.1rem + 9px), 38% calc(2.1rem + 3px), 33% calc(2.1rem + 8px), 27% calc(2.1rem + 2px), 22% calc(2.1rem + 9px), 16% calc(2.1rem + 4px), 11% calc(2.1rem + 8px), 6% calc(2.1rem + 3px), 0 calc(2.1rem + 7px));
  box-shadow: inset 0 -1px 0 rgba(var(--ink-rgb), .06);
  opacity: 0;
}
/* 撕下飛走的那一頁：上緣是同一道鋸齒（跟紙根咬得起來），色帶留在牆上 */
html.has-intro .intro-commit .pad-today { clip-path: polygon(0 calc(2.1rem + 7px), 6% calc(2.1rem + 3px), 11% calc(2.1rem + 8px), 16% calc(2.1rem + 4px), 22% calc(2.1rem + 9px), 27% calc(2.1rem + 2px), 33% calc(2.1rem + 8px), 38% calc(2.1rem + 3px), 44% calc(2.1rem + 9px), 49% calc(2.1rem + 4px), 55% calc(2.1rem + 9px), 60% calc(2.1rem + 2px), 66% calc(2.1rem + 8px), 71% calc(2.1rem + 4px), 77% calc(2.1rem + 9px), 82% calc(2.1rem + 2px), 87% calc(2.1rem + 8px), 92% calc(2.1rem + 3px), 96% calc(2.1rem + 9px), 100% calc(2.1rem + 4px), 100% 100%, 0 100%); }
.pad-bits { position: absolute; left: 0; right: 0; top: 2.1rem; height: 0; z-index: 4; pointer-events: none; }
.pad-bits i {
  position: absolute;
  top: 0;
  width: 9px; height: 6px;
  background: var(--paper-raise);
  box-shadow: 0 0 0 .5px rgba(var(--ink-rgb), .2);
  clip-path: polygon(0 20%, 60% 0, 100% 45%, 80% 100%, 15% 85%);
  opacity: 0;
}
.pad-bits i:nth-child(1) { left: 8%;  --bx: -18px; --br: 230deg; }
.pad-bits i:nth-child(2) { left: 22%; --bx: 10px;  --br: -160deg; width: 7px; }
.pad-bits i:nth-child(3) { left: 37%; --bx: -8px;  --br: 300deg; }
.pad-bits i:nth-child(4) { left: 51%; --bx: 16px;  --br: -250deg; width: 11px; }
.pad-bits i:nth-child(5) { left: 64%; --bx: -12px; --br: 190deg; width: 6px; }
.pad-bits i:nth-child(6) { left: 78%; --bx: 20px;  --br: -300deg; }
.pad-bits i:nth-child(7) { left: 90%; --bx: -6px;  --br: 260deg; width: 8px; }
/* 三片大紙屑：慢慢飄（撕下去那一格最想截圖的那幾片） */
.pad-bits i.big { width: 18px; height: 12px; box-shadow: 0 0 0 .5px rgba(var(--ink-rgb), .22), 0 3px 4px -2px rgba(var(--ink-rgb), .3); }
.pad-bits i.big:nth-child(8)  { left: 18%; --bx: -26px; --br: 140deg; }
.pad-bits i.big:nth-child(9)  { left: 58%; --bx: 30px;  --br: -120deg; }
.pad-bits i.big:nth-child(10) { left: 81%; --bx: -14px; --br: 200deg; }
html.has-intro .intro-commit .pad-bits i.big { animation: oh-bit 1.6s cubic-bezier(.25, .3, .5, 1) calc(var(--oh-d) + .08s) both; }

/* 手勢中：跟手（不加 transition）；放手反悔：紙彈回去 */
html.has-intro .intro-wait:not(.is-dragging) .pad-today { transition: transform .55s cubic-bezier(.3, 1.45, .5, 1); }
html.has-intro .intro-wait.is-dragging .pad-today { transition: none; }

/* auto：先把今天那一頁輕輕掀一下（像有人伸手過來），再撕 */
html.has-intro .intro-play .pad-today { animation: oh-lift .4s ease-in-out both; }
@keyframes oh-lift {
  0%, 100% { transform: none; }
  55% { transform: perspective(1100px) rotateX(14deg) translateY(-1%); }
}
/* 撕：今天那一頁沿撕線撕下、往上飛走（keyframes 沒寫 0%＝從手指放開那一刻的樣子接手） */
html.has-intro .intro-commit .pad-today {
  animation: oh-tear .62s cubic-bezier(.55, 0, .75, .2) var(--oh-d) both;
  pointer-events: none;
}
html.has-intro .intro-play.intro-commit .pad-today {
  animation: oh-lift .4s ease-in-out both, oh-tear .62s cubic-bezier(.55, 0, .75, .2) var(--oh-d) both;
}
@keyframes oh-tear {
  25%  { transform: perspective(1100px) rotateX(38deg) translateY(-4%) rotate(-1.5deg); opacity: 1; }
  100% { transform: perspective(1100px) rotateX(58deg) translate(-6%, -125vh) rotate(-13deg); opacity: 1; }
}
html.has-intro .intro-commit .pad-nail { opacity: 0; transition: opacity .12s ease var(--oh-d); }
html.has-intro .intro-commit .pad-stub { opacity: 1; transition: none; }
html.has-intro .intro-commit .pad-bits i { animation: oh-bit 1s cubic-bezier(.3, .2, .6, 1) calc(var(--oh-d) + .12s) both; }
html.has-intro .intro-commit .pad-bits i:nth-child(even) { animation-delay: calc(var(--oh-d) + .2s); animation-duration: 1.15s; }
@keyframes oh-bit {
  0%   { opacity: 1; transform: translate(0, 0) rotate(0); }
  100% { opacity: 0; transform: translate(var(--bx), 46vh) rotate(var(--br)); }
}
html.has-intro .intro-commit .pad-next::after { opacity: 0; transition: opacity .4s ease var(--oh-d); }

/* 落定：底下那一頁（婚期）飛到 Hero 的日曆紙上；牆、釘子、紙根、厚度一起淡掉 */
html.has-intro .intro-land .pad-next {
  transform: translate(var(--fx, 0px), var(--fy, 0px)) scale(var(--fs, 1));
  transition: transform .86s cubic-bezier(.62, 0, .22, 1);
}
html.has-intro .intro-land :is(.intro-wall, .pad-nail, .pad-edge, .pad-stub) {
  opacity: 0;
  transition: opacity .42s ease 0s;
}
/* 牆上撕剩的那截色帶先走（飛行中不留半透明的舊頁眉殘影） */
html.has-intro .intro-land .pad-stub { transition-duration: .16s; }
html.has-intro .intro-land .pad-next { box-shadow: 0 1px 0 rgba(var(--ink-rgb), .08), 0 24px 46px -30px rgba(var(--ink-rgb), .5); }

/* 引導與跳過 */
.intro-guide {
  position: absolute;
  left: 50%;
  bottom: max(2.4rem, env(safe-area-inset-bottom, 0px) + 1.6rem);
  transform: translateX(-50%);
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: .35rem;
  min-height: 44px;
  padding: .5rem 1.4rem;
  border: 0;
  background: none;
  color: var(--accent);
  font: inherit;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: .26em;
  text-indent: .26em;
  white-space: nowrap;
  cursor: pointer;
}
.intro-guide::before {        /* 往上指的小箭頭 */
  content: "";
  width: 10px; height: 10px;
  border-left: 1.8px solid currentColor;
  border-top: 1.8px solid currentColor;
  transform: rotate(45deg);
  animation: oh-nudge 1.8s ease-in-out infinite;
}
@keyframes oh-nudge { 0%, 100% { translate: 0 2px; } 50% { translate: 0 -5px; } }
.intro-skip {
  position: absolute;
  top: max(.6rem, env(safe-area-inset-top, 0px));
  right: max(.6rem, env(safe-area-inset-right, 0px));
  min-height: 44px;
  padding: .6rem 1.2rem;
  border: 0;
  background: none;
  color: var(--ink);
  opacity: .72;
  font: inherit;
  font-size: .92rem;
  letter-spacing: .14em;
  cursor: pointer;
}
html.has-intro .intro-wait.is-touched .intro-guide::before { animation: none; }
html.has-intro .intro-commit :is(.intro-guide, .intro-skip) { opacity: 0; transition: opacity .2s ease; pointer-events: none; }
html.has-intro :is(.intro-play) .intro-guide { opacity: 0; }

/* ═══════════════════════════════════════════════════════════
   ② Story：每一段的日期是一張小日曆，捲進畫面時從釘子上翻下來
   ═══════════════════════════════════════════════════════════ */
.timeline {
  list-style: none;
  margin: clamp(2.6rem, 8vw, 3.4rem) auto 0;
  padding: 0;
  max-width: 30rem;
  display: grid;
  gap: clamp(2.6rem, 9vw, 3.4rem);
}
.timeline-item {
  position: relative;
  display: grid;
  justify-items: center;
  gap: .4rem;
  width: min(100%, 22rem);
  margin-inline: auto;
  padding: 0 0 1.5rem;
  background: var(--paper-raise);
  box-shadow: 0 1px 0 rgba(var(--ink-rgb), .08), 0 20px 34px -26px rgba(var(--ink-rgb), .55);
  rotate: -1.2deg;
  transform-origin: 50% 0;
}
.timeline-item:nth-child(even) { rotate: 1.4deg; }
.timeline-item:nth-child(3n) { rotate: -.4deg; }
/* 釘子 */
.timeline-item::before {
  content: "";
  position: absolute;
  left: 50%; top: -5px;
  width: 9px; height: 9px;
  margin-left: -4.5px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, rgba(255, 255, 255, .7) 0 18%, transparent 30%), var(--ink);
  z-index: 1;
}
.tl-date {
  justify-self: stretch;
  display: block;
  padding: .5rem 1rem .45rem;
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--wk-f-latin, var(--font-serif-latin));
  font-size: calc(1.02rem * var(--wk-fs-latin, 1));
  font-weight: 700;
  letter-spacing: .2em;
  font-variant-numeric: lining-nums;
  position: relative;
}
.tl-date::after {         /* 撕線 */
  content: "";
  position: absolute;
  left: .4rem; right: .4rem; bottom: -6px;
  border-top: 1.5px dotted rgba(var(--ink-rgb), .3);
}
.tl-date:empty { display: none; }
.timeline-item > :not(.tl-date) { padding-inline: 1.3rem; }
/* 進場＝從釘子上翻下來（日曆紙翻動） */
html.fx .timeline-item.reveal { transform: perspective(900px) rotateX(-75deg); transition: opacity .7s ease, transform .9s cubic-bezier(.2, .9, .3, 1.18); }
html.fx .timeline-item.reveal.is-in { transform: none; }
.tl-title {
  margin-top: 1rem;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(clamp(1.15rem, 4.2vw, 1.32rem) * var(--wk-fs-heading, 1));
  font-weight: 600;
  letter-spacing: .08em;
}
.tl-text { max-width: 26em; color: var(--ink-soft); white-space: pre-line; text-wrap: pretty; }
.tl-photo { margin: .6rem 0 .4rem; width: 100%; }
.tl-photo img {
  width: 100%;
  display: block;
  box-shadow: 0 0 0 7px var(--paper-raise), 0 0 0 8px rgba(var(--ink-rgb), .12), 0 18px 30px -22px rgba(var(--ink-rgb), .55);
}

/* ═══════════════════════════════════════════════════════════
   ③ Gallery：原生版式「鐵窗花」（ironwin）
   原生規則全部包在 #gallery:not([data-wk-gallery]) 底下——新人選了 shared 版式時一條都選不到。
   ═══════════════════════════════════════════════════════════ */
#gallery:not([data-wk-gallery]) .photo-grid {
  display: grid;
  align-items: start;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(2.2rem, 7vw, 3rem) clamp(1.4rem, 5.5vw, 2.2rem);
  margin-top: clamp(2.4rem, 8vw, 3.2rem);
  padding-inline: 10px;
}
#gallery:not([data-wk-gallery]) .photo-item {
  position: relative;
  margin: 0;
  padding: 7px;
  cursor: zoom-in;
  background: var(--paper-raise);
  box-shadow: 0 0 0 1px rgba(var(--ink-rgb), .12), 0 22px 36px -26px rgba(var(--ink-rgb), .6);
}
#gallery:not([data-wk-gallery]) .win-head { border-bottom-width: 6px; }
#gallery:not([data-wk-gallery]) .photo-item:nth-child(even) { margin-top: clamp(2rem, 9vw, 3rem); }
#gallery:not([data-wk-gallery]) .photo-item img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  display: block;
}
#gallery:not([data-wk-gallery]) .win-caption {
  position: absolute;
  left: -7px; right: -7px; top: 100%;
  padding-top: .8rem;
  font-size: .84rem;
  color: var(--ink-soft);
  letter-spacing: .06em;
  line-height: 1.5;
  text-wrap: balance;
}
#gallery:not([data-wk-gallery]) .win-caption:empty { display: none; }
#gallery:not([data-wk-gallery]) .photo-item:has(.win-caption:not(:empty)) { margin-bottom: 2.2rem; }
@media (hover: hover) {
  #gallery:not([data-wk-gallery]) .photo-item img { transition: filter .4s ease; }
  #gallery:not([data-wk-gallery]) .photo-item:hover img { filter: brightness(1.05); }
}
@media (min-width: 720px) {
  #gallery:not([data-wk-gallery]) .photo-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  #gallery:not([data-wk-gallery]) .photo-item:nth-child(even) { margin-top: 0; }
  #gallery:not([data-wk-gallery]) .photo-item:nth-child(3n+2) { margin-top: 3rem; }
}

/* 燈箱 */
.wk-lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(26, 25, 22, .94);
  padding: 1rem;
}
.wk-lightbox.is-open { display: flex; }
.wk-lightbox img {
  max-width: 100%;
  max-height: 86vh;
  object-fit: contain;
  box-shadow: 0 0 0 6px var(--paper-raise);
}
.wk-lightbox button {
  position: absolute;
  min-width: 48px; min-height: 48px;
  border: 0;
  background: none;
  color: #f4f1e9;
  font-size: 2rem;
  line-height: 1;
  cursor: pointer;
  opacity: .82;
}
.wk-lightbox button:hover { opacity: 1; }
.wk-lb-close { top: max(.5rem, env(safe-area-inset-top, 0px)); right: max(.75rem, env(safe-area-inset-right, 0px)); font-size: 2.4rem; }
.wk-lb-prev { left: max(.25rem, env(safe-area-inset-left, 0px)); top: 50%; transform: translateY(-50%); }
.wk-lb-next { right: max(.25rem, env(safe-area-inset-right, 0px)); top: 50%; transform: translateY(-50%); }

/* shared 婚紗照版式的覆寫（只有選了非原生版式時 #gallery 才有 data-wk-gallery；
   特異度 (1,1,0) 才蓋得過 gallery-layouts.css :root 的預設） */
#gallery[data-wk-gallery] {
  --gl-frame-shadow: var(--shadow-soft);
}
/* 新人照片卡：白色窗框＋細框，跟相簿的窗同一副語彙（不畫窗花——那是婚紗照才有的） */
#gallery .wk-duo-frame { box-shadow: 0 0 0 7px var(--paper-raise), 0 0 0 8px rgba(var(--ink-rgb), .13); }

/* ═══════════════════════════════════════════════════════════
   ③b 婚禮影片：一台老電視（墨色機殼＋圓角螢幕）
   ═══════════════════════════════════════════════════════════ */
.video-frame {
  position: relative;
  margin-top: clamp(1.6rem, 5vw, 2.2rem);
  aspect-ratio: 16 / 9;
  background: #000;
  border-radius: 1.1rem;
  overflow: hidden;
  box-shadow: 0 0 0 11px var(--ink), 0 0 0 12px rgba(var(--ink-rgb), .4), 0 26px 44px -26px rgba(var(--ink-rgb), .7);
}
.video-frame[data-ratio="portrait"] { aspect-ratio: 9 / 16; width: min(100%, 20rem); margin-inline: auto; }
.video-frame.is-noposter { background: var(--accent); }
.video-frame.is-noposter .video-poster { display: none; }
.video-frame[data-provider="instagram"] { aspect-ratio: 10 / 19; width: min(100%, 20rem); margin-inline: auto; }
.video-facade {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  padding: 0;
  border: 0;
  background: none;
  display: block;
  cursor: pointer;
}
.video-poster { width: 100%; height: 100%; object-fit: cover; display: block; }
.video-facade::after { content: ""; position: absolute; inset: 0; background: rgba(0, 0, 0, .24); }
.video-play-ico {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 3.8rem; height: 3.8rem;
  z-index: 1;
  color: #f4f1e9;
  border: 1.5px solid rgba(244, 241, 233, .85);
  border-radius: 50%;
}
.video-play-ico::before {
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-38%, -50%);
  border-style: solid;
  border-width: .5rem 0 .5rem .86rem;
  border-color: transparent transparent transparent currentColor;
}
.video-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; }
@media (hover: hover) { .video-facade:hover::after { background: rgba(0, 0, 0, .12); } }
.video-facade:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: -4px; }

/* ═══════════════════════════════════════════════════════════
   ④ 婚禮資訊：月曆上那一天用鉛筆圈起來
   ═══════════════════════════════════════════════════════════ */
/* 中段換一次節奏：整面寬的大日期，淡到像印在牆上的月份牌，捲進來時從下方浮上 */
.oh-bigdate {
  margin: 0 calc(50% - 50vw) .4rem;
  font-family: var(--wk-f-latin, var(--font-serif-latin));
  font-size: clamp(6.4rem, 36vw, 15rem);
  font-weight: 700;
  line-height: .8;
  letter-spacing: -.02em;
  color: color-mix(in srgb, var(--accent) 13%, transparent);
  text-align: center;
  white-space: nowrap;
  font-variant-numeric: lining-nums;
  pointer-events: none;
  user-select: none;
}
.oh-bigdate:empty { display: none; }
.details-date {
  margin-top: clamp(1.6rem, 5vw, 2rem);
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(clamp(1.25rem, 5vw, 1.6rem) * var(--wk-fs-heading, 1));
  font-weight: 600;
  letter-spacing: .08em;
  line-height: 1.5;
}
.details-note { color: var(--ink-soft); font-size: var(--text-small); margin-top: .5rem; white-space: pre-line; }
.details-note:empty { display: none; }
.wk-cal {
  width: min(100%, 20rem);
  margin: clamp(1.8rem, 6vw, 2.4rem) auto 0;
  padding: 0 .9rem 1rem;
  background: var(--paper-raise);
  box-shadow: 0 1px 0 rgba(var(--ink-rgb), .08), 0 18px 34px -26px rgba(var(--ink-rgb), .5);
}
.wk-cal[hidden] { display: none; }
.wk-cal-title {
  margin: 0 -.9rem .8rem;
  padding: .45rem 0;
  background: var(--accent);
  color: var(--accent-ink);
  font-family: var(--wk-f-latin, var(--font-serif-latin));
  font-size: calc(.95rem * var(--wk-fs-latin, 1));
  font-weight: 700;
  letter-spacing: .2em;
}
.wk-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; }
.wk-cal-wd, .wk-cal-d, .wk-cal-pad { position: relative; }
.wk-cal-wd { padding-bottom: .4rem; color: var(--ink-soft); font-size: .84rem; letter-spacing: .04em; }
.wk-cal-d, .wk-cal-pad { aspect-ratio: 1; }
.wk-cal-d { display: grid; place-items: center; font-size: clamp(.86rem, 3.3vw, .95rem); font-variant-numeric: lining-nums; }
.wk-cal-grid > :nth-child(7n+1):not(.wk-cal-wd) { color: var(--accent); }
.wk-cal-heart { display: none; }
.wk-cal-d.is-day { color: var(--accent); font-weight: 700; }
.wk-cal-d.is-day::before {      /* 鉛筆圈 */
  content: "";
  position: absolute;
  inset: 4%;
  border: 1.7px solid var(--pencil);
  border-radius: 47% 53% 44% 56% / 56% 46% 54% 44%;
  transform: rotate(-12deg);
  opacity: .85;
}
.wk-cal-n { position: relative; }
.wk-cal-count { display: none; }
.event-list {
  margin: clamp(2.2rem, 7vw, 3rem) auto 0;
  max-width: 24rem;
  display: grid;
  text-align: left;
}
.event-row {
  display: grid;
  grid-template-columns: 4.6rem 1fr;
  column-gap: 1.1rem;
  align-items: baseline;
  padding-block: clamp(.95rem, 3.4vw, 1.2rem);
  border-top: 1px solid var(--hairline);
}
.event-row:last-child { border-bottom: 1px solid var(--hairline); }
.event-row dt {
  font-family: var(--wk-f-latin, var(--font-serif-latin));
  font-size: calc(1.14rem * var(--wk-fs-latin, 1));
  font-weight: 700;
  color: var(--accent);
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: .04em;
}
.event-row dd strong {
  display: block;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(clamp(1.08rem, 3vw, 1.2rem) * var(--wk-fs-heading, 1));
  font-weight: 600;
  letter-spacing: .06em;
}
.event-row dd span { color: var(--ink-soft); font-size: var(--text-small); }
.calendar-actions {
  display: flex; flex-wrap: wrap; gap: .75rem; justify-content: center;
  margin-top: clamp(2.2rem, 7vw, 3rem);
}
.parents {
  margin-top: clamp(2.2rem, 7vw, 3rem);
  color: var(--ink-soft);
  font-size: var(--text-small);
  line-height: 2;
  white-space: pre-line;
}
.parents:empty { display: none; }

/* ═══════════════════════════════════════════════════════════
   ④b 服裝色系：一片一片的花磚（磁磚中間一朵淡淡的菱花）
   ═══════════════════════════════════════════════════════════ */
.dc-note { max-width: 26em; margin: clamp(1.4rem, 4vw, 1.8rem) auto 0; color: var(--ink-soft); white-space: pre-line; text-wrap: balance; }
.dc-note:empty { display: none; }
.dc-swatches {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 3px;
  width: fit-content;
  max-width: 100%;
  margin: clamp(1.8rem, 6vw, 2.4rem) auto 0;
  padding: 3px;
  background: #d9d3c6;          /* 磚縫的水泥灰（物件本色） */
  box-shadow: 0 18px 30px -24px rgba(var(--ink-rgb), .55);
}
.dc-swatch {
  position: relative;
  width: clamp(4.1rem, 19vw, 5.2rem);
  aspect-ratio: 1;
  overflow: hidden;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .06);
}
/* 花磚紋：四角四分之一圓＋中間一朵四瓣花（白線，疊在新人選的顏色上） */
.dc-swatch::before,
.dc-swatch::after {
  content: "";
  position: absolute;
  pointer-events: none;
}
.dc-swatch::before {
  inset: 0;
  background:
    radial-gradient(circle at 0 0, transparent 26%, rgba(255, 255, 255, .5) 27% 29%, transparent 30%),
    radial-gradient(circle at 100% 0, transparent 26%, rgba(255, 255, 255, .5) 27% 29%, transparent 30%),
    radial-gradient(circle at 0 100%, transparent 26%, rgba(255, 255, 255, .5) 27% 29%, transparent 30%),
    radial-gradient(circle at 100% 100%, transparent 26%, rgba(255, 255, 255, .5) 27% 29%, transparent 30%);
}
.dc-swatch::after {
  left: 50%; top: 50%;
  width: 34%; height: 34%;
  translate: -50% -50%;
  rotate: 45deg;
  border: 1.5px solid rgba(255, 255, 255, .55);
  border-radius: 50% 0;
  box-shadow: inset 0 0 0 3px rgba(255, 255, 255, .12);
}

/* ═══════════════════════════════════════════════════════════
   ⑤ 地點：地圖洗成一張老照片（白邊、下緣留寬、微微歪）
   ═══════════════════════════════════════════════════════════ */
.venue-tag {
  width: fit-content;
  margin: 0 auto .8rem;
  padding: .12rem .9rem;
  font-size: var(--text-small);
  color: var(--accent-tx);
  border: 1.5px solid var(--accent);
  border-radius: 2px;
  letter-spacing: .14em;
}
.venue-hall {
  margin-top: clamp(1.2rem, 4vw, 1.5rem);
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(1.12rem * var(--wk-fs-heading, 1));
  font-weight: 600;
  letter-spacing: .08em;
  color: var(--ink);
}
.venue-hall:empty { display: none; }
.venue-address { font-size: var(--text-body); color: var(--ink-soft); margin-top: .3rem; text-wrap: balance; }
.venue--dual .venue-card2 {
  margin-top: clamp(3rem, 9vw, 4rem);
  padding-top: clamp(3rem, 9vw, 4rem);
  border-top: 1px solid var(--hairline);
}
.venue2-name {
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(clamp(1.3rem, 4.8vw, 1.7rem) * var(--wk-fs-heading, 1));
  font-weight: 600;
  letter-spacing: .08em;
  line-height: 1.5;
}
.map-frame {
  position: relative;
  max-width: 40rem;
  margin: clamp(1.9rem, 6vw, 2.6rem) auto 0;
  padding: 10px 10px 30px;
  background: var(--paper-raise);
  aspect-ratio: 4 / 3.35;
  box-shadow: 0 1px 0 rgba(var(--ink-rgb), .08), 0 22px 40px -26px rgba(var(--ink-rgb), .55);
  rotate: -1.2deg;
}
.venue-card2 .map-frame { rotate: 1deg; }
@media (min-width: 700px) { .map-frame { aspect-ratio: 16 / 8.6; } }
.map-frame iframe {
  position: relative;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
  filter: sepia(.5) saturate(.55) contrast(.92) brightness(1.03);
  transition: opacity .6s ease;
}
/* 載入前：一張淡淡的格線地圖紙＋中間一根大頭針（不是一片白） */
.map-frame {
  background:
    radial-gradient(circle at 50% 46%, var(--accent) 0 5px, transparent 6px),
    linear-gradient(rgba(var(--ink-rgb), .07) 1px, transparent 1px) 10px 10px / 28px 28px,
    linear-gradient(90deg, rgba(var(--ink-rgb), .07) 1px, transparent 1px) 10px 10px / 28px 28px,
    var(--paper-raise);
  background-clip: content-box, content-box, content-box, border-box;
  background-origin: content-box, content-box, content-box, border-box;
}
html.fx .map-frame:not(.is-loaded) iframe { opacity: 0; }
/* 壓一層紙色＝洗成老照片（Google 的介面也一起被洗淡） */
.map-frame::before {
  content: "";
  position: absolute;
  inset: 10px 10px 30px;
  background: #e9dfc9;
  mix-blend-mode: multiply;
  opacity: .32;
  pointer-events: none;
  z-index: 1;
}
.map-frame::after {
  content: attr(data-cap);
  position: absolute;
  left: 14px; right: 14px; bottom: 5px;
  font-family: var(--font-pencil);
  font-size: .98rem;
  line-height: 1.2;
  color: var(--pencil);
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}
.venue-bottom {
  margin: clamp(1.9rem, 5.5vw, 2.6rem) auto 0;
  max-width: 28rem;
  display: grid;
  gap: 1.4rem;
  justify-items: center;
}
.transport {
  list-style: none;
  padding: 0;
  display: grid;
  gap: .9rem;
  text-align: left;
  width: 100%;
}
.transport li { display: grid; grid-template-columns: 4.2rem 1fr; gap: .9rem; align-items: baseline; }
.transport strong {
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-weight: 600;
  font-size: .92rem;
  color: var(--accent-tx);
  letter-spacing: .1em;
}
.transport span { color: var(--ink-soft); text-wrap: pretty; line-break: strict; }
#btn-nav, #btn-nav2 { background: var(--accent-tx); color: var(--accent-ink); box-shadow: none; }
#btn-nav:hover, #btn-nav2:hover { filter: brightness(1.08); }

/* ═══════════════════════════════════════════════════════════
   ⑤b 自訂區塊：卡片樣式＝冰箱上用磁鐵壓著的一張便條
   ═══════════════════════════════════════════════════════════ */
.custom-block { margin-top: clamp(.4rem, 2vw, .8rem); }
.custom-block:not(.custom-block-card):not(.custom-block-quote) .custom-text {
  max-width: 24rem;
  padding: 1.1rem 1.4rem 1.2rem;
  text-align: left;
  line-height: 2rem;
  background:
    repeating-linear-gradient(to bottom, transparent 0 calc(2rem - 1px), rgba(var(--ink-rgb), .1) calc(2rem - 1px) 2rem),
    var(--paper-raise);
  background-position: 0 1.1rem;
  box-shadow: 0 1px 0 rgba(var(--ink-rgb), .08), 0 16px 28px -22px rgba(var(--ink-rgb), .5);
  rotate: -.8deg;
}
.custom-block + .custom-block { margin-top: clamp(2.6rem, 8vw, 3.6rem); }
.custom-text { max-width: 28em; margin: clamp(1.2rem, 4vw, 1.5rem) auto 0; white-space: pre-line; text-wrap: balance; }
.custom-text:empty { display: none; }
.custom-block-card {
  position: relative;
  padding: clamp(1.8rem, 6vw, 2.4rem) clamp(1.3rem, 5vw, 2rem) clamp(1.6rem, 5vw, 2.2rem);
  background:
    repeating-linear-gradient(to bottom, transparent 0 1.85rem, rgba(var(--ink-rgb), .06) 1.85rem calc(1.85rem + 1px)),
    var(--paper-raise);
  box-shadow: 0 1px 0 rgba(var(--ink-rgb), .08), 0 18px 32px -24px rgba(var(--ink-rgb), .5);
}
.custom-block-card::before {   /* 磁鐵 */
  content: "";
  position: absolute;
  left: 50%; top: -9px;
  width: 22px; height: 22px;
  margin-left: -11px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, rgba(255, 255, 255, .55) 0 16%, transparent 32%), var(--accent);
  box-shadow: 0 4px 6px -2px rgba(var(--ink-rgb), .45);
}
.custom-block-quote .custom-text {
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(clamp(1.1rem, 4vw, 1.25rem) * var(--wk-fs-heading, 1));
  line-height: 2;
  letter-spacing: .06em;
}
.custom-anchored { padding-bottom: var(--section-y); text-align: center; }
.custom-img {
  display: block;
  width: min(100%, 22rem);
  margin: 0 auto clamp(1.2rem, 4vw, 1.6rem);
  box-shadow: 0 0 0 7px var(--paper-raise), 0 0 0 8px rgba(var(--ink-rgb), .12);
}
.custom-block-side::after { content: ""; display: block; clear: both; }
@media (min-width: 560px) {
  .custom-block-side .custom-img { float: left; width: 42%; margin: .3rem 1.6rem .8rem 0; }
  .custom-block-side .custom-text { text-align: left; }
}

/* ═══════════════════════════════════════════════════════════
   ⑤c 刮刮樂：塗層是一塊磨石子
   ═══════════════════════════════════════════════════════════ */
.secret .scratch-wrap { margin-top: clamp(1.8rem, 6vw, 2.4rem); }
.secret .scratch-card {
  max-width: 28rem;
  margin-inline: auto;
  background: var(--paper-raise);
  border-radius: 4px;
  box-shadow: 0 1px 0 rgba(var(--ink-rgb), .08), 0 18px 32px -24px rgba(var(--ink-rgb), .5);
}
/* 一角被指甲摳起來的樣子：塗層翹起一個小三角，露出底下的紙 */
.secret .scratch-card::before {
  content: "";
  position: absolute;
  right: 0; bottom: 0;
  width: 2.4rem; height: 2.4rem;
  z-index: 3;
  background: linear-gradient(135deg, transparent 50%, var(--paper-raise) 50%);
  box-shadow: -3px -3px 6px -3px rgba(var(--ink-rgb), .35);
  clip-path: polygon(100% 0, 100% 100%, 0 100%);
  pointer-events: none;
  transition: opacity .4s ease;
}
.secret .scratch-card.is-scratching::before,
.secret .scratch-card.is-revealed::before { opacity: 0; }
.secret .scratch-text {
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(1.08rem * var(--wk-fs-heading, 1));
  color: var(--ink);
  white-space: pre-line;      /* 長悄悄話的換行靠這條（功能，不是裝飾，別刪） */
}
.secret .scratch-hint { z-index: 3; color: var(--ink); font-size: .95rem; letter-spacing: .14em; text-indent: .14em; }
.secret .scratch-open { color: var(--ink); opacity: .78; border-radius: .5rem; min-height: 44px; padding-inline: 1.2rem; }
@media (hover: hover) and (pointer: fine) and (min-width: 1024px) {
  .secret .scratch-hint { font-size: 0; }
  .secret .scratch-hint::after { content: "用滑鼠輕輕刮開"; font-size: .95rem; }
}

/* ═══════════════════════════════════════════════════════════
   ⑥ RSVP：比較深的那一片磨石子地，捲進畫面時一道反光掃過一次（.is-sheen，render.js 掛）
   ═══════════════════════════════════════════════════════════ */
.rsvp {
  background: var(--terrazzo), var(--sand);
  background-size: var(--terrazzo-size), auto;
  padding-top: var(--section-y);
  overflow: hidden;
}
.rsvp::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(105deg, transparent 38%, rgba(255, 255, 255, .5) 50%, transparent 62%) no-repeat;
  background-size: 260% 100%;
  background-position: 130% 0;
  opacity: 0;
}
.rsvp.is-sheen::before { animation: oh-sheen 2.2s cubic-bezier(.4, 0, .2, 1) .2s 1 both; }
@keyframes oh-sheen {
  0%   { opacity: 1; background-position: 130% 0; }
  100% { opacity: 1; background-position: -30% 0; }
}
.rsvp > .container { position: relative; }
.rsvp-intro { max-width: 28em; margin: clamp(1.2rem, 4vw, 1.5rem) auto 0; white-space: pre-line; text-wrap: balance; }
.rsvp-deadline { font-size: 1rem; font-weight: 600; color: var(--accent-tx); margin-top: .7rem; letter-spacing: .06em; }
.rsvp-form {
  position: relative;
  margin-top: clamp(2.2rem, 7vw, 3rem);
  padding: clamp(1.6rem, 6vw, 2.4rem) clamp(1.2rem, 5vw, 2rem);
  display: grid;
  gap: 1.5rem;
  text-align: left;
  background: var(--paper-raise);
  border-top: 6px solid var(--accent);
  box-shadow: var(--shadow-soft);
}
.rsvp-form::before {      /* 剪線：沿這裡撕下來寄回去 */
  content: "";
  position: absolute;
  left: 0; right: 0; top: -14px;
  border-top: 1.5px dashed rgba(var(--ink-rgb), .35);
}
.rsvp-form::after {       /* 回條章：騎在卡片上緣、剪線上方，像蓋在紙邊的一枚章 */
  content: "回條";
  position: absolute;
  top: -1.45rem; right: 1rem;
  padding: .12rem .55rem .14rem;
  background: var(--paper-raise);
  border: 1.5px solid var(--accent);
  border-radius: 2px;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .3em;
  text-indent: .3em;
  color: var(--accent);
  rotate: -4deg;
  pointer-events: none;
}
html.wk-lang-en .rsvp-form::after { content: "REPLY"; letter-spacing: .14em; text-indent: .14em; font-family: var(--wk-f-latin, var(--font-serif-latin)); }
.rsvp .field label, .rsvp .field legend {
  font-size: .95rem;
  letter-spacing: .04em;
  color: var(--ink);
  font-weight: 600;
}
.rsvp .field input, .rsvp .field textarea, .rsvp .field select {
  background: var(--paper);
  border: 1.5px solid rgba(var(--ink-rgb), .22);
  border-radius: .45rem;
}
.field input:focus-visible, .field textarea:focus-visible, .field select:focus-visible {
  border-color: var(--accent-tx);
  box-shadow: 0 0 0 3px rgba(var(--ink-rgb), .1);
}
.rsvp .field select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1.5 L6 6.5 L11 1.5' fill='none' stroke='%23555' stroke-width='1.4' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  padding-right: 2.6rem;
}
.rsvp .field ::placeholder { color: var(--ink-soft); opacity: 1; }
.attend-field { border: 0; }
.companion-list { display: grid; gap: .5rem; }
[data-rsvp-custom] { display: grid; gap: 1.5rem; }
.cq-checks { display: grid; gap: .5rem; }
.rsvp .cq-checks label { display: flex; align-items: center; gap: .5rem; font-size: 1rem; font-weight: 400; cursor: pointer; }
.rsvp .cq-checks input[type="checkbox"] { width: 1.15rem; height: 1.15rem; flex: none; accent-color: var(--accent-tx); }
.attend-options { display: grid; grid-template-columns: 1fr 1fr; gap: .75rem; margin-top: .6rem; }
.attend-options.is-stack { grid-template-columns: 1fr; }
.attend-options.is-stack .attend-pill span { text-align: center; line-height: 1.5; letter-spacing: .06em; text-wrap: balance; }
.attend-pill input { position: absolute; opacity: 0; pointer-events: none; }
.attend-pill span {
  position: relative;
  display: flex; align-items: center; justify-content: center; gap: .45rem;
  min-height: 50px;
  padding: .7rem 1rem;
  background: var(--paper);
  box-shadow: inset 0 0 0 1.5px rgba(var(--ink-rgb), .22);
  border-radius: .5rem;
  letter-spacing: .08em;
  transition: background .35s var(--ease-out), color .35s var(--ease-out), box-shadow .35s var(--ease-out), scale .2s var(--ease-out);
  user-select: none;
  cursor: pointer;
}
.attend-pill:active span { scale: .97; }
.attend-pill input:checked + span { background: var(--accent-tx); color: var(--accent-ink); box-shadow: none; }
.attend-pill input:checked + span::before {      /* 選了就打一個勾（不只靠顏色分辨） */
  content: "";
  width: .7rem; height: .38rem;
  margin-top: -.2rem;
  border-left: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
}
.attend-pill input:focus-visible + span { box-shadow: 0 0 0 3px rgba(var(--ink-rgb), .2); }
.rsvp-details { display: grid; gap: 1.5rem; }
.field-row { display: grid; gap: 1.5rem; }
@media (min-width: 520px) { .field-row { grid-template-columns: repeat(3, 1fr); } }
.stepper {
  display: grid;
  grid-template-columns: 3rem 1fr 3rem;
  align-items: stretch;
  min-height: 48px;
  background: var(--paper);
  box-shadow: inset 0 0 0 1.5px rgba(var(--ink-rgb), .22);
  border-radius: .5rem;
  overflow: hidden;
}
.rsvp .field .stepper input { border: 0; background: transparent; text-align: center; padding-inline: .25rem; }
.stepper input::-webkit-outer-spin-button,
.stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.stepper input[type="number"] { -moz-appearance: textfield; }
.rsvp .field .stepper input:focus-visible { box-shadow: none; border-color: transparent; }
.stepper:focus-within { box-shadow: inset 0 0 0 1.5px var(--accent-tx), 0 0 0 3px rgba(var(--ink-rgb), .1); }
.stepper button {
  border: 0;
  background: transparent;
  cursor: pointer;
  color: var(--ink);
  font-size: 1.2rem;
  line-height: 1;
}
.stepper button:active { background: rgba(var(--ink-rgb), .08); }
.stepper button[disabled] { opacity: .3; cursor: default; }
.cap-note { font-size: var(--text-small); color: var(--ink-soft); }
/* 錯誤字：表單卡是日曆紙底，--warn 對它 ≥4.5（base.css 磚紅 #8a4b32 ≈ 6.4） */
.rsvp-error { color: var(--warn); font-size: var(--text-small); font-weight: 600; }
.rsvp-submit { width: 100%; min-height: 52px; letter-spacing: .16em; }
.rsvp-success, .rsvp-closed {
  position: relative;
  margin-top: clamp(2.2rem, 7vw, 3rem);
  text-align: center;
  display: grid;
  gap: .75rem;
  justify-items: center;
  padding: clamp(2rem, 6vw, 3rem) var(--gutter);
  background: var(--paper-raise);
  border-top: 6px solid var(--accent);
  box-shadow: var(--shadow-soft);
}
.success-mark {
  width: 2.8rem; height: 2.8rem;
  display: grid; place-items: center;
  background: var(--accent-tx);
  color: var(--accent-ink);
  font-size: 1.3rem;
  border-radius: 50%;
}
.rsvp-success h3, .rsvp-closed h3 {
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(clamp(1.2rem, 3.2vw, 1.4rem) * var(--wk-fs-heading, 1));
  font-weight: 600;
  letter-spacing: .08em;
}
.success-summary { white-space: pre-line; color: var(--ink-soft); font-size: var(--text-small); }
.success-note { font-size: var(--text-small); color: var(--ink-soft); }
/* 回覆紀念章：一枚郵戳（圓框＋一小格鐵窗紋） */
.rsvp-stamp {
  --stamp-rot: -9deg;
  position: absolute;
  top: .9rem; right: .9rem;
  width: 4.4rem; height: 4.4rem;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: .3rem;
  border: 1.5px solid var(--accent-tx);
  border-radius: 50%;
  color: var(--accent-tx);
  rotate: var(--stamp-rot);
}
.rsvp-stamp i {
  width: 1.1rem; height: 1.1rem;
  border: 1.5px solid currentColor;
  background:
    linear-gradient(currentColor, currentColor) center / 1.5px 100% no-repeat,
    linear-gradient(currentColor, currentColor) center / 100% 1.5px no-repeat;
}
.rsvp-stamp em {
  font-family: var(--wk-f-latin, var(--font-serif-latin));
  font-style: italic;
  font-size: .56rem;
  line-height: 1.2;
  max-width: 3.4rem;
  letter-spacing: .06em;
}
.rsvp-stamp.is-stamped { animation: oh-stamp .55s cubic-bezier(.3, 1.6, .5, 1) both; }
@keyframes oh-stamp {
  0%   { opacity: 0; scale: 1.8; rotate: calc(var(--stamp-rot) + var(--stamp-jitter, 0deg) - 10deg); }
  100% { opacity: 1; scale: 1; rotate: calc(var(--stamp-rot) + var(--stamp-jitter, 0deg)); }
}

/* ═══════════════════════════════════════════════════════════
   ⑦ Footer
   ═══════════════════════════════════════════════════════════ */
.footer {
  padding-top: var(--section-y);
  padding-bottom: max(3.2rem, env(safe-area-inset-bottom, 0px) + 2.4rem);
  text-align: center;
}
.footer-yours {
  font-family: var(--wk-f-latin, var(--font-serif-latin));
  font-size: calc(.92rem * var(--wk-fs-latin, 1));
  font-style: italic;
  letter-spacing: .14em;
  color: var(--accent-tx);
}
.footer-message { max-width: 24em; margin: 1.2rem auto 0; white-space: pre-line; text-wrap: balance; }
.footer-names {
  margin-top: 1rem;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(1.12rem * var(--wk-fs-heading, 1));
  font-weight: 600;
  letter-spacing: .12em;
}
.footer-brand {
  display: block;
  width: fit-content;
  margin-inline: auto;
  margin-top: 2.4rem;
  padding: .6rem 1rem;
  min-height: 44px;
  line-height: calc(44px - 1.2rem);
  font-size: var(--text-tiny);
  color: var(--ink-soft);
  text-decoration: none;
  letter-spacing: .06em;
}
.footer-brand:hover { color: var(--ink); }

/* 終章祝福「焊一朵窗花」：花瓣依序焊出來（每一瓣佔進度的 1/9，最後是花心那一圈）；
   蓄滿（.is-sealed）：花瓣填上一層淡淡的墨綠、花心亮起賓客的名字。沒蓄滿放手＝--wk-press 歸零、焊線收回去。 */
.blessing { margin-top: clamp(3rem, 10vw, 4.2rem); }
.blessing[hidden] { display: none; }
.blessing-lead { max-width: 22em; margin-inline: auto; color: var(--ink-soft); font-size: .95rem; text-wrap: balance; }
.blessing-seal {
  display: block;
  margin: 1.6rem auto 0;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.blessing-seal:focus-visible { outline: 2px solid var(--accent); outline-offset: 6px; }
.weld-stage {
  position: relative;
  display: block;
  width: clamp(11.5rem, 56vw, 14rem);
  aspect-ratio: 1;
}
.weld-win { width: 100%; height: 100%; display: block; overflow: visible; filter: drop-shadow(1.4px 2.4px 1.6px rgba(20, 25, 20, .34)); }
.weld-win :is(.ww-frame, .ww-ring, .ww-corner, .ww-bar) { fill: none; stroke-linecap: round; }
.weld-win .ww-under > * { stroke: var(--iron-dark); stroke-width: 4.2; }
.weld-win .ww-under > .ww-frame { stroke-width: 8.6; }
.weld-win .ww-paint > * { stroke: var(--iron); stroke-width: 3.6; }
.weld-win .ww-paint > .ww-frame { stroke-width: 8; }
.weld-win .ww-shine > * { stroke: rgba(255, 255, 255, .5); stroke-width: 1; }
.weld-win .ww-shine > .ww-frame { stroke-width: 1.6; }
.weld-win .ww-rivets circle { fill: var(--iron); stroke: var(--iron-dark); stroke-width: .8; }
.weld-win .ww-ghost :is(path, circle) {
  fill: none;
  stroke: var(--accent);
  stroke-opacity: .22;
  stroke-width: 1.6;
  stroke-dasharray: 2 4;
  stroke-linecap: round;
}
.blessing.is-sealed .weld-win .ww-ghost { opacity: 0; transition: opacity .4s; }
.weld-win :is(.ww-flower, .ww-flower-under, .ww-flower-shine) :is(.petal, .ww-heart) {
  fill: transparent;
  stroke: var(--iron);
  stroke-width: 4.2;
  stroke-linecap: butt;   /* round 的話零長度的焊線會留一顆點 */
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: calc(1 - clamp(0, var(--wk-press, 0) * 9 - var(--i, 0), 1));
  transition: fill .5s ease;
}
.weld-win .ww-heart { --i: 8; }
/* 花瓣跟窗框同一套漆鐵：背光暗邊＋左上高光；暗邊與高光不填色 */
.weld-win .ww-flower-under :is(.petal, .ww-heart) { stroke: var(--iron-dark); stroke-width: 5; fill: none !important; }
/* 花瓣彼此交疊：高光那一層會畫到隔壁那片玻璃上，所以花瓣只留背光暗邊（窗框才有高光） */
.weld-win .ww-flower-shine { display: none; }
/* 花瓣根部焊到花心環上的焊點：焊滿才出現 */
.weld-win .ww-roots circle { fill: var(--iron); stroke: var(--iron-dark); stroke-width: .8; opacity: 0; transform-box: fill-box; transform-origin: center; }
.blessing.is-sealed .weld-win .ww-roots circle { animation: oh-weld .5s ease-out both; }
.blessing.is-sealed .weld-win .ww-roots circle:nth-child(2n) { animation-delay: .08s; }
/* 底稿：還沒焊的花用一道很淡的虛線畫著（看得出「按這裡會長出一朵花」） */
.weld-win .ww-flower { filter: drop-shadow(0 0 0 transparent); }

.blessing.is-sealed .weld-win :is(.ww-flower, .ww-flower-under, .ww-flower-shine) :is(.petal, .ww-heart) { stroke-dashoffset: 0; }
/* 焊好的花瓣＝一片一片霧面玻璃（冷灰綠），窗後的燈從花心透出來 */
/* 焊好的花瓣＝一片一片霧面玻璃：花心的燈往外透（同一個漸層、每瓣位置不同＝每片玻璃亮度不同） */
.blessing.is-sealed .weld-win .petal { fill: url(#oh-ww-glass); }
.blessing.is-sealed .weld-win .ww-heart { fill: var(--paper-raise); }
/* 焊槍的火花：繞著花轉（跟進度同步），按著才閃 */
.weld-spark {
  position: absolute;
  inset: 0;
  pointer-events: none;
  transform: rotate(calc(min(var(--wk-press, 0) * 1.125, 1) * 360deg));
  opacity: 0;
}
.weld-spark::before {
  content: "";
  position: absolute;
  left: 50%; top: 9%;
  width: 15px; height: 15px;
  margin-left: -7.5px;
  border-radius: 50%;
  background: #fff8e6;
  box-shadow: 0 0 8px 4px rgba(255, 226, 160, .95), 0 0 22px 9px color-mix(in srgb, var(--accent) 45%, transparent), -10px 6px 10px -4px rgba(255, 236, 190, .8);
  animation: oh-flicker .12s steps(2) infinite;
}
.blessing-seal.is-pressing .weld-spark { opacity: 1; }
/* 按著＝在焊：窗心透出一點燒紅的熱光 */
.blessing-seal.is-pressing .weld-stage::after { opacity: .55; background: radial-gradient(closest-side, rgba(255, 214, 160, .9), rgba(255, 170, 110, .3) 55%, transparent); transition-delay: 0s; }
@keyframes oh-flicker { 50% { opacity: .35; scale: .7; } }
.weld-tag {
  position: absolute;
  left: 50%; top: 50%;
  width: 24%;
  translate: -50% calc(-50% + 10px);
  font-family: var(--font-pencil);
  font-size: clamp(1.1rem, 5vw, 1.3rem);
  line-height: 1.2;
  color: var(--accent);
  opacity: 0;
  scale: .6;
  transition: opacity .4s ease .15s, scale .5s cubic-bezier(.3, 1.6, .5, 1) .15s;
  word-break: keep-all;
}
.blessing.is-long .weld-tag { font-size: clamp(.9rem, 4vw, 1.02rem); }
.blessing.is-sealed .weld-tag { opacity: 1; scale: 1; translate: -50% -50%; }
.blessing.is-sealed .weld-win { animation: oh-flash .7s ease-out both; }
@keyframes oh-flash {
  0%   { filter: none; }
  14%  { filter: brightness(1.9) drop-shadow(0 0 14px rgba(255, 244, 214, .95)); }
  100% { filter: none; }
}
/* 焊好之後，窗後的燈亮起來 */
.weld-stage { isolation: isolate; }
.weld-stage::after {
  content: "";
  position: absolute;
  inset: 10%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 232, 178, .85), rgba(255, 214, 150, .35) 60%, transparent);
  opacity: 0;
  z-index: -1;
  transition: opacity 1.1s ease .2s;
}
.blessing.is-sealed .weld-stage::after { opacity: 1; }
.blessing-hint {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  margin-top: 1.4rem;
  padding: .5rem 1.1rem;
  border: 1.5px solid rgba(var(--ink-rgb), .3);
  border-radius: .5rem;
  font-size: .92rem;
  letter-spacing: .12em;
  color: var(--ink);
}
.blessing-hint::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent);
  animation: oh-hint 1.6s ease-in-out infinite paused;
}
.blessing.is-live .blessing-hint::before { animation-play-state: running; }
@keyframes oh-hint { 50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent) 18%, transparent); } }
.blessing-done { margin-top: 1.2rem; font-weight: 600; letter-spacing: .06em; text-wrap: balance; }
.blessing:not(.is-sealed) .blessing-done { display: none; }
.blessing.is-sealed .blessing-hint { display: none; }
.blessing.is-sealed .blessing-done { animation: oh-pop .45s cubic-bezier(.3, 1.4, .5, 1); }
@keyframes oh-pop { from { opacity: 0; scale: .9; } to { opacity: 1; scale: 1; } }

/* 新人聯絡方式（頁尾；填了才由 render.js 生成，空則 [hidden]） */
.footer-contacts { margin-top: 2rem; display: flex; flex-direction: column; align-items: center; row-gap: 1.5rem; }
.footer-contacts[hidden] { display: none; }
.contact-row { display: inline-flex; align-items: center; gap: .7rem; }
.contact-who { font-size: .92rem; color: var(--ink); letter-spacing: .04em; }
.contact-ico {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  margin-block: -12px;
  color: var(--ink-soft);
  transition: color .3s, transform .3s;
}
.contact-ico + .contact-ico { margin-left: -.2rem; }
.contact-ico svg { width: 20px; height: 20px; display: block; }
.contact-ico:hover { color: var(--accent-tx); transform: translateY(-1px); }
.contact-ico[data-kind]::after {
  position: absolute;
  top: 100%;
  left: 50%;
  translate: -50% -6px;
  font-size: .74rem;
  letter-spacing: .04em;
  color: var(--ink-soft);
  white-space: nowrap;
}
.contact-ico[data-kind="phone"]::after { content: "電話"; }
.contact-ico[data-kind="line"]::after  { content: "LINE"; }
.contact-ico[data-kind="ig"]::after    { content: "IG"; }

/* 頁尾 P.S.：門口的信箱，點開抽出一張鉛筆寫的字條 */
.ps-egg {
  display: block;
  margin-inline: auto;
  margin-top: 2.2rem;
  min-height: 44px;
  padding: .55rem 1rem;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: .92rem;
  letter-spacing: .08em;
  text-decoration: underline;
  text-decoration-color: rgba(var(--ink-rgb), .3);
  text-underline-offset: .35em;
  cursor: pointer;
}
.ps-egg:hover { text-decoration-color: var(--ink); }
.ps-egg-text {
  max-width: 19rem;
  margin: 2rem auto 0;
  padding: 1.1rem 1.2rem;
  background: var(--paper-raise);
  box-shadow: 0 1px 0 rgba(var(--ink-rgb), .08), 0 14px 26px -20px rgba(var(--ink-rgb), .55);
  font-family: var(--font-pencil);
  font-size: 1.12rem;
  line-height: 1.6;
  color: var(--pencil);
  rotate: -1.5deg;
  opacity: 0;
  translate: 0 12px;
  transition: opacity .5s ease, translate .6s var(--ease-out);
}
.ps-egg-text.is-open { opacity: 1; translate: none; }
.ps-egg-say { margin: 0; }

/* ═══════════════════════════════════════════════════════════
   彩蛋③ 彈珠＋粒子的皮
   ═══════════════════════════════════════════════════════════ */
.oh-marble { position: absolute; z-index: 60; width: 0; height: 0; pointer-events: none; }
.oh-marble i {
  position: absolute;
  left: -11px; top: -11px;
  width: 22px; height: 22px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 34% 30%, rgba(255, 255, 255, .95) 0 14%, transparent 30%),
    radial-gradient(circle at 60% 66%, color-mix(in srgb, var(--accent) 80%, transparent) 0 22%, transparent 48%),
    radial-gradient(circle at 50% 50%, rgba(255, 255, 255, .25), rgba(170, 200, 190, .55) 70%, rgba(var(--ink-rgb), .35));
  box-shadow: 0 3px 4px -1px rgba(var(--ink-rgb), .45);
  animation: oh-marble-jump 1.5s cubic-bezier(.3, 0, .4, 1) both;
}
@keyframes oh-marble-jump {
  0%   { transform: translate(0, 0) scale(.3); opacity: 0; }
  12%  { opacity: 1; }
  30%  { transform: translate(calc(var(--dir) * 18px), -70px) scale(1) rotate(calc(var(--dir) * 120deg)); }
  52%  { transform: translate(calc(var(--dir) * 34px), 0) rotate(calc(var(--dir) * 260deg)); }
  66%  { transform: translate(calc(var(--dir) * 44px), -22px) rotate(calc(var(--dir) * 330deg)); }
  78%  { transform: translate(calc(var(--dir) * 52px), 0) rotate(calc(var(--dir) * 400deg)); }
  100% { transform: translate(calc(var(--dir) * 78px), 0) rotate(calc(var(--dir) * 560deg)); opacity: 1; }
}
.oh-marble b {
  position: absolute;
  left: 22px; top: -44px;
  translate: 0 0;
  white-space: nowrap;
  font-family: var(--font-pencil);
  font-weight: 400;
  font-size: 1.02rem;
  color: var(--pencil);
  background: var(--paper-raise);
  padding: .2rem .6rem;
  box-shadow: 0 6px 14px -8px rgba(var(--ink-rgb), .5);
  animation: oh-marble-say 3s ease both;
}
@keyframes oh-marble-say {
  0%, 18% { opacity: 0; translate: -50% 6px; }
  30%, 82% { opacity: 1; translate: -50% 0; }
  100% { opacity: 0; translate: -50% -4px; }
}
/* 焊好的那一瞬間的火花（WKFX.burstAt 的物件池；位置與動畫由 shared/fx.js 管） */
.oh-spark-p {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: #fff6dc;
  box-shadow: 0 0 4px 1px var(--accent);
}

/* ---------- reduced-motion：不降級 ----------
   2026-10-01 起全站賓客頁的規則（DESIGN §7）：index.html 的旗標 script 在 <html> 掛 wk-keep-motion，
   base.css 的 RM 通殺整段讓位、WKFX（GSAP 層）與 WK.press 也照常。所以這裡沒有
   @media (prefers-reduced-motion) 區塊：開場撕日曆、焊線、窗燈、翻頁全部跟一般模式同一套。
   動態本來就克制：沒有視差、沒有 scroll-scrub，大位移只有開場那一秒（而且是賓客自己撕的）。
   ?preview=1 不掛旗標＝編輯器預覽照樣素顏。 */

/* ═══════════════════════════════════════════════════════════
   桌機（≥1024）：Hero 對開——左邊牆上的日曆、右邊那扇窗；其餘單欄放大
   ═══════════════════════════════════════════════════════════ */
@media (min-width: 1024px) {
  :root { --sheet-w: 25rem; --content-max: 44rem; }
  .weld-stage { width: 24rem; }
  .weld-tag { font-size: 1.7rem; }
  .blessing.is-long .weld-tag { font-size: 1.3rem; }
  .timeline-item { width: min(100%, 30rem); }
  .tl-text { text-wrap: balance; }
  .dc-swatch { width: 7.2rem; }
  .hero { padding-top: 4.2rem; padding-bottom: 5.4rem; }
  .hero-content {
    max-width: 62rem;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 4.5rem;
    align-items: center;
  }
  .hero-greeting { grid-column: 1 / -1; margin-bottom: 2rem; font-size: 1.05rem; }
  .hero-sheet-wrap { grid-column: 1; grid-row: 2 / span 2; justify-self: end; }
  .hero-frame { grid-column: 2; grid-row: 2; justify-self: start; width: 21rem; margin-top: 0; }
  .win-note { grid-column: 2; grid-row: 3; justify-self: start; width: 22rem; align-self: start; }
  .countdown { grid-column: 1 / -1; margin-top: 3rem; }
  .cal-day { font-size: calc(10.4rem * var(--wk-fs-latin, 1)); }
  .pad { width: var(--sheet-w); }
  body { font-size: 1.06rem; }
  .cal-line, .tl-text, .venue-address, .transport span { font-size: 1.02rem; }
  #gallery:not([data-wk-gallery]) .photo-grid { max-width: 54rem; margin-inline: auto; }
  .intro-skip { font-size: 1rem; }
}

/* ============================================================
   字型庫 bridge（P2-26，2026-08-24）——由 shared/fonts.js（WKFONTS）驅動
   font-family 已經在各條規則用 var(--wk-f-<role>, 原值) 包好；
   字級倍率（--wk-fs-*）也已經乘在各自的 font-size 上。
   這一段補的是字距／行距／字重／斜體：新人沒調的時候 <html> 上沒有對應的
   gate 屬性，整條規則選不到＝本檔上面的原值一個都不動。
   ⚠ gate 屬性名與變數名都由引擎決定（tools/fonts-check.mjs 會逐條核對），別改拼法。
   ============================================================ */
html[data-wkf-ls-heading] :is(.hero-names, .cal-names, .section-title, .tl-title, .event-row dd strong, .venue2-name, .venue-hall, .footer-names, .details-date, .cal-week, .rsvp-success h3, .rsvp-closed h3) { letter-spacing: var(--wk-fls-heading); }
html[data-wkf-lh-heading] :is(.hero-names, .cal-names, .section-title, .tl-title, .event-row dd strong, .venue2-name, .venue-hall, .footer-names, .details-date, .cal-week, .rsvp-success h3, .rsvp-closed h3) { line-height: var(--wk-flh-heading); }
html[data-wkf-w-heading] :is(.hero-names, .cal-names, .section-title, .tl-title, .event-row dd strong, .venue2-name, .venue-hall, .footer-names, .details-date, .cal-week, .rsvp-success h3, .rsvp-closed h3) { font-weight: var(--wk-fw-heading); }

html[data-wkf-ls-body] :is(body, .tl-text, .hero-note, .venue-tag, .cal-line, .hero-greeting) { letter-spacing: var(--wk-fls-body); }
html[data-wkf-lh-body] :is(body, .tl-text, .hero-note, .venue-tag, .cal-line, .hero-greeting) { line-height: var(--wk-flh-body); }
html[data-wkf-w-body] :is(body, .tl-text, .hero-note, .venue-tag, .cal-line, .hero-greeting) { font-weight: var(--wk-fw-body); }

html[data-wkf-ls-latin] :is(.label-en, .hero-names-en, .cal-day, .cd-cell strong, .tl-date, .wk-cal-title, .event-row dt, .footer-yours) { letter-spacing: var(--wk-fls-latin); }
html[data-wkf-lh-latin] :is(.label-en, .hero-names-en, .cal-day, .cd-cell strong, .tl-date, .wk-cal-title, .event-row dt, .footer-yours) { line-height: var(--wk-flh-latin); }
html[data-wkf-w-latin] :is(.label-en, .hero-names-en, .cal-day, .cd-cell strong, .tl-date, .wk-cal-title, .event-row dt, .footer-yours) { font-weight: var(--wk-fw-latin); }
html[data-wkf-i-latin] :is(.label-en, .hero-names-en, .cal-day, .cd-cell strong, .tl-date, .wk-cal-title, .event-row dt, .footer-yours) { font-style: italic; }

/* ============================================================
   英文版（P2-10）：中文的寬字距、直排在英文都收掉
   ============================================================ */
html.wk-lang-en { --font-body-tc: "Old Standard TT", Georgia, var(--font-serif-tc); }
html.wk-lang-en body { letter-spacing: .005em; line-height: 1.75; hyphens: manual; }
html.wk-lang-en .section-title { letter-spacing: .02em; text-indent: 0; text-wrap: balance; }
html.wk-lang-en :is(.cal-names, .hero-names) { letter-spacing: .03em; }
html.wk-lang-en :is(.tl-title, .details-date, .event-row dd strong, .venue2-name, .venue-hall, .footer-names, .rsvp-success h3, .rsvp-closed h3, .custom-block-title) { letter-spacing: .02em; }
html.wk-lang-en :is(.cal-line, .hero-greeting, .hero-note, .venue-tag, .contact-who, .footer-brand, .cal-bind) { letter-spacing: .04em; }
html.wk-lang-en :is(.rsvp .field label, .rsvp .field legend, .attend-pill span, .btn, .intro-guide, .intro-skip, .blessing-hint, .cal-today) { letter-spacing: .03em; text-indent: 0; }
html.wk-lang-en .cal-week { letter-spacing: .14em; text-indent: .14em; }
html.wk-lang-en :is(.cal-yi, .cal-today, .intro-guide, .intro-skip, .cal-bind, .cal-week, .blessing-hint) { font-family: var(--wk-f-latin, var(--font-serif-latin)); }
html.wk-lang-en .cal-yi:not(.cal-yi--today) > span { writing-mode: horizontal-tb; padding: .3rem .8rem; }
html.wk-lang-en .cal-lunar { display: none; }
html.wk-lang-en .cal-body { grid-template-columns: minmax(0, 1fr); row-gap: .6rem; padding-bottom: .3rem; }
html.wk-lang-en .cal-yi { min-height: 44px; margin-top: 1.5rem; letter-spacing: .06em; font-size: .9rem; }
html.wk-lang-en .cal-circle { width: 88%; top: 50%; }
html.wk-lang-en .cal-yi--today { writing-mode: horizontal-tb; min-height: 0; }
html.wk-lang-en .pad-today .cal-body { flex: 0 1 auto; padding-top: 2.4rem; padding-bottom: 1.4rem; row-gap: 1.4rem; }
html.wk-lang-en .pad-today .cal-today { margin-top: auto; }
html.wk-lang-en .cal-yi--today { padding: 0; font-size: .84rem; line-height: 1.5; letter-spacing: .02em; }
html.wk-lang-en .cal-yi--today b { margin: 0 .3em 0 0; }
html.wk-lang-en .contact-ico[data-kind="phone"]::after { content: "Phone"; }
@media (hover: hover) and (pointer: fine) and (min-width: 1024px) {
  html.wk-lang-en .secret .scratch-hint::after { content: "Scratch gently with your mouse"; }
}
html.wk-lang-en :is(.blessing-lead, .rsvp-intro, .footer-message, .tl-text, .dc-note) { text-wrap: balance; }
html.wk-lang-en .parents { text-wrap: balance; }

/* 有中英切換鈕的帖（中文、英文都掛 wk-has-lang；鈕固定在右上角 12px、z-index 90 蓋在開場層上面）：
   開場的「跳過」往下讓出那個角（不然點跳過會點到切換鈕），手機 Hero 的開頭語也往下讓 16px */
html.wk-has-lang .intro-skip { top: calc(max(.6rem, env(safe-area-inset-top, 0px)) + 46px); }
@media (max-width: 720px) {
  html.wk-has-lang .hero { padding-top: calc(clamp(2.2rem, 8vw, 3.4rem) + 16px); }
}

/* ════════════════════════════════════════════════════════════════
   v2「印刷廠版」（2026-10-31 Jacob：「中規中矩，要讓人打開就『哇』」）
   參考：楊發明〈報時光老派日曆〉（藍綠紅三色、刻意錯版疊印）、五金行日曆（大紅大藍數字）、
   傳統撕日曆（大字佔半頁、上面密排干支沖煞）。
   改的是尺度與印刷感，不是概念：
   - 日曆紙放大成海報：大字佔版面一半、上面多印一排黃曆、大字有兩色套印的錯版殘影
   - 每一區的開頭＝一張新日曆紙的頂端色帶（不再是小英文＋小標＋細線）＋特粗明體大標、靠左
   - 整片色塊分章：故事那一區整片墨綠（翻到另一疊日曆）
   ════════════════════════════════════════════════════════════════ */
:root { --sheet-w: min(100%, 24.5rem); }
.pad { width: min(calc(100vw - 2rem), 24.5rem); }

/* ── 日曆紙：海報尺度 ── */
.cal-bind { font-size: .78rem; }
.cal-bind .cb-m { font-size: 1.14rem; letter-spacing: .14em; font-weight: 700; }
.cal-alm {
  display: flex;
  margin: 11px .75rem 0;
  border-block: 1.5px solid rgba(var(--ink-rgb), .62);
  font-size: .76rem;
  line-height: 1.3;
  letter-spacing: .1em;
  color: var(--ink);
  white-space: nowrap;
}
.cal-alm:empty { display: none; }
.cal-alm span { flex: 1 1 auto; padding: .34rem .2rem; text-align: center; }
.cal-alm span + span { border-left: 1px solid rgba(var(--ink-rgb), .38); }
.cal-body { grid-template-columns: 2.3rem minmax(0, 1fr) 2.6rem; padding-top: .7rem; }
.cal-day {
  position: relative;
  font-size: calc(clamp(8.6rem, 48vw, 11.6rem) * var(--wk-fs-latin, 1));
  line-height: .8;
  letter-spacing: -.045em;
}
/* 套印錯版：墨版比綠版偏一點點（老印刷廠的對位誤差）；只是殘影，不影響讀 */
.cal-day[data-d]::after {
  content: attr(data-d);
  position: absolute;
  left: 0; top: 0;
  color: var(--ink);
  opacity: .14;
  translate: .028em -.022em;
  mix-blend-mode: multiply;
  pointer-events: none;
}
.cal-lunar { font-size: 1.02rem; color: var(--ink); }
.cal-yi { font-size: 1.08rem; }
.cal-yi:not(.cal-yi--today) > span { padding: .7rem .34rem; border-width: 2px; }
.cal-week { font-size: 1.12rem; margin-top: .9rem; border-bottom: 1.5px solid rgba(var(--ink-rgb), .55); }
.cal-names { font-size: calc(clamp(1.7rem, 7.6vw, 2.3rem) * var(--wk-fs-heading, 1)); font-weight: 900; letter-spacing: .1em; }
.cal-line { font-size: .95rem; color: var(--ink); }
.hero { padding-top: clamp(1.4rem, 5vw, 2.6rem); padding-inline: 1rem; }
.hero-greeting { margin-bottom: .9rem; }

/* 倒數：四張撕日曆的大數字 */
.countdown { gap: .5rem; }
.cd-cell strong { font-size: calc(clamp(2.3rem, 11vw, 3.2rem) * var(--wk-fs-latin, 1)); line-height: 1; letter-spacing: -.03em; }

/* ── 每一區的開頭：新的一張日曆紙 ── */
main > .section > .container,
main > .section > .container-wide { text-align: left; }
.label-en {
  position: relative;
  display: flex;
  align-items: center;
  height: 2.1rem;
  margin: 0 0 1.4rem;
  padding: 0 .9rem;
  background: var(--accent);
  color: var(--accent-ink);
  font-style: normal;
  font-size: calc(.84rem * var(--wk-fs-latin, 1));
  letter-spacing: .24em;
  text-align: left;
}
.label-en::after {              /* 撕線 */
  content: "";
  position: absolute;
  left: .4rem; right: .4rem; bottom: -6px;
  border-top: 1.5px dotted rgba(var(--ink-rgb), .32);
}
.section-title {
  text-align: left;
  text-indent: 0;
  font-size: calc(clamp(2.4rem, 11vw, 4.6rem) * var(--wk-fs-heading, 1));
  font-weight: 900;
  letter-spacing: .03em;
  line-height: 1.12;
  text-wrap: balance;
}
.bar-rule { display: none; }

/* ── 故事：整片墨綠（另一疊日曆） ── */
.section.story { background: var(--accent); color: var(--accent-ink); }
.story .section-title { color: var(--accent-ink); }
.story .label-en { background: var(--accent-ink); color: var(--accent); }
.story .label-en::after { border-top-color: rgba(255, 255, 255, .4); }
.timeline { max-width: 34rem; margin-inline: 0; gap: clamp(2rem, 7vw, 3rem); }
.timeline-item {
  width: 88%;
  margin: 0;
  justify-items: start;
  text-align: left;
  border-top: 10px solid var(--iron-dark);
  box-shadow: 0 24px 40px -22px rgba(0, 0, 0, .55);
  color: var(--ink);
}
.timeline-item:nth-child(even) { justify-self: end; }
.timeline-item::before { top: -10px; }
.tl-date {
  justify-self: start;
  padding: .9rem 1.3rem 0;
  background: none;
  color: var(--accent);
  font-size: calc(clamp(3rem, 15vw, 4.4rem) * var(--wk-fs-latin, 1));
  line-height: .9;
  letter-spacing: -.03em;
}
.tl-date::after { display: none; }
.tl-title { margin-top: .5rem; font-size: calc(clamp(1.3rem, 5.4vw, 1.6rem) * var(--wk-fs-heading, 1)); font-weight: 900; }
.tl-text { color: var(--ink-soft); }

/* ── 相簿：第一張放大成整面窗 ── */
#gallery:not([data-wk-gallery]) .photo-grid { padding-inline: 0; }
#gallery:not([data-wk-gallery]) .photo-item:first-child { grid-column: 1 / -1; }
#gallery:not([data-wk-gallery]) .photo-item:first-child img { aspect-ratio: 4 / 5; }
#gallery:not([data-wk-gallery]) .photo-item:nth-child(even) { margin-top: 0; }
#gallery:not([data-wk-gallery]) .photo-item:nth-child(odd):not(:first-child) { margin-top: clamp(2rem, 9vw, 3rem); }

@media (min-width: 1024px) {
  :root { --sheet-w: 27rem; }
  .cal-day { font-size: calc(12.4rem * var(--wk-fs-latin, 1)); }
  .hero-frame { width: 23rem; }
  .section-title { font-size: calc(4.8rem * var(--wk-fs-heading, 1)); }
  main > .section > .container { max-width: 52rem; }
  #gallery:not([data-wk-gallery]) .photo-item:first-child { grid-column: 1 / span 2; grid-row: span 2; }
  #gallery:not([data-wk-gallery]) .photo-item:first-child img { aspect-ratio: auto; height: 100%; }
}
@media (min-width: 720px) {
  #gallery:not([data-wk-gallery]) .photo-item:nth-child(n) { margin-top: 0; }
}

/* ── 牆裙：老房子「上白下綠」的油漆牆（開場牆面＋首屏下半整片漆綠） ──
   日曆掛在白牆上、下緣微微壓過牆裙那條線；窗與婚紗照嵌在綠牆裡。
   牆裙頂端一條深色收邊（油漆分色線），其餘是平的一片漆色——不加漸層。 */
.cal-day[data-d]::after { left: 0; right: 0; text-align: inherit; }
.intro-wall {
  background:
    linear-gradient(to bottom, transparent 0 70%, var(--iron-dark) 70% calc(70% + 5px), var(--accent) calc(70% + 5px)),
    var(--terrazzo), var(--paper);
  background-size: auto, var(--terrazzo-size), auto;
}
.intro-wall::after { background: radial-gradient(70% 40% at 50% 20%, rgba(255, 252, 244, .7), transparent 75%); }
.intro-guide { color: var(--accent-ink); }
.intro-guide::before { border-color: var(--accent-ink); }
.hero-content { isolation: isolate; }
@media (max-width: 1023px) {
  /* 子層一律指定欄（只指定列的話，自動排版會避開牆裙佔的格子、另開一欄） */
  .hero-content > * { grid-column: 1; }
  .hero-greeting { grid-row: 1; }
  .hero-sheet-wrap { grid-row: 2; z-index: 1; }
  .hero-frame { grid-row: 3; }
  .win-note { grid-row: 4; }
  .countdown { grid-row: 5; }
  .hero-content::before {
    content: "";
    grid-row: 3 / 6;
    grid-column: 1 / -1;
    align-self: stretch;
    justify-self: stretch;
    z-index: -1;
    margin: -4.2rem calc(50% - 50vw) calc(-1 * clamp(3.4rem, 10vw, 5rem));
    width: 100vw; justify-self: center;
    border-top: 5px solid var(--iron-dark);
    background: var(--accent);
  }
  .hero-frame { margin-top: 1.4rem; }
  .win-note { color: var(--accent-ink); }
}
@media (min-width: 1024px) {
  .hero {
    background: linear-gradient(to bottom, transparent 0 58%, var(--iron-dark) 58% calc(58% + 5px), var(--accent) calc(58% + 5px));
  }
  .win-note { color: var(--accent-ink); }
}
.cd-cell { width: clamp(4.4rem, 20vw, 5.4rem); border-top-color: var(--iron-dark); box-shadow: 0 14px 22px -14px rgba(0, 0, 0, .55); }

/* ── 色帶上的字放大一點（原本小到像註腳） ── */
.label-en { font-size: calc(.98rem * var(--wk-fs-latin, 1)); letter-spacing: .16em; }

/* ── 婚禮資訊開頭的大日期：不再是淡淡的浮水印，是印上去的大字（同樣帶套印錯版） ── */
.oh-bigdate {
  margin: 0 0 .6rem;
  color: var(--accent);
  text-align: left;
  font-size: clamp(6.4rem, 40vw, 15rem);
  letter-spacing: -.05em;
  text-shadow: .028em -.022em 0 rgba(var(--ink-rgb), .14);
}

/* ── 服裝色系：花磚放大成一整排 ── */
.dc-swatches { justify-content: flex-start; }

/* ── 終章：夜裡的老宅。整片入夜的牆、那扇窗從屋裡亮著燈 ── */
.footer {
  --night: color-mix(in srgb, var(--iron-dark) 78%, #050504);
  background: var(--night);
  color: var(--accent-ink);
  text-align: left;
}
.footer > .container { text-align: left; }
.footer-yours { color: color-mix(in srgb, var(--accent-ink) 72%, transparent); font-style: normal; letter-spacing: .2em; }
.footer-message { margin-inline: 0; color: var(--accent-ink); }
.footer-names {
  font-size: calc(clamp(2.2rem, 10vw, 4.4rem) * var(--wk-fs-heading, 1));
  font-weight: 900;
  letter-spacing: .04em;
  line-height: 1.2;
  text-wrap: balance;
}
.footer .blessing { text-align: center; }
.footer .blessing-lead, .footer .blessing-done { color: var(--accent-ink); }
.footer .blessing-lead { opacity: .82; }
.footer .blessing-hint { color: var(--accent-ink); border-color: rgba(255, 255, 255, .38); }
.footer .blessing-hint::before { background: #ffd894; }
/* 窗後那盞燈：從屋裡亮出來的暖光，鐵窗花成了逆光的剪影 */
.footer .weld-stage::before {
  content: "";
  position: absolute;
  inset: 3%;
  z-index: -1;
  background: radial-gradient(75% 75% at 50% 45%, #fff1cf 0, #f2d7a0 46%, #b8925a 100%);
  box-shadow: 0 0 60px 10px rgba(255, 210, 140, .22);
}
.footer .weld-win { filter: drop-shadow(0 2px 2px rgba(0, 0, 0, .45)); }
.footer .weld-win .ww-ghost :is(path, circle) { stroke: rgba(40, 30, 15, .32); }
.footer :is(.contact-who, .contact-ico, .contact-ico[data-kind]::after, .ps-egg, .footer-brand) { color: color-mix(in srgb, var(--accent-ink) 84%, transparent); }
.footer .footer-brand:hover { color: var(--accent-ink); }
.footer .ps-egg { text-decoration-color: rgba(255, 255, 255, .4); }

/* ── 桌機：每一區左右對開（左＝標題與文字、右＝那一區的主角：月曆／地圖／回條） ── */
@media (min-width: 1024px) {
  main > .section > .container { max-width: 64rem; }
  :is(#details, #venue, #rsvp) > .container {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    grid-template-rows: repeat(9, auto) 1fr;
    column-gap: 4.5rem;
    align-items: start;
  }
  :is(#details, #venue, #rsvp) > .container > * { grid-column: 1; }
  #details .oh-bigdate { grid-column: 1 / -1; }
  #details .wk-cal { grid-column: 2; grid-row: 2 / -1; width: 100%; max-width: none; margin-top: 0; }
  #venue .map-frame { grid-column: 2; grid-row: 1 / -1; margin-top: 0; }
  #venue .venue-card2 { grid-column: 1 / -1; grid-row: 11; }
  #rsvp :is(.rsvp-form, .rsvp-success, .rsvp-closed) { grid-column: 2; grid-row: 1 / -1; margin-top: 0; }
  #details .calendar-actions { justify-content: flex-start; }
  .footer > .container { max-width: 64rem; display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 4rem; align-items: center; }
  .footer > .container > * { grid-column: 1; }
  .footer .blessing { grid-column: 2; grid-row: 1 / span 6; margin-top: 0; }
}
/* 服裝色系＝一片花磚地：磚放大、鋪滿整個欄寬 */
.dc-swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(9.5rem, 46%), 1fr)); gap: 4px; width: 100%; margin-inline: 0; }
.dc-swatch { width: auto; }
@media (min-width: 1024px) { .dc-swatches { grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr)); } }
/* 署名：名字不從中間斷開 */
.footer-names { font-size: calc(clamp(1.9rem, 8.4vw, 4rem) * var(--wk-fs-heading, 1)); word-break: keep-all; line-break: strict; }
@media (min-width: 1024px) {
  #venue > .container-wide {
    max-width: 64rem;
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    grid-template-rows: repeat(9, auto) 1fr;
    column-gap: 4.5rem;
    align-items: start;
  }
  #venue > .container-wide > * { grid-column: 1; }
  #venue .map-frame { grid-column: 2; grid-row: 1 / -1; margin-top: 0; }
  #venue .venue-card2 { grid-column: 1 / -1; grid-row: 11; }
}
.venue-bottom { margin-inline: 0; justify-items: start; }
@media (min-width: 1024px) {
  #venue .map-frame { width: 100%; max-width: none; aspect-ratio: 4 / 3.6; }
}
.oh-bigdate { font-size: clamp(6rem, 35vw, 15rem); }

/* ════ v2 評審第 1 輪修正 ════ */
/* P0：英文版沒有黃曆排，大字不能頂到色帶；中文版大字也跟黃曆排多留一點 */
.cal-body { padding-top: 1.05rem; }
.cal-alm:empty + .cal-body { padding-top: 2rem; }
/* P0：月曆標頭字貼邊 */
.wk-cal-title { padding-inline: 1rem; }
/* P0：桌機花磚不留空格（auto-fit 收掉空軌道） */
@media (min-width: 1024px) { .dc-swatches { grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr)); } }

/* 套印錯版：不是陰影，是兩塊版——墨版往右下偏、跟綠版疊出一條更深的重疊色 */
.cal-day[data-d]::after { opacity: .32; translate: .05em .035em; color: var(--iron-dark); }
.oh-bigdate { text-shadow: .05em .035em 0 color-mix(in srgb, var(--iron-dark) 34%, transparent); }

/* 牆面質感：上半粗糙的石灰白牆、下半滾筒刷過的油漆（feTurbulence 噪點，非圖片）；分色線雙線 */
:root {
  --wall-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .2 0 0 0 0 .18 0 0 0 0 .14 0 0 0 .5 0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.38'/%3E%3C/svg%3E");
  --roller: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1600' height='240'%3E%3Cfilter id='r'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.012 .9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .1 0'/%3E%3C/filter%3E%3Crect width='1600' height='240' filter='url(%23r)'/%3E%3C/svg%3E");
}
/* 由上而下：分色雙線／滾筒刷紋（白牆上幾乎看不見、綠牆上看得到）／綠牆裙／石灰牆噪點／磨石子點 */
.intro-wall { background-image: linear-gradient(to bottom, transparent 0 70%, var(--iron-dark) 70% calc(70% + 4px), rgba(255, 255, 255, .28) calc(70% + 4px) calc(70% + 5px), transparent calc(70% + 5px)), var(--roller), linear-gradient(to bottom, transparent 0 70%, var(--accent) 70%), var(--wall-grain), var(--terrazzo); }
.intro-wall { background-size: auto, 1600px 240px, auto, 180px 180px, var(--terrazzo-size); background-color: var(--paper); }
.intro-wall::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* 午後斜射進來的一片窗光，光裡有窗框的影子（落在白牆上、日曆的右上方） */
  background:
    repeating-linear-gradient(90deg, transparent 0 calc(25% - 5px), rgba(70, 50, 20, .14) calc(25% - 5px) 25%),
    linear-gradient(transparent 0 calc(50% - 4px), rgba(70, 50, 20, .14) calc(50% - 4px) 50%, transparent 50%),
    rgba(255, 238, 200, .42);
  left: 46%; top: 4%; width: 62%; height: 40%;
  transform: skewX(-24deg) rotate(-4deg);
  filter: blur(1.5px);
  mix-blend-mode: multiply;
  animation: oh-sun 9s ease-in-out both;
}
@keyframes oh-sun { from { translate: 12% 0; opacity: .4; } to { translate: 0 0; opacity: 1; } }
.hero-content::before { background: var(--roller), var(--accent); background-size: 1600px 240px, auto; box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25); }
@media (min-width: 1024px) {
  .hero { background: var(--roller) 0 58% / 1600px 240px, linear-gradient(to bottom, transparent 0 58%, var(--iron-dark) 58% calc(58% + 5px), var(--accent) calc(58% + 5px)); }
}
/* 一疊日曆的厚度：多幾層紙 */
.pad-edge { bottom: -11px; height: 11px; background: repeating-linear-gradient(to bottom, var(--paper-raise) 0 1.3px, rgba(var(--ink-rgb), .2) 1.3px 2.2px); }

/* 桌機首屏放大 */
@media (min-width: 1024px) {
  :root { --sheet-w: 30rem; }
  .hero-content { max-width: 68rem; column-gap: 5rem; }
  .hero-frame { width: 26rem; }
  .cal-day { font-size: calc(14rem * var(--wk-fs-latin, 1)); }
  .cal-names { font-size: calc(2.5rem * var(--wk-fs-heading, 1)); }
}

/* 桌機故事：三張日曆紙橫排、高低錯落 */
@media (min-width: 1024px) {
  .timeline { max-width: none; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 2.4rem; align-items: start; }
  .timeline-item { width: 100%; }
  .timeline-item:nth-child(even) { justify-self: stretch; margin-top: 4rem; }
  .timeline-item:nth-child(3n) { margin-top: 1.5rem; }
  .tl-date { font-size: calc(5rem * var(--wk-fs-latin, 1)); }
}
/* 相簿說明：長輩讀得到 */
#gallery:not([data-wk-gallery]) .win-caption { font-size: .92rem; color: var(--ink); left: 0; right: 0; }
/* 時程與標題同一條左緣 */
.event-list { margin-inline: 0; max-width: 30rem; }

/* ── 各區底色交替：白紙頁／綠牆／米牆，像一頁一頁翻過去 ── */
/* 白紙頁：頂端一排日曆裝訂孔 */
.section.details, .section.secret { background: var(--paper-raise); }
.section.details::before, .section.secret::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 22px;
  background: radial-gradient(circle at 50% 11px, rgba(var(--ink-rgb), .55) 0 3.5px, rgba(var(--ink-rgb), .12) 4.5px, transparent 5.5px) center top / 44px 22px repeat-x;
  pointer-events: none;
}
.details .wk-cal { box-shadow: 0 0 0 1.5px rgba(var(--ink-rgb), .14); }
/* 地點：整片綠牆（跟首屏同一面牆） */
.section.venue { background: var(--roller), var(--accent); background-size: 1600px 240px, auto; color: var(--accent-ink); }
.venue :is(.section-title, .venue-hall, .venue-address, .transport span, .transport strong, .venue-tag) { color: var(--accent-ink); }
.venue .label-en { background: var(--accent-ink); color: var(--accent); }
.venue .label-en::after { border-top-color: rgba(255, 255, 255, .4); }
.venue .btn:not(.btn-ghost) { background: var(--accent-ink); color: var(--accent); }
.venue .btn-ghost { color: var(--accent-ink); box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .5); }
.venue .map-frame { box-shadow: 0 28px 44px -24px rgba(0, 0, 0, .6); }
/* 小提醒：便條紙放大 */
.custom-block-card { font-size: 1.06rem; }
/* 悄悄話：刮刮卡放大成一整張 */
.secret .scratch-card { max-width: none; min-height: 13rem; display: grid; place-items: center; box-shadow: 0 0 0 1.5px rgba(var(--ink-rgb), .12), 0 24px 36px -26px rgba(var(--ink-rgb), .55); }
.secret .scratch-text { font-size: 1.2rem; }
/* RSVP：一整張撕下來寄回去的回條，上緣鋸齒 */
.rsvp-form {
  border-top: 0;
  padding-top: clamp(2.4rem, 8vw, 3rem);
  -webkit-mask: conic-gradient(from 135deg at top, #0000, #000 1deg 89deg, #0000 90deg) top / 16px 9px repeat-x, linear-gradient(#000 0 0) bottom / 100% calc(100% - 8.5px) no-repeat;
  mask: conic-gradient(from 135deg at top, #0000, #000 1deg 89deg, #0000 90deg) top / 16px 9px repeat-x, linear-gradient(#000 0 0) bottom / 100% calc(100% - 8.5px) no-repeat;
}
.rsvp-form::before { top: 1.1rem; left: 1rem; right: 1rem; border-top: 2px dashed rgba(var(--ink-rgb), .3); }
.rsvp-form::after { top: .35rem; }
.rsvp > .container { filter: drop-shadow(0 18px 22px rgba(var(--ink-rgb), .16)); }
/* 窗光：邊緣清楚一點、暖一點，窗框影子是實的 */
.intro-wall::before {
  background:
    repeating-linear-gradient(90deg, transparent 0 calc(25% - 7px), rgba(60, 42, 16, .2) calc(25% - 7px) 25%),
    linear-gradient(transparent 0 calc(50% - 5px), rgba(60, 42, 16, .2) calc(50% - 5px) 50%, transparent 50%),
    rgba(255, 228, 170, .5);
  filter: blur(.7px);
  left: 52%; top: 6%; width: 52%; height: 34%;
}
@media (min-width: 1024px) {
  .pad { width: var(--sheet-w); }
  .tl-date { font-size: calc(3.7rem * var(--wk-fs-latin, 1)); }
  .intro-wall::before { left: 58%; width: 34%; height: 46%; }
}
/* 焊疤：比鐵條暗一點的一圈焊料，邊緣不平 */
.tr-rivets .tr-weld { fill: color-mix(in srgb, var(--iron) 70%, #1a1712); stroke: var(--iron-dark); stroke-width: .6; stroke-dasharray: 1.4 .9; opacity: .9; }

/* ════ v2 評審第 2 輪修正 ════ */
/* P0 地圖還沒載入時：不是空白方格，是一張手繪的老街道圖（大馬路、巷子、一條溪），中間一根圖釘 */
.map-frame {
  background:
    radial-gradient(circle at 50% 46%, var(--accent) 0 6px, rgba(255, 255, 255, .9) 6px 8px, transparent 9px),
    linear-gradient(transparent calc(58% - 7px), #fdfaf2 calc(58% - 7px) calc(58% + 7px), transparent calc(58% + 7px)),
    linear-gradient(90deg, transparent calc(36% - 6px), #fdfaf2 calc(36% - 6px) calc(36% + 6px), transparent calc(36% + 6px)),
    linear-gradient(118deg, transparent calc(62% - 5px), #fdfaf2 calc(62% - 5px) calc(62% + 5px), transparent calc(62% + 5px)),
    linear-gradient(160deg, transparent calc(78% - 10px), color-mix(in srgb, var(--accent) 20%, #e8e2d2) calc(78% - 10px) calc(78% + 10px), transparent calc(78% + 10px)),
    linear-gradient(rgba(var(--ink-rgb), .09) 1.5px, transparent 1.5px) 10px 10px / 34px 30px,
    linear-gradient(90deg, rgba(var(--ink-rgb), .09) 1.5px, transparent 1.5px) 10px 10px / 34px 30px,
    #ebe4d3;
  background-clip: content-box;
  background-origin: content-box;
  box-shadow: inset 0 0 0 10px var(--paper-raise), inset 0 -30px 0 0 var(--paper-raise), 0 28px 44px -24px rgba(0, 0, 0, .55);
}
/* P0 小提醒：便條貼在牆上、靠左、放大，頂端一條紙膠帶 */
.custom-block-card { margin-inline: 0; max-width: 40rem; font-size: 1.12rem; line-height: 1.85rem; }
.custom-block-card::after {
  content: "";
  position: absolute;
  left: 50%; top: -12px;
  width: 7rem; height: 24px;
  translate: -50% 0;
  rotate: -3deg;
  background: color-mix(in srgb, var(--accent) 22%, rgba(250, 244, 226, .82));
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12);
  pointer-events: none;
}
.custom-text { margin-inline: 0; }
/* P0 桌機開場：窗光斜射過整本日曆（在日曆上面一層、乘色，日曆也被照到），日曆壓過牆裙線 */
.intro-stage::after {
  content: "";
  position: absolute;
  pointer-events: none;
  z-index: 3;
  left: 30%; top: -4%; width: 54%; height: 72%;
  background:
    repeating-linear-gradient(90deg, transparent 0 calc(25% - 8px), rgba(60, 42, 16, .16) calc(25% - 8px) 25%),
    linear-gradient(transparent 0 calc(50% - 6px), rgba(60, 42, 16, .16) calc(50% - 6px) 50%, transparent 50%),
    rgba(255, 214, 140, .22);
  transform: skewX(-26deg) rotate(-6deg);
  filter: blur(1px);
  mix-blend-mode: multiply;
  animation: oh-sun 9s ease-in-out both;
}
.intro-wall::before { display: none; }
html.has-intro .intro-commit .intro-stage::after { opacity: 0; transition: opacity .3s ease; }
@media (min-width: 1024px) {
  .pad { width: min(var(--sheet-w), 58vh); top: 50%; }
  .intro-stage::after { left: 34%; width: 40%; height: 84%; }
}
/* P1 套印殘影：同一個強調色壓深一階（不是灰），疊出更深的重疊色 */
.cal-day[data-d]::after { color: color-mix(in srgb, var(--accent) 72%, #0b0a08); opacity: .5; }
.oh-bigdate { text-shadow: .05em .035em 0 color-mix(in srgb, color-mix(in srgb, var(--accent) 72%, #0b0a08) 50%, transparent); }
/* P1 桌機首屏下半：倒數放大、貼近 */
@media (min-width: 1024px) {
  .countdown { margin-top: 2rem; gap: .9rem; }
  .cd-cell { width: 7.4rem; padding: .8rem 0; }
  .cd-cell strong { font-size: calc(4.4rem * var(--wk-fs-latin, 1)); }
  .cd-cell span { font-size: .95rem; }
}
/* P1 回條：拿掉整個容器的投影（會把標題字也暈髒） */
.rsvp > .container { filter: none; }
.rsvp-form { background: #fffdf7; }
/* P1 導航鈕在綠牆上：米白實心 */
.venue #btn-nav, .venue .venue-bottom .btn { background: var(--accent-ink); color: var(--accent); box-shadow: none; }
/* P1 手機相簿：大、對、大、對的節奏（第 1、4 張整面窗） */
@media (max-width: 719px) {
  #gallery:not([data-wk-gallery]) .photo-item:nth-child(3n+1) { grid-column: 1 / -1; margin-top: 0; }
  #gallery:not([data-wk-gallery]) .photo-item:nth-child(3n+1) img { aspect-ratio: 4 / 5; }
  #gallery:not([data-wk-gallery]) .photo-item:nth-child(odd):not(:first-child) { margin-top: 0; }
  #gallery:not([data-wk-gallery]) .photo-item:nth-child(3n) { margin-top: clamp(1.6rem, 7vw, 2.4rem); }
}
/* P1 桌機故事：卡片與年份放大 */
@media (min-width: 1024px) {
  .story > .container { max-width: 72rem; }
  .tl-date { font-size: calc(4.6rem * var(--wk-fs-latin, 1)); letter-spacing: -.05em; }
  .tl-title { font-size: 1.7rem; }
  .tl-text { font-size: 1.08rem; }
}
/* P1 服裝色系說明靠左 */
.dc-note { margin-inline: 0; }
/* P2 終章彩蛋連結靠左 */
.footer .ps-egg { margin-inline: 0; }
/* 小提醒的純文字便條（不是卡片款）：同樣放大、貼牆、紙膠帶 */
.custom-block:not(.custom-block-card):not(.custom-block-quote) .custom-text {
  position: relative;
  max-width: 40rem;
  padding: 1.6rem 1.6rem 1.5rem;
  font-size: 1.1rem;
  line-height: 2.2rem;
  background:
    repeating-linear-gradient(to bottom, transparent 0 calc(2.2rem - 1px), rgba(var(--ink-rgb), .1) calc(2.2rem - 1px) 2.2rem),
    var(--paper-raise);
  background-position: 0 1.6rem;
}
.custom-block:not(.custom-block-card):not(.custom-block-quote) .custom-text::before {
  content: "";
  position: absolute;
  left: 50%; top: -12px;
  width: 7rem; height: 24px;
  translate: -50% 0;
  rotate: 2deg;
  background: color-mix(in srgb, var(--accent) 22%, rgba(250, 244, 226, .82));
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12);
}
@media (min-width: 1024px) {
  .custom-block:not(.custom-block-card):not(.custom-block-quote) .custom-text,
  .custom-block-card { max-width: 46rem; font-size: 1.3rem; line-height: 2.6rem; background-size: auto; }
  .custom-block:not(.custom-block-card):not(.custom-block-quote) .custom-text {
    background: repeating-linear-gradient(to bottom, transparent 0 calc(2.6rem - 1px), rgba(var(--ink-rgb), .1) calc(2.6rem - 1px) 2.6rem) 0 1.6rem, var(--paper-raise);
  }
}

/* ════ v2 評審第 3 輪修正 ════ */
/* 終章窗花：跟楣窗同一套漆鐵材質；花瓣鐵條加粗一級、帶高光 */
.weld-win .ww-paint, .weld-win .ww-flower { filter: url(#oh-ww-iron); }
.weld-win .ww-flower :is(.petal, .ww-heart) { stroke-width: 4.4; }
.weld-win .ww-flower-shine { display: inline; }
.weld-win .ww-flower-shine :is(.petal, .ww-heart) { stroke: rgba(255, 255, 255, .42); stroke-width: 1.1; fill: none !important; }
/* P0 桌機婚禮資訊：右欄月曆底下接「加入日曆」與主婚人，左欄是日期與時程，兩欄等長 */
@media (min-width: 1024px) {
  #details .wk-cal { grid-row: 2 / 7; }
  #details .calendar-actions { grid-column: 2; grid-row: 7; margin-top: 1.6rem; }
  #details .parents { grid-column: 2; grid-row: 8; }
  #details .event-list { grid-row: 6 / span 4; }
}
/* P0 地圖載入後：洗成老照片的色調（跟整本同一個時代），下緣圖說一定在紙上 */
.map-frame {
  background-clip: content-box, content-box, content-box, content-box, content-box, content-box, content-box, content-box, border-box;
  background-origin: content-box, content-box, content-box, content-box, content-box, content-box, content-box, content-box, border-box;
  background-image:
    radial-gradient(circle at 50% 46%, var(--accent) 0 6px, rgba(255, 255, 255, .9) 6px 8px, transparent 9px),
    linear-gradient(transparent calc(58% - 7px), #fdfaf2 calc(58% - 7px) calc(58% + 7px), transparent calc(58% + 7px)),
    linear-gradient(90deg, transparent calc(36% - 6px), #fdfaf2 calc(36% - 6px) calc(36% + 6px), transparent calc(36% + 6px)),
    linear-gradient(118deg, transparent calc(62% - 5px), #fdfaf2 calc(62% - 5px) calc(62% + 5px), transparent calc(62% + 5px)),
    linear-gradient(160deg, transparent calc(78% - 10px), color-mix(in srgb, var(--accent) 20%, #e8e2d2) calc(78% - 10px) calc(78% + 10px), transparent calc(78% + 10px)),
    linear-gradient(rgba(var(--ink-rgb), .09) 1.5px, transparent 1.5px),
    linear-gradient(90deg, rgba(var(--ink-rgb), .09) 1.5px, transparent 1.5px),
    linear-gradient(#ebe4d3, #ebe4d3),
    linear-gradient(var(--paper-raise), var(--paper-raise));
  background-size: auto, auto, auto, auto, auto, 34px 30px, 34px 30px, auto, auto;
  background-color: var(--paper-raise);
  box-shadow: 0 28px 44px -24px rgba(0, 0, 0, .55);
}
.map-frame iframe { filter: sepia(.38) saturate(.72) contrast(.94) brightness(1.02); }
.map-frame::after { color: var(--pencil); z-index: 2; }
/* P1 悄悄話：整片綠牆，刮刮卡是貼在牆上的一張大紙（紙膠帶、微斜） */
.section.secret { background: var(--roller), var(--accent); background-size: 1600px 240px, auto; color: var(--accent-ink); }
.section.secret::before { display: none; }
.secret .section-title { color: var(--accent-ink); }
.secret .label-en { background: var(--accent-ink); color: var(--accent); }
.secret .label-en::after { border-top-color: rgba(255, 255, 255, .4); }
.secret .scratch-wrap { position: relative; rotate: -1.2deg; }
.secret .scratch-wrap::before {
  content: "";
  position: absolute;
  left: 50%; top: -12px; z-index: 4;
  width: 7.5rem; height: 26px;
  translate: -50% 0;
  rotate: 3deg;
  background: rgba(250, 244, 226, .78);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .15);
  pointer-events: none;
}
.secret .scratch-card { min-height: 15rem; box-shadow: 0 26px 40px -22px rgba(0, 0, 0, .55); }
.secret .scratch-open { color: var(--accent-ink); }
/* P1 回條：在磨石子地上斜放一點 */
.rsvp-form { rotate: -.7deg; }
@media (min-width: 1024px) { .rsvp-form { rotate: 1deg; } }
/* P1 手機相簿：小圖那一對楣窗高一點（鐵件看得清楚） */
@media (max-width: 719px) {
  #gallery:not([data-wk-gallery]) .photo-grid { gap: clamp(2rem, 7vw, 2.6rem) 12px; }
}
/* P1 開場：綠牆上一個老式電燈開關（白色膠殼、黑色撥桿），讓那一片牆有生活痕跡 */
.intro-stage::before {
  content: "";
  position: absolute;
  z-index: 1;
  left: max(1.4rem, calc(50% - 15rem)); top: calc(70% + 2.6rem);
  width: 2.5rem; height: 3.9rem;
  border-radius: 5px;
  background:
    radial-gradient(circle at 50% 12%, #9a958a 0 1.6px, transparent 2.4px),
    radial-gradient(circle at 50% 88%, #9a958a 0 1.6px, transparent 2.4px),
    linear-gradient(#2b2925, #2b2925) 50% 50% / 7px 15px no-repeat,
    linear-gradient(160deg, #fbf7ec, #e3ddcd);
  box-shadow: 1px 2px 0 rgba(0, 0, 0, .2), 3px 7px 10px -4px rgba(0, 0, 0, .45);
  pointer-events: none;
}
html.has-intro .intro-commit .intro-stage::before { opacity: 0; transition: opacity .4s ease; }
.intro-skip { color: var(--ink); }
.intro-stage::before { left: 1.6rem; top: calc(70% + 4.6rem); }
@media (min-width: 1024px) { .intro-stage::before { left: calc(50% - 21rem); top: calc(70% + 3.4rem); } }

/* ════ v2 評審第 4 輪修正 ════ */
/* 時程：時間印成日曆大字（不是細線小字），每一列一條撕線 */
.event-row { grid-template-columns: 7.2rem 1fr; align-items: center; border-top: 1.5px dotted rgba(var(--ink-rgb), .35); }
.event-row:last-child { border-bottom: 1.5px dotted rgba(var(--ink-rgb), .35); }
.event-row dt { font-size: calc(clamp(2rem, 9vw, 2.4rem) * var(--wk-fs-latin, 1)); line-height: 1; letter-spacing: -.02em; }
.event-row dd strong { font-size: calc(1.2rem * var(--wk-fs-heading, 1)); font-weight: 900; }
.event-row dd span { font-size: .95rem; color: var(--ink-soft); }
.parents { font-size: .98rem; color: var(--ink-soft); }
.wk-cal-d { font-size: clamp(.95rem, 3.6vw, 1.05rem); }
.wk-cal-wd { font-size: .9rem; }
/* 桌機婚禮資訊：改用浮動排兩欄——右欄（月曆、加入日曆、主婚人）往右靠，左欄字照常流下來，不再被格線拉出空洞 */
@media (min-width: 1024px) {
  #details > .container { display: block; }
  #details > .container::after { content: ""; display: table; clear: both; }
  #details > .container > :is(.label-en, .section-title, .details-date, .details-note, .event-list) { max-width: 46%; }
  #details .wk-cal, #details .calendar-actions, #details .parents { float: right; clear: right; width: 48%; max-width: none; margin-top: 0; }
  #details .calendar-actions { margin-top: 1.6rem; justify-content: flex-start; }
  #details .parents { margin-top: 1.2rem; }
  #details .wk-cal { margin-top: -10rem; }
  #details .event-list { margin-top: 2.6rem; }
  .event-row dt { font-size: calc(3rem * var(--wk-fs-latin, 1)); }
  .event-row { grid-template-columns: 8.6rem 1fr; }
}
/* 小提醒：手機不提早折行；桌機放大成海報尺度 */
.custom-text { text-wrap: pretty; }
@media (min-width: 1024px) {
  .custom-block:not(.custom-block-card):not(.custom-block-quote) .custom-text,
  .custom-block-card { max-width: none; font-size: 1.65rem; line-height: 3.2rem; padding: 2.4rem 2.6rem 2.2rem; }
  .custom-block:not(.custom-block-card):not(.custom-block-quote) .custom-text {
    background: repeating-linear-gradient(to bottom, transparent 0 calc(3.2rem - 1px), rgba(var(--ink-rgb), .1) calc(3.2rem - 1px) 3.2rem) 0 2.4rem, var(--paper-raise);
  }
}
/* 地圖：再洗舊一點 */
.map-frame iframe { filter: sepia(.55) saturate(.5) contrast(.92) brightness(1.03); }
/* 頁尾：全部靠左一條線 */
.footer .ps-egg { padding-left: 0; }
.footer .footer-brand { margin-inline: 0; padding-left: 0; }

/* ════ v2 評審第 5 輪修正 ════ */
/* 桌機婚禮資訊：左欄＝日期、時程、加入日曆、主婚人；右欄只放月曆 */
@media (min-width: 1024px) {
  #details .calendar-actions, #details .parents { float: none; clear: none; width: auto; max-width: 46%; }
  #details .wk-cal { margin-top: -9rem; width: 48%; }
  #details .wk-cal-d { font-size: 1.12rem; }
}
/* 服裝色系＝一整片花磚地：出血滿版、磚縫 3px，一直鋪到區塊底 */
.section.dresscode { padding-bottom: 0; }
.dc-swatches {
  width: auto;
  margin: clamp(2rem, 7vw, 2.8rem) calc(50% - 50vw) 0;
  gap: 3px;
  padding: 3px 0 0;
  background: color-mix(in srgb, var(--paper) 70%, #b9b2a3);
  grid-template-columns: repeat(auto-fit, minmax(min(10rem, 48%), 1fr));
}
@media (min-width: 1024px) {
  .dc-swatches { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 1fr; }
  .dc-swatch { aspect-ratio: 1 / 1.08; }
}
/* 頁尾連結靠左 */
.footer .ps-egg { text-align: left; }
/* 桌機相簿：跟標題同一條左緣、撐滿 */
@media (min-width: 1024px) {
  #gallery:not([data-wk-gallery]) .photo-grid { max-width: none; margin-inline: 0; }
  #gallery > .container-wide { max-width: 64rem; }
}
#gallery:not([data-wk-gallery]) .win-caption { font-size: 1rem; }
/* 刮刮卡提示字放大 */
.secret .scratch-hint { font-size: 1.12rem; }
@media (hover: hover) and (pointer: fine) and (min-width: 1024px) { .secret .scratch-hint::after { font-size: 1.15rem; } }
@media (min-width: 1024px) { .secret .scratch-card { min-height: 18rem; } .secret .scratch-text { font-size: 1.5rem; } }
.dc-swatches { max-width: none; }
.section.dresscode { overflow-x: clip; }
/* 桌機滑鼠版提示字：本體字收掉、只留 ::after 那一句（上面放大字級時別把它蓋回來） */
@media (hover: hover) and (pointer: fine) and (min-width: 1024px) { .secret .scratch-hint { font-size: 0; } }

/* ════ v2 評審第 6 輪（桌機三區尺度）════ */
.tl-date { padding-top: 1.2rem; }
@media (min-width: 1024px) {
  .story > .container { max-width: 76rem; }
  .timeline { column-gap: 2rem; }
  .tl-date { font-size: calc(5.2rem * var(--wk-fs-latin, 1)); }
  .timeline-item > :not(.tl-date) { padding-inline: 1.6rem; }
  .tl-title { font-size: 1.9rem; }
  .tl-text { font-size: 1.15rem; line-height: 1.9; }
  .timeline-item { padding-bottom: 2rem; }
  .section.story { padding-bottom: clamp(3.5rem, 6vw, 5rem); }
  /* 婚禮資訊：月曆長到跟左欄等高 */
  #details .wk-cal { padding: 0 1.4rem 1.6rem; }
  #details .wk-cal-title { margin: 0 -1.4rem 1.2rem; padding: .7rem 1.4rem; font-size: 1.2rem; }
  #details .wk-cal-d { height: 3.6rem; font-size: 1.3rem; }
  #details .wk-cal-wd { font-size: 1.05rem; padding-bottom: .8rem; }
  /* 小提醒：字放大到兩行就把便條撐滿 */
  .custom-block:not(.custom-block-card):not(.custom-block-quote) .custom-text,
  .custom-block-card { max-width: 50rem; font-size: 1.95rem; line-height: 3.6rem; padding: 2.8rem 3rem 2.6rem; }
  .custom-block:not(.custom-block-card):not(.custom-block-quote) .custom-text {
    background: repeating-linear-gradient(to bottom, transparent 0 calc(3.6rem - 1px), rgba(var(--ink-rgb), .1) calc(3.6rem - 1px) 3.6rem) 0 2.8rem, var(--paper-raise);
  }
}
@media (min-width: 1024px) {
  main > .section.story > .container { max-width: 76rem; }
  #details .wk-cal-d { height: 4.5rem; }
}
@media (min-width: 1024px) { #details .wk-cal-d { aspect-ratio: auto; } #details .wk-cal-grid { grid-template-columns: repeat(7, minmax(0, 1fr)); } }
/* 桌機婚禮資訊最後一哩：大日期撐滿欄寬；月曆格再高一點，底緣跟左欄主婚人那一行對齊 */
@media (min-width: 1024px) {
  .oh-bigdate { font-size: calc(23.5rem * var(--wk-fs-latin, 1)); }
  #details .wk-cal-d { height: 6rem; }
}

/* ════ v2 評審第 8 輪 ════ */
/* WebKit 雷：<svg> 本身掛 CSS drop-shadow，會在頁面左上角 (0,0) 畫出一小塊白方塊（iPhone Safari 同引擎）。
   終章窗花的投影改由 SVG 裡的暗邊層（.ww-under）負責，svg 本身不掛 filter。 */
.weld-win, .footer .weld-win { filter: none; }
.weld-win .ww-under > * { stroke-width: 5.2; }
.weld-win .ww-under > .ww-frame { stroke-width: 9.6; }
/* 桌機故事內文加深；桌機小提醒便條撐滿欄寬 */
.tl-text { color: var(--ink); }
@media (min-width: 1024px) {
  .custom-block:not(.custom-block-card):not(.custom-block-quote) .custom-text,
  .custom-block-card { max-width: none; font-size: 2.15rem; line-height: 3.9rem; padding: 3rem 3.2rem 2.8rem; }
  .custom-block:not(.custom-block-card):not(.custom-block-quote) .custom-text {
    background: repeating-linear-gradient(to bottom, transparent 0 calc(3.9rem - 1px), rgba(var(--ink-rgb), .1) calc(3.9rem - 1px) 3.9rem) 0 3rem, var(--paper-raise);
  }
}

/* ════ 2026-10-31 Jacob 實測回報 ════ */
/* ① 小提醒帶照片：照片是一張貼在牆上的白邊相片，便條在旁邊或底下——絕不疊在照片上
   （之前便條的紙底＋position:relative 蓋過了左浮動的照片）。並排版改用格線、不用 float。 */
.custom-block .custom-img {
  display: block;
  margin: 1.6rem 0 0;
  box-shadow: 0 0 0 7px var(--paper-raise), 0 0 0 8px rgba(var(--ink-rgb), .1), 0 20px 32px -20px rgba(var(--ink-rgb), .5);
  rotate: .8deg;
}
.custom-block:has(.custom-img) .custom-text { margin-top: 2rem; }
.custom-block-side::after { display: none; }
@media (min-width: 720px) {
  .custom-block-side { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: 2.6rem; align-items: start; }
  .custom-block-side > :not(.custom-img):not(.custom-text) { grid-column: 1 / -1; }
  .custom-block-side .custom-img { float: none; width: 100%; margin: 1.8rem 0 0; }
  .custom-block-side .custom-text { margin-top: 1.8rem; }
}
/* ② 桌機字級整體收一階（Jacob：「桌面版文字都有點太大」）——尺度靠大日期與色塊撐，內文回到好讀的大小 */
@media (min-width: 1024px) {
  body { font-size: 1rem; }
  .section-title { font-size: calc(3.6rem * var(--wk-fs-heading, 1)); }
  .label-en { font-size: calc(.9rem * var(--wk-fs-latin, 1)); }
  .cal-names { font-size: calc(2.1rem * var(--wk-fs-heading, 1)); }
  .cd-cell { width: 6.2rem; }
  .cd-cell strong { font-size: calc(3.3rem * var(--wk-fs-latin, 1)); }
  .tl-date { font-size: calc(4.3rem * var(--wk-fs-latin, 1)); }
  .tl-title { font-size: 1.45rem; }
  .tl-text { font-size: 1.02rem; line-height: 1.85; }
  .event-row dt { font-size: calc(2.4rem * var(--wk-fs-latin, 1)); }
  .event-row { grid-template-columns: 7rem 1fr; }
  .event-row dd strong { font-size: 1.12rem; }
  #details .wk-cal-d { height: 4.6rem; font-size: 1.08rem; }
  #details .wk-cal-title { font-size: 1.05rem; }
  .custom-block:not(.custom-block-card):not(.custom-block-quote) .custom-text,
  .custom-block-card { font-size: 1.35rem; line-height: 2.9rem; padding: 2.2rem 2.4rem 2rem; }
  .custom-block:not(.custom-block-card):not(.custom-block-quote) .custom-text {
    background: repeating-linear-gradient(to bottom, transparent 0 calc(2.9rem - 1px), rgba(var(--ink-rgb), .1) calc(2.9rem - 1px) 2.9rem) 0 2.2rem, var(--paper-raise);
  }
  .secret .scratch-text { font-size: 1.25rem; }
  .footer-names { font-size: calc(3rem * var(--wk-fs-heading, 1)); }
  .weld-tag { font-size: 1.5rem; }
}
/* 小提醒帶照片（桌機）：並排時便條垂直置中對齊照片；上圖下文時照片放大到欄寬的七成 */
@media (min-width: 1024px) {
  .custom-block-side { align-items: center; }
  .custom-block-side .custom-text { margin-top: 1.8rem; }
  .custom-block:not(.custom-block-side) .custom-img { width: min(100%, 42rem); }
  .custom-block:not(.custom-block-card):not(.custom-block-quote) .custom-text,
  .custom-block-card { font-size: 1.2rem; line-height: 2.7rem; }
  .custom-block:not(.custom-block-card):not(.custom-block-quote) .custom-text {
    background: repeating-linear-gradient(to bottom, transparent 0 calc(2.7rem - 1px), rgba(var(--ink-rgb), .1) calc(2.7rem - 1px) 2.7rem) 0 2.2rem, var(--paper-raise);
  }
  .tl-text { font-size: 1.06rem; }
  .parents { font-size: 1.02rem; }
  .footer .blessing-lead { font-size: 1.05rem; }
}

/* 祝福留言牆在夜色頁尾：共用樣式的次要字吃 --ink-soft（深色），在 --night 上只有 1.8。
   只改直接落在夜色上的小標與引導文案（卡片、表單有自己的紙底，不動），用米白與夜色的實色混合 */
.footer .wk-bless :is(.wk-bless-kicker, .wk-bless-lead) { color: color-mix(in srgb, var(--accent-ink) 80%, var(--night)); }
.footer .wk-bless.is-invited .wk-bless-lead { color: var(--accent-ink); }
.footer .wk-bless-more { color: var(--accent-ink); border-color: color-mix(in srgb, var(--accent-ink) 55%, var(--night)); }
.footer .wk-bless-more:focus-visible { outline-color: var(--accent-ink); }

/* A+ 放大字＋360 窄手機：倒數四格的最小寬 4.4rem 跟著根字級放大，四格加間距撐破版面（372/360）。
   只在放大模式＋手機寬收斂：格寬不超過四等分、數字不超過 11vw */
@media (max-width: 559px) {
  html.wk-aplus .cd-cell { width: min(clamp(4.4rem, 20vw, 5.4rem), calc((100% - 1.5rem) / 4)); }
  html.wk-aplus .cd-cell strong { font-size: calc(min(2.3rem, 11vw) * var(--wk-fs-latin, 1)); }
}
