/* ============================================================
   wedding-blueprint｜兩人的家（一張兩人要一起蓋的家的設計圖）
   概念：喜帖＝描圖紙上的一張設計圖，每一區是這個家的一個房間
   （客廳＝故事、陽台＝相簿、餐廳＝婚禮資訊、玄關＝地點、書房＝小叮嚀、信箱＝回函）。
   全站第一款「理性、俐落、篤定」的模板：跟簡約策展（看展）不同，這一套是「我們要一起蓋這個家」。
   - 開場：從頂端捲筒把圖紙往下拉開（六款裡唯一的「下拉」），圖框的線邊拉邊畫；
     攤平後圖紙下緣的圖框（title block）飛進 Hero 落定＝一鏡到底
   - Hero：圖框（繪圖＝新人、日期＝婚期、比例 1:1、審核＝賓客）＋自己畫出來的立面圖，
     婚紗照嵌在大窗洞裡、兩側尺寸標註線
   - 相簿原生版式「立面圖」（elevation）：照片嵌在窗洞裡，三種開口輪替，下緣尺寸標註＝窗號＋圖說
   - 終章「鎖上門牌」：按住，四顆螺絲轉緊，門牌刻賓客名字＋「歡迎回家」
   色彩與間距 token 覆寫自 /shared/base.css。

   ── 這一套的體系規則，改這份檔案前先讀 ──
   ① 「靜就是貴」判準：把製圖線（尺寸線、房間標籤、立面線、方格）全拿掉，版面仍是一張
      乾淨、留白、單一強調色、襯線標題的喜帖。線只用 --accent，一律細（≤1.5px）。
   ② 單一強調色＝製圖藍。--accent 對紙底與浮起表面都 ≥4.5，所以文字與線條共用一階
      （不像韓系／牽手要拆兩階）；新增配色只要給 --accent 與 --accent-rgb 兩個值。
   ③ 拉丁字與所有標註數字一律 IBM Plex Mono（圖面上的標註字本來就是等寬字），
      中文標題 Serif TC、內文 Sans TC。數字另外寫 lnum／tnum 兩種寫法（DESIGN §7 ③）。
   ④ 版面靠左（理性的圖面語言），只有頁尾「門口」置中。
   ⑤ 動態預算低：線條畫出來（dash）、尺寸線伸長、圖章蓋下、指北針微轉（陀螺儀，手機才動）。
      全部一次性、只在捲進畫面時跑；絕不 scroll-scrub、沒有無限循環。
   ⑥ 不因 reduced-motion 降級（wk-keep-motion），這裡沒有 RM 區塊；預設 CSS 是完成態。
   ============================================================ */

:root {
  /* 2026-10-31 改版：真正的曬圖（cyanotype）——深普魯士藍底、白線、白字。
     曬圖的原理是「線擋住光、沒擋到的地方曬成藍」，所以圖面上的一切都是白的；
     唯一的暖色是燈（--lamp）：房子亮燈、主按鈕、門牌。 */
  --paper:        #173e6e;              /* 曬圖藍（底） */
  --paper-raise:  #1d4a80;              /* 浮起表面（圖框、卡片、輸入框）：比底亮一階 */
  --paper-deep:   #102d52;              /* 沉下去的面（窗、凹槽） */
  --ink:          #f3f6fa;              /* 粉筆白（正文／標題／圖框外框） */
  --ink-soft:     #bccbe0;              /* 次要文字（對底 6.9／對浮起 5.7） */
  --accent:       #a9d0f7;              /* 淡青白（線、標註、強調字）：曬圖上比紙白淡一階的那種白 */
  --accent-rgb:   169, 208, 247;
  --accent-ink:   #10294a;              /* 強調色底上的文字色 */
  --lamp:         #ffcf73;              /* 燈（唯一的暖色：亮燈、主按鈕、門牌） */
  --lamp-rgb:     255, 207, 115;
  --lamp-ink:     #2a1d05;
  --line-rgb:     243, 246, 250;        /* 製圖白線 */
  --hairline:     rgba(243, 246, 250, .2);
  --ink-rgb:      243, 246, 250;
  --shade-rgb:    5, 16, 33;
  --warn:         #ffb9a8;              /* 錯誤字（淡珊瑚：深藍底上要看得清楚） */            /* 陰影一律用暗色（ink 是白的，不能拿來做影子） */
  --desk:         #0c2141;              /* 開場的製圖桌面（夜裡的桌子） */
  --scratch-a:    #2a5b94;              /* 刮刮樂塗層＝還沒曬的感光紙 */
  --scratch-b:    #22507f;
  --font-sans-tc: "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", sans-serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  --font-serif-latin: var(--font-mono);

  --radius: .2rem;                      /* 圖面是直角的；「圓潤」檔位由 base.css 覆寫 */
  --section-y: clamp(3.8rem, 11vw, 6.5rem);
  --shadow-soft: 0 22px 50px -26px rgba(var(--shade-rgb), .7);
  --line: 1px;                          /* 製圖線的粗細 */
}

/* ---------- 配色變體（只覆寫色彩 token，版式一律不動；DESIGN §7）---------- */
/* 配色變體：墨綠曬圖（二氮曬圖 diazo 的墨綠） */
html[data-wk-theme="engineer"] {
  --paper: #163f35; --paper-raise: #1c4d41; --paper-deep: #0f2e27; --desk: #0a2019;
  --ink-soft: #bcd5cb;
  --accent: #a8e0c6; --accent-rgb: 168, 224, 198; --accent-ink: #0d2a20;
  --scratch-a: #2a6a58; --scratch-b: #225a4b;
}
/* 配色變體：棕色印樣（Van Dyke 照片印樣的深棕，燈光最暖的一組） */
html[data-wk-theme="redline"] {
  --paper: #3d2219; --paper-raise: #4b2c21; --paper-deep: #2c1811; --desk: #1f110b;
  --ink-soft: #e2c7bb;
  --accent: #f2c3ae; --accent-rgb: 242, 195, 174; --accent-ink: #34190f;
  --scratch-a: #6a3e2d; --scratch-b: #5a3426;
}
/* 配色變體：炭灰（最安靜的一組） */
html[data-wk-theme="graphite"] {
  --paper: #23272d; --paper-raise: #2d3239; --paper-deep: #191c20; --desk: #121417;
  --ink-soft: #c3cad3;
  --accent: #cdd6e1; --accent-rgb: 205, 214, 225; --accent-ink: #1b1f24;
  --scratch-a: #474e58; --scratch-b: #3c424b;
}

/* 主按鈕：方角（圖面是直角的）、強調色實底 */
/* 主按鈕＝這張藍圖上唯一的暖色（燈）：該按的東西一眼就找得到 */
.btn { border-radius: var(--radius); letter-spacing: .14em; font-weight: 500; background: var(--lamp); color: var(--lamp-ink); }
.btn.btn-ghost { background: transparent; color: var(--ink); }
.btn-ghost { box-shadow: inset 0 0 0 1px rgba(var(--ink-rgb), .45); }
.btn-ghost:hover { box-shadow: inset 0 0 0 1px var(--ink); }

/* ---------- 紙＝描圖紙＋極淡方格 ----------
   底色放 html、body 透明；方格是 body 的固定偽元素（負 z，不擋點擊）。
   桌機：方格只露在內文欄兩側的大片留白裡（中間 40rem 遮掉，絕不壓字）；
   手機：內文欄就是整個畫面，方格淡到只剩一層紙感（對比量測不受影響，見 blueprint-check）。 */
html { background: var(--paper); }
body {
  font-family: var(--wk-f-body, var(--font-sans-tc));
  font-weight: 400;
  font-size: var(--text-body);
  line-height: 1.8;
  letter-spacing: .02em;
  background: transparent;
  color: var(--ink);
  overflow-x: hidden;
}
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(rgba(var(--line-rgb), .07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--line-rgb), .07) 1px, transparent 1px),
    linear-gradient(rgba(var(--line-rgb), .03) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--line-rgb), .03) 1px, transparent 1px);
  background-size: 64px 64px, 64px 64px, 16px 16px, 16px 16px;
  background-position: -1px -1px;
  opacity: .55;
}
/* 曬圖紙的斑駁：藥水刷不勻＋紙纖維（固定層，不跟著捲；最上層、不擋點擊） */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' 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 .55 -.22'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E"),
    radial-gradient(120% 70% at 12% 8%, rgba(var(--line-rgb), .07), transparent 60%),
    radial-gradient(90% 60% at 92% 88%, rgba(var(--shade-rgb), .35), transparent 65%);
  opacity: .9;
}
@media (min-width: 900px) {
  body::before {
    opacity: 1;
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(50% - 26rem), transparent calc(50% - 21rem), transparent calc(50% + 21rem), #000 calc(50% + 26rem));
    mask-image: linear-gradient(90deg, #000 0, #000 calc(50% - 26rem), transparent calc(50% - 21rem), transparent calc(50% + 21rem), #000 calc(50% + 26rem));
  }
}

/* ---------- 動態語彙：淡入、位移很小（圖面上的東西不會飄） ---------- */
.reveal {
  transform: translateY(10px);
  transition: opacity .9s var(--ease-out), transform .9s var(--ease-out);
}

/* ═══════════════════════════════════════════════════════════
   開場：從頂端捲筒把圖紙往下拉開
   - 桌面（#intro 底色）上方一根捲筒；圖紙在捲筒「後面」，只露出下緣那一段（＝圖框）
   - 拉＝圖紙往下滑出來（transform，跟手 --wk-open）；圖框四條邊線跟著畫出來（scale）
   - .intro-slot 從捲筒中線往下裁切：還捲在筒裡的那一段看不見
   - 收場：圖紙背景、捲筒、桌面淡掉，圖框（.tb--intro）飛到 Hero 的圖框上（--fx/--fy/--fs）
   ⚠ 跟手期間（.is-dragging）一律關 transition；放手沒過閾值＝值歸零，transition 負責回彈。
   ⚠ 每幀寫的 --wk-open 掛在 #intro 上（開場層只有這幾個節點，沒有大量子孫要重算）。
   ═══════════════════════════════════════════════════════════ */
.intro {
  /* 捲筒的高度：讓「捲筒＋露出的圖框＋提示＋婚期」整組在畫面上垂直置中（--peek 由開場 script 量好寫上） */
  --tube-y: max(3.4rem, calc(env(safe-area-inset-top, 0px) + 2.4rem), calc((100vh - var(--peek) - 12rem) / 2 + 1.6rem));
  /* 圖紙寬＝Hero 圖框寬（容器寬，最多 30rem）＋兩側 12px：圖紙上的圖框跟 Hero 的同寬，飛過去縮放比＝1 */
  --sw: calc(min(calc(100vw - 2 * var(--gutter, 1.25rem)), 30rem) + 24px);
  --sh: calc(100vh - var(--tube-y) - 11px - 1.25rem);
  --peek: 17rem;
  position: fixed;
  inset: 0;
  z-index: 80;
  background-color: var(--desk);
  color: var(--ink);
  touch-action: none;
  cursor: grab;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  transition: background-color .5s var(--ease-out);
}
@supports (height: 100svh) {
  .intro {
    --tube-y: max(3.4rem, calc(env(safe-area-inset-top, 0px) + 2.4rem), calc((100svh - var(--peek) - 12rem) / 2 + 1.6rem));
    --sh: calc(100svh - var(--tube-y) - 11px - 1.25rem);
  }
}
.intro.is-dragging { cursor: grabbing; }
.intro-stage { position: absolute; inset: 0; }

.intro-desk {
  position: absolute;
  left: 0; right: 0;
  top: calc(var(--tube-y) + 11px + var(--peek) + 6.2rem);
  text-align: center;
  opacity: calc(1 - var(--wk-open, 0) * 2.2);
}
.intro-kicker {
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: .8rem;
  letter-spacing: .32em;
  text-indent: .32em;
  color: var(--ink-soft);
}
.intro-date {
  margin-top: .3rem;
  font-family: var(--wk-f-latin, var(--font-mono));
  font-weight: 500;
  font-size: 1.05rem;
  letter-spacing: .22em;
  text-indent: .22em;
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "lnum" 1, "tnum" 1;
}
.intro-date:empty { display: none; }

.intro-slot {
  position: absolute;
  top: calc(var(--tube-y) + 11px);
  left: 0; right: 0; bottom: 0;
  overflow: hidden;
}
.intro-sheet {
  position: absolute;
  top: 0;
  left: 50%;
  width: var(--sw);
  height: var(--sh);
  margin-left: calc(var(--sw) / -2);
  transform: translateY(calc((var(--wk-open, 0) - 1) * (var(--sh) - var(--peek))));
  transition: transform .6s linear(0, .06 2%, .23 5%, .53 10%, .8 16%, .95 22%, 1.03 29%, 1.05 35%, 1.04 42%, 1.01 55%, .995 70%, 1);
  will-change: transform;
}
/* 圖紙本身（紙、陰影、方格）在偽元素上：收場時紙淡掉、圖框留著飛走 */
.intro-sheet::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(rgba(var(--accent-rgb), .06) 1px, transparent 1px) -1px -1px / 16px 16px,
    linear-gradient(90deg, rgba(var(--accent-rgb), .06) 1px, transparent 1px) -1px -1px / 16px 16px,
    var(--paper);
  box-shadow: 0 1px 0 rgba(var(--shade-rgb), .3), 0 24px 44px -20px rgba(var(--shade-rgb), .75);
  transition: opacity .45s var(--ease-out) .08s;
}
/* 圖框邊線：四條，跟著拉的進度畫出來（上→右→下→左順時針的原點） */
.isf { position: absolute; background: var(--ink); transition: transform .6s var(--ease-out), opacity .45s var(--ease-out) .08s; }
.isf-t { top: 12px; left: 12px; right: 12px; height: 1px; transform-origin: 0 50%; transform: scaleX(var(--wk-open, 0)); }
.isf-r { top: 12px; right: 12px; bottom: 12px; width: 1px; transform-origin: 50% 0; transform: scaleY(var(--wk-open, 0)); }
.isf-b { bottom: 12px; left: 12px; right: 12px; height: 1px; transform-origin: 100% 50%; transform: scaleX(var(--wk-open, 0)); }
.isf-l { top: 12px; left: 12px; bottom: 12px; width: 1px; transform-origin: 50% 100%; transform: scaleY(var(--wk-open, 0)); }
.intro-sheet-no {
  position: absolute;
  top: 24px; left: 24px;
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: .62rem;
  letter-spacing: .24em;
  color: var(--ink-soft);
  opacity: var(--wk-open, 0);
  transition: opacity .45s var(--ease-out);
}
.intro-house {
  position: absolute;
  left: 50%; top: 3rem;
  /* 大小由「圖框上方剩多少高度」決定，矮螢幕也不會壓到圖框 */
  height: min(calc(var(--sh) - var(--peek) - 2rem), calc(min(72vw, 17.5rem) * 1.3614));
  aspect-ratio: 332 / 452;
  translate: -50% 0;
  opacity: calc(var(--wk-open, 0) * 3);
  transition: opacity .45s var(--ease-out) .08s;
}
.intro-house-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
/* 窗洞內框 viewBox x40–260、y114–406（同 Hero 立面圖的算式） */
.intro-photo {
  position: absolute;
  left: 16.867%; top: 25.221%;
  width: 66.265%; height: 64.602%;
  object-fit: cover;
  object-position: center 30%;
  filter: grayscale(1) contrast(1.12) brightness(1.04);
  mix-blend-mode: multiply;
  opacity: clamp(0, calc((var(--wk-open, 0) - .3) * 1.4), .82);
  transition: opacity .5s var(--ease-out);
}
.intro-photo:not([src]), .intro-photo[src=""] { display: none; }
.intro.is-dragging .intro-photo { transition: none; }
.intro-house :is(path, rect, circle) {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.4;
  stroke-dasharray: 1 1;
  stroke-dashoffset: calc(1 - var(--wk-open, 0));
  transition: stroke-dashoffset .6s var(--ease-out);
}
.intro.is-dragging .intro-house :is(path, rect, circle) { transition: none; }
.intro-commit .intro-house :is(path, rect, circle) { transition: stroke-dashoffset .5s cubic-bezier(.3, .7, .2, 1); }
.intro-land .intro-house { opacity: 0; }
.tb--intro {
  position: absolute;
  left: 12px; right: 12px; bottom: 12px;
  transform-origin: 0 0;
}

.intro-roof {
  position: absolute;
  left: 50%;
  /* 屋頂底邊貼在捲筒上緣；大小依捲筒上方剩多少空間（矮螢幕自動變小、不撞「跳過」） */
  top: auto;
  bottom: calc(100% - var(--tube-y) + 2px);
  width: min(74vw, 19rem, calc((var(--tube-y) - 3.2rem) * 3.26));
  translate: -50% 0;
  overflow: visible;
  opacity: max(.28, calc(1 - var(--wk-open, 0) * 2.4));
  transition: opacity .35s var(--ease-out);
}
.intro-roof :is(path, circle) { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linecap: square; }
.intro-roof path:nth-child(2), .intro-roof circle, .intro-roof path:last-child { stroke-width: .9; }
.intro-land .intro-roof { opacity: 0; }
.intro-tube {
  position: absolute;
  top: var(--tube-y);
  left: 50%;
  width: min(calc(var(--sw) + 1.4rem), calc(100vw - .5rem));
  height: 22px;
  translate: -50% 0;
  border-radius: 11px;
  background: linear-gradient(180deg, #fdfcf9 0%, #ecebe5 42%, #cfccc3 100%);
  box-shadow: inset 0 0 0 1px rgba(var(--ink-rgb), .14), 0 8px 14px -8px rgba(var(--ink-rgb), .5);
  overflow: hidden;
  transition: opacity .35s var(--ease-out);
}
/* 筒身的細紋：跟著拉的進度往下捲（＝圖紙從筒裡轉出來） */
.intro-tube i {
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(180deg, transparent 0 6px, rgba(var(--ink-rgb), .07) 6px 7px);
  background-position: 0 calc(var(--wk-open, 0) * 140px);
}
/* 兩端的筒蓋 */
.intro-tube::before, .intro-tube::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  width: .7rem;
  background: linear-gradient(180deg, #5b626d, #2b3038);
}
.intro-tube::before { left: 0; }
.intro-tube::after { right: 0; }

.intro-guide {
  position: absolute;
  left: 50%;
  /* 緊貼在圖紙下緣下方（拉的那個手勢就從這裡開始）；圖紙往下拉時它淡掉 */
  top: calc(var(--tube-y) + 11px + var(--peek) + 1.6rem);
  transform: translateX(-50%);
  min-height: 44px;
  padding: .4rem 1rem;
  border: 0;
  background: none;
  color: var(--ink);
  font-family: var(--wk-f-body, var(--font-sans-tc));
  font-size: .95rem;
  font-weight: 500;
  letter-spacing: .24em;
  text-indent: .24em;
  white-space: nowrap;
  cursor: inherit;
  opacity: calc(1 - var(--wk-open, 0) * 3);
}
/* 往下的箭頭：一條線＋箭頭，輕輕往下點（只在等待時） */
.intro-guide::after {
  content: "";
  display: block;
  width: 9px; height: 9px;
  margin: .45rem auto 0;
  border-right: 1.5px solid var(--accent);
  border-bottom: 1.5px solid var(--accent);
  transform: rotate(45deg);
}
.intro-wait:not(.is-touched) .intro-guide::after { animation: bp-nudge 1.8s var(--ease-out) infinite; }
@keyframes bp-nudge {
  0%, 100% { translate: 0 0; opacity: .6; }
  50% { translate: 0 5px; opacity: 1; }
}
.intro-skip {
  position: absolute;
  top: max(.6rem, env(safe-area-inset-top, 0px));
  right: .6rem;
  min-width: 44px; min-height: 44px;
  padding: .3rem .8rem;
  border: 0;
  background: none;
  color: var(--ink-soft);
  font-size: .85rem;
  letter-spacing: .12em;
  cursor: pointer;
}
.intro-skip:focus-visible, .intro-guide:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* 跟手：關 transition */
.intro.is-dragging .intro-sheet,
.intro.is-dragging .isf { transition: none; }
/* 收場：從當下的位置一路展開到底（--wk-open 已被設成 1） */
.intro-commit .intro-sheet { transition: transform .5s cubic-bezier(.3, .7, .2, 1); }
.intro-commit .isf { transition: transform .5s cubic-bezier(.3, .7, .2, 1), opacity .45s var(--ease-out) .08s; }
.intro-play.intro-commit .intro-sheet,
.intro-play.intro-commit .isf { transition-duration: .9s; }
.intro-commit .intro-guide, .intro-commit .intro-skip { opacity: 0; transition: opacity .25s; pointer-events: none; }
/* land()：紙、捲筒、桌面淡掉，圖框飛向 Hero */
.intro-land { background-color: transparent; }
.intro-land .intro-slot { overflow: visible; }
.intro-land .intro-sheet::before,
.intro-land .isf,
.intro-land .intro-sheet-no,
.intro-land .intro-tube,
.intro-land .intro-desk { opacity: 0; }
html.wk-bp-landed .intro-land .tb--intro {
  transform: translate(var(--fx, 0px), var(--fy, 0px)) scale(var(--fs, 1));
  transition: transform .62s cubic-bezier(.65, 0, .25, 1);
  animation: bp-lift .62s cubic-bezier(.65, 0, .25, 1);
}
@keyframes bp-lift {
  0%, 100% { box-shadow: inset 0 0 0 1.5px var(--ink), 0 0 0 transparent; }
  45% { box-shadow: inset 0 0 0 1.5px var(--ink), 0 26px 40px -18px rgba(var(--shade-rgb), .7); }
}
/* 飛行中畫面上只准有一張圖框：Hero 那張先藏著（版面還在），開場層撤掉的同一幀交棒 */
html.has-intro.wk-bp-landed .hero .tb { visibility: hidden; }
html.fx.wk-bp-landed .hero .tb.reveal { opacity: 1; transform: none; transition: none; }

/* 開場期間 Hero 先藏著（收場後淡入）；一鏡到底的路徑在圖框飛的時候就開始浮現 */
html.fx.has-intro:not(.wk-bp-landed) .hero .reveal { opacity: 0; transform: translateY(10px); }
/* Hero 圖框不位移（只淡入）：land() 量它的位置時必須已經是落定的位置，不然飛過去會差 10px */
html.fx .hero .tb.reveal,
html.fx.has-intro:not(.wk-bp-landed) .hero .tb.reveal { transform: none; }

/* ═══════════════════════════════════════════════════════════
   圖框（title block）：Hero 與開場圖紙共用同一套
   ═══════════════════════════════════════════════════════════ */
.tb {
  display: grid;
  grid-template-columns: 1fr 1fr minmax(6.8rem, 1fr);
  background: var(--paper-raise);
  box-shadow: inset 0 0 0 1.5px var(--ink);
  text-align: left;
}
.tb-c {
  position: relative;
  min-width: 0;
  padding: .55rem .75rem .6rem;
  border-right: 1px solid rgba(var(--ink-rgb), .55);
  border-bottom: 1px solid rgba(var(--ink-rgb), .55);
}
.tb-title, .tb-date, .tb-check { grid-column: span 2; }
.tb-drawn { grid-column: 1 / -1; border-right: 0; padding-right: 1.4rem; }
.tb-no, .tb-scale, .tb-north { border-right: 0; }
.tb-check, .tb-north { border-bottom: 0; }
.tb-k {
  display: block;
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: .76rem;
  line-height: 1.4;
  letter-spacing: .12em;
  color: var(--ink-soft);
  white-space: nowrap;
}
.tb-k b {
  margin-right: .45em;
  font-family: var(--wk-f-body, var(--font-sans-tc));
  font-size: .8rem;
  font-weight: 500;
  letter-spacing: .22em;
  color: var(--ink);
}
.tb-k em { font-style: normal; }
.tb-v {
  display: block;
  margin-top: .15rem;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(1.05rem * var(--wk-fs-heading, 1));
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: .12em;
}
.tb-mono {
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: calc(1.02rem * var(--wk-fs-latin, 1));
  font-weight: 500;
  letter-spacing: .04em;
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "lnum" 1, "tnum" 1;
}
.hero-names {
  margin: .2rem 0 0;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(clamp(1.7rem, 7.2vw, 2.5rem) * var(--wk-fs-heading, 1));
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: .1em;
  white-space: nowrap;
}
.hero-names .amp {
  margin: 0 .28em;
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: .68em;
  font-weight: 400;
  color: var(--accent);
  vertical-align: .1em;
  letter-spacing: 0;
}
.hero-names-en {
  margin-top: .2rem;
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: calc(.76rem * var(--wk-fs-latin, 1));
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  white-space: pre;
}
.hero-names-en:empty { display: none; }
.hero-date {
  margin-top: .15rem;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(1rem * var(--wk-fs-heading, 1));
  font-weight: 500;
  line-height: 1.55;
  letter-spacing: .06em;
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "lnum" 1, "tnum" 1;
}
/* 圖框的日期欄窄：星期換到第二行（小一階），不在「星／期六」中間斷 */
.tb .hero-date .dot-sep { display: block; height: 0; overflow: hidden; }
.tb .hero-date .dot-sep + span { font-size: .86em; color: var(--ink-soft); letter-spacing: .1em; }
.hero-note {
  display: block;
  font-family: var(--wk-f-body, var(--font-sans-tc));
  font-size: var(--text-small);
  font-weight: 400;
  color: var(--ink-soft);
  letter-spacing: .04em;
  white-space: pre-line;
}
.hero-note:empty { display: none; }

/* 比例尺：1:1＋一段黑白相間的比例尺 */
.tb-bar {
  display: block;
  width: 4.2rem; height: 5px;
  margin-top: .35rem;
  box-shadow: inset 0 0 0 1px var(--accent);
  background: linear-gradient(90deg, var(--accent) 0 25%, transparent 25% 50%, var(--accent) 50% 75%, transparent 75%);
  transform-origin: 0 50%;
}
/* 審核欄：賓客名字（強調色＝冠名）；沒有名字＝一條待簽的虛線 */
.tb-checked { color: var(--accent); min-height: 1.6em; padding-right: 4.2rem; overflow-wrap: anywhere; }
.tb-checked:empty::after {
  content: "";
  display: block;
  width: min(6rem, 70%);
  height: 1.35em;
  border-bottom: 1px dashed rgba(var(--ink-rgb), .45);
}
/* 指北針 */
.tb-compass { display: block; margin-top: .1rem; }
.tb-compass svg { display: block; width: 34px; height: 34px; overflow: visible; }
.tb-compass circle { fill: none; stroke: var(--accent); stroke-width: 1.2; }
.tb-compass .needle { fill: var(--accent); transform-box: view-box; transform-origin: 20px 20px; }

/* 圖框上的三顆彩蛋按鈕（比例尺／審核章／指北針） */
.tb-egg {
  position: relative;
  display: block;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* 觸控目標：按鈕本體就 ≥44×44（第 6 輪評審 P0：用偽元素外撐的點擊區會被隔壁格的圖層蓋掉、斜的章也撐不夠） */
.tb-egg { min-width: 44px; min-height: 44px; }
.tb-egg:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
html:not([data-wk-eggs]) .tb-egg { cursor: default; }
.tb-scale-btn { display: block; }
.tb-compass { width: 44px; height: 44px; display: grid; place-items: center start; }
.tb-compass .needle { rotate: var(--gyro, 0deg); transition: rotate .4s var(--ease-out); }
/* 指北針：收場後輕輕脈動三下（提示可以點），不無限循環 */
html[data-wk-eggs]:not(.has-intro) .hero .tb-compass::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  box-shadow: 0 0 0 1.5px var(--accent);
  opacity: 0;
  animation: bp-ping 1.4s var(--ease-out) 1.6s 2;
  pointer-events: none;
}
@keyframes bp-ping {
  0% { opacity: .9; scale: 1; }
  100% { opacity: 0; scale: 1.6; }
}
.tb.is-pointing .tb-compass .needle { rotate: var(--nr, 0deg); transition: rotate 1s linear(0, .06 2%, .23 5%, .53 10%, .8 16%, .95 22%, 1.03 29%, 1.05 35%, 1.04 42%, 1.01 55%, .995 70%, 1); }
.tb.is-real .tb-bar { animation: bp-scale-real .9s var(--ease-out); }
@keyframes bp-scale-real {
  0% { transform: scaleX(1); }
  45% { transform: scaleX(1.8); }
  100% { transform: scaleX(1); }
}
/* 審核章：長方形雙線章（建築師的核准章是方的），斜蓋在審核欄右側 */
.tb-stamp {
  position: absolute;
  z-index: 2;
  right: 1.15rem;   /* 離方位欄遠一點：兩顆彩蛋的點擊區不能互相重疊 */
  top: 50%;
  translate: 0 -50%;
  rotate: -8deg;
  min-width: 3.6rem;
  padding: .25rem .75rem;
  display: grid;
  place-items: center;
  border: 3px double var(--accent);
  color: var(--accent);
  text-align: center;
}
.tb-stamp-ink {
  display: block;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: .86rem;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: .18em;
  text-indent: .18em;
  white-space: pre-line;
}
.tb.is-approved .tb-stamp { animation: bp-stamp .55s cubic-bezier(.2, 1.3, .4, 1); }
/* 開場：圖紙上的章在 commit 之前是空的，拉滿／點下去的那一刻蓋下（同一段 .5s 內，不拉長開場） */
.tb--intro .tb-stamp { opacity: 0; }
.intro-commit .tb--intro .tb-stamp { animation: bp-stamp-big .5s cubic-bezier(.2, 1.3, .4, 1) .08s both; }
@keyframes bp-stamp-big {
  0% { scale: 2.6; opacity: 0; }
  55% { scale: .92; opacity: 1; }
  100% { scale: 1; opacity: 1; }
}
.intro-commit .tb--intro { animation: bp-press .3s cubic-bezier(.3, 1.4, .5, 1) .15s; }   /* .45s 前收完，land() 換上 bp-lift 時不會跳 */
@keyframes bp-press {
  0%, 100% { translate: 0 0; }
  35% { translate: 0 5px; }
}
@keyframes bp-stamp {
  0% { scale: 1.7; opacity: 0; }
  60% { scale: .94; opacity: 1; }
  100% { scale: 1; opacity: 1; }
}
/* 彩蛋說的話：圖框下面一行，像圖面上用引線拉出來的註記 */
.hero-content { position: relative; }
.tb-say {
  position: absolute;
  z-index: 3;
  width: 100%;
  margin-top: .6rem;
  padding: .75rem 1rem .75rem 1.2rem;
  background: var(--paper-raise);
  box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), .55), var(--shadow-soft);
  text-wrap: balance;
  padding-left: 1.6rem;
  font-family: var(--wk-f-body, var(--font-sans-tc));
  font-size: .95rem;
  font-weight: 500;
  color: var(--accent);
  letter-spacing: .06em;
}
.tb-say::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--accent);
}
.tb-say.is-pop { animation: bp-say .5s var(--ease-out); }
@keyframes bp-say {
  from { opacity: 0; translate: -6px 0; }
  to { opacity: 1; translate: 0 0; }
}

/* ═══════════════════════════════════════════════════════════
   ① Hero
   ═══════════════════════════════════════════════════════════ */
.hero {
  padding: clamp(2.4rem, 8vw, 3.6rem) var(--gutter) clamp(1rem, 4vw, 2rem);
}
.hero-content {
  max-width: 30rem;
  margin: 0 auto;
}
.hero-label {
  margin-bottom: 1rem;
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: calc(.78rem * var(--wk-fs-latin, 1));
  letter-spacing: .2em;
  color: var(--accent);
}
/* 立面圖：viewBox -16 0 332 452；窗洞內框 x 40–260、y 114–406 → 照片的百分比位置 */
.hero-frame {
  position: relative;
  width: 100%;
  max-width: 27rem;
  margin: clamp(2.2rem, 8vw, 3rem) auto 0;
  aspect-ratio: 332 / 452;
}
.hero-elev {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  overflow: visible;
}
.hero-elev path, .hero-elev rect, .hero-elev circle {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.1;
  stroke-linecap: square;
}
.hero-elev .thin { stroke-width: .6; }
.hero-elev .tri { fill: var(--accent); stroke: none; }
.hero-elev text {
  fill: var(--accent);
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: 11px;
  letter-spacing: .06em;
}
.hero-photo {
  position: absolute;
  left: 16.867%;
  top: 25.221%;
  width: 66.265%;
  height: 64.602%;
  object-fit: cover;
  object-position: center 30%;
  background: rgba(var(--accent-rgb), .06);
}
/* 線條畫出來：每一段 pathLength＝1，dashoffset 1→0，依 --i 錯開。
   預設是完成態（offset 0）；只有 html.fx 下「還沒捲進畫面」或「開場還沒收」才藏起來。 */
.dl {
  stroke-dasharray: 1 1;
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1.2s cubic-bezier(.5, .1, .25, 1) calc(var(--i, 0) * .13s + .1s);
}
.hero-elev text, .hero-elev .tri { transition: opacity .8s var(--ease-out) .85s; }
.hero-photo { transition: opacity 1.1s var(--ease-out) .85s; }   /* 窗框先畫好，照片才亮 */
html.fx .hero-frame:not(.is-in) .dl,
html.fx.has-intro:not(.wk-bp-landed) .hero-frame .dl { stroke-dashoffset: 1; }
html.fx .hero-frame:not(.is-in) :is(text, .tri),
html.fx.has-intro:not(.wk-bp-landed) .hero-frame :is(text, .tri),
html.fx .hero-frame:not(.is-in) .hero-photo,
html.fx.has-intro:not(.wk-bp-landed) .hero-frame .hero-photo { opacity: 0; }
html.fx.wk-bp-landed .hero-frame .dl { stroke-dashoffset: 0; transition: none; }
html.fx.wk-bp-landed .hero-frame :is(text, .tri) { transition-delay: .2s; }
html.fx.wk-bp-landed .hero-frame .hero-photo { transition-delay: .35s; }
/* 立面圖本身不做位移（線是畫出來的，框不該再飄一次） */
.hero-frame.reveal { transform: none; }

/* 附註：新人的開頭那一行 */
.hero-notes {
  margin-top: clamp(1.8rem, 6vw, 2.4rem);
  padding-left: .9rem;
  border-left: 2px solid var(--accent);
}
.hero-notes:has(#hero-greeting[hidden]) { display: none; }
.hero-notes-k {
  display: block;
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: .78rem;
  letter-spacing: .18em;
  color: var(--accent);
}
.hero-greeting {
  margin-top: .15rem;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(1.08rem * var(--wk-fs-heading, 1));
  font-weight: 500;
  line-height: 1.75;
  letter-spacing: .06em;
}

/* 倒數：一列四格的表 */
.countdown {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  margin-top: 1.6rem;
  box-shadow: inset 0 0 0 1px var(--ink);
  background: var(--paper-raise);
}
.cd-cell {
  padding: .6rem 0 .5rem;
  text-align: center;
  border-right: 1px solid var(--hairline);
}
.cd-cell:last-child { border-right: 0; }
.cd-cell strong {
  display: block;
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: calc(clamp(1.35rem, 6vw, 1.7rem) * var(--wk-fs-latin, 1));
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: .02em;
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "lnum" 1, "tnum" 1;
}
.cd-cell span { font-size: .86rem; letter-spacing: .24em; text-indent: .24em; color: var(--ink-soft); }

/* 桌機：整張圖紙——雙線外框、左邊立面圖、右下角圖框 */
@media (min-width: 960px) {
  .hero { padding-top: clamp(2rem, 4vw, 3rem); }
  .hero-content {
    max-width: 68rem;
    display: grid;
    grid-template-columns: 6fr 6fr;
    grid-template-rows: auto 1fr auto auto auto auto;
    grid-template-areas:
      "label label"
      "frame ."
      "frame tb"
      "frame say"
      "frame notes"
      "frame cd";
    column-gap: clamp(2.5rem, 5vw, 4.5rem);
    padding: clamp(2rem, 3.5vw, 3rem);
    box-shadow: inset 0 0 0 1px var(--ink), inset 0 0 0 6px var(--paper), inset 0 0 0 7px rgba(var(--ink-rgb), .55);
    background: rgba(var(--shade-rgb), .12);
  }
  .hero-label { grid-area: label; text-align: center; margin-bottom: 1.6rem; }
  .hero .tb { grid-area: tb; }
  .tb-say { grid-area: say; }
  .hero-frame { grid-area: frame; margin: 0 auto; max-width: 30rem; }
  .hero-notes { grid-area: notes; }
  .countdown { grid-area: cd; }
}

/* ═══════════════════════════════════════════════════════════
   房間：標籤（房號由 CSS counter 依實際顯示順序編）＋標題＋尺寸線
   ═══════════════════════════════════════════════════════════ */
main { counter-reset: room; }
main > .section:not([hidden]) { counter-increment: room; }
.section { text-align: left; }
.room-tag {
  display: flex;
  align-items: baseline;
  gap: .6rem;
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: calc(.74rem * var(--wk-fs-latin, 1));
  letter-spacing: .14em;
  color: var(--accent);
}
.room-no::before { content: "R-" counter(room, decimal-leading-zero); }
.room-tag::after {
  content: "";
  order: 2;
  flex: 1;
  min-width: 1rem;
  border-top: 1px solid rgba(var(--accent-rgb), .45);
  transform: translateY(-.28em);
}
.room-zh {
  order: 3;
  font-family: var(--wk-f-body, var(--font-sans-tc));
  font-size: .84rem;
  font-weight: 500;
  letter-spacing: .3em;
  color: var(--ink);
}
.section-title {
  margin-top: .7rem;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(var(--text-h2) * var(--wk-fs-heading, 1));
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: .12em;
}
/* 尺寸線：一條帶兩端斜撇的標註線，中間寫尺寸；捲進畫面時從左往右伸長 */
.dim {
  position: relative;
  display: block;
  width: min(62%, 17rem);
  height: 14px;
  margin: .6rem 0 clamp(1.8rem, 6vw, 2.4rem);
}
.dim::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 7px;
  border-top: 1px solid var(--accent);
  transform-origin: 0 50%;
  transition: transform 1.1s cubic-bezier(.5, .1, .25, 1) .15s;
}
.dim i, .dim::after {
  position: absolute;
  top: 1px;
  width: 1px; height: 12px;
  background: var(--accent);
  rotate: 45deg;
}
.dim i { left: 0; }
.dim::after { content: ""; right: 0; transition: opacity .3s 1.1s; }
.dim em {
  position: absolute;
  left: 50%; top: -.55rem;
  translate: -50% 0;
  padding: 0 .45em;
  background: var(--paper);
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: .7rem;
  font-style: normal;
  letter-spacing: .1em;
  color: var(--accent);
  transition: opacity .5s .8s;
  font-variant-numeric: lining-nums tabular-nums;
}
.dim.reveal { transform: none; }
html.fx .dim.reveal:not(.is-in)::before { transform: scaleX(0); }
html.fx .dim.reveal:not(.is-in)::after,
html.fx .dim.reveal:not(.is-in) em { opacity: 0; }

/* 桌機：所有區塊共用同一條左緣（container 與 container-wide 同寬），文字欄各自限寬 */
@media (min-width: 1024px) {
  main .container { max-width: var(--wide-max); }
  :is(.timeline, .custom-text, .custom-block-card, .rsvp-intro, .rsvp-form, .rsvp-success, .rsvp-closed, .scratch-wrap, .dc-note, .details-note) { max-width: 40rem; }
  .video-frame:not([data-ratio="portrait"]):not([data-provider="instagram"]) { max-width: 52rem; }
}

/* ── 房間之間的門（平面圖符號）──
   相鄰兩個房間之間畫一道牆：左右兩段牆線，中間留一個門洞，門扇＋開門的四分之一弧。
   顏色吃 --accent（mask 上色，四組配色與自訂色都跟），純裝飾、不佔版面（絕對定位在區塊上緣）。 */
main > .section, .footer { position: relative; }
main > .section:not([hidden]) ~ .section:not([hidden])::before,
.footer::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: min(calc(100% - 2 * var(--gutter)), var(--wide-max));
  height: 2.6rem;
  translate: -50% 0;
  background: rgba(var(--accent-rgb), .78);
  -webkit-mask:
    linear-gradient(#000, #000) 0 0 / calc(50% - 1.3rem) 1px no-repeat,
    linear-gradient(#000, #000) 100% 0 / calc(50% - 1.3rem) 1px no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='42' height='42' viewBox='0 0 42 42'%3E%3Cpath d='M.5 0V41.5' stroke='%23000' fill='none'/%3E%3Cpath d='M.5 41.5A41 41 0 0 0 41.5 .5' stroke='%23000' stroke-dasharray='3 3' fill='none'/%3E%3C/svg%3E") 50% 0 / 2.6rem 2.6rem no-repeat;
  mask:
    linear-gradient(#000, #000) 0 0 / calc(50% - 1.3rem) 1px no-repeat,
    linear-gradient(#000, #000) 100% 0 / calc(50% - 1.3rem) 1px no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='42' height='42' viewBox='0 0 42 42'%3E%3Cpath d='M.5 0V41.5' stroke='%23000' fill='none'/%3E%3Cpath d='M.5 41.5A41 41 0 0 0 41.5 .5' stroke='%23000' stroke-dasharray='3 3' fill='none'/%3E%3C/svg%3E") 50% 0 / 2.6rem 2.6rem no-repeat;
  pointer-events: none;
}

/* 門的變化：玄關＝雙開大門、閣樓＝推拉門、信箱＝投信口 */
main > .section:not([hidden]) ~ #venue:not([hidden])::before {
  -webkit-mask-image: linear-gradient(#000, #000), linear-gradient(#000, #000), url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='42' height='42' viewBox='0 0 42 42'%3E%3Cpath d='M.5 0V21M41.5 0V21' stroke='%23000' fill='none'/%3E%3Cpath d='M.5 21A20.5 20.5 0 0 0 21 .5M41.5 21A20.5 20.5 0 0 1 21 .5' stroke='%23000' stroke-dasharray='3 3' fill='none'/%3E%3C/svg%3E");
  mask-image: linear-gradient(#000, #000), linear-gradient(#000, #000), url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='42' height='42' viewBox='0 0 42 42'%3E%3Cpath d='M.5 0V21M41.5 0V21' stroke='%23000' fill='none'/%3E%3Cpath d='M.5 21A20.5 20.5 0 0 0 21 .5M41.5 21A20.5 20.5 0 0 1 21 .5' stroke='%23000' stroke-dasharray='3 3' fill='none'/%3E%3C/svg%3E");
}
main > .section:not([hidden]) ~ #secret:not([hidden])::before {
  -webkit-mask-image: linear-gradient(#000, #000), linear-gradient(#000, #000), url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='42' height='42' viewBox='0 0 42 42'%3E%3Cpath d='M0 3.5H24M18 7.5H42' stroke='%23000' stroke-width='1.6' fill='none'/%3E%3Cpath d='M30 13l6 0M33 10l3 3l-3 3' stroke='%23000' fill='none'/%3E%3C/svg%3E");
  mask-image: linear-gradient(#000, #000), linear-gradient(#000, #000), url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='42' height='42' viewBox='0 0 42 42'%3E%3Cpath d='M0 3.5H24M18 7.5H42' stroke='%23000' stroke-width='1.6' fill='none'/%3E%3Cpath d='M30 13l6 0M33 10l3 3l-3 3' stroke='%23000' fill='none'/%3E%3C/svg%3E");
}
main > .section:not([hidden]) ~ #rsvp:not([hidden])::before {
  -webkit-mask-image: linear-gradient(#000, #000), linear-gradient(#000, #000), url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='42' height='42' viewBox='0 0 42 42'%3E%3Crect x='6.5' y='-.5' width='29' height='7' stroke='%23000' fill='none'/%3E%3Cpath d='M12 3.5H30' stroke='%23000' stroke-dasharray='2 2' fill='none'/%3E%3C/svg%3E");
  mask-image: linear-gradient(#000, #000), linear-gradient(#000, #000), url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='42' height='42' viewBox='0 0 42 42'%3E%3Crect x='6.5' y='-.5' width='29' height='7' stroke='%23000' fill='none'/%3E%3Cpath d='M12 3.5H30' stroke='%23000' stroke-dasharray='2 2' fill='none'/%3E%3C/svg%3E");
}

/* ============ ② Story：客廳——施工進度表 ============ */
.timeline {
  list-style: none;
  margin-left: .35rem;
  border-left: 1px solid var(--accent);
}
.timeline-item { position: relative; padding: 0 0 clamp(2rem, 7vw, 2.6rem) 1.6rem; }
.timeline-item:last-child { padding-bottom: .3rem; }
.timeline-item::before {
  content: "";
  position: absolute;
  left: -5px; top: .55rem;
  width: 9px; height: 9px;
  border: 1px solid var(--accent);
  background: var(--paper);
  rotate: 45deg;
}
.tl-date {
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: calc(.8rem * var(--wk-fs-latin, 1));
  font-weight: 500;
  letter-spacing: .08em;
  color: var(--accent);
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "lnum" 1, "tnum" 1;
}
.tl-title {
  margin-top: .1rem;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(clamp(1.1rem, 4vw, 1.25rem) * var(--wk-fs-heading, 1));
  font-weight: 600;
  letter-spacing: .08em;
  line-height: 1.5;
}
.tl-text { margin-top: .35rem; color: var(--ink-soft); white-space: pre-line; text-wrap: pretty; }
.tl-photo { margin: .9rem 0 .2rem; max-width: 22rem; }
.tl-photo img { display: block; width: 100%; box-shadow: 0 0 0 4px var(--paper), 0 0 0 5px var(--accent); }
@media (min-width: 1024px) {
  .timeline-item:has(.tl-photo) { display: grid; grid-template-columns: 1fr 15rem; column-gap: 2rem; }
  .timeline-item:has(.tl-photo) .tl-photo { grid-column: 2; grid-row: 1 / span 3; margin-top: .3rem; }
  .timeline-item:has(.tl-photo) > :not(.tl-photo) { grid-column: 1; }
}

/* ============ ③ Gallery：原生版式「立面圖」（elevation） ============
   照片＝窗洞：雙線框（內框 4px 紙色間隙＋1px 製圖藍），上緣一道過樑線；
   三種開口輪替：落地窗（跨兩欄 4:5）／方窗（1:1）／直窗（3:4），底對齊（同一條地平線）。
   下緣尺寸標註：一條帶端點的標註線＋窗號（W-01，CSS counter）＋新人寫的圖說。
   ⚠ 原生規則全包在 #gallery:not([data-wk-gallery]) 底下：切到 shared 版式時一條都選不到。 */
#gallery:not([data-wk-gallery]) .photo-grid {
  counter-reset: win;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(3.6rem, 10vw, 4.4rem) clamp(1.1rem, 4vw, 1.6rem);
  align-items: end;
  margin-top: .4rem;
}
#gallery:not([data-wk-gallery]) .photo-item {
  position: relative;
  margin: 0;
  counter-increment: win;
  cursor: zoom-in;
  padding-top: 12px;
}
/* 過樑線（窗洞上緣多出兩側的一道粗線） */
#gallery:not([data-wk-gallery]) .photo-item::before {
  content: "";
  position: absolute;
  top: 0; left: -9px; right: -9px;
  border-top: 1.5px solid var(--accent);
  transform-origin: 0 50%;
  transition: transform 1s cubic-bezier(.5, .1, .25, 1) .25s;
}
/* 窗一扇一扇裝上去：過樑線在照片淡入後從左伸出來 */
html.fx #gallery:not([data-wk-gallery]) .photo-item.reveal:not(.is-in)::before { transform: scaleX(0); }
#gallery:not([data-wk-gallery]) .photo-item img {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  box-shadow: 0 0 0 4px var(--paper), 0 0 0 5px var(--accent);
  background: rgba(var(--accent-rgb), .06);
}
#gallery:not([data-wk-gallery]) .photo-item:nth-child(3n+1) { grid-column: 1 / -1; }
#gallery:not([data-wk-gallery]) .photo-item:nth-child(3n+1) img { aspect-ratio: 4 / 3; }
#gallery:not([data-wk-gallery]) .photo-item:nth-child(3n+2) img { aspect-ratio: 1; }
/* 落單的最後一張（3n+2 是最後一個）：不留半排空白，自己置中 */
#gallery:not([data-wk-gallery]) .photo-item:nth-child(3n+2):last-child { grid-column: 1 / -1; width: calc(50% - .8rem); justify-self: center; }
/* 桌機：三欄一排＝一面立面，三種開口站在同一條地平線上（落地窗最高） */
@media (min-width: 880px) {
  #gallery:not([data-wk-gallery]) .photo-grid { grid-template-columns: repeat(3, 1fr); column-gap: clamp(1.6rem, 3vw, 2.6rem); }
  #gallery:not([data-wk-gallery]) .photo-item:nth-child(3n+1) { grid-column: auto; }
  #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(3n+2) img { aspect-ratio: 10 / 11; }
  #gallery:not([data-wk-gallery]) .photo-item:nth-child(3n+2):last-child { grid-column: auto; width: auto; justify-self: stretch; }
}
/* 標註掛在窗洞正下方、不佔版面高度：同一排的窗洞底緣才會對齊在同一條地平線（圖說長短不影響） */
.elev-cap {
  position: absolute;
  left: 0; right: 0; top: 100%;
  display: block;
  margin-top: 14px;
  padding-top: 14px;
  background:
    linear-gradient(var(--accent), var(--accent)) 0 4px / 100% 1px no-repeat,
    linear-gradient(var(--accent), var(--accent)) 0 0 / 1px 9px no-repeat,
    linear-gradient(var(--accent), var(--accent)) 100% 0 / 1px 9px no-repeat;
  font-family: var(--wk-f-body, var(--font-sans-tc));
  font-size: .86rem;
  line-height: 1.6;
  color: var(--ink-soft);
  letter-spacing: .04em;
  text-wrap: pretty;
}
.elev-cap::before {
  content: "W-" counter(win, decimal-leading-zero);
  margin-right: .7em;
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: .68rem;
  font-weight: 500;
  letter-spacing: .08em;
  color: var(--accent);
}
/* 燈箱（WK.initLightbox）：冷墨底、方角 */
.wk-lightbox {
  position: fixed; inset: 0; z-index: 100;
  display: none;
  align-items: center; justify-content: center;
  background: rgba(18, 21, 26, .95);
  padding: max(4vh, env(safe-area-inset-top, 0px)) max(4vw, env(safe-area-inset-right, 0px))
           max(4vh, env(safe-area-inset-bottom, 0px)) max(4vw, env(safe-area-inset-left, 0px));
  overscroll-behavior: contain;
}
.wk-lightbox.is-open { display: flex; }
.wk-lightbox img { max-width: 100%; max-height: 88dvh; margin-inline: auto; }
.wk-lightbox button {
  position: absolute;
  color: #f7f8fb;
  font-size: 2rem;
  line-height: 1;
  padding: .75rem 1rem;
  min-width: 44px; min-height: 44px;
  display: grid; place-items: center;
  border: 0;
  background: none;
  opacity: .8;
  cursor: pointer;
  transition: opacity .3s var(--ease-out);
}
.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 版式的覆寫：特異度 (1,1,0) 才蓋得過晚載入的 gallery-layouts.css :root */
#gallery[data-wk-gallery] { --gl-frame-shadow: var(--shadow-soft); }

/* ============ ③b 婚禮影片（P2-20）：facade——一面投影牆，雙線框同窗洞 ============ */
.video-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #0f1216;
  overflow: hidden;
  box-shadow: 0 0 0 4px var(--paper), 0 0 0 5px var(--accent);
}
.video-frame[data-ratio="portrait"] { aspect-ratio: 9 / 16; width: min(100%, 20rem); margin-inline: auto; }
.video-frame.is-noposter { background: #0f1216; }
.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.4rem; height: 3.4rem;
  z-index: 1;
  color: #f7f8fb;
  border: 1.5px solid rgba(247, 248, 251, .85);
}
.video-play-ico::before {
  content: "";
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-38%, -50%);
  border-style: solid;
  border-width: .46rem 0 .46rem .8rem;
  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); outline-offset: 6px; }

/* ============ ④ Event Details：餐廳 ============ */
.details-date {
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(clamp(1.25rem, 5vw, 1.55rem) * var(--wk-fs-heading, 1));
  font-weight: 600;
  letter-spacing: .06em;
  line-height: 1.5;
  font-variant-numeric: lining-nums tabular-nums;
}
.details-note { color: var(--ink-soft); font-size: var(--text-small); margin-top: .4rem; white-space: pre-line; }
.details-date { margin-bottom: .9rem; }
.details-note:empty { display: none; }
/* 月曆：一張小小的格子圖。⚠ 絕不對 .wk-cal 宣告 display（顯隱靠 [hidden]） */
.wk-cal {
  width: 100%;
  max-width: 28rem;
  margin-top: clamp(1.8rem, 6vw, 2.4rem);
  padding: 1rem 1rem 1.1rem;
  background: var(--paper-raise);
  box-shadow: inset 0 0 0 1px var(--ink);
  text-align: center;
}
.wk-cal-title {
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: calc(1.2rem * var(--wk-fs-latin, 1));
  font-weight: 500;
  letter-spacing: .14em;
  color: var(--accent);
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "lnum" 1, "tnum" 1;
}
.wk-cal-grid {
  position: relative;
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  margin-top: .8rem;
  border-top: 1px solid var(--hairline);
  font-family: var(--wk-f-latin, var(--font-mono));
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "lnum" 1, "tnum" 1;
}
.wk-cal-wd, .wk-cal-d, .wk-cal-pad { position: relative; }
.wk-cal-wd { padding: .45rem 0; color: var(--ink-soft); font-family: var(--wk-f-body, var(--font-sans-tc)); font-size: .84rem; }
.wk-cal-d, .wk-cal-pad { aspect-ratio: 1; }
.wk-cal-d { display: grid; place-items: center; font-size: .86rem; }
/* 婚期：實心方格＋反白數字（愛心不畫：圖面語言是方格與圓圈） */
.wk-cal-heart { display: none; }
.wk-cal-d.is-day { background: var(--accent); color: var(--accent-ink); font-weight: 500; outline: 1px solid var(--accent); outline-offset: 3px; }
.wk-cal-n { position: relative; z-index: 1; }
/* 「還有 N 天」隱藏：它算日曆日、Hero 倒數算到時刻，同頁會讀成兩個數字（DESIGN §7 ④） */
.wk-cal-count { display: none; }
/* 時程表：像圖面上的門窗表——上下兩條粗線、一行一道細線 */
.event-list {
  margin-top: clamp(1.8rem, 6vw, 2.4rem);
  max-width: 28rem;
  border-top: 1.5px solid var(--ink);
  border-bottom: 1.5px solid var(--ink);
}
.event-row {
  display: grid;
  grid-template-columns: 4.6rem 1fr;
  column-gap: 1rem;
  align-items: baseline;
  padding-block: .9rem;
}
.event-row + .event-row { border-top: 1px solid var(--hairline); }
.event-row dt {
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: calc(1.05rem * var(--wk-fs-latin, 1));
  font-weight: 500;
  color: var(--accent);
  letter-spacing: .04em;
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "lnum" 1, "tnum" 1;
}
.event-row dd strong {
  display: block;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(clamp(1.05rem, 3vw, 1.15rem) * 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; margin-top: clamp(1.8rem, 6vw, 2.4rem); }
.parents { margin-top: clamp(1.8rem, 6vw, 2.4rem); color: var(--ink-soft); font-size: var(--text-small); line-height: 2; white-space: pre-line; }
.parents:empty { display: none; }


/* ============ ④b Dress Code：衣帽間——材料表的色卡 ============ */
.dc-note { max-width: 28em; color: var(--ink-soft); white-space: pre-line; }
.dc-note:empty { display: none; }
.dc-swatches { counter-reset: sw; display: flex; flex-wrap: wrap; gap: 1.2rem 1rem; margin-top: 1.6rem; list-style: none; }
.dc-swatch {
  counter-increment: sw;
  position: relative;
  width: clamp(3.2rem, 15vw, 3.8rem);
  aspect-ratio: 1;
  box-shadow: 0 0 0 3px var(--paper), 0 0 0 4px rgba(var(--ink-rgb), .55);
  margin-bottom: 2.4rem;
}
.dc-swatch::after {
  content: "C-" counter(sw, decimal-leading-zero) "\A" attr(data-hex);
  white-space: pre;
  line-height: 1.5;
  position: absolute;
  left: 0; top: calc(100% + .45rem);
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: .7rem;
  letter-spacing: .08em;
  color: var(--ink-soft);
}

/* ============ ⑤b 自訂區塊：書房 ============ */
.custom-text { max-width: 30em; white-space: pre-line; }
.custom-text:empty { display: none; }
.custom-block + .custom-block { margin-top: clamp(2.6rem, 8vw, 3.4rem); }
.custom-block-title { margin-top: .9rem; }
.custom-block-card {
  padding: clamp(1.4rem, 5vw, 2rem) clamp(1.2rem, 5vw, 1.8rem);
  background: var(--paper-raise);
  box-shadow: inset 0 0 0 1px var(--ink);
}
.custom-block-card .custom-block-title { margin-top: 0; }
.custom-block-quote .custom-text {
  padding-left: 1rem;
  border-left: 2px solid var(--accent);
  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: 1.95;
  letter-spacing: .04em;
}
.custom-anchored { padding-bottom: var(--section-y); }
.custom-img {
  display: block;
  width: min(100%, 22rem);
  margin: .4rem 0 clamp(1.2rem, 4vw, 1.6rem);
  box-shadow: 0 0 0 4px var(--paper), 0 0 0 5px var(--accent);
}
.custom-block-side::after { content: ""; display: block; clear: both; }
@media (min-width: 560px) {
  .custom-block-side .custom-img { float: left; width: 42%; margin: .4rem 1.6rem .8rem 0; }
}

/* ============ ⑤c 悄悄話：閣樓——描圖紙蓋在上面，刮開看底下那張 ============ */
.secret .scratch-wrap { text-align: left; }
.secret .scratch-card {
  background: var(--paper-raise);
  box-shadow: inset 0 0 0 1px var(--ink);
  border-radius: 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 { color: var(--ink); font-size: 1rem; font-weight: 500; letter-spacing: .14em; text-indent: .14em; }
.secret .scratch-card { box-shadow: inset 0 0 0 1.5px var(--accent); }
.secret .scratch-card::after {
  content: "";
  position: absolute;
  inset: 10px;
  z-index: 2;
  pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), .7);
  background:
    /* 四角定位十字 */
    linear-gradient(var(--accent), var(--accent)) 6px 14px / 17px 1px no-repeat,
    linear-gradient(var(--accent), var(--accent)) 14px 6px / 1px 17px no-repeat,
    linear-gradient(var(--accent), var(--accent)) calc(100% - 6px) calc(100% - 14px) / 17px 1px no-repeat,
    linear-gradient(var(--accent), var(--accent)) calc(100% - 14px) calc(100% - 6px) / 1px 17px no-repeat,
    /* 方格 */
    linear-gradient(rgba(var(--accent-rgb), .2) 1px, transparent 1px) -1px -1px / 16px 16px,
    linear-gradient(90deg, rgba(var(--accent-rgb), .2) 1px, transparent 1px) -1px -1px / 16px 16px;
  transition: opacity .4s var(--ease-out);
}
.secret .scratch-card.is-scratching::after { opacity: .35; }
.secret .scratch-card.is-revealed::after { opacity: 0; }
.secret .scratch-hint {
  z-index: 3;
  display: grid;
  gap: .35rem;
  justify-items: center;
  color: var(--accent);
}
.secret .scratch-hint::before {
  content: "DETAIL A";
  padding: .1rem .55rem;
  box-shadow: inset 0 0 0 1px var(--accent);
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: .2em;
  text-indent: .2em;
  background: var(--paper-raise);
}
.secret .scratch-open {
  min-height: 44px;
  color: var(--accent);
  font-size: .92rem;
  font-weight: 500;
  text-decoration: underline;
  text-decoration-color: rgba(var(--accent-rgb), .5);
  text-underline-offset: .3em;
}

/* ============ ⑤ Venue：玄關 ============ */
.venue-hall { font-family: var(--wk-f-heading, var(--font-serif-tc)); font-weight: 500; letter-spacing: .06em; }
.venue-hall:empty { display: none; }
.venue-address { color: var(--ink-soft); font-size: var(--text-small); margin-top: .15rem; }
/* 雙地點的標籤：⚠ 絕不宣告 display（會蓋掉 [hidden]） */
.venue-tag {
  width: fit-content;
  margin: 0 0 .9rem;
  padding: .1rem .6rem;
  font-family: var(--wk-f-body, var(--font-sans-tc));
  font-size: var(--text-small);
  color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}
.venue--dual .venue-card2 {
  margin-top: clamp(3rem, 9vw, 4rem);
  padding-top: clamp(2.6rem, 8vw, 3.4rem);
  border-top: 1px dashed rgba(var(--accent-rgb), .55);
}
.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: .1em;
  line-height: 1.5;
}
/* 地圖：線稿底圖色調——去彩、再染一層製圖色；四角是裁切記號 */
.map-frame {
  position: relative;
  margin-top: clamp(1.6rem, 5vw, 2.2rem);
  aspect-ratio: 4 / 3;
  box-shadow: 0 0 0 4px var(--paper), 0 0 0 5px var(--accent);
  background:
    linear-gradient(rgba(var(--accent-rgb), .1) 1px, transparent 1px) -1px -1px / 16px 16px,
    linear-gradient(90deg, rgba(var(--accent-rgb), .1) 1px, transparent 1px) -1px -1px / 16px 16px,
    var(--paper-raise);
}
@media (min-width: 700px) { .map-frame { aspect-ratio: 16 / 8; } }
.map-frame iframe { position: relative; width: 100%; height: 100%; border: 0; display: block; filter: grayscale(1) contrast(1.06) brightness(1.04); }
/* 地圖載入前（或被擋）的底紙說明：不像沒做完 */
.map-frame::before {
  content: "SITE PLAN — 地圖載入中，也可以直接按「開啟導航」";
  position: absolute;
  left: 1rem; right: 1rem; top: 50%;
  translate: 0 -50%;
  text-align: center;
  font-size: var(--text-small);
  letter-spacing: .06em;
  color: var(--ink-soft);
  text-wrap: balance;
}
html.wk-lang-en .map-frame::before { content: "SITE PLAN — loading the map; you can also tap \201CGet directions\201D"; }
.map-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--accent);
  mix-blend-mode: color;
  opacity: .5;
  pointer-events: none;
}
.venue-bottom {
  margin-top: clamp(1.7rem, 5vw, 2.3rem);
  max-width: 30rem;
  display: grid;
  gap: 1.5rem;
  justify-items: start;
}
.transport { display: grid; width: 100%; list-style: none; border-top: 1.5px solid var(--ink); border-bottom: 1.5px solid var(--ink); }
.transport:empty { display: none; }
.transport li { display: grid; grid-template-columns: 3.8rem 1fr; gap: 1rem; align-items: baseline; padding-block: .85rem; }
.transport li + li { border-top: 1px solid var(--hairline); }
.transport strong { font-weight: 500; color: var(--accent); font-size: var(--text-small); letter-spacing: .1em; }
.transport span { color: var(--ink-soft); white-space: pre-line; }


/* ============ ⑥ RSVP：信箱——回函是一張送審單 ============ */
.rsvp-intro { max-width: 30em; white-space: pre-line; }
.rsvp-deadline {
  margin-top: .45rem;
  font-size: var(--text-small);
  color: var(--accent);
  font-weight: 500;
  letter-spacing: .06em;
}
.rsvp-form {
  margin-top: clamp(1.8rem, 6vw, 2.4rem);
  padding: clamp(1.4rem, 5vw, 2rem) clamp(1.1rem, 5vw, 1.8rem);
  display: grid;
  gap: 1.45rem;
  background: var(--paper-raise);
  box-shadow: inset 0 0 0 1.5px var(--ink);
}
/* 送審單的表頭（裝飾，⚠ 是 grid 的第一個項目，不能放互動） */
.rsvp-form::before {
  content: "TRANSMITTAL  ·  REPLY FORM";
  padding-bottom: .7rem;
  border-bottom: 1px solid rgba(var(--ink-rgb), .55);
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: .7rem;
  letter-spacing: .2em;
  color: var(--accent);
}
.rsvp .field label, .rsvp .field legend {
  font-size: .95rem;
  letter-spacing: .04em;
  color: var(--ink);
  font-weight: 500;
}
/* ⚠ input 字級一律 ≥16px：這裡不宣告 font-size＝繼承 body（var(--text-body) ≥1rem） */
.rsvp .field input, .rsvp .field textarea, .rsvp .field select {
  background: var(--paper);
  border: 1px solid rgba(var(--ink-rgb), .42);
  border-radius: var(--radius);
}
.field input:focus-visible, .field textarea:focus-visible, .field select:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), .18);
}
.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='%23555c67' stroke-width='1.4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  padding-right: 2.6rem;
}
.attend-field { border: 0; }
.companion-list { display: grid; gap: .5rem; }
[data-rsvp-custom] { display: grid; gap: 1.45rem; }
.cq-checks { display: grid; gap: .5rem; }
.rsvp .cq-checks label { display: flex; align-items: center; gap: .5rem; font-size: 1rem; cursor: pointer; }
.rsvp .cq-checks input[type="checkbox"] { width: 1.15rem; height: 1.15rem; flex: none; accent-color: var(--accent); }

.attend-options { display: grid; grid-template-columns: 1fr 1fr; gap: .7rem; margin-top: .6rem; }
.attend-options.is-stack { grid-template-columns: 1fr; }
.attend-options.is-stack .attend-pill span { line-height: 1.5; text-wrap: balance; }
.attend-pill { position: relative; }
.attend-pill input { position: absolute; opacity: 0; pointer-events: none; }
/* 選項卡：方框；已選＝製圖藍粗框＋強調色字＋左上一個線畫的勾（實心留給「送出」） */
.attend-pill span {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: .7rem 1rem .7rem 1.6rem;
  background: var(--paper);
  box-shadow: inset 0 0 0 1px rgba(var(--ink-rgb), .42);
  border-radius: var(--radius);
  letter-spacing: .06em;
  text-align: center;
  transition: box-shadow .3s var(--ease-out), color .3s var(--ease-out);
  user-select: none;
  cursor: pointer;
}
.attend-pill span::before {
  content: "";
  position: absolute;
  left: .85rem; top: 50%;
  width: .42rem; height: .74rem;
  margin-top: -.45rem;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  rotate: 45deg;
  opacity: 0;
  transition: opacity .25s;
}
.attend-pill input:checked + span { color: var(--accent); font-weight: 500; box-shadow: inset 0 0 0 2px var(--accent); }
.attend-pill input:checked + span::before { opacity: 1; }
.attend-pill input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }

.rsvp-details { display: grid; gap: 1.45rem; }
.field-row { display: grid; gap: 1.45rem; }
@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 1px rgba(var(--ink-rgb), .42);
  border-radius: var(--radius);
}
.rsvp .field .stepper input { border: 0; background: transparent; text-align: center; padding-inline: .25rem; font-family: var(--wk-f-latin, var(--font-mono)); }
.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; }
.stepper:focus-within { box-shadow: inset 0 0 0 1px var(--accent), 0 0 0 3px rgba(var(--accent-rgb), .18); }
.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), .07); }
.stepper button[disabled] { opacity: .3; cursor: default; }
.cap-note { font-size: var(--text-small); color: var(--ink-soft); }
/* 錯誤字：--warn 對浮起表面 ≥4.5（blueprint-check 量） */
.rsvp-error { color: var(--warn); font-size: var(--text-small); }
.rsvp-submit { width: 100%; min-height: 52px; letter-spacing: .2em; }

.rsvp-success, .rsvp-closed {
  position: relative;
  margin-top: clamp(1.8rem, 6vw, 2.4rem);
  display: grid;
  gap: .7rem;
  justify-items: start;
  padding: clamp(1.8rem, 6vw, 2.4rem) clamp(1.2rem, 5vw, 1.8rem);
  background: var(--paper-raise);
  box-shadow: inset 0 0 0 1.5px var(--ink);
}
.success-mark {
  width: 2.4rem; height: 2.4rem;
  display: grid; place-items: center;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 1.15rem;
}
.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;
}
/* 收件章：長方形雙線章（落章動畫在 base.css wk-stamp-drop） */
.rsvp-stamp {
  --stamp-rot: -8deg;
  position: absolute;
  top: 1rem; right: 1rem;
  padding: .35rem .6rem;
  display: grid;
  justify-items: center;
  gap: .15rem;
  border: 3px double var(--accent);
  color: var(--accent);
}
.rsvp-stamp i::before { content: "收件"; font-style: normal; font-family: var(--wk-f-heading, var(--font-serif-tc)); font-weight: 600; font-size: .8rem; letter-spacing: .2em; }
.rsvp-stamp em {
  font-family: var(--wk-f-latin, var(--font-mono));
  font-style: normal;
  font-size: .62rem;
  letter-spacing: .16em;
  text-transform: uppercase;
}
.success-note { font-size: var(--text-small); color: var(--ink-soft); }

/* ============ ⑦ Footer：門口 ============ */
.footer {
  padding-top: var(--section-y);
  padding-bottom: max(3.2rem, calc(env(safe-area-inset-bottom, 0px) + 2.4rem));
  text-align: center;
}
.footer-yours {
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: calc(.8rem * var(--wk-fs-latin, 1));
  letter-spacing: .34em;
  text-indent: .34em;
  color: var(--accent);
}
.footer-message { max-width: 24em; margin: 1.1rem auto 0; white-space: pre-line; }
.footer-names {
  margin-top: .9rem;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(1.1rem * var(--wk-fs-heading, 1));
  font-weight: 600;
  letter-spacing: .12em;
}
.footer-end {
  display: flex;
  align-items: center;
  gap: .9rem;
  max-width: 22rem;
  margin: 2.6rem auto 0;
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: .72rem;
  letter-spacing: .24em;
  color: var(--accent);
  white-space: nowrap;
}
.footer-end::before, .footer-end::after { content: ""; flex: 1; border-top: 1px solid rgba(var(--accent-rgb), .45); }
.footer-end span { padding: .1rem .45rem; box-shadow: inset 0 0 0 1px var(--accent); letter-spacing: .1em; }
.footer-brand {
  display: inline-block;
  margin-top: 1.2rem;
  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); }

/* ---------- 終章祝福「鎖上門牌」 ----------
   按住：門牌從歪斜、浮著的位置被壓上牆，四顆螺絲跟著 --wk-press 轉（最多一圈半）；
   蓄滿（.is-committed）：鎖好，門牌刻上賓客名字＋「歡迎回家」（.is-sealed 由 render.js 掛）。
   沒蓄滿放手＝--wk-press 歸零，門牌退回歪斜的位置。 */
.blessing { margin-top: clamp(2.6rem, 8vw, 3.4rem); }
.blessing-lead { max-width: 20em; margin-inline: auto; color: var(--ink-soft); font-size: .98rem; line-height: 1.7; }
.blessing-lead--done { display: none; color: var(--accent); font-weight: 500; letter-spacing: .12em; }
.blessing.is-sealed .blessing-lead:not(.blessing-lead--done) { display: none; }
.blessing.is-sealed .blessing-lead--done { display: block; animation: bp-say .6s var(--ease-out); }
/* 門廊燈：鎖好的那一刻，門牌後面的牆亮起一圈（同一個製圖藍的淡透明，不是第二個顏色） */
.plate-wall::before {
  content: "";
  position: absolute;
  inset: 0;
  inset: -1.6rem;
  background: radial-gradient(58% 60% at 50% 48%, rgba(var(--lamp-rgb), .55), rgba(var(--lamp-rgb), .22) 45%, rgba(var(--lamp-rgb), .05) 70%, rgba(var(--lamp-rgb), 0) 82%);
  opacity: 0;
  transition: opacity 1s var(--ease-out) .25s;
  pointer-events: none;
}
.blessing.is-sealed .plate-wall::before { opacity: 1; }
.blessing-seal {
  display: block;
  width: min(100%, 17rem);
  margin: 1.1rem auto 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
  touch-action: none;                 /* 按住蓄力期間不捲頁（小面積按鈕才准用 none） */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}
.blessing-seal:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
/* 牆上門牌的預留位置：一個虛線框（＝圖面上的「預留」） */
.plate-wall {
  display: block;
  padding: 1.3rem 1.2rem;
  box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), .5);
  background:
    repeating-linear-gradient(0deg, transparent 0 21px, rgba(var(--ink-rgb), .06) 21px 22px),
    var(--paper);
}
.plate {
  position: relative;
  z-index: 1;
  display: grid;
  justify-items: center;
  gap: .1rem;
  padding: 1rem 1.6rem .95rem;
  background: var(--paper-raise);
  box-shadow: inset 0 0 0 1.5px var(--ink), 0 calc((1 - var(--wk-press, 0)) * 16px) 20px -10px rgba(var(--shade-rgb), .7);
  transform: translateY(calc((1 - var(--wk-press, 0)) * -12px)) rotate(calc((1 - var(--wk-press, 0)) * -6deg));
  transition: transform .35s var(--ease-out), box-shadow .35s var(--ease-out);
}
/* 蓄力：門牌外緣一圈製圖藍線跟著按的時間畫出來（第 1 輪評審 P0：按住 600ms 看不出有在蓄力） */
.plate-wall { position: relative; }
.plate-ring { position: absolute; inset: calc(1.3rem - 7px) calc(1.2rem - 7px); pointer-events: none; z-index: 1; }
.plate-ring i { position: absolute; background: var(--accent); transition: transform .35s var(--ease-out); }
/* 上→右→下→左順時針，每條吃四分之一的進度 */
/* 四邊同時從各自的中點往兩端長，按到底四邊同時閉合（任何一格截圖都是對稱的） */
.pr-t { top: 0; left: 0; right: 0; height: 2px; transform: scaleX(var(--wk-press, 0)); }
.pr-r { top: 0; right: 0; bottom: 0; width: 2px; transform: scaleY(var(--wk-press, 0)); }
.pr-b { bottom: 0; left: 0; right: 0; height: 2px; transform: scaleX(var(--wk-press, 0)); }
.pr-l { top: 0; left: 0; bottom: 0; width: 2px; transform: scaleY(var(--wk-press, 0)); }
.blessing-seal.is-pressing .plate-ring i { transition: none; }
.blessing-seal.is-committed .plate-ring i { transform: none; }
/* 還沒刻字的門牌：一條待刻的虛線（＝這裡會刻上你的名字） */
.plate::after {
  content: "";
  position: absolute;
  left: 50%; top: 58%;
  width: 46%;
  translate: -50% 0;
  border-bottom: 1px dashed rgba(var(--ink-rgb), .4);
  transition: opacity .3s;
}
.blessing.is-sealed .plate::after { opacity: 0; }
.plate-date {
  min-height: 1.2em;
  margin-top: .3rem;
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: .72rem;
  letter-spacing: .14em;
  color: var(--accent);
  font-variant-numeric: lining-nums tabular-nums;
  opacity: 0;
  transition: opacity .6s var(--ease-out) .9s;
}
.blessing.is-sealed .plate-date { opacity: 1; }
/* 鎖好的那一下：門牌被「釘」下去（輕壓再彈回） */
.blessing.is-sealed .plate { animation: bp-nail .42s cubic-bezier(.3, 1.4, .5, 1); }
@keyframes bp-nail {
  0% { scale: 1; }
  35% { scale: .965; }
  100% { scale: 1; }
}
.blessing-seal.is-pressing .plate { transition: none; }
.plate-no {
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: .76rem;
  letter-spacing: .24em;
  color: var(--accent);
}
.plate-name {
  min-height: 1.5em;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-size: calc(1.35rem * var(--wk-fs-heading, 1));
  font-weight: 600;
  letter-spacing: .14em;
  text-indent: .14em;
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.plate-sub { font-size: .8rem; letter-spacing: .34em; text-indent: .34em; color: var(--ink-soft); }
/* 刻字：鎖好之前是空白的門牌（字先藏著），鎖好才由左往右刻出來 */
/* 待機：門牌上已經淡淡寫著名字（像鉛筆打的底稿，＝這塊是你的）；鎖好才刻深 */
.plate-name { color: var(--accent); transition: color .7s var(--ease-out) .12s; }   /* 待刻＝製圖藍（賓客名字要看得清楚，對比 ≥4.5），鎖好刻成墨色 */
.blessing.is-sealed .plate-name { color: var(--ink); animation: bp-glow 1s var(--ease-out) .3s; }
@keyframes bp-glow {
  0%, 100% { text-shadow: 0 0 0 transparent; }
  40% { text-shadow: 0 0 18px rgba(var(--accent-rgb), .55); }
}
.plate-sub { opacity: 0; transition: opacity .7s var(--ease-out) .45s; }
.blessing.is-sealed .plate-sub { opacity: 1; }
.screw {
  position: absolute;
  width: 9px; height: 9px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px var(--ink);
  background: var(--paper);
}
.screw::after {
  content: "";
  position: absolute;
  left: 1px; right: 1px; top: 4px;
  border-top: 1px solid var(--ink);
  rotate: calc(var(--wk-press, 0) * 540deg + 20deg);
}
.blessing-seal.is-committed .screw::after { rotate: 560deg; }
.blessing-seal.is-committed .plate { transform: none; box-shadow: inset 0 0 0 1.5px var(--ink), 0 0 0 transparent; }
.s1 { left: 6px; top: 6px; } .s2 { right: 6px; top: 6px; } .s3 { left: 6px; bottom: 6px; } .s4 { right: 6px; bottom: 6px; }
.blessing-hint { margin-top: .9rem; font-size: .9rem; letter-spacing: .12em; text-indent: .12em; color: var(--ink-soft); }
.blessing-seal.wants-hold + .blessing-hint { color: var(--accent); }
.blessing-done {
  margin-top: .9rem;
  font-family: var(--wk-f-heading, var(--font-serif-tc));
  font-weight: 600;
  letter-spacing: .08em;
  color: var(--accent);
}
.blessing:not(.is-sealed) .blessing-done { display: none; }
.blessing.is-sealed .blessing-hint { display: none; }

/* 44px 點擊框用負的上下 margin 吃回來（列高＝名字那一行，跟其他模板同一套零位移規則，ux-check 量）；
   圖示下方的 TEL／LINE／IG 標籤掛在框外，所以列與列之間、整組下緣都要留出標籤的位置 */
.footer-contacts { margin-top: 2.2rem; padding-bottom: 1.6rem; display: flex; flex-direction: column; align-items: center; gap: 2.9rem; }
.footer-contacts[hidden] { display: none; }
.contact-row { display: inline-flex; align-items: center; gap: .6rem; }
.contact-who { align-self: center; min-width: 4.5em; text-align: right; font-size: var(--text-small); letter-spacing: .06em; color: var(--ink-soft); }
.contact-ico {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  color: var(--accent);
  box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), .45);
  margin-block: -12px;
}
.contact-ico svg { width: 20px; height: 20px; display: block; }
.contact-ico::after {
  position: absolute;
  top: calc(100% + .2rem);
  left: 50%;
  translate: -50% 0;
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: .6rem;
  letter-spacing: .06em;
  color: var(--ink-soft);
  white-space: nowrap;
}
.contact-ico[data-kind="phone"]::after { content: "TEL"; }
.contact-ico[data-kind="line"]::after { content: "LINE"; }
.contact-ico[data-kind="ig"]::after { content: "IG"; }

/* 頁尾彩蛋：圖面附註 */
.ps-egg {
  display: block;
  margin: 1.8rem auto 0;
  min-height: 44px;
  padding: .4rem 1rem;
  border: 0;
  background: none;
  color: var(--ink-soft);
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: .78rem;
  letter-spacing: .1em;
  text-decoration: underline dotted rgba(var(--ink-rgb), .45);
  text-underline-offset: .35em;
  cursor: pointer;
}
.ps-egg-text {
  max-width: 24em;
  margin: 1.4rem auto 0;
  padding: .9rem 1rem;
  box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), .55);
  font-size: .92rem;
  color: var(--ink);
  text-align: left;
  opacity: 0;
  translate: 0 6px;
  transition: opacity .5s var(--ease-out), translate .5s var(--ease-out);
}
.ps-egg-text.is-open { opacity: 1; translate: 0 0; }

/* ---------- 點按粒子（WKFX.tapBurst／burstAt 的皮）：定位十字、小方框、小圓 ---------- */
.wk-bp-p { width: 16px; height: 16px; }
.wk-bp-p1 {
  background:
    linear-gradient(var(--accent), var(--accent)) center / 100% 1.5px no-repeat,
    linear-gradient(var(--accent), var(--accent)) center / 1.5px 100% no-repeat;
}
.wk-bp-p2 { box-shadow: inset 0 0 0 1.5px var(--accent); width: 11px; height: 11px; }
.wk-bp-p3 { border-radius: 50%; box-shadow: inset 0 0 0 1.5px var(--accent); width: 10px; height: 10px; }

/* ---------- reduced-motion：這一款不降級（體系規則⑥），沒有 RM 區塊 ---------- */

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

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

/* ============================================================
   英文版（P2-10）：只在 html.wk-lang-en（shared/i18n.js 掛的）生效，中文版一個像素都不動。
   ① 中文用的寬字距在英文會把字拆散——正文、標題歸到 0–.04em；Mono 小標保留
   ② 重複的英文副標收掉（圖框的 em 英文標籤、拉丁名、房間的中文名）
   ============================================================ */
@font-face {
  font-family: "WK Latin Quotes";
  src: local("Georgia"), local("Times New Roman"), local("Noto Serif"), local("Droid Serif");
  unicode-range: U+2018-201F;
}
html.wk-lang-en {
  --font-serif-tc: "WK Latin Quotes", "Xitie Serif", "Noto Serif TC", "Songti TC", "PMingLiU", serif;
  --font-sans-tc: system-ui, -apple-system, "Segoe UI", "Noto Sans TC", "PingFang TC", sans-serif;
}
html.wk-lang-en body { letter-spacing: 0; hyphens: manual; }
html.wk-lang-en .hero-names-en,
html.wk-lang-en .tb-k em,
html.wk-lang-en .room-zh { display: none; }
html.wk-lang-en .tb-k b { letter-spacing: .08em; font-family: var(--wk-f-latin, var(--font-mono)); text-transform: uppercase; font-size: .6rem; color: var(--ink-soft); }
html.wk-lang-en :is(.section-title, .hero-names, .tl-title, .details-date, .event-row dd strong, .venue2-name, .footer-names, .tb-v, .hero-greeting, .plate-name, .rsvp-success h3, .rsvp-closed h3, .custom-block-quote .custom-text) { letter-spacing: .02em; text-indent: 0; }
html.wk-lang-en :is(.section-title, .hero-greeting, .rsvp-intro, .footer-message, .blessing-lead, .tb-say, .details-date) { text-wrap: balance; }
html.wk-lang-en :is(.rsvp .field label, .rsvp .field legend, .attend-pill span, .btn, .blessing-hint, .plate-sub, .cd-cell span, .intro-guide, .secret .scratch-hint) { letter-spacing: .03em; text-indent: 0; }
html.wk-lang-en .tb-stamp-ink { letter-spacing: .06em; text-indent: 0; font-family: var(--wk-f-latin, var(--font-mono)); text-transform: uppercase; }
html.wk-lang-en .intro-guide { white-space: normal; width: max-content; max-width: min(19em, calc(100vw - 2.5rem)); text-align: center; line-height: 1.4; }
html.wk-lang-en .rsvp-stamp i::before { content: "RECEIVED"; font-family: var(--wk-f-latin, var(--font-mono)); font-size: .6rem; letter-spacing: .14em; }
html.wk-lang-en .rsvp-stamp em { display: none; }
html.wk-lang-en .parents { text-wrap: balance; }
@media (max-width: 720px) {
  html.wk-has-lang .hero { padding-top: calc(clamp(2.4rem, 8vw, 3.6rem) + 26px); }
}

@media (max-height: 700px) {
  .intro { --tube-y: max(5.8rem, calc(env(safe-area-inset-top, 0px) + 4.8rem)); }
  .tb .hero-names-en { display: none; }
  .tb :is(.tb-title, .tb-no) { display: none; }
  .intro-sheet-no { display: none; }
  .intro-house { top: 1.6rem; height: min(calc(var(--sh) - var(--peek) - .6rem), calc(min(72vw, 17.5rem) * 1.3614)); }
  .intro-desk { top: calc(var(--tube-y) + 11px + var(--peek) + 5.9rem); }
}
/* 矮螢幕（≤700 高，iPhone SE 等）：Hero 上下間距收緊，首屏就看得到窗洞裡的婚紗照（第 3 輪 P1-4） */
@media (max-height: 700px) and (max-width: 959px) {
  .hero-label { display: none; }
  .hero { padding-top: 1rem; }
  .hero-label { margin-bottom: .7rem; }
  .tb-c { padding-top: .45rem; padding-bottom: .5rem; }
  .hero-frame { margin-top: 1.2rem; }
}
/* 桌機：區塊之間不要隔出整屏的空白（第 3 輪 P1-5） */
@media (min-width: 1024px) {
  :root { --section-y: 3.8rem; }

}

/* 桌機：終章門牌放大一階 */
@media (min-width: 1024px) {
  .blessing-seal { width: min(100%, 23rem); }
  .plate-name { font-size: calc(1.7rem * var(--wk-fs-heading, 1)); }
}

/* ════════════════════════════════════════════════════════════
   軸測房子（2026-10-31 改版的招牌）：一棟兩層樓＋閣樓的白線軸測圖，<use> 引同一份符號
   - 狀態全靠自訂屬性：--b-*（蓋好了沒）、--l-*（亮燈）、--c-*（標註），由 render.js 寫在 <svg> 上
   - 預設＝全部蓋好、不亮燈（preview、腳本沒跑也是一棟完整的房子）
   - 線寬 --hw 是符號的使用者單位：圖畫得越小，線要越粗
   ════════════════════════════════════════════════════════════ */
:root { --cyano: grayscale(1) sepia(1) hue-rotate(178deg) saturate(2.4) brightness(.8) contrast(1.18); }
.bh-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.bh-use { display: block; width: 100%; height: auto; overflow: visible; }
.bh-grid, .bh-solid, .bh-ghost, .bh-thin, .bh-hidden, .bh-dim path, .bh-call path, .bh-mull {
  fill: none; stroke: rgb(var(--line-rgb)); stroke-linecap: round; stroke-linejoin: round;
}
.bh-grid { stroke-width: calc(var(--hw, 1.4) * .4); }
.bh-solid { stroke-width: var(--hw, 1.4); stroke-dasharray: 1 1; stroke-dashoffset: calc(1 - var(--b)); transition: stroke-dashoffset var(--bh-t, 1.5s) cubic-bezier(.3, .6, .2, 1); }
.bh-ghost { stroke-width: calc(var(--hw, 1.4) * .7); stroke-dasharray: 3 5; opacity: calc((1 - var(--b)) * .55); transition: opacity 1s; }
.bh-hidden { stroke-dasharray: 4 4; stroke-width: calc(var(--hw, 1.4) * .55); opacity: calc(var(--b) * .45); transition: opacity 1s; }
.bh-thin { stroke-width: calc(var(--hw, 1.4) * .45); opacity: calc(var(--b) * .5); transition: opacity 1s; }
.bh-face { stroke: none; opacity: var(--b); transition: opacity 1.1s .25s; }
.bh-front { fill: color-mix(in srgb, var(--paper) 88%, #fff); }
.bh-side  { fill: color-mix(in srgb, var(--paper) 94%, #fff); }
.bh-top   { fill: color-mix(in srgb, var(--paper) 80%, #fff); }
.bh-roof  { fill: color-mix(in srgb, var(--paper) 84%, #fff); }
.bh-low   { fill: color-mix(in srgb, var(--paper) 88%, #000); }
.bh-dim path { stroke-width: calc(var(--hw, 1.4) * .55); opacity: .75; }
.bh-dim text, .bh-call text { fill: rgb(var(--line-rgb)); font-family: var(--wk-f-latin, var(--font-mono)); font-size: 13px; letter-spacing: .12em; }
.bh-call text { fill: var(--lamp); font-size: 22px; letter-spacing: .14em; }
.bh-call text tspan { font-size: 15px; }
.bh-call path { stroke: var(--lamp); stroke-width: 1; }
.bh-call circle { fill: var(--lamp); }
.bh-call { transition: opacity .5s; }
.bh-win { opacity: calc(.25 + .75 * var(--b)); }
.bh-pane { fill: color-mix(in srgb, var(--lamp) calc(var(--l) * 100%), var(--paper-deep)); stroke: rgb(var(--line-rgb)); stroke-width: var(--hw, 1.4); transition: fill .9s; }
.bh-mull { stroke-width: calc(var(--hw, 1.4) * .6); }
.bh-win .bh-glow { fill: none; stroke: rgba(var(--lamp-rgb), calc(var(--l) * .22)); stroke-width: 12; stroke-linejoin: round; transition: stroke .9s; }
.bh-lamp circle { fill: rgba(var(--lamp-rgb), var(--l)); stroke: rgb(var(--line-rgb)); stroke-width: 1; transition: fill .6s; }
.bh-lamp .bh-glow { fill: rgba(var(--lamp-rgb), calc(var(--l) * .3)); stroke: none; }

/* Hero：圖框底下的那一棟（手機；桌機的房子在左欄工地） */
.hero-house { margin: clamp(1.6rem, 6vw, 2.4rem) -.6rem 0; }
.bh-hero { --hw: 1.5; }
@media (min-width: 960px) { .hero-house { display: none; } }

/* 每個房間開頭的小圖：同一棟房子，只亮這一間 */
.room-tag { align-items: center; }
.bh-mini { --hw: 3.2; flex: none; width: 4.6rem; margin: -.4rem .1rem -.4rem -.35rem; }
.room-tag .room-no, .room-tag .room-en { align-self: center; }
#story .bh-mini { --l-living: 1; }
#gallery .bh-mini { --l-balcony: 1; }
#video .bh-mini { --l-media: 1; }
#details .bh-mini { --l-dining: 1; }
#dresscode .bh-mini { --l-wardrobe: 1; }
#venue .bh-mini { --l-entrance: 1; --l-lamp: 1; }
#custom .bh-mini { --l-study: 1; }
#secret .bh-mini { --l-loft: 1; }
#rsvp .bh-mini { --l-mailbox: 1; }

/* 標題放大一階：房間的名字是這一頁的骨架 */
.section-title { font-size: calc(clamp(1.75rem, 7.4vw, 2.6rem) * var(--wk-fs-heading, 1)); line-height: 1.3; letter-spacing: .08em; }

/* 終章：門口——整棟房子，鎖上門牌那一刻一盞一盞亮起來 */
.finale-house { width: min(100%, 26rem); margin: 0 auto 1.4rem; }
.bh-finale { --hw: 1.6; }

/* 桌機工地欄（手機不出現） */
.bp-site { display: none; }
@media (min-width: 1024px) {
  main {
    display: grid;
    grid-template-columns: minmax(0, 40fr) minmax(0, 60fr);
    column-gap: clamp(2rem, 4vw, 4.5rem);
    max-width: 92rem;
    margin-inline: auto;
    padding-inline: clamp(1.5rem, 3vw, 3rem);
  }
  main > .bp-site { display: block; grid-column: 1; grid-row: 1 / span 40; }
  main > .section { grid-column: 2; min-width: 0; }
  main > .section > :is(.container, .container-wide) { margin-left: 0; max-width: 46rem; }
  main > .section.gallery > .container-wide { max-width: none; }
  .bp-site-in {
    position: sticky;
    top: 0;
    height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 1rem;
    padding: 2rem 0;
  }
  .bh-big { --hw: 1.3; --bh-t: .7s; }
  .bp-site-k, .bp-site-cap {
    display: flex;
    align-items: baseline;
    gap: .8rem;
    font-family: var(--wk-f-latin, var(--font-mono));
    font-size: .74rem;
    letter-spacing: .18em;
    color: var(--accent);
  }
  .bp-site-k b { font-family: var(--wk-f-body, var(--font-sans-tc)); font-weight: 500; letter-spacing: .3em; color: var(--ink); }
  .bp-site-k::after { content: ""; order: 2; flex: 1; border-top: 1px solid rgba(var(--accent-rgb), .4); transform: translateY(-.3em); }
  .bp-site-n { order: 3; font-style: normal; color: var(--ink); font-variant-numeric: tabular-nums; }
  .bp-site-cap { justify-content: flex-start; min-height: 1.4em; color: var(--lamp); font-size: .9rem; }
  .bp-site-room b { font-family: var(--wk-f-body, var(--font-sans-tc)); font-weight: 500; letter-spacing: .28em; margin-left: .6em; color: var(--ink); }
  /* 房間的小圖在桌機收掉（左欄就是那一棟） */
  .bh-mini { display: none; }
}

/* 照片顯影：上層是同一張照片的曬圖版，主照片淡入後它停一下再慢慢淡掉（兩層交叉，中途不會發綠） */
.hero-photo-cy { filter: var(--cyano); pointer-events: none; opacity: 0; }
html.fx .hero-frame.is-in .hero-photo-cy { animation: bp-develop 2.6s cubic-bezier(.45, 0, .25, 1) .5s both; }
html.fx.has-intro:not(.wk-bp-landed) .hero-frame .hero-photo-cy { animation: none; opacity: 0; }
@keyframes bp-develop { 0% { opacity: 0; } 12% { opacity: 1; } 45% { opacity: 1; } 100% { opacity: 0; } }

/* 圖說：圖面上每一張圖下面的「圖號＋圖名＋比例」 */
.dwg-cap {
  display: flex;
  align-items: center;
  gap: .6rem;
  font-family: var(--wk-f-latin, var(--font-mono));
  font-size: .7rem;
  letter-spacing: .16em;
  color: var(--accent);
}
.dwg-cap b {
  display: grid;
  place-items: center;
  width: 1.7rem; height: 1.7rem;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px var(--accent);
  font-weight: 500;
  letter-spacing: 0;
  color: var(--ink);
}
.dwg-cap span { font-family: var(--wk-f-body, var(--font-sans-tc)); font-size: .86rem; letter-spacing: .3em; color: var(--ink); }
.dwg-cap em { font-style: normal; }
.dwg-cap em::before { content: ""; display: inline-block; width: 1.4rem; margin-right: .6rem; vertical-align: middle; border-top: 1px solid rgba(var(--accent-rgb), .5); }
.hero-house .dwg-cap { margin: 0 .6rem -.4rem; }
.hero-frame .dwg-cap { position: absolute; left: 0; right: 0; bottom: -2.9rem; justify-content: center; }
.hero-frame { margin-bottom: 2.6rem; }

/* 手機 Hero 的軸測圖再大一點：符號左右留了給標註的空白，這裡吃掉 */
.hero-house { margin-left: -14%; margin-right: -14%; }
.hero-house .dwg-cap { margin-left: calc(14% / 1.28 + .6rem); }

/* 桌機 Hero：圖框上方放這棟房子的「位置圖」（真的圖紙，圖框旁邊就是一張小小的 key plan） */
@media (min-width: 960px) {
  .hero-house { display: block; grid-area: key; margin: -1rem 0 .4rem; justify-self: end; width: min(100%, 22rem); }
  .hero-house .dwg-cap { display: none; }
  .hero-content {
    grid-template-rows: auto auto auto auto auto auto;
    grid-template-areas:
      "label label"
      "frame key"
      "frame tb"
      "frame say"
      "frame notes"
      "frame cd";
  }
  .hero-frame { align-self: center; }
}

/* 桌機工地欄：房子再大一點、標註字放大 */
@media (min-width: 1024px) {
  .bh-big { width: 118%; margin-left: -9%; }
}

/* 門牌＝一塊白色琺瑯門牌（藍字），整頁唯一一塊白的東西：鎖上去的那一刻最亮。
   門牌裡面把墨色換成曬圖藍（自訂屬性在這一塊裡重新定義，其餘樣式照舊吃 token） */
.plate {
  --ink: var(--paper);
  --accent: var(--paper);
  --ink-soft: color-mix(in srgb, var(--paper) 78%, #fff);
  --ink-rgb: 23, 62, 110;
  background: #f5f2ea;
  color: var(--paper);
}
.plate .screw { background: #e2ddd0; }
.blessing.is-sealed .plate-name { color: var(--paper); }

/* ── 第 1 輪評審修正 ── */
/* 圖框收緊：「圖名／圖號」那一列收掉（兩張圖框同一套規則，一鏡到底照樣對得上）；首屏讓給房子 */
.tb :is(.tb-title, .tb-no) { display: none; }
@media (max-width: 959px) {
  .hero { padding-top: clamp(1.6rem, 6vw, 2.6rem); }
  .hero-house { margin: .4rem -19% 0; }
  .hero-house .dwg-cap { margin-left: calc(19% / 1.38 + .6rem); margin-top: -.6rem; }
}

/* 桌機 Hero：右欄上方是這棟房子（實線、亮燈，不再是水印），下面才是圖框 */
@media (min-width: 960px) {
  .hero-content { max-width: 74rem; grid-template-columns: 5fr 6fr; }
  .hero-house { width: 100%; margin: -1.4rem 0 .2rem; justify-self: stretch; }
  .hero-house .bh-use { width: 112%; margin-left: -6%; }
}

/* 桌機工地欄：房子放大、下面一張施工清單（走過的打勾、現在這一間亮） */
@media (min-width: 1024px) {
  .bh-big { width: 136%; margin-left: -18%; }
  .bp-site-in { gap: .8rem; }
  .bp-site-list {
    display: grid;
    grid-template-columns: repeat(3, auto);
    justify-content: start;
    gap: .35rem 1.6rem;
    list-style: none;
    counter-reset: bl;
    font-size: .84rem;
    letter-spacing: .14em;
    color: var(--ink-soft);
  }
  .bp-site-list li { counter-increment: bl; display: flex; align-items: center; gap: .5rem; transition: color .4s; }
  .bp-site-list li::before {
    content: counter(bl, decimal-leading-zero);
    font-family: var(--wk-f-latin, var(--font-mono));
    font-size: .72rem;
    letter-spacing: .06em;
    color: var(--accent);
  }
  .bp-site-list li::after { content: ""; width: .5rem; height: .5rem; border-radius: 50%; box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), .6); }
  .bp-site-list li.is-done { color: var(--ink); }
  .bp-site-list li.is-done::after { background: rgba(var(--lamp-rgb), .45); box-shadow: none; }
  .bp-site-list li.is-now { color: var(--lamp); }
  .bp-site-list li.is-now::after { background: var(--lamp); box-shadow: 0 0 0 4px rgba(var(--lamp-rgb), .2); }
}

/* 次要按鈕：白線描邊、白字（深藍底上要看得到）；暖色只留給「回覆」「送出」「加入行事曆」這種主要動作 */
.btn-ghost, .btn.btn-ghost { box-shadow: inset 0 0 0 1.5px rgba(var(--line-rgb), .7); color: var(--ink); }
.venue .btn { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1.5px rgba(var(--line-rgb), .75); }
.venue .btn:hover { box-shadow: inset 0 0 0 1.5px var(--ink); opacity: 1; }

/* 蓄力：門牌外框改暖色、加粗（按住時看得出「在蓄力」） */
.plate-ring i { background: var(--lamp); box-shadow: 0 0 10px rgba(var(--lamp-rgb), .6); }
.pr-t, .pr-b { height: 3px; }
.pr-r, .pr-l { width: 3px; }

/* 地圖＝曬圖：反白後染成底色（白路、藍地），底紙只寫「基地配置圖」——不寫「載入中」，沒載到也不像壞掉 */
.map-frame iframe { filter: grayscale(1) invert(.9) contrast(1.15) brightness(1.05); }
.map-frame::after { background: var(--paper); mix-blend-mode: color; opacity: .9; }
.map-frame::before {
  content: "SITE PLAN  基地配置圖";
  top: auto; bottom: 1rem; translate: none;
  font-family: var(--wk-f-latin, var(--font-mono));
  letter-spacing: .2em;
  color: var(--accent);
}
html.wk-lang-en .map-frame::before { content: "SITE PLAN"; }
@media (max-width: 959px) { .hero-house .dwg-cap { margin-top: .9rem; } }

/* ── 第 2 輪評審修正 ── */
/* ⚠ Hero 的房子刻意放得比欄寬大（符號兩側留給標註的空白要吃掉）：Hero 一定要裁掉橫向溢出，
   不然手機的版面視窗會被撐寬，整頁可以左右滑、按鈕座標也會錯位（實測 visualViewport 偏 102px） */
.hero { overflow-x: clip; }

/* 手機：房子在上、圖框在下（真的圖紙，圖框本來就在圖紙下緣）。iPhone SE 首屏也一定看得到房子 */
@media (max-width: 959px) {
  .hero-content { display: flex; flex-direction: column; }
  .hero-label { order: 0; }
  .hero-house { order: 1; margin-top: -.6rem; margin-bottom: .9rem; }
  .hero .tb { order: 2; }
  .tb-say { order: 3; }
  .hero-frame { order: 4; }
  .hero-notes { order: 5; }
  .countdown { order: 6; }
  .hero-house .dwg-cap { margin-top: -.2rem; }
}
@media (max-width: 959px) and (max-height: 700px) {
  .hero-house { margin-top: -1.6rem; margin-bottom: .2rem; }
  .hero-house .bh-use { width: 88%; margin-inline: auto; }
  .hero-house .dwg-cap { display: none; }
}

/* 桌機 Hero：房子是右欄的主角（放大），圖框在它下面 */
@media (min-width: 960px) {
  .hero-content { max-width: 78rem; grid-template-columns: 4fr 6fr; }
  .hero-house .bh-use { width: 128%; margin: -1rem 0 -1.4rem -14%; }
}

/* 桌機工地欄：字放大（長輩看得到） */
@media (min-width: 1024px) {
  .bp-site-k { font-size: .86rem; }
  .bp-site-cap { font-size: 1.05rem; }
  .bp-site-list { font-size: .95rem; gap: .45rem 1.8rem; }
  .bp-site-list li::before { font-size: .8rem; }
}

/* 房間小圖放大：看得出亮的是哪一間 */
.bh-mini { --hw: 2.8; width: 6rem; margin: -.8rem 0 -.8rem -.6rem; }

/* 暖色只給「燈」與最重要的一個動作（送出回覆）：行事曆按鈕改白線描邊 */
.details .btn { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1.5px rgba(var(--line-rgb), .75); }
.details .btn:hover { box-shadow: inset 0 0 0 1.5px var(--ink); opacity: 1; }

/* 地圖還沒載入時：底紙是一張畫好的「基地配置圖」（道路、街廓、指北），不是空框 */
.map-frame {
  background:
    linear-gradient(90deg, transparent 0 calc(38% - 9px), rgba(var(--line-rgb), .22) calc(38% - 9px) calc(38% - 8px), transparent calc(38% - 8px) calc(38% + 8px), rgba(var(--line-rgb), .22) calc(38% + 8px) calc(38% + 9px), transparent 0),
    linear-gradient(0deg, transparent 0 calc(58% - 9px), rgba(var(--line-rgb), .22) calc(58% - 9px) calc(58% - 8px), transparent calc(58% - 8px) calc(58% + 8px), rgba(var(--line-rgb), .22) calc(58% + 8px) calc(58% + 9px), transparent 0),
    radial-gradient(circle at 38% 42%, var(--lamp) 0 5px, rgba(var(--lamp-rgb), .25) 6px 16px, transparent 17px),
    linear-gradient(rgba(var(--accent-rgb), .08) 1px, transparent 1px) -1px -1px / 16px 16px,
    linear-gradient(90deg, rgba(var(--accent-rgb), .08) 1px, transparent 1px) -1px -1px / 16px 16px,
    var(--paper-raise);
}

/* 按住門牌：除了外框線，牆上整圈跟著蓄力亮起暖光 */
.plate-wall { transition: box-shadow .35s var(--ease-out); }
.blessing-seal.is-pressing .plate-wall { box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), .5), 0 0 calc(var(--wk-press, 0) * 46px) calc(var(--wk-press, 0) * 6px) rgba(var(--lamp-rgb), .32); transition: none; }
@media (max-width: 959px) { .hero-house { margin-bottom: -.4rem; } }

/* ── 第 3 輪評審修正 ── */
/* 開場圖紙上的房子：同一棟軸測圖，拉的進度＝施工進度，拉到底門燈亮 */
.intro-house {
  aspect-ratio: 733 / 550;
  height: min(calc(var(--sh) - var(--peek) - 1.6rem), calc(min(96vw, 32rem) * .75));
  top: 1.2rem;
  opacity: clamp(0, calc(var(--wk-open, 0) * 4), 1);
}
.bh-intro {
  --hw: 1.5;
  --bh-t: .25s;
  --b-site: clamp(0, calc(var(--wk-open, 0) * 5), 1);
  --b-f1: clamp(0, calc(var(--wk-open, 0) * 2.6 - .2), 1);
  --b-f2: clamp(0, calc(var(--wk-open, 0) * 2.6 - .9), 1);
  --b-roof: clamp(0, calc(var(--wk-open, 0) * 2.6 - 1.6), 1);
  --l-lamp: clamp(0, calc(var(--wk-open, 0) * 6 - 5), 1);
  width: 100%;
}
.intro-commit .bh-intro { --bh-t: .5s; }
@media (max-height: 700px) { .intro-house { top: .6rem; height: min(calc(var(--sh) - var(--peek) - .6rem), calc(min(96vw, 32rem) * .75)); } }

/* 桌機的定位點：一個暖色點＋慢慢外擴的圈（房名在左欄圖說） */
.bh-call circle { fill: var(--lamp); }
.bh-call .bh-ping { fill: none; stroke: var(--lamp); stroke-width: 1.5; transform-box: fill-box; transform-origin: center; animation: bh-ping 2.2s ease-out infinite; }
@keyframes bh-ping { 0% { transform: scale(.4); opacity: .9; } 100% { transform: scale(1.5); opacity: 0; } }

/* 桌機 Hero：房子當右欄主角（放大，圖框壓在它的地基上） */
@media (min-width: 960px) {
  .hero-house .bh-use { width: 150%; margin: .4rem 0 -2.6rem -25%; }
  .hero .tb { position: relative; z-index: 1; }
}
/* 桌機工地欄：欄位放寬、房子放大（左右的空白是符號留的，裁掉不影響） */
@media (min-width: 1024px) {
  main { grid-template-columns: minmax(0, 44fr) minmax(0, 56fr); }
  .bp-site { overflow-x: clip; }
  .bh-big { width: 150%; margin-left: -25%; margin-block: -1.5rem -1rem; }
}

/* 終章：房子放大；按住的過程中燈跟著一盞盞亮（--p＝按住的進度，render.js 同步），放手就熄 */
.finale-house { width: min(118%, 30rem); margin: 0 -9% 1rem; }
@media (min-width: 560px) { .finale-house { margin-inline: auto; } }
.bh-finale {
  --p: 0;
  --l-lamp: clamp(0, calc(var(--p) * 11), 1);
  --l-entrance: clamp(0, calc(var(--p) * 11 - 1), 1);
  --l-living: clamp(0, calc(var(--p) * 11 - 2), 1);
  --l-dining: clamp(0, calc(var(--p) * 11 - 3), 1);
  --l-study: clamp(0, calc(var(--p) * 11 - 4), 1);
  --l-balcony: clamp(0, calc(var(--p) * 11 - 5), 1);
  --l-media: clamp(0, calc(var(--p) * 11 - 6), 1);
  --l-wardrobe: clamp(0, calc(var(--p) * 11 - 7), 1);
  --l-loft: clamp(0, calc(var(--p) * 11 - 8), 1);
  --l-mailbox: clamp(0, calc(var(--p) * 11 - 9), 1);
}
.blessing-seal.is-pressing ~ * .bh-finale { --bh-t: 0s; }

/* 地圖還沒載入時的底紙：畫成一張配置圖（兩條路、一塊基地、場地的位置、指北），線要看得到 */
.map-frame {
  background:
    radial-gradient(circle at 38% 42%, var(--lamp) 0 5px, rgba(var(--lamp-rgb), .3) 6px 18px, transparent 19px),
    linear-gradient(rgba(var(--line-rgb), .55), rgba(var(--line-rgb), .55)) 26% 30% / 24% 1.5px no-repeat,
    linear-gradient(rgba(var(--line-rgb), .55), rgba(var(--line-rgb), .55)) 26% 54% / 24% 1.5px no-repeat,
    linear-gradient(90deg, rgba(var(--line-rgb), .55), rgba(var(--line-rgb), .55)) 26% 30% / 1.5px 24% no-repeat,
    linear-gradient(90deg, rgba(var(--line-rgb), .55), rgba(var(--line-rgb), .55)) 50% 30% / 1.5px 24% no-repeat,
    linear-gradient(90deg, transparent 0 calc(62% - 12px), rgba(var(--line-rgb), .4) calc(62% - 12px) calc(62% - 11px), transparent calc(62% - 11px) calc(62% + 11px), rgba(var(--line-rgb), .4) calc(62% + 11px) calc(62% + 12px), transparent 0),
    linear-gradient(0deg, transparent 0 calc(30% - 12px), rgba(var(--line-rgb), .4) calc(30% - 12px) calc(30% - 11px), transparent calc(30% - 11px) calc(30% + 11px), rgba(var(--line-rgb), .4) calc(30% + 11px) calc(30% + 12px), transparent 0),
    linear-gradient(rgba(var(--accent-rgb), .08) 1px, transparent 1px) -1px -1px / 16px 16px,
    linear-gradient(90deg, rgba(var(--accent-rgb), .08) 1px, transparent 1px) -1px -1px / 16px 16px,
    var(--paper-raise);
}

/* 刮開區：提示放大、加一個描線的手指在框中間輕輕來回（＝這裡可以刮） */
.secret .scratch-hint { font-size: 1.05rem; color: var(--ink); }
.secret .scratch-hint::after {
  content: "";
  width: 2.6rem; height: 2.6rem;
  margin-top: .4rem;
  background: var(--lamp);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 11V5.5a1.5 1.5 0 0 1 3 0V11'/%3E%3Cpath d='M12 10.5V9a1.5 1.5 0 0 1 3 0v2'/%3E%3Cpath d='M15 10.5a1.5 1.5 0 0 1 3 0V15a6 6 0 0 1-6 6h-1a6 6 0 0 1-4.6-2.2L4 15.6a1.5 1.5 0 0 1 2.3-1.9L9 16'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 11V5.5a1.5 1.5 0 0 1 3 0V11'/%3E%3Cpath d='M12 10.5V9a1.5 1.5 0 0 1 3 0v2'/%3E%3Cpath d='M15 10.5a1.5 1.5 0 0 1 3 0V15a6 6 0 0 1-6 6h-1a6 6 0 0 1-4.6-2.2L4 15.6a1.5 1.5 0 0 1 2.3-1.9L9 16'/%3E%3C/svg%3E") center / contain no-repeat;
  animation: bp-rub 2.4s ease-in-out infinite;
}
@keyframes bp-rub { 0%, 100% { translate: -14px 0; } 50% { translate: 14px 0; } }
.secret .scratch-card.is-scratching .scratch-hint, .secret .scratch-card.is-revealed .scratch-hint { opacity: 0; }

/* 色票的色碼放大（長輩讀得到） */
.dc-swatch::after { font-size: .82rem; }

/* ── 第 4 輪評審修正 ── */
/* 開場待拉：捲筒上的屋頂改白、加粗，閣樓圓窗亮著一盞暖燈（拉之前就知道「這是一個有人在的家」） */
.intro-roof :is(path, circle) { stroke: rgb(var(--line-rgb)); }
.intro-roof path:first-child { stroke-width: 2.6; }
.intro-roof circle { fill: var(--lamp); stroke: var(--lamp); filter: drop-shadow(0 0 6px rgba(var(--lamp-rgb), .9)); animation: bp-breathe 2.8s ease-in-out infinite; }
.intro-roof circle + path { stroke: var(--lamp-ink); }
@keyframes bp-breathe { 0%, 100% { opacity: .75; } 50% { opacity: 1; } }

/* 地圖底紙：圖名移到左上角（像圖框的圖名，有底色，不會被線穿過），配置圖多畫幾塊街廓 */
.map-frame::before {
  content: "SITE PLAN 基地配置圖";
  top: .8rem; left: .8rem; right: auto; bottom: auto; translate: none;
  z-index: 1;
  padding: .2rem .55rem;
  background: var(--paper-raise);
  box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), .6);
  font-size: .74rem;
  text-align: left;
}
.map-frame {
  background:
    radial-gradient(circle at 38% 42%, var(--lamp) 0 7px, rgba(var(--lamp-rgb), .3) 8px 22px, transparent 23px),
    linear-gradient(rgba(var(--line-rgb), .5), rgba(var(--line-rgb), .5)) 26% 30% / 24% 1.5px no-repeat,
    linear-gradient(rgba(var(--line-rgb), .5), rgba(var(--line-rgb), .5)) 26% 54% / 24% 1.5px no-repeat,
    linear-gradient(90deg, rgba(var(--line-rgb), .5), rgba(var(--line-rgb), .5)) 26% 30% / 1.5px 24% no-repeat,
    linear-gradient(90deg, rgba(var(--line-rgb), .5), rgba(var(--line-rgb), .5)) 50% 30% / 1.5px 24% no-repeat,
    linear-gradient(rgba(var(--line-rgb), .14), rgba(var(--line-rgb), .14)) 76% 18% / 16% 22% no-repeat,
    linear-gradient(rgba(var(--line-rgb), .14), rgba(var(--line-rgb), .14)) 76% 82% / 16% 26% no-repeat,
    linear-gradient(rgba(var(--line-rgb), .14), rgba(var(--line-rgb), .14)) 18% 86% / 26% 20% no-repeat,
    linear-gradient(90deg, transparent 0 calc(62% - 12px), rgba(var(--line-rgb), .45) calc(62% - 12px) calc(62% - 11px), transparent calc(62% - 11px) calc(62% + 11px), rgba(var(--line-rgb), .45) calc(62% + 11px) calc(62% + 12px), transparent 0),
    linear-gradient(0deg, transparent 0 calc(30% - 12px), rgba(var(--line-rgb), .45) calc(30% - 12px) calc(30% - 11px), transparent calc(30% - 11px) calc(30% + 11px), rgba(var(--line-rgb), .45) calc(30% + 11px) calc(30% + 12px), transparent 0),
    linear-gradient(rgba(var(--accent-rgb), .08) 1px, transparent 1px) -1px -1px / 16px 16px,
    linear-gradient(90deg, rgba(var(--accent-rgb), .08) 1px, transparent 1px) -1px -1px / 16px 16px,
    var(--paper-raise);
}

/* 行事曆兩顆按鈕等寬兩欄（不像殘缺的一排） */
.calendar-actions { display: grid; grid-template-columns: 1fr 1fr; gap: .7rem; max-width: 34rem; }
.calendar-actions .btn { width: 100%; padding-inline: .6rem; }
@media (max-width: 420px) { .calendar-actions { grid-template-columns: 1fr; } }

/* 房間小圖：再大一點（符號左右的空白用負邊距吃掉），亮的那一間看得出來 */
.bh-mini { --hw: 2.4; width: 8rem; margin: -1.2rem -.6rem -1.2rem -1.4rem; }

/* 桌機工地欄：房子再大 */
@media (min-width: 1024px) {
  .bh-big { width: 158%; margin-left: -20%; margin-block: -2.5rem -1.5rem; }
}

/* 終章：門牌離房子近一點（同一個門口） */
.finale-house { margin-bottom: -.4rem; }
.blessing-lead { margin-top: 0; }

/* 刮開區的「直接打開」：做成有框的次要按鈕 */
.secret .scratch-open {
  display: inline-flex; align-items: center; justify-content: center;
  margin-top: 1rem; padding: .55rem 1.2rem;
  text-decoration: none;
  color: var(--ink);
  box-shadow: inset 0 0 0 1.5px rgba(var(--line-rgb), .7);
  border-radius: var(--radius);
}
.bh-mini { width: 9.6rem; margin: -1.5rem -1rem -1.5rem -1.8rem; }

/* 終章房子刻意出血（.finale-house margin -9%）：頁尾一定要裁掉橫向溢出，
   不然 390／360 手機整頁可以左右滑（祝福牆、A+ 放大、當天卡三支回歸 2026-11-04 抓到） */
.footer { overflow-x: clip; }
