/* aweivic 個人官網 — 版面語彙參考 yokanka.com（2026-09-10 第二次改版）
   淺灰底、黑字、明朝體內文、Marcellus 大字英文標、斜線導覽＋膠囊鈕、
   左右分割圖文、( 01 ) 編號特色段、深底照片跑馬帶、置中大字 NEXT →、頁尾全幅照片壓字標
   2026-09-11 第四輪視覺與互動：全站最小字 13px／字級階層、毛玻璃卡片、圖片圓角、
   icon-btn、分頁、購物車元件
   2026-09-12 第七輪：背景氛圍層改為窗光＋樹影搖曳（取代小花粒子），見下方 S8 區塊
   2026-09-13：背景改為 S13 和紙＋空色時辰，其上疊 S14 水盤（雲影移除），見檔尾 */

:root {
  --bg: #ECECEA;
  --card: #F4F4F2;
  --ink: #111111;
  --muted: #6B6B67;
  /* S11：結帳／購物車的說明文字專用。比 --muted 深一階，給 40 歲以上使用者讀。
     只在 .cartbar／.cart-drawer／.menu-card 範圍內用，全站其他 --muted 不動。 */
  --ink-2: #46463F;
  --line: rgba(0, 0, 0, .14);
  --dark: #1B1B1B;
  --wrap: 1320px;
  --read: 720px;
  --gutter: clamp(20px, 3.2vw, 44px);
  --serif: "Noto Serif TC", "Hiragino Mincho ProN", "Songti TC", Georgia, serif;
  --display: "Marcellus", "Noto Serif TC", Georgia, serif;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--serif);
  font-weight: 400;
  font-size: 17px;
  line-height: 1.9;
  letter-spacing: .04em;
  overflow-x: hidden;
}

h1, h2, h3 { margin: 0; font-weight: 400; line-height: 1.4; }
p { margin: 0 0 1.6em; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; height: auto; display: block; }
blockquote { margin: 1.6em 0; padding-left: 1.2em; border-left: 1px solid var(--line); color: var(--muted); }
ul, ol { padding-left: 1.4em; margin: 0 0 1.6em; }

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 var(--gutter); }

/* 英文大字標（Marcellus） */
.display {
  font-family: var(--display);
  font-weight: 400;
  letter-spacing: .06em;
  line-height: 1.1;
  text-transform: uppercase;
}
.eyebrow {
  font-size: 13px;
  letter-spacing: .08em;
  color: var(--ink);
  margin: 0 0 1.2em;
}

/* ===== 頁首 ===== */
.site-header {
  position: sticky; top: 0; z-index: 30;
  background: rgba(236, 236, 234, .9);
  backdrop-filter: blur(8px);
}
.site-header__inner {
  max-width: none; margin: 0; padding: 0 var(--gutter);
  height: 72px;
  display: flex; align-items: center; gap: clamp(16px, 2.4vw, 32px);
}
.site-header__brand {
  font-family: var(--display); font-size: 20px; letter-spacing: .24em;
  min-height: 44px; display: inline-flex; align-items: center; white-space: nowrap;
}
.site-header__zh { font-family: var(--serif); letter-spacing: .16em; margin-right: .5em; }
.site-nav { display: flex; align-items: center; gap: .6em; flex: 1; }
.site-nav a {
  font-size: 13px; letter-spacing: .08em; text-transform: uppercase;
  min-height: 44px; display: inline-flex; align-items: center;
  border-bottom: 1px solid transparent;
}
.site-nav a[aria-current="page"], .site-nav a:hover { border-bottom-color: var(--ink); }
.site-nav .sep { color: var(--muted); font-size: 13px; }
.site-header__cta { display: flex; align-items: center; gap: .6em; }

.pill {
  display: inline-flex; align-items: center; gap: .5em;
  min-height: 44px; padding: 0 1.3em;
  border: 1px solid var(--ink); border-radius: 999px;
  font-size: 13px; letter-spacing: .08em; text-transform: uppercase;
  transition: background-color .18s ease, color .18s ease;
}
.pill:hover { background: var(--ink); color: var(--bg); }
.pill--fill { background: var(--ink); color: var(--bg); }
.pill--fill:hover { background: #333; }
.pill__ico { width: 14px; height: 14px; border: 1.5px solid currentColor; border-radius: 4px; display: inline-block; position: relative; }
.pill__ico::after { content: ""; position: absolute; inset: 3px; border: 1.5px solid currentColor; border-radius: 50%; }

/* 頁首右上圖示鈕（IG／蝦皮／LINE 等）：44px 圓形、hover 反白（2026-09-11） */
.icon-btn {
  width: 44px; height: 44px; flex: 0 0 44px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--ink); border-radius: 50%; color: var(--ink);
  transition: background-color .18s ease, color .18s ease, border-color .18s ease, transform .18s ease;
}
.icon-btn .icon { width: 20px; height: 20px; fill: currentColor; display: block; }
.icon-btn:hover { background: var(--ink); color: var(--bg); transform: translateY(-1px); }
.icon-btn:active { transform: translateY(0) scale(.97); }
.icon-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
@media (hover: none) { .icon-btn:hover { transform: none; } }
@media (prefers-reduced-motion: reduce) { .icon-btn { transition: none; } }

/* ===== 首頁開場（置中、單一物件） ===== */
.hero {
  min-height: calc(100vh - 72px);
  display: grid; grid-template-rows: auto 1fr auto; justify-items: center; align-items: start;
  padding: clamp(32px, 6vh, 72px) var(--gutter) 40px;
  position: relative;
}
.hero__tag { font-size: clamp(18px, 2.2vw, 26px); letter-spacing: .16em; margin: 0 0 .5em; text-align: center; }
.hero__logo { font-size: clamp(40px, 8.6vw, 112px); letter-spacing: .22em; line-height: 1; text-align: center; margin: 0 0 clamp(24px, 5vh, 56px); }
.hero__figure { width: min(720px, 90vw); align-self: center; }
.hero__figure img { width: 100%; }
.hero__caption {
  display: flex; align-items: center; gap: 1.4em; font-size: 13px; letter-spacing: .1em; color: var(--muted);
  margin-top: 2em; justify-self: start; width: 100%; max-width: var(--wrap);
}
.hero__caption .rule { width: 56px; height: 1px; background: var(--ink); }
.scroll-hint {
  position: absolute; right: var(--gutter); bottom: 40px;
  writing-mode: vertical-rl; font-size: 13px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
  padding-bottom: 56px;
}
.scroll-hint::after { content: ""; position: absolute; left: 50%; bottom: 0; width: 1px; height: 48px; background: var(--ink); }

/* ===== 置中標題區塊（商品一覧／Collection 語彙） ===== */
.section { padding: clamp(72px, 11vw, 160px) 0 0; }
.section__center { text-align: center; margin-bottom: clamp(40px, 5vw, 72px); }
.section__center .eyebrow { margin-bottom: .8em; }
.section__display { font-size: clamp(40px, 6.4vw, 86px); }

/* ===== 文章卡片：淺卡底、圖內縫（舊卡片牆，部分頁面仍可能引用） ===== */
.post-grid {
  list-style: none; padding: 0; margin: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(24px, 2.6vw, 40px);
}
.post-card { display: block; }
.post-card__cover { background: var(--card); padding: clamp(14px, 1.6vw, 22px); aspect-ratio: 4 / 3; overflow: hidden; }
.post-card__cover img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s ease; }
.post-card:hover .post-card__cover img { transform: scale(1.02); }
.post-card__date { font-size: 13px; letter-spacing: .08em; color: var(--muted); margin: 1.1em 0 .3em; }
.post-card__title { font-size: 15px; line-height: 1.7; letter-spacing: .04em; margin: 0; }
.post-card__excerpt { display: none; }
.post-card__cover--text { display: flex; }
.post-card__cover--text > div {
  flex: 1; display: flex; align-items: center; justify-content: center;
  padding: clamp(18px, 2.4vw, 34px); border: 1px solid var(--line); overflow: hidden;
}
.post-card__cover--text p {
  margin: 0; text-align: center;
  font-family: var(--serif); font-size: clamp(15px, 1.4vw, 19px); line-height: 2; letter-spacing: .1em; color: var(--muted);
  overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4;
  transition: color .6s ease;
}
.post-card:hover .post-card__cover--text p { color: var(--ink); }

/* ===== 左右分割圖文 ===== */
.split { display: grid; grid-template-columns: 1fr 1fr; min-height: 80vh; margin-top: clamp(72px, 11vw, 160px); }
.split__media { position: relative; overflow: hidden; }
.split__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: 10px; }
.split__body { padding: clamp(40px, 6vw, 96px) clamp(28px, 5vw, 80px); display: flex; flex-direction: column; justify-content: center; }
.split__display { font-size: clamp(36px, 5.2vw, 72px); margin: 0 0 1.2em; }
.split__lines { font-size: 15px; line-height: 2.6; letter-spacing: .1em; max-width: 30em; margin: 0 0 2em; }
.split__lines br { display: block; content: ""; margin-bottom: .2em; }

/* ===== 深底照片跑馬帶 ===== */

/* ===== NEXT → 大字連結 ===== */
.next { padding: clamp(80px, 12vw, 180px) var(--gutter); text-align: center; }
.next a { display: inline-block; }
.next__label, .next__target {
  font-family: var(--display); text-transform: uppercase; letter-spacing: .08em; line-height: 1.15;
  display: inline-block; border-bottom: 1px solid var(--ink); padding-bottom: .1em;
}
.next__label { font-size: clamp(28px, 4vw, 56px); }
.next__target { font-size: clamp(34px, 5.6vw, 80px); margin-top: .3em; }
.next__target .zh { font-family: var(--serif); letter-spacing: .2em; }

/* ===== 大杯居頁 ===== */
.coffee-hero {
  min-height: calc(100vh - 72px); display: grid; justify-items: center; align-content: center; gap: 1.2em;
  padding: clamp(32px, 6vh, 72px) var(--gutter); text-align: center; position: relative;
}
.coffee-hero__badge { width: clamp(220px, 30vw, 360px); height: auto; }
.coffee-hero__tag { font-size: clamp(17px, 2vw, 24px); letter-spacing: .16em; margin: 0; }
.coffee-hero__display { font-size: clamp(36px, 7.4vw, 96px); letter-spacing: .2em; line-height: 1; }
.coffee-hero__cta { display: flex; gap: .8em; flex-wrap: wrap; justify-content: center; margin-top: 1em; }

.chapter { padding: clamp(64px, 9vw, 128px) 0 0; }
.chapter__grid { display: grid; grid-template-columns: minmax(200px, 1fr) 2fr; gap: 1.6em clamp(32px, 5vw, 96px); }
.chapter__num { display: block; font-family: var(--display); font-size: 13px; letter-spacing: .3em; color: var(--muted); margin-bottom: 1.2em; }
.chapter__title { font-size: clamp(22px, 2.4vw, 30px); letter-spacing: .16em; line-height: 1.6; }
.chapter__year { display: block; font-family: var(--display); font-size: 13px; letter-spacing: .1em; color: var(--muted); margin-top: .8em; }
.chapter__body { max-width: 36em; font-size: 15px; line-height: 2.2; padding: clamp(18px, 2.4vw, 28px); }
.chapter__body p:last-child { margin-bottom: 0; }

.strip { margin: clamp(32px, 4vw, 56px) calc(50% - 50vw) 0; }
.strip__track { display: flex; gap: 6px; overflow-x: auto; scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch; scrollbar-width: none; padding: 0 var(--gutter); }
.strip__track::-webkit-scrollbar { display: none; }
.strip__track img { flex: 0 0 auto; height: clamp(240px, 40vw, 520px); width: auto; object-fit: cover; scroll-snap-align: start; border-radius: 0; }
.strip__caption { padding: 1em var(--gutter) 0; font-family: var(--display); font-size: 13px; letter-spacing: .1em; color: var(--muted); }

/* ===== Menu（Collection） ===== */
/* S16（2026-09-15）：訂購區拆成「個人享用」／「月份方案」兩條輪播（見
   coffee_render.py menu_section_html），不再是單一 3 欄格線；卡片改成沿用
   assets/bloom.js 的 .gallery 輪播互動，不是第三種橫向捲動實作。 */
.menu-jump { display: flex; justify-content: center; gap: .8em; margin: 0 0 1.6em; flex-wrap: wrap; }
/* S19（2026-09-23）：分類快捷從錨點 <a> 改成 <button>（單軌輪播沒有可跳的區塊 id，
   改由 assets/bloom.js 把輪播捲到該類第一張卡），要清掉按鈕的預設背景與字型繼承。 */
.menu-jump__pill { min-height: 44px; display: inline-flex; align-items: center;
  background: none; color: inherit; font-family: inherit; cursor: pointer; }
.menu-subsection { margin: 0 0 clamp(28px, 4vw, 44px); }
.menu-subsection__h {
  font-family: var(--display); font-size: 15px; letter-spacing: .16em; color: var(--ink-2);
  margin: 0 0 1em; text-align: center; scroll-margin-top: 90px;
}

/* .menu-carousel：套在 .gallery 上的修飾詞。互動邏輯（拖移／鍵盤／按鈕／位置指示／
   自動輪播）完全共用 assets/bloom.js 的 setupGallery，這裡只覆寫外觀。
   S19 三修（2026-09-24，Vic 指定「左右兩側不要留白，像一條完整的輸送帶」）：改回沿用
   .gallery 的左右滿版出血 calc(50% - 50vw)，只覆寫上下邊距。padding 仍是 var(--gutter)，
   第一張卡不會貼死螢幕邊；nav 按鈕的 calc(var(--gutter) - 4px) 因此也不必改。
   （先前為了把輪播收在 .wrap 內而整個 margin 歸零，左右各留一條 gutter 空白。） */
.gallery.menu-carousel { margin: 0 calc(50% - 50vw); }
.menu-track { list-style: none; padding: 0 0 4px; margin: 0; align-items: stretch; }
/* 桌面約 3 張＋一截，手機約 1 張＋一截（S16 規格）。flex-basis 用「軌道寬度的
   百分比」而不是 vw：卡片所在的 .gallery__track 寬度已經扣掉 .wrap 的 gutter 與
   .menu-carousel 自己的 padding，用 vw 算會比軌道實際可視寬度更寬，導致卡片
   置中時左右兩側被裁掉（2026-09-15 實測踩到，見 scripts/shoot_howto.py 重拍時
   文字被切一半）。clamp() 同時擋住极端窄／寬螢幕。卡片同軌等高由 flex 預設的
   align-items: stretch 自然做到，不必額外量高度。 */
/* min-width: 0 破解 flex item 預設 min-width: auto 的「自動最小尺寸」——沒有這行，
   卡片內較長的一行文字（例如 .menu-card__meta 產地／處理法／烘焙／規格那行）會把
   卡片撐超過 flex-basis，2026-09-15 實測會撐到 339px（clamp 上限只有 320px）。 */
.menu-card.gallery__item { flex: 0 0 clamp(240px, 82%, 320px); min-width: 0; display: flex; flex-direction: column; }
@media (min-width: 721px) {
  .menu-card.gallery__item { flex-basis: clamp(280px, 30%, 360px); }
}
.menu-card__image { background: var(--card); padding: clamp(16px, 2vw, 28px); aspect-ratio: 1 / 1; overflow: hidden; border-radius: 10px; }
.menu-card__image img { width: 100%; height: 100%; object-fit: cover; }
/* 卡片同時是 .gallery__item，要蓋掉照片牆的 .gallery__item img 固定高度（60vh／max-height），否則圖被撐大、超出外框被裁掉 */
.menu-card.gallery__item .menu-card__image img { width: 100%; height: 100%; max-height: none; }
/* 個人享用的單品情境照改 4:3（2026-09-15 主線指定）：目的是縮圖片區高度（1:1 時
   圖高＝卡片寬，佔卡片總高一大截）。逐張核對過裁切安全（見回報，豆袋／罐頂距
   置中裁切線都留有 ≥130px 餘裕，object-fit: cover 置中裁不到主體）；排除耳掛組合
   （data-item="drip-set"；不能用 data-sku，切到「單包」規格時 data-sku 會變）——那張是 6 包散落擺拍的多主體構圖，最上面的包裝
   已經貼近畫面上緣，裁 25% 高度風險較高，保留 1:1。月份方案情境照維持 1:1，不在此
   規則範圍內（主線明講不可以裁）。
   S19（2026-09-23）：兩條輪播併成單軌後 #menu-personal／#menu-plan 這兩個容器 id 已
   不存在，改用卡片自己的 data-section 屬性（coffee_render.py 的 menu_card_html 輸出）。 */
.menu-card[data-section="personal"]:not([data-item="drip-set"]) .menu-card__image { aspect-ratio: 4 / 3; }
.menu-card__body { padding: clamp(16px, 2vw, 22px); display: flex; flex-direction: column; flex: 1; }
/* 視覺權重（S19 三修，2026-09-24 Vic 指定）：第一順位是系列名（精品特殊處理／單品淺焙
   ／居家中焙／單品淺焙耳掛包／隨身堅果／月份方案），第二順位才是品項。所以系列名拿
   主標字級與主色，品名降一階、用次要色——原本兩者的權重是反過來的。
   系列名在 .menu-card__vinfo-wrap 之外、不隨規格換；品名在裡面、切規格會換，
   這個結構正好對應「系列固定、品項浮動」。 */
/* 字重與呼吸感（S20，2026-09-24 Vic 指定）：系列名是第一順位，原本沒有 font-weight
   宣告、與下方品名只隔 .2em，四列幾乎等距，看起來像一份清單而不是有主從的卡片。
   font-weight: 500 沿用站台慣例——build.py 載的是 Noto+Serif+TC:wght@400;500，
   中文系列名落在 Noto Serif TC 的真 500 字重，不是瀏覽器合成粗體（寫 700 才會）。
   下方間距 .2em → .55em：系列名自成一層，品名／產地／風味三列成為下面那一組。
   8 張卡靠 flex stretch 等高，這一行讓整排卡高 +7px（改前桌面 862、375px 787，
   最高的是耳掛月份方案那張，見 2026-09-24 量測）。 */
/* 系列名（2026-09-24）：沿用文章頁 .article mark 的螢光底（64% 起的淡色塊），讓商城的
   系列名與正文裡的重點標記是同一種視覺語彙。width: fit-content 讓色塊只包住文字——
   block 元素的 background 預設會鋪滿整列，看起來會像一條橫槓而不是螢光筆。 */
.menu-card__cat {
  font-family: var(--display); font-size: 21px; font-weight: 500; letter-spacing: .1em;
  color: var(--ink); margin: 0 0 .55em; line-height: 1.3;
  width: fit-content; background: linear-gradient(transparent 64%, rgba(0, 0, 0, .07) 0);
}
.menu-card__name { font-size: 16px; letter-spacing: .06em; color: var(--ink-2); margin: 0 0 .3em; line-height: 1.35; }
.menu-card__meta { font-size: 15px; letter-spacing: .04em; color: var(--ink-2); margin: 0 0 .3em; line-height: 1.35; }
.menu-card__flavor { font-size: 15px; margin: 0 0 .4em; line-height: 1.35; }
/* 本期出貨／輪替說明（S20，2026-09-24）：系列化之後，同一個系列底下可能有好幾支豆，
   卡面要讓客人看得到實際會拿到哪一支。字級與色都壓在風味之下——它是佐證，不跟
   品名與風味搶權重。在 .menu-card__vinfo 疊層裡（每個規格各一份），所以切規格時
   跟著換、高度不跳。 */
.menu-card__rotate { font-size: 14px; color: var(--muted); margin: 0 0 .4em; line-height: 1.45; }
/* line-height: 1.3（2026-09-15 主線親驗抓到的高度大戶）：這一行繼承全站 body 的
   line-height:1.9，24px 字級只要換行成兩行（組合規格「NT$ 300 單買 NT$ 360」＋
   「省 NT$ 60」），單這一個元素就吃掉 91px；改窄行距後兩行只要 62px，單行的卡片
   （沒有 compare 的品項）也從 45.6px 降到 31.2px，同步幫所有卡片瘦身。 */
.menu-card__price { font-family: var(--display); font-size: 24px; letter-spacing: .1em; color: var(--ink); margin: 0 0 .3em; line-height: 1.3; }
/* 價格列疊層（S16 二修，2026-09-15 主線親驗抓到「切規格卡片高度會跳」）：有 variants
   的品項，每個規格自己的價格列（含各自的 compare／save，長度不同）都會渲染出來，
   全部疊在同一個 grid cell（grid-area: 1/1），只有 .is-active 那列 visibility:visible，
   其餘 visibility:hidden 但照樣佔位。grid 容器的高度＝這張卡「所有規格裡最高的
   那一列」，不管切到哪個規格都不會變——不是估出一個「兩行」的 min-height 去賭，
   是真的把每種規格的實際內容都量進去，寬度、字型、換行邏輯改了也不必回來調數字。
   沒有 variants 的品項維持單一 <p>，不套這層（coffee_render.py 的 price_html 分支）。 */
.menu-card__price-wrap { display: grid; margin: 0 0 .3em; }
.menu-card__price-wrap .menu-card__price { grid-area: 1 / 1; margin: 0; visibility: hidden; }
.menu-card__price-wrap .menu-card__price.is-active { visibility: visible; }
/* 品名／產地處理法／風味／已售出的疊層（S19，2026-09-23 合併等價商品）：跟上面的
   價格列同一套機制。合併卡的每個規格是不同的豆子——「橙花、蜂蜜、檸檬」與「茉莉花、
   檸檬、杏桃、蜂蜜」在 375 窄卡片上的換行數不同，用 JS 改文字內容就會跳高度。改成
   每個規格各渲染一份、疊在同一個 grid cell，容器高度＝最高的那一份，切規格永遠不變。
   只有一個規格的卡片（居家中焙）也走這層，grid 單格不影響版面。 */
.menu-card__vinfo-wrap { display: grid; }
.menu-card__vinfo { grid-area: 1 / 1; visibility: hidden; }
.menu-card__vinfo.is-active { visibility: visible; }
/* 組合規格的「單買」刪除線與「省 NT$」pill（S15，2026-09-15）：只有 compare_price
   的規格顯示，沒有的規格 build.py 已輸出 hidden，切規格由 assets/cart.js 切換。
   兩者跟價格數字同一行（inline），toggle hidden 不會讓這一列的高度跳動。
   white-space: nowrap（2026-09-15 主線親驗）：375 窄卡片排不下整行時，要嘛「單買
   NT$」跟數字一起被推到下一行，不能從中間斷開變成「單買 NT$」／「1200」兩截。 */
.menu-card__compare { font-family: var(--serif); font-size: 14px; letter-spacing: 0; color: var(--muted); text-decoration: line-through; margin-left: .3em; white-space: nowrap; }
.menu-card__save {
  display: inline-block; margin-left: .4em; padding: .1em .6em; border-radius: 999px;
  background: rgba(200, 114, 43, .08); border: 1px solid rgba(200, 114, 43, .3); font-family: var(--serif); font-size: 13px; letter-spacing: .02em;
  color: #9A4B12; vertical-align: middle; white-space: nowrap;
}
/* 月份方案的「每杯約 NT$」（S16）：只有 section=plan 的卡片會有這個元素，字級介於
   價格與 meta 之間，色用 --ink-2（佐證性質，不跟主價格搶視覺權重）。 */
.menu-card__percup { font-size: 15px; color: var(--ink-2); margin: 0 0 .3em; line-height: 1.3; }
.menu-card__note { font-size: 15px; color: var(--ink-2); margin: 0; }
/* 月份方案的說明收進 <details>（S16）：summary 用跟 FAQ 一致的可點樣式，
   放在卡片最下面、不影響上面價格／每杯單價／庫存的固定位置。 */
.menu-card__details { margin-top: .4em; }
.menu-card__details summary {
  cursor: pointer; font-size: 15px; letter-spacing: .04em; color: var(--ink-2);
  min-height: 44px; display: flex; align-items: center;
}
.menu-card__details summary:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.menu-card__details[open] summary { color: var(--ink); }
.menu-card__details .menu-card__note { margin-top: .3em; }
.order-note { text-align: center; font-size: 13px; letter-spacing: .06em; color: var(--muted); margin: 2.4em 0 0; }
.pill[data-todo]::after { content: "（準備中）"; font-size: 13px; letter-spacing: 0; opacity: .7; }

/* 規格切換（僅耳掛有）：pill 選項，選中為 ink 底 */
.variant { display: flex; flex-wrap: wrap; gap: .5em; margin: 0 0 .4em; }
.variant__opt {
  min-height: 44px; padding: 0 1.2em; border: 1px solid var(--line); border-radius: 999px;
  font-size: 16px; letter-spacing: .04em; background: transparent; color: var(--ink); cursor: pointer;
  transition: background-color .18s ease, color .18s ease, border-color .18s ease, transform .18s ease;
}
.variant__opt:hover { border-color: var(--ink); transform: translateY(-1px); }
.variant__opt[aria-checked="true"] { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.variant__opt:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.variant__opt:active { transform: translateY(0) scale(.98); }

/* 375 下規格按鈕改 2 欄格線（2026-09-15 主線親驗）：月份方案 3–4 顆規格原本靠
   flex-wrap 自然換行，但窄卡片（~242px）裝不下 2 顆「辦公室／50 包」這種較長標籤，
   會變成一顆一行、疊 3–4 行，卡片被撐高。改 grid 2 欄強制「兩顆一排」，不管文字
   多長都固定欄數，跟桌面版的視覺節奏一致；文字太長時按鈕會長高（allow wrap），
   仍保證 ≥44px，不強制單行截斷。 */
@media (max-width: 720px) {
  .menu-carousel .variant { display: grid; grid-template-columns: repeat(2, 1fr); gap: .5em; }
  .menu-carousel .variant__opt { padding: .3em .5em; font-size: 14px; text-align: center; white-space: normal; line-height: 1.3; }
}
/* S19（2026-09-24）：桌面也套 2 欄格線與不換行的購買列。
   單軌之後所有卡片同軌等高，最高那張決定全部——量到耳掛月份方案（4 顆長標籤規格）
   在桌面靠 flex-wrap 排成 4 行、佔 202px，而購買列因為 flex-wrap 也裂成兩行佔 122px，
   兩者把最矮的居家中焙卡撐出 500px 的空白。改成 2 欄後規格固定兩行、購買列固定一行，
   最高與最矮的差距大幅縮小。這兩條原本只寫在 720px 以下的媒體查詢裡，桌面沒有。 */
@media (min-width: 721px) {
  .menu-carousel .variant { display: grid; grid-template-columns: repeat(2, 1fr); gap: .5em; }
  .menu-carousel .variant__opt {
    padding: .3em .6em; font-size: 15px; text-align: center; white-space: normal; line-height: 1.3;
  }
  .menu-carousel .buy { flex-wrap: nowrap; gap: .6em; }
  .menu-carousel .qty__btn { width: 42px; height: 46px; }
  /* 按鈕的左右內距與 white-space 必須一起收（2026-09-24 親驗）：卡片在 800px 視窗下
     只有 280px 寬，數量控制佔掉 145px，剩給按鈕 79px 而預設左右內距各 30.6px，
     「加入購物車」被壓成直排、單這一列就 122px 高，反而比換行還糟。 */
  .menu-carousel .buy__add {
    flex: 1 1 auto; min-width: 0; min-height: 46px; padding: 0 1em;
    font-size: 16px; letter-spacing: .04em; justify-content: center; white-space: nowrap;
  }
}

/* 數量與加入購物車 */
/* margin-top: auto（在 flex column 的 .menu-card__body 裡）把「加入購物車」列推到卡片
   底部，同軌卡片內容長短不一時，按鈕仍對齊在同一條水平線（S16，2026-09-15）。 */
.buy { display: flex; align-items: center; gap: .8em; flex-wrap: wrap; margin-top: auto; padding-top: .4em; }
.qty { display: inline-flex; align-items: center; border: 1px solid var(--line); border-radius: 999px; overflow: hidden; }
.qty__btn {
  width: 48px; height: 48px; display: inline-flex; align-items: center; justify-content: center;
  font-size: 22px; background: transparent; border: none; color: var(--ink); cursor: pointer; font-family: var(--serif);
  transition: background-color .18s ease;
}
.qty__btn:hover { background: rgba(0, 0, 0, .06); }
.qty__btn:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.qty__val { min-width: 2.6em; text-align: center; font-family: var(--display); font-size: 18px; }
.buy__add {
  min-height: 52px; padding: 0 1.8em; border-radius: 999px; border: 1px solid var(--ink);
  background: var(--ink); color: var(--bg); font-size: 17px; letter-spacing: .08em; cursor: pointer;
  display: inline-flex; align-items: center; gap: .5em;
  transition: background-color .18s ease, transform .18s ease;
}
.buy__add:hover { background: #333; transform: translateY(-1px); }
.buy__add:active { transform: translateY(0); }
.buy__add:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.buy__add.is-added { background: #3a5a40; border-color: #3a5a40; }
@media (hover: none) { .variant__opt:hover, .buy__add:hover { transform: none; } }
/* 數量與加入購物車擠進同一行（2026-09-15 主線親驗）：375 窄卡片下，原本的 48px
   qty 按鈕＋2.6em 數字＋1.8em/17px 加入購物車鈕三者相加超過卡片可用寬度，
   flex-wrap 會把它們拆成兩行。這裡只在 .menu-carousel 縮小尺寸（仍 ≥44px 可點高度），
   讓兩者維持同一行；桌面版（更寬的卡片）不受影響，維持原尺寸。 */
@media (max-width: 720px) {
  .menu-carousel .buy { flex-wrap: nowrap; gap: .5em; }
  .menu-carousel .qty__btn { width: 40px; height: 44px; font-size: 20px; }
  .menu-carousel .qty__val { min-width: 1.6em; font-size: 16px; }
  .menu-carousel .buy__add {
    min-height: 44px; padding: 0 1em; font-size: 15px; letter-spacing: .04em;
    flex: 1 1 auto; justify-content: center; white-space: nowrap;
  }
}
/* 375 卡片高度目標（個人享用 ≤740px、月份方案 ≤812px，2026-09-15 主線指定）：
   縮圖片區與卡片內距的邊角空間、meta／flavor 字級再收一階。耳掛組合（唯一還維持
   1:1 圖的個人享用卡片，見上面 aspect-ratio 4/3 那條的排除清單）是個人享用裡最高
   的一張，月份方案的耳掛方案（4 規格＋最長的 meta／flavor）是月份方案裡最高的一張，
   這裡的收斂主要是為了壓這兩張。 */
@media (max-width: 720px) {
  .menu-carousel .menu-card__body { padding: 12px 14px 10px; }
  .menu-carousel .menu-card__meta,
  .menu-carousel .menu-card__flavor { font-size: 14px; line-height: 1.3; }
}
@media (prefers-reduced-motion: reduce) { .variant__opt, .qty__btn, .buy__add { transition: none; } }

/* 免運湊單提示（.ship-tip，S15 加、S16 2026-09-15 搬家）：S15 時掛在每張卡片的加入
   購物車按鈕下方；S16 起改成單一個、掛在 .cartbar-dock 裡、位置在 .cartbar 正上方
   （見 assets/cart.js 的共用 renderShipTipGap／renderShipTipReached），跨越視窗全寬、
   貼齊購物車列，不再是卡片內的圓角浮卡。
   沒有另定新色：暖色沿用庫存徽章「僅剩」的 #C8722B／#9A4B12（.stock--low），
   達標沿用「已加入」按鈕的 #3a5a40，各自以低透明度當底色。 */
.ship-tip {
  display: flex; flex-direction: column; gap: .5em;
  padding: .7em clamp(16px, 3vw, 32px); border-top: 1px solid rgba(200, 114, 43, .28);
  /* 毛玻璃（2026-09-24）：底色改半透明、暖色疊層鋪在上面，由 backdrop-filter 把背後的
     頁面糊掉。這同時修掉「已達免運」狀態的舊瑕疵——.ship-tip--reached 會整個覆蓋
     background，底色只剩 rgba(58,90,64,.08)，過去底下文字其實會透出來。
     不支援 backdrop-filter 的瀏覽器由本節末的 @supports 退回不透明實底。 */
  background: linear-gradient(rgba(200, 114, 43, .12), rgba(200, 114, 43, .12)), rgba(247, 247, 245, .66);
  -webkit-backdrop-filter: blur(14px) saturate(1.6);
  backdrop-filter: blur(14px) saturate(1.6);
  opacity: 0; transform: translateY(6px);
  transition: opacity .22s ease, transform .22s ease;
}
.ship-tip.is-visible { opacity: 1; transform: translateY(0); }
.ship-tip__row { display: flex; align-items: flex-start; gap: .6em; }
.ship-tip__icon { flex: 0 0 auto; width: 20px; height: 20px; margin-top: .1em; color: #9A4B12; }
.ship-tip__text { min-width: 0; }
.ship-tip__main { margin: 0; font-size: 15px; line-height: 1.5; color: var(--ink); }
.ship-tip__sub { margin: .25em 0 0; font-size: 13px; color: var(--ink-2); }
.ship-tip__track { height: 4px; border-radius: 999px; background: rgba(200, 114, 43, .16); overflow: hidden; }
.ship-tip__bar { width: 0; height: 100%; background: #C8722B; border-radius: 999px; transition: width .24s ease; }
.ship-tip--reached .ship-tip__track, .ship-tip--reached .ship-tip__sub { display: none; }
.ship-tip--reached { background: linear-gradient(rgba(58, 90, 64, .1), rgba(58, 90, 64, .1)), rgba(247, 247, 245, .66); border-color: rgba(58, 90, 64, .3); }
.ship-tip--reached .ship-tip__icon { color: #3a5a40; }
@media (prefers-reduced-motion: reduce) {
  .ship-tip, .ship-tip__bar { transition: none; }
}
/* 毛玻璃的回退：沒有 backdrop-filter 就沒有「糊掉背後」這件事，半透明底會讓底下的
   頁面文字直接透過來，提示反而讀不清楚——退回改版前的不透明實底。 */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .ship-tip { background: linear-gradient(rgba(200, 114, 43, .1), rgba(200, 114, 43, .1)), rgb(247, 247, 245); }
  .ship-tip--reached { background: linear-gradient(rgba(58, 90, 64, .1), rgba(58, 90, 64, .1)), rgb(247, 247, 245); }
  .cartbar { background: rgba(247, 247, 245, .96); }
}

/* ===== 文章頁 ===== */
.article { max-width: var(--read); margin: 0 auto; padding: clamp(48px, 7vw, 96px) var(--gutter) 0; }
.article__panel { padding: clamp(20px, 4vw, 48px); }
.article__meta { font-family: var(--display); font-size: 13px; letter-spacing: .1em; color: var(--muted); margin: 0 0 1em; }
.article__title { font-size: clamp(22px, 2.6vw, 30px); letter-spacing: .1em; line-height: 1.6; margin-bottom: 2em; }
.article__body { font-size: 18px; line-height: 2; }
.article__body img { margin: 2em 0; border-radius: 10px; overflow: hidden; }
.article__body h2, .article__body h3 { margin: 2.4em 0 .8em; font-size: 19px; letter-spacing: .1em; }
.article__source { margin-top: 3em; padding-top: 1.4em; border-top: 1px solid var(--line); font-size: 13px; color: var(--muted); }
.article__source a { border-bottom: 1px solid var(--line); }
.back-link { display: inline-flex; align-items: center; min-height: 44px; font-size: 13px; letter-spacing: .08em; color: var(--muted); }

/* ===== 頁尾：全幅照片壓字標 ===== */
.site-footer { position: relative; margin-top: clamp(72px, 11vw, 160px); color: #f2f2f0; min-height: 62vh; display: flex; align-items: flex-end; overflow: hidden; }
.site-footer__bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: brightness(.55); }
.site-footer__inner { position: relative; width: 100%; padding: 48px var(--gutter) 0; }
.site-footer__row { display: flex; flex-wrap: wrap; gap: 1em 2.4em; align-items: center; justify-content: space-between; font-size: 13px; letter-spacing: .08em; text-transform: uppercase; }
.site-footer__links { display: flex; gap: 1.8em; flex-wrap: wrap; }
.site-footer__links a { min-height: 44px; display: inline-flex; align-items: center; border-bottom: 1px solid transparent; }
.site-footer__links a:hover { border-bottom-color: currentColor; }
.site-footer__mark {
  font-family: var(--display); text-transform: uppercase; letter-spacing: .12em; line-height: .9;
  font-size: clamp(56px, 13vw, 200px); color: rgba(255, 255, 255, .28); margin: 40px 0 -.12em; white-space: nowrap;
}

.error-page { text-align: center; padding: 6em var(--gutter); }

/* ===== 無障礙與降級 ===== */
a:focus-visible, .pill:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
@media (hover: none) { .post-card:hover .post-card__cover img { transform: none; } }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition-duration: .001ms !important; animation-duration: .001ms !important; }
}

/* ===== 響應式 ===== */
@media (max-width: 1080px) {
  .site-nav .site-nav__ext { display: none; }
}
@media (max-width: 960px) {
  .post-grid { grid-template-columns: repeat(2, 1fr); }
  .split { grid-template-columns: 1fr; min-height: 0; }
  .split__media { aspect-ratio: 4 / 3; }
  .split__media img { position: static; height: 100%; }
}
@media (max-width: 720px) {
  .site-header__inner { height: 60px; gap: 12px; }
  .site-header__brand { font-size: 16px; letter-spacing: .2em; }
  .site-nav a { font-size: 13px; letter-spacing: .06em; }
  .site-header__cta .pill:not(.pill--fill) { display: none; }
  .pill { padding: 0 1em; font-size: 13px; }
  .hero { min-height: 0; padding-bottom: 24px; }
  .scroll-hint { display: none; }
  .post-grid { grid-template-columns: 1fr; gap: 32px; }
  .chapter__grid { grid-template-columns: 1fr; gap: 1em; }
  .strip__track img { height: 62vw; }
  .site-footer { min-height: 48vh; }
}

/* 手機頁首：收掉次要導覽，避免橫向溢出 */
.site-nav { min-width: 0; overflow: hidden; white-space: nowrap; }
@media (max-width: 720px) {
  .site-header__brand { letter-spacing: .14em; font-size: 15px; }
  .site-header__inner { padding: 0 16px; }
  .hero__logo { letter-spacing: .14em; }
  .site-footer__mark { font-size: clamp(40px, 12vw, 200px); letter-spacing: .08em; }
}

/* 高度改用 min(vh, 上限)：避免超高視窗（整頁截圖、桌機大螢幕）把開場拉成整片空白 */
.hero { min-height: min(calc(100vh - 72px), 880px); justify-items: stretch; }
.hero > div { max-width: 100%; text-align: center; }
.hero__figure { justify-self: center; }
.hero__tag { font-size: clamp(15px, 2.2vw, 26px); }
.hero__logo { font-size: clamp(34px, 8.6vw, 112px); }
.coffee-hero { min-height: min(calc(100vh - 72px), 820px); }
.split { min-height: min(80vh, 720px); }
.site-footer { min-height: min(62vh, 560px); }

/* 手機頁首再收：三件東西要塞進 390px */
@media (max-width: 720px) {
  .site-header__inner { gap: 10px; padding: 0 14px; }
  .site-header__brand { font-size: 14px; letter-spacing: .1em; }
  .site-nav { flex: 1 1 0; }
  .site-nav a { letter-spacing: .05em; }
  .pill--fill { padding: 0 .9em; font-size: 13px; letter-spacing: .04em; }
  .icon-btn { width: 40px; height: 40px; flex-basis: 40px; }
  .icon-btn .icon { width: 18px; height: 18px; }
  .site-header__cta { gap: .4em; }
}

@media (max-width: 720px) {
  .coffee-hero__display { font-size: clamp(26px, 6.6vw, 96px); letter-spacing: .1em; }
  .hero__logo { font-size: clamp(30px, 8vw, 112px); }
  .section__display { font-size: clamp(34px, 9vw, 86px); }
  .split__display { font-size: clamp(30px, 8vw, 72px); }
  .next__label { font-size: clamp(22px, 6vw, 56px); }
  .next__target { font-size: clamp(26px, 7vw, 80px); }
}

/* 開場區的 grid 欄寬鎖在容器內，避免子元素的 max-content 把欄撐寬 */
.hero { grid-template-columns: minmax(0, 1fr); }
.hero > * { min-width: 0; max-width: 100%; }
.hero__caption { width: auto; justify-self: stretch; }
.hero__tag, .hero__logo { overflow-wrap: anywhere; }

/* 首頁主視覺：四張個人照對應「書寫、歌唱、說故事、泡咖啡」（2026-09-11） */
.hero__quad {
  list-style: none; margin: 0; padding: 0; align-self: center; justify-self: center;
  width: min(1180px, 100%);
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(10px, 1.4vw, 20px);
}
.hero__quad figure { margin: 0; }
.hero__quad img { width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; display: block; }
.hero__quad figcaption {
  margin-top: .9em; font-size: 13px; letter-spacing: .24em; text-align: center;
}
.hero__quad .num { font-family: var(--display); font-size: 13px; letter-spacing: .12em; color: var(--muted); margin-right: .8em; }
@media (max-width: 720px) {
  .hero__quad { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 10px; }
  .hero__quad figcaption { margin-top: .6em; font-size: 13px; letter-spacing: .16em; }
}

/* ===== 頁首杯徽、文章分類索引（2026-09-11） ===== */
.site-header__mark { width: 30px; height: 30px; object-fit: contain; margin-right: .7em; }
.cat-nav {
  display: flex; flex-wrap: wrap; justify-content: center; gap: .4em 1.6em;
  margin: 0 auto clamp(36px, 4.4vw, 60px); padding: 0; font-size: 14px; letter-spacing: .12em;
}
.cat-nav a {
  min-height: 44px; display: inline-flex; align-items: center; gap: .1em;
  border-bottom: 1px solid transparent; transition: border-color .18s ease;
}
.cat-nav a:hover, .cat-nav a[aria-current="page"] { border-bottom-color: var(--ink); }
.cat-nav__num { font-family: var(--display); font-size: 13px; letter-spacing: .12em; color: var(--muted); margin-right: .6em; }
.cat-nav__count { font-family: var(--display); font-size: 13px; color: var(--muted); margin-left: .5em; }
.cat-head { padding-top: clamp(48px, 7vw, 104px); }
.cat-head__count { font-size: 13px; letter-spacing: .1em; color: var(--muted); margin: 1.2em 0 0; }
.article__cats { margin-left: 1.2em; }
.article__cat { border-bottom: 1px solid var(--line); margin-right: .9em; transition: border-color .18s ease; }
.article__cat:hover { border-bottom-color: var(--ink); }
@media (max-width: 720px) {
  .site-header__mark { width: 24px; height: 24px; margin-right: .5em; }
  .cat-nav { gap: 0 1.1em; font-size: 13px; }
}

/* ===== 大杯居頁：常見問題（2026-09-11；特色配圖區塊已於 2026-09-12 移除） ===== */
.faq__wrap { max-width: 860px; }
.faq__item { padding: 0 clamp(16px, 2vw, 24px); margin-bottom: 10px; }
.faq__item:last-child { margin-bottom: 0; }
.faq__item summary {
  min-height: 56px; display: flex; align-items: center; cursor: pointer; list-style: none;
  font-size: 16px; letter-spacing: .08em; padding: .6em 2em .6em 0; position: relative;
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary::after { content: "+"; position: absolute; right: .2em; font-family: var(--display); font-size: 20px; transition: transform .18s ease; }
.faq__item[open] summary::after { transform: rotate(45deg); }
.faq__item summary:focus-visible { outline: 1px solid var(--ink); outline-offset: 4px; }
.faq__item p { font-size: 15px; line-height: 2.1; color: var(--ink); margin: 0 0 1.4em; max-width: 40em; }
/* 第六輪（2026-09-11）：FAQ 答案支援小標、條列、粗體（build.py render_faq_answer）。
   粗體用 500：Noto Serif TC 只載入 400／500，寫 700 會變成瀏覽器假粗體。 */
.faq__item .faq__sub {
  font-size: 13px; font-weight: 500; letter-spacing: .2em; color: var(--muted);
  margin: 1.8em 0 .7em; padding-left: .9em; border-left: 2px solid var(--line); line-height: 1.4;
}
.faq__item .faq__sub:first-of-type { margin-top: .4em; }
.faq__item ul, .faq__item ol {
  font-size: 15px; line-height: 1.9; margin: 0 0 1.4em; padding-left: 1.5em; max-width: 40em;
}
.faq__item li + li { margin-top: .45em; }
.faq__item li::marker { color: var(--muted); }
.faq__item ol li::marker { font-family: var(--display); font-size: 14px; }
.faq__item strong { font-weight: 500; background: linear-gradient(transparent 64%, rgba(0, 0, 0, .07) 0); }
.article mark { color: inherit; font-weight: 500; background: linear-gradient(transparent 64%, rgba(0, 0, 0, .07) 0); }
.coffee-hero { min-height: auto; padding-bottom: clamp(40px, 6vh, 72px); }
@media (prefers-reduced-motion: reduce) { .faq__item summary::after { transition: none; } }

/* ===== 文章卡片封面比例：依 vocus 縮圖規格 1200×630（官方幫助中心，查證 2026-09-11），
   比例套在圖片本身、不含卡片內距，vocus 帶字封面才不會被裁 ===== */
.post-card__cover { aspect-ratio: auto; }
.post-card__cover img { aspect-ratio: 1200 / 630; height: auto; }
.post-card__cover--text > div { aspect-ratio: 1200 / 630; }
.post-card__cover--text p { -webkit-line-clamp: 3; }

/* ===== 首頁四格主視覺：分類入口（hover 浮起、照片微放大、標題底線展開＋箭頭；2026-09-11） ===== */
.hero__quad a { display: block; border-radius: 2px; transition: transform .18s ease; -webkit-tap-highlight-color: transparent; }
.hero__quad figure { overflow: hidden; border-radius: 10px; }
.hero__quad figure > img { transition: transform .6s ease, filter .6s ease; }
.hero__quad figcaption { position: relative; overflow: visible; }
.hero__quad .label { position: relative; padding-bottom: .35em; }
.hero__quad .label::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: var(--ink);
  transform: scaleX(0); transform-origin: left center; transition: transform .3s ease;
}
.hero__quad .arrow { display: inline-block; margin-left: .5em; opacity: 0; transform: translateX(-6px); transition: opacity .18s ease, transform .18s ease; }
.hero__quad a:hover { transform: translateY(-2px); }
.hero__quad a:hover figure > img { transform: scale(1.04); filter: saturate(1.06); }
.hero__quad a:hover .label::after, .hero__quad a:focus-visible .label::after { transform: scaleX(1); }
.hero__quad a:hover .arrow, .hero__quad a:focus-visible .arrow { opacity: 1; transform: translateX(0); }
.hero__quad a:active { transform: translateY(0) scale(.99); }
.hero__quad a:focus-visible { outline: 1px solid var(--ink); outline-offset: 6px; }
@media (hover: none) {
  .hero__quad a:hover { transform: none; }
  .hero__quad a:hover figure > img { transform: none; filter: none; }
  .hero__quad .arrow { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .hero__quad a, .hero__quad figure > img, .hero__quad .label::after, .hero__quad .arrow { transition: none; }
}

/* ===== S5 首頁五格主視覺：新增「寫生活」。桌機維持單列（5 欄等寬），
   避免兩列把 .hero 撐破原本的 viewport-fit min-height（見下方說明）；
   手機改 2+2+1（第五格獨自一列置中）（2026-09-11） =====
   桌機刻意不做 3+2 兩列：.hero 是 min-height:min(100vh-72px,880px) 的「一屏塞滿」設計，
   四格原本剛好一列撐滿可視高度；兩列會讓格子區塊的實際內容高度遠超過那個 min-height，
   而 min-height 對「比它高的內容」不會裁切，.hero 整段跟著長高快一倍，破壞開場一屏的設計初衷。
   單列五欄不改變列數，只是欄變窄，安全。 */
.hero__quad { grid-template-columns: repeat(5, minmax(0, 1fr)); }
/* 第六輪（2026-09-11）：手機由 2+2+1 改為五格同一列的橫向捲軸（scroll-snap），
   捲軸左右貼齊螢幕邊緣（抵銷 .hero 的 --gutter），每格 40vw，右側露出下一格當作「可以滑」的提示。 */
@media (max-width: 720px) {
  .hero__quad {
    display: flex; gap: 10px;
    justify-self: stretch; width: auto; max-width: none;
    margin: 0 calc(-1 * var(--gutter));
    padding: 0 var(--gutter) 4px; scroll-padding-inline: var(--gutter);
    overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
  }
  .hero__quad::-webkit-scrollbar { display: none; }
  .hero__quad li { flex: 0 0 40vw; scroll-snap-align: start; }
}

/* ===== S4 文章一覽條列：post-list／post-row，取代首頁／/blog/（301 到首頁）／分類頁的
   post-grid 卡片牆。左封面縮圖、右標題（主）／摘要（次）／日期分類（註腳），整列可點（2026-09-11）
   2026-09-11 第四輪：改為毛玻璃卡片（見下方 .glass），移除框線改用列間距＋圓角 ===== */
.post-list { list-style: none; padding: 0; margin: 0; }
.post-row {
  display: flex; align-items: flex-start; gap: clamp(20px, 3vw, 32px);
  padding: clamp(16px, 2.2vw, 22px);
  margin-bottom: clamp(12px, 1.6vw, 16px);
  transition: background-color .18s ease;
}
.post-list li:last-child .post-row { margin-bottom: 0; }
/* 縮圖一律 4:5 直式（2026-09-18 手機、2026-09-19 桌機 Vic 拍板）。桌機寬 176px（高 220px，約等於
   標題兩行＋摘要三行＋日期的文字欄高），原本的 240px 換成 4:5 會高達 300px、把每列撐高一截。
   橫圖（build.py 判寬大於高）不裁切：寬度撐滿、整張顯示，上下襯同一張圖放大模糊的毛玻璃底，色系跟著照片走 */
.post-row__cover {
  flex: 0 0 176px; width: 176px; aspect-ratio: 4 / 5; background: var(--card); overflow: hidden; border-radius: 10px;
}
.post-row__cover img { width: 100%; height: 100%; object-fit: cover; transition: filter .18s ease; border-radius: 10px; }
.post-row__cover--landscape { position: relative; }
.post-row__cover--landscape img { position: relative; z-index: 2; object-fit: contain; border-radius: 0; }
.post-row__cover--landscape img.post-row__cover-bg {
  position: absolute; inset: 0; z-index: 0; object-fit: cover;
  filter: blur(12px) saturate(1.1); transform: scale(1.4);
}
.post-row__cover--landscape::after { content: ""; position: absolute; inset: 0; z-index: 1; background: rgba(255, 255, 255, .2); }
.post-row:hover .post-row__cover img.post-row__cover-bg { filter: blur(12px) saturate(1.1); }
.post-row__cover--text { display: flex; }
.post-row__cover--text > div {
  flex: 1; display: flex; align-items: center; justify-content: center;
  padding: clamp(10px, 1.4vw, 18px); border: 1px solid var(--line); overflow: hidden;
}
.post-row__cover--text p {
  margin: 0; text-align: center; font-family: var(--serif); font-size: clamp(13px, 1vw, 14px);
  line-height: 1.7; letter-spacing: .06em; color: var(--muted);
  overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  transition: color .18s ease;
}
.post-row__body { flex: 1; min-width: 0; }
.post-row__title {
  font-size: clamp(19px, 2vw, 24px); line-height: 1.5; letter-spacing: .04em; margin: 0 0 .5em;
  text-decoration-line: underline; text-decoration-color: transparent; text-underline-offset: .28em;
  transition: text-decoration-color .18s ease;
}
.post-row__excerpt {
  font-size: 15px; line-height: 1.9; color: var(--ink); margin: 0 0 1em;
  overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
}
.post-row__meta { font-size: 13px; letter-spacing: .06em; color: var(--muted); margin: 0; }
.post-row:hover .post-row__title, .post-row:focus-visible .post-row__title { text-decoration-color: var(--ink); }
.post-row:hover .post-row__cover img { filter: brightness(1.04); }
.post-row:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }
@media (hover: none) {
  .post-row:hover .post-row__title { text-decoration-color: transparent; }
  .post-row:hover .post-row__cover img { filter: none; }
}
@media (prefers-reduced-motion: reduce) {
  .post-row, .post-row__cover img, .post-row__title, .post-row__cover--text p { transition: none; }
}
@media (max-width: 720px) {
  .post-row { gap: 14px; padding: 14px; }
  .post-row__cover { flex-basis: 112px; width: 112px; }
  .post-row__cover--text > div { padding: 8px; }
  .post-row__cover--text p { font-size: 13px; -webkit-line-clamp: 2; }
  .post-row__title { font-size: 17px; margin-bottom: .35em; }
  .post-row__excerpt { font-size: 13px; -webkit-line-clamp: 2; margin-bottom: .6em; }
}

/* ===== S3 照片牆輪播（gallery 排版模式）：橫向捲動＋scroll-snap，拖移見 assets/bloom.js
   （2026-09-11） ===== */
.gallery { position: relative; margin: 2em calc(50% - 50vw) 2.4em; padding: 0 var(--gutter); }
.gallery__track {
  display: flex; gap: 10px; overflow-x: auto; scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch; scrollbar-width: none; cursor: grab; padding-bottom: 4px;
}
.gallery__track::-webkit-scrollbar { display: none; }
.gallery__track.is-dragging { cursor: grabbing; scroll-snap-type: none; }
/* 軌道自己關掉平滑捲動（S19，2026-09-24）：html 有全站的 scroll-behavior: smooth，
   而拖移是逐幀直接設 track.scrollLeft——每次賦值都被當成一次平滑動畫，前一幀還沒
   跑完就被下一幀蓋掉，手感變得黏滯又抖動；同時 smooth 與 scroll-snap 本身就會互搶
   終點（Mozilla #1643217、WebKit #160622／#169800）。橫向輪播的平滑感一律交給
   CSS 的 scroll-snap 負責，JS 只設落點。 */
.gallery__track { scroll-behavior: auto; }
/* scroll-snap-stop: always（MDN 與 Chrome 團隊對單卡輪播的建議）：快速滑動時一張一張
   停，不會被慣性帶著跳過中間幾張。 */
.gallery__item { margin: 0; flex: 0 0 auto; scroll-snap-align: start; scroll-snap-stop: always; }
.gallery__item img {
  height: 420px; width: auto; max-width: 82vw; object-fit: cover; display: block;
  margin: 0; pointer-events: none; border-radius: 0;
}
.gallery__nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--line);
  background: rgba(236, 236, 234, .88); color: var(--ink);
  display: flex; align-items: center; justify-content: center; font-size: 20px; line-height: 1;
  cursor: pointer; z-index: 2; transition: background-color .18s ease, color .18s ease;
}
.gallery__nav:hover { background: var(--ink); color: var(--bg); }
/* 到頭尾停用（2026-09-15）：淡出＋不可點，與 hover 態明顯不同；:disabled 原生就會
   移出 tab 順序，aria-disabled 由 assets/bloom.js 一起補上（雙保險，不同 AT 版本
   對兩者支援度不一）。 */
.gallery__nav:disabled { opacity: .3; cursor: default; background: rgba(236, 236, 234, .88); color: var(--ink); }
.gallery__nav:disabled:hover { background: rgba(236, 236, 234, .88); color: var(--ink); }
.gallery__nav--prev { left: calc(var(--gutter) - 4px); }
.gallery__nav--next { right: calc(var(--gutter) - 4px); }
.gallery:focus-visible, .gallery__nav:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
@media (max-width: 720px) {
  .gallery__item img { height: 60vh; max-height: 360px; }
  .gallery__nav { width: 40px; height: 40px; font-size: 17px; }
  /* .menu-carousel（訂購區輪播）維持 44px 可點下限，不跟著照片牆縮到 40px（S16）。 */
  .menu-carousel .gallery__nav { width: 44px; height: 44px; }
}
@media (prefers-reduced-motion: reduce) {
  .gallery__track { scroll-behavior: auto; }
  .gallery__nav { transition: none; }
}

/* 輪播位置指示「2／5」（S16，2026-09-15）：只有訂購區的兩條輪播會渲染這個元素
   （coffee_render.py），文字內容由 assets/bloom.js 在捲動時更新。 */
.gallery__status {
  text-align: center; font-family: var(--display); font-size: 13px; letter-spacing: .1em;
  color: var(--muted); margin: .6em 0 0;
}

/* ===== S7 毛玻璃卡片（.glass）：桌機用 backdrop-filter，手機／觸控／不支援時降級為不透明淺底
   （2026-09-11）。套用對象：a.post-row、.chapter__body、details.faq__item、
   .split__body、.menu-card__body（清單卡片）；div.article__panel 額外帶 .glass--static
   （hover 只提亮邊框、不位移）。 ===== */
.glass {
  border-radius: 22px;
  background: rgba(247, 247, 245, .88);
  border: 1px solid var(--line);
}
@media (hover: hover) and (pointer: fine) and (min-width: 721px) {
  @supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .glass {
      background: rgba(247, 247, 245, .56);
      backdrop-filter: blur(12px) saturate(1.08);
      -webkit-backdrop-filter: blur(12px) saturate(1.08);
      border: 1px solid rgba(255, 255, 255, .55);
      box-shadow: 0 8px 20px rgba(40, 40, 36, .05);
      transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
    }
    .glass:hover {
      transform: translateY(-2px);
      border-color: rgba(255, 255, 255, .9);
      box-shadow: 0 10px 26px rgba(40, 40, 36, .08);
    }
    .glass--static:hover { transform: none; border-color: rgba(255, 255, 255, .9); }
  }
}
@media (prefers-reduced-motion: reduce) { .glass { transition: none; } }

/* ===== S8 分頁（.pager）與清單尾端「看更多」（.list-more）（2026-09-11） ===== */
.pager { display: flex; align-items: center; justify-content: center; gap: .6em; flex-wrap: wrap; margin: clamp(40px, 5vw, 72px) 0 0; }
.pager__prev, .pager__next {
  min-height: 44px; padding: 0 1.3em; display: inline-flex; align-items: center;
  border: 1px solid var(--ink); border-radius: 999px; font-size: 13px; letter-spacing: .06em;
  transition: background-color .18s ease, color .18s ease;
}
.pager__prev:hover, .pager__next:hover { background: var(--ink); color: var(--bg); }
.pager__pages { list-style: none; display: flex; gap: .4em; margin: 0; padding: 0; }
/* 頁碼多於一列時換行（2026-09-15）：原本不換行，12 頁在 600px 以下置中往兩側溢出，手機上前幾頁的鈕跑到畫面左外側、捲不到 */
.pager__pages { flex-wrap: wrap; justify-content: center; max-width: 100%; }
.pager__pages li { display: contents; }
.pager__pages a {
  min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 6px; font-family: var(--display); font-size: 13px;
  transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}
.pager__pages a:hover { border-color: var(--ink); }
.pager__pages a[aria-current="page"] { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.pager a:focus-visible, .pager__pages a:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.list-more { text-align: center; margin: clamp(32px, 4vw, 56px) 0 0; }
@media (prefers-reduced-motion: reduce) { .pager__prev, .pager__next, .pager__pages a { transition: none; } }

/* ===== S9 購物車（.cartbar／.cart-drawer）：由 assets/cart.js 建立 DOM，
   樣式在此預先備妥（2026-09-11）。固定於視窗底部，考慮 iOS safe-area。
   S16（2026-09-15）：.cartbar 本身不再自己 fixed，改由外層 .cartbar-dock 固定，
   .ship-tip 與 .cartbar 依文件流疊在 dock 裡（提示永遠在購物車列正上方，
   不會互相蓋住——這正是舊版「按鈕在畫面最底時提示被 cartbar 蓋住」的解法）。 ===== */
.cartbar-dock {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: flex; flex-direction: column;
}
.cartbar {
  display: flex; align-items: center; justify-content: space-between; gap: 1em;
  padding: 12px clamp(16px, 3vw, 32px) calc(12px + env(safe-area-inset-bottom, 0px));
  /* 與 .ship-tip 同一種材質（2026-09-24）：兩條緊貼在同一個 dock 裡，只有一條是毛玻璃
     會看得出接縫。 */
  background: rgba(247, 247, 245, .72); border-top: 1px solid var(--line);
  -webkit-backdrop-filter: blur(14px) saturate(1.6);
  backdrop-filter: blur(14px) saturate(1.6);
  font-size: 16px; letter-spacing: .04em;
  transform: translateY(0); transition: transform .24s ease;
}
.cartbar[hidden] { display: none; }
.cartbar__info { display: flex; align-items: baseline; gap: .8em; min-width: 0; }
.cartbar__count { font-family: var(--display); font-size: 16px; color: var(--ink-2); }
.cartbar__total { font-size: 20px; font-weight: 400; }
.cartbar__open {
  min-height: 52px; padding: 0 1.6em; border-radius: 999px; border: 1px solid var(--ink);
  background: var(--ink); color: var(--bg); font-size: 17px; letter-spacing: .06em; cursor: pointer;
  transition: background-color .18s ease;
}
.cartbar__open:hover { background: #333; }
.cartbar__open:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

.cart-drawer { position: fixed; inset: 0; z-index: 50; display: flex; justify-content: flex-end; }
.cart-drawer[hidden] { display: none; }
.cart-drawer__backdrop { position: absolute; inset: 0; background: rgba(17, 17, 17, .32); }
.cart-drawer__panel {
  position: relative; width: min(420px, 100%); height: 100%; background: var(--bg);
  display: flex; flex-direction: column; padding: clamp(20px, 3vw, 32px);
  padding-bottom: calc(clamp(20px, 3vw, 32px) + env(safe-area-inset-bottom, 0px));
  overflow-y: auto;
}
.cart-drawer__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1.2em; }
.cart-drawer__title { font-family: var(--display); font-size: 22px; letter-spacing: .1em; }
.cart-drawer__close {
  width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--line);
  display: inline-flex; align-items: center; justify-content: center; font-size: 18px; cursor: pointer;
  transition: border-color .18s ease, background-color .18s ease;
}
.cart-drawer__close:hover { border-color: var(--ink); background: rgba(0, 0, 0, .04); }
.cart-drawer__close:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.cart-drawer__list { list-style: none; margin: 0 0 1.2em; padding: 0; flex: 1; }
.cart-row { display: flex; align-items: center; gap: .8em; padding: .9em 0; border-bottom: 1px solid var(--line); }
.cart-row__name { flex: 1; min-width: 0; font-size: 17px; line-height: 1.6; }
.cart-row__price { font-size: 15px; color: var(--ink-2); }
.cart-row__remove {
  width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--line); background: transparent;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer; color: var(--muted);
  transition: border-color .18s ease, color .18s ease;
}
.cart-row__remove:hover { border-color: var(--ink); color: var(--ink); }
.cart-drawer__progress { margin: 0 0 1.2em; }
.cart-drawer__progress-label { font-size: 15px; color: var(--ink-2); margin: 0 0 .5em; }
.cart-drawer__progress-track { height: 6px; border-radius: 999px; background: var(--line); overflow: hidden; }
.cart-drawer__progress-bar { width: 0; height: 100%; background: var(--ink); border-radius: 999px; transition: width .24s ease; }
.cart-drawer__totals { font-size: 17px; line-height: 2; color: var(--ink-2); margin-bottom: .6em; }
.cart-drawer__totals strong { color: var(--ink); font-weight: 400; font-size: 22px; }
/* ===== S19（2026-09-23）購物車視覺權重與差額免運加購位 =====
   權重原則（見 canonical 的「網頁設計先問視覺權重」）：主角是「應付總額、免運進度、
   送出鈕」，佐證（運費怎麼算、到貨時程、次要找法）一律降成註腳字級與次要色。
   色票沿用既有 tokens，不新增顏色。 */

/* 免運進度：從 6px 細線提到 8px，標籤加粗一階——這是購物車裡唯一會「動」的數字，
   也是加購決策的依據。分母是真正可達成的量（門檻本身），不做永遠到不了 100% 的假進度。 */
.cart-drawer__progress { margin: 0 0 1em; }
.cart-drawer__progress-label { font-size: 15.5px; color: var(--ink); margin: 0 0 .5em; letter-spacing: .02em; }
.cart-drawer__progress-track { height: 8px; }

/* 差額免運加購位：卡片式一格，圖片 56px、品名一行、補差說明降一階、按鈕 44px 可點。
   達標後整格 hidden（.cart-drawer [hidden] 的 display:none !important 蓋得到這裡的
   display:flex，見上方共用規則）。 */
.cart-upsell {
  display: flex; align-items: center; gap: .8em;
  margin: 0 0 1.2em; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--card);
}
.cart-upsell__img { width: 56px; height: 56px; border-radius: 10px; object-fit: cover; flex: 0 0 auto; }
.cart-upsell__body { flex: 1; min-width: 0; }
.cart-upsell__name { font-size: 15.5px; color: var(--ink); margin: 0; line-height: 1.35; }
.cart-upsell__hint { font-size: 13px; color: var(--muted); margin: .2em 0 0; line-height: 1.4; }
.cart-upsell__add {
  flex: 0 0 auto; min-height: 44px; padding: 0 1.1em;
  border: 1px solid var(--ink); border-radius: 999px; background: none; color: var(--ink);
  font-family: inherit; font-size: 14px; letter-spacing: .06em; cursor: pointer;
  transition: background-color .18s ease, color .18s ease;
}
.cart-upsell__add:hover { background: var(--ink); color: var(--bg); }
.cart-upsell__add:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* 收合式次要區塊（優惠碼、改用縣市找）：summary 是可點的一行，不是標題也不搶權重。
   min-height 44px 是觸控目標下限（Apple HIG 44pt／Material 48dp）。 */
.checkout__promo-toggle,
.checkout__store-more > summary {
  display: flex; align-items: center; min-height: 44px;
  font-size: 14.5px; color: var(--ink-2); cursor: pointer; letter-spacing: .02em;
}
.checkout__promo-toggle:focus-visible,
.checkout__store-more > summary:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.checkout__promo[open] .checkout__promo-toggle,
.checkout__store-more[open] > summary { margin-bottom: .6em; }
.checkout__store-more { margin-top: .4em; }

/* 佐證降為註腳：到貨時程與運費說明不與金額爭視覺。總計本身再放大一階，
   它是使用者按下送出前唯一要確認的數字。 */
.cart-drawer__eta { font-size: 13px; color: var(--muted); }
.cart-drawer__totals { font-size: 15px; line-height: 1.85; color: var(--muted); margin-bottom: .8em; }
.cart-drawer__totals strong { color: var(--ink); font-weight: 400; font-size: 24px; letter-spacing: .04em; }

@media (prefers-reduced-motion: reduce) {
  .cart-upsell__add { transition: none; }
}
.cart-drawer__submit {
  min-height: 56px; width: 100%; border-radius: 999px; border: 1px solid var(--ink);
  background: var(--ink); color: var(--bg); font-size: 19px; letter-spacing: .08em; cursor: pointer;
  transition: background-color .18s ease;
}
/* 市集現場限時訂購鈕（S19，2026-09-16）：只有場次 order_window 之內才出現，
   與一般送出鈕並排、以深墨底區分，避免客人在家也按到現場限定的加贈。 */
.cart-drawer__submit--onsite { margin-top: 8px; background: #46463F; }
.cart-drawer__submit--onsite:hover { background: #2F2F2A; }
.cart-drawer__submit--onsite[hidden] { display: none; }

.cart-drawer__submit:hover { background: #333; }
.cart-drawer__submit:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.cart-drawer__hint { font-size: 14px; color: var(--ink-2); text-align: center; margin: .8em 0 0; }
.cartbar__count { display: inline-block; transform-origin: center; }
@media (prefers-reduced-motion: reduce) {
  .cartbar, .cartbar__open, .cart-drawer__close, .cart-drawer__progress-bar, .cart-drawer__submit { transition: none; }
}

/* 手機頁首改兩列（第四輪）：品牌＋三顆社群鈕一列、導覽一列。
   一列塞不下三件東西，先前的做法把「大杯居」導覽裁掉了；社群鈕維持 44px 可點下限。 */
@media (max-width: 720px) {
  .site-header__inner { height: auto; flex-wrap: wrap; row-gap: 0; padding: 6px 14px 0; }
  .site-header__brand { order: 1; flex: 1 1 auto; min-height: 44px; }
  .site-header__cta { order: 2; gap: 6px; }
  .site-nav { order: 3; flex: 1 0 100%; justify-content: center; overflow: visible; }
  .site-nav a { min-height: 44px; display: inline-flex; align-items: center; }
  .icon-btn { width: 44px; height: 44px; flex-basis: 44px; }
}

/* ===== S9 第五輪（2026-09-11）：首頁五格加重、右上角 Line@訂購膠囊 ===== */
/* 五格是首頁的鉤子：圖放大約 25%、標題 13→22px、編號改到標題上方；主標略收，讓 1440×900 首屏容得下完整五格 */
@media (min-width: 721px) {
  .hero__logo { font-size: clamp(34px, 7.2vw, 100px); margin-bottom: clamp(20px, 4vh, 44px); }
  .hero__quad { width: min(1360px, 100%); gap: clamp(12px, 1.6vw, 24px); }
  .hero__quad figcaption { margin-top: 1.1em; font-size: clamp(18px, 1.55vw, 22px); letter-spacing: .22em; }
  .hero__quad .num { display: block; margin: 0 0 .4em; font-size: 15px; letter-spacing: .16em; }
}
@media (max-width: 720px) {
  .hero__quad figcaption { margin-top: .7em; font-size: 17px; letter-spacing: .16em; }
  .hero__quad .num { display: block; margin: 0 0 .2em; font-size: 13px; }
}
/* 箭頭改成零寬、字形往右溢出，標題才會真正置中（原本透明箭頭仍佔寬，把標題推偏） */
.hero__quad .arrow { width: 0; margin-left: 0; white-space: nowrap; transform: translateX(.1em); }
.hero__quad a:hover .arrow, .hero__quad a:focus-visible .arrow { transform: translateX(.45em); }
@media (hover: none) { .hero__quad .arrow { transform: translateX(.45em); } }

/* Line@訂購：墨色實心膠囊，權重高於 FB／IG 圓鈕；外圈一層柔光做 4 秒一次的呼吸。
   2026-09-16：原本是會放大的細環，在擁擠版型會蓋到隔壁元素。改成 box-shadow 柔光，
   只動 opacity，不動 scale／inset，佔位與視覺尺寸全程不變。 */
.line-cta {
  position: relative; display: inline-flex; align-items: center; gap: .45em;
  min-height: 44px; padding: 0 1.15em 0 .95em; margin-left: 6px; border-radius: 999px;
  background: var(--ink); color: #fff; font-size: 14px; letter-spacing: .06em; white-space: nowrap;
  transition: background-color .18s ease;
}
.line-cta .icon { width: 20px; height: 20px; fill: currentColor; display: block; flex: 0 0 auto; }
.line-cta::after {
  content: ""; position: absolute; inset: -5px; border-radius: inherit; pointer-events: none;
  box-shadow: 0 0 8px 2px rgba(17, 17, 17, .3);
  animation: line-breathe 4s ease-in-out infinite;
}
@keyframes line-breathe {
  0%, 100% { opacity: .12; }
  50%      { opacity: .5; }
}
.line-cta:hover { background: #06C755; }
.line-cta:hover::after { box-shadow: 0 0 9px 2px rgba(6, 199, 85, .45); }
.line-cta:active { background: #05A948; }
.line-cta:focus-visible { outline: 2px solid var(--ink); outline-offset: 8px; }
@media (max-width: 720px) {
  .line-cta { font-size: 13px; padding: 0 .9em 0 .75em; margin-left: 4px; }
  .line-cta .icon { width: 18px; height: 18px; }
}
@media (max-width: 480px) { .site-header__en { display: none; } }
@media (prefers-reduced-motion: reduce) { .line-cta::after { animation: none; opacity: .35; } }

/* 內文連結：全站 a 預設無底線，正文、沿革、QA 裡的連結會跟一般文字無法分辨（第五輪補） */
.chapter__body p a, .faq__item p a, .article__body p a {
  border-bottom: 1px solid currentColor; padding-bottom: 1px;
  transition: color .18s ease, border-color .18s ease;
}
.chapter__body p a:hover, .faq__item p a:hover, .article__body p a:hover { color: var(--muted); }
/* 首頁／文章頁共用的頁尾照（海邊手碟）：人物在畫面上方，取景下移，頭部才不會貼齊頁尾上緣 */
.site-footer__bg[src$="/footer-bg.jpg"] { object-position: 50% 22%; }

/* === 結帳表單（2026-09-12）===
   購物車抽屜內、總額下方、送出鈕上方的三段結帳表單（取件門市／收件資料／付款）。
   只用既有 :root tokens，外觀與既有抽屜一致（細線、圓角、無高對比浮空）。 */
.checkout { margin: 0 0 1.4em; display: flex; flex-direction: column; gap: 1.6em; }
.checkout__section { border-top: 1px solid var(--line); padding-top: 1.2em; }
.checkout__h { font-family: var(--display); font-size: 17px; letter-spacing: .1em; color: var(--ink); margin: 0 0 .9em; }

.checkout__geo-btn {
  min-height: 44px; padding: 0 1.2em; border-radius: 999px; border: 1px solid var(--line);
  background: transparent; color: var(--ink); font-size: 16px; letter-spacing: .04em; cursor: pointer;
  transition: border-color .18s ease, background-color .18s ease;
}
.checkout__geo-btn:hover { border-color: var(--ink); background: rgba(0, 0, 0, .04); }
.checkout__geo-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.checkout__geo-status { font-size: 15px; color: var(--ink-2); margin: .6em 0 0; min-height: 1.4em; }
.checkout__store-loading { font-size: 15px; color: var(--ink-2); margin: .6em 0 0; }
.checkout__store-fail { font-size: 15px; color: var(--ink-2); line-height: 1.8; margin: .6em 0 0; }
.checkout__store-fail a { border-bottom: 1px solid currentColor; }

.checkout__store-list { list-style: none; margin: .8em 0 0; padding: 0; display: flex; flex-direction: column; gap: .5em; max-height: 240px; overflow-y: auto; }
.checkout__store-list[hidden] { display: none; }
.checkout__store-btn {
  width: 100%; min-height: 44px; padding: .6em .9em; border: 1px solid var(--line); border-radius: 10px;
  background: var(--card); color: var(--ink); text-align: left; cursor: pointer;
  display: flex; flex-direction: column; gap: .2em;
  transition: border-color .18s ease, background-color .18s ease;
}
.checkout__store-btn:hover { border-color: var(--ink); }
.checkout__store-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.checkout__store-btn-name { font-size: 17px; }
.checkout__store-btn-addr { font-size: 14px; color: var(--ink-2); }

.checkout__row { display: flex; gap: .6em; margin-top: .9em; }
.checkout__city, .checkout__town {
  flex: 1; min-width: 0; min-height: 44px; padding: 0 .8em; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg); color: var(--ink); font-family: var(--serif); font-size: 17px;
}
.checkout__town:disabled { color: var(--muted); }
.checkout__store-search {
  width: 100%; min-height: 44px; padding: 0 .9em; margin-top: .9em; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg); color: var(--ink); font-family: var(--serif); font-size: 14px;
}
.checkout__store-manual {
  width: 100%; min-height: 44px; padding: 0 .9em; margin-top: .9em; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg); color: var(--ink); font-family: var(--serif); font-size: 14px;
}
.checkout__store-search:focus-visible, .checkout__store-manual:focus-visible,
.checkout__city:focus-visible, .checkout__town:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.checkout__store-selected {
  margin-top: .9em; padding: .9em 1em; border: 1px solid var(--line); border-radius: 10px;
  background: var(--card); display: flex; align-items: center; justify-content: space-between; gap: .8em;
}
/* 元件自己宣告了 display 時，HTML 的 hidden 屬性（UA 的 [hidden]{display:none}）會被蓋過去，
   症狀是「JS 明明設了 el.hidden = true，畫面上東西還在」。2026-09-12 就踩到：還沒選門市時
   .checkout__store-selected 照樣畫出一個 77px 的空白灰框加一顆「更換」鈕。
   下面這條把購物車與結帳區內所有帶 hidden 的元件一次收乾淨，避免同一個坑再犯。 */
.cartbar[hidden], .cart-drawer[hidden], .cart-drawer [hidden], .ship-tip[hidden], .gallery__nav[hidden] { display: none !important; }
/* 同一個坑：menu-card__compare／__save／__percup 也靠 hidden 屬性切換，一併收進來，
   不必逐一補 [hidden] 規則。.ship-tip（S16 起搬到 .cartbar-dock，不再是 .menu-card 的
   子元素）自己宣告 display: flex，已併進上面那條。 */
.menu-card [hidden] { display: none !important; }
.checkout__store-selected-label { margin: 0; font-size: 17px; line-height: 1.6; }
.checkout__store-change {
  flex: 0 0 auto; min-height: 44px; padding: 0 1em; border-radius: 999px; border: 1px solid var(--ink);
  background: transparent; color: var(--ink); font-size: 16px; cursor: pointer;
  transition: background-color .18s ease, color .18s ease;
}
.checkout__store-change:hover { background: var(--ink); color: var(--bg); }
.checkout__store-change:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

.checkout__error { color: #B3261E; font-size: 15px; font-weight: 500; margin: .5em 0 0; }
.checkout__reused {
  font-size: 15px; line-height: 1.7; color: #9A4B12; margin: .5em 0 0;
  padding: .5em .7em; border-radius: 8px; background: rgba(200, 114, 43, .14);
}
.checkout__error[hidden] { display: none; }

.checkout__field { display: block; margin-top: 1.1em; }
.checkout__field:first-child { margin-top: 0; }
.checkout__field > span { display: block; font-size: 16px; color: var(--ink); margin-bottom: .4em; }
.checkout__field input[type="text"], .checkout__field input[type="tel"] {
  width: 100%; min-height: 52px; padding: 0 .9em; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg); color: var(--ink); font-family: var(--serif); font-size: 18px;
}
.checkout__field input:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.checkout__field input[aria-invalid="true"] { border-color: #B3261E; }
.checkout__field small { display: block; margin-top: .4em; font-size: 14px; color: var(--ink-2); }

.checkout__check {
  display: flex; align-items: center; gap: .7em; min-height: 48px; margin-top: .8em;
  font-size: 16px; color: var(--ink); cursor: pointer;
}
.checkout__check input { width: 24px; height: 24px; flex: 0 0 auto; }

/* === 優惠碼／攤位取貨（2026-09-17）===
   沿用既有 checkout__field／checkout__error 的顏色 token，不新增配色：
   --bad 借既有錯誤紅（#B3261E，見 .checkout__error），--gift 借既有提醒橘
   （見 .checkout__reused），中性訊息用 --ink-2。 */
.checkout__promo-msg { font-size: 15px; line-height: 1.7; margin: .6em 0 0; color: var(--ink-2); }
.checkout__promo-msg[hidden] { display: none; }
.checkout__promo-msg--bad { color: #B3261E; font-weight: 500; }
.checkout__promo-msg--gift {
  color: #9A4B12; background: rgba(200, 114, 43, .14); padding: .5em .7em; border-radius: 8px;
}
.checkout__promo-combos { margin: .4em 0 0; padding-left: 1.2em; }
.checkout__promo-combos li { margin-top: .3em; }

.checkout__pickup-toggle { display: flex; flex-direction: column; gap: .2em; margin: 0 0 1em; }
.checkout__pickup-toggle[hidden] { display: none; }
.checkout__radio {
  display: flex; align-items: center; gap: .7em; min-height: 44px;
  font-size: 16px; color: var(--ink); cursor: pointer;
}
.checkout__radio input { width: 24px; height: 24px; flex: 0 0 auto; }
.checkout__radio input:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.checkout__pay-total { font-size: 17px; color: var(--ink-2); margin: 0 0 1em; }
.checkout__pay-total-amt { font-size: 26px; font-weight: 400; color: var(--ink); }
/* --- 付款：帳號是主角（長輩多數手動輸入轉帳，不是掃碼），QR 降為備選 --- */
.checkout__account {
  margin: 0 0 1.4em; padding: 1.1em 1.2em; border: 1px solid var(--line); border-radius: 14px;
  background: var(--card); text-align: center;
}
.checkout__account[hidden] { display: none; }
.checkout__account-label { font-size: 18px; color: var(--ink); margin: 0 0 .3em; }
.checkout__account-label[hidden] { display: none; }
.checkout__account-num {
  font-family: var(--display); font-size: clamp(26px, 7.4vw, 32px); line-height: 1.25;
  letter-spacing: .06em; color: var(--ink); margin: 0 0 .3em;
  /* 數字每四碼一組（cart.js 插空白），長數字在窄螢幕要能折行才不會撐破卡片 */
  overflow-wrap: anywhere;
}
.checkout__account-name { font-size: 17px; color: var(--ink-2); margin: 0 0 .9em; }
.checkout__account-name[hidden] { display: none; }
.checkout__copy {
  min-height: 52px; padding: 0 1.8em; border-radius: 999px; border: 1px solid var(--ink);
  background: var(--ink); color: var(--bg); font-size: 18px; letter-spacing: .06em; cursor: pointer;
  transition: background-color .18s ease, transform .18s ease;
}
.checkout__copy:hover { background: #333; transform: translateY(-1px); }
.checkout__copy:active { transform: translateY(0) scale(.98); }
.checkout__copy:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.checkout__pay-hint { font-size: 15px; color: var(--ink-2); margin: .9em 0 0; line-height: 1.7; }

/* --- 付款：QR（備選，視覺份量刻意低一階） --- */
.checkout__qr { margin: 0 0 1.2em; text-align: center; }
.checkout__qr[hidden] { display: none; }
.checkout__qr-h { font-size: 16px; color: var(--ink-2); margin: 0 0 .6em; }
.checkout__qr-btn {
  display: inline-block; padding: 6px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--card); cursor: pointer; line-height: 0;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.checkout__qr-btn:hover {
  transform: translateY(-2px); border-color: var(--ink);
  box-shadow: 0 8px 20px rgba(0, 0, 0, .12);
}
.checkout__qr-btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
/* 圖片不加 pointer-events/user-select 的遮蔽，否則 iOS 長按「加入照片」的選單會消失 */
.checkout__qr-img { width: min(180px, 100%); border-radius: 8px; }
.checkout__qr-tip { font-size: 15px; color: var(--ink-2); margin: .7em 0 0; line-height: 1.7; }
.checkout__qr-status { font-size: 15px; color: #3a5a40; margin: .3em 0 0; min-height: 1.6em; }

@media (hover: none) {
  .checkout__qr-btn:hover, .checkout__copy:hover { transform: none; box-shadow: none; }
  .checkout__qr-btn:active { transform: scale(.97); }
}

/* ===== S11 庫存標示與到貨時程（2026-09-12） ===== */
.stock { display: flex; align-items: center; gap: .5em; font-size: 16px; margin: 0 0 .2em; line-height: 1.3; }
.stock__dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; background: var(--muted); }
.stock--in { color: var(--ink-2); }
.stock--in .stock__dot { background: #3a5a40; }
.stock--low { color: #9A4B12; font-weight: 500; }
.stock--low .stock__dot { background: #C8722B; }
.stock--pre { color: var(--ink-2); }

/* 本批售完：不接單也不接預購，標示比 pre 更沉，並把整張卡降一階對比（S17，2026-09-16）。 */
.stock--out .stock__dot { background: #8C6A64; }
.stock--out .stock__text { color: #8C6A64; }
.menu-card--soldout .menu-card__image { position: relative; }
.menu-card--soldout .menu-card__image img { filter: grayscale(.35) sepia(.4) brightness(.78) blur(1.5px); }
.menu-card--soldout .menu-card__image::before {
  content: ""; position: absolute; inset: 0; background: rgba(62, 41, 30, .46); border-radius: inherit;
}
.menu-card--soldout .menu-card__image::after {
  content: "已售完"; position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%) rotate(-11deg);
  font-family: var(--display); font-size: clamp(19px, 4.4vw, 27px); letter-spacing: .3em; text-indent: .3em;
  color: #F1E7DD; border: 3px double #F1E7DD; border-radius: 7px; padding: 7px 20px 9px;
  background: rgba(62, 41, 30, .3); white-space: nowrap;
}
.menu-card--soldout .buy__add[disabled] { opacity: .5; cursor: not-allowed; }
.stock--pre .stock__dot { background: #9B9B95; }
.menu-card__eta { font-size: 15px; color: var(--ink-2); margin: 0 0 .4em; line-height: 1.3; }
.cart-row__pre {
  display: inline-block; margin-left: .5em; padding: 0 .6em; border-radius: 999px;
  background: rgba(200, 114, 43, .16); color: #9A4B12; font-size: 14px;
}
.cart-drawer__eta {
  font-size: 17px; line-height: 1.7; color: var(--ink); margin: 0 0 1.2em;
  padding: .7em .9em; border-radius: 10px; background: var(--card); border: 1px solid var(--line);
}
.cart-drawer__eta[hidden] { display: none; }

/* ===== S11 抽屜頂端的圖文教學入口 ===== */
/* S19（2026-09-23）：教學連結降階。原本是整面虛線框＋置中 16px，開啟購物車第一眼
   看到的是「第一次買？」而不是自己買了什麼——這是輔助資訊，不該壓過商品列與金額。
   改成靠左的一行小字，保留可點與 44px 觸控高度。 */
.cart-drawer__howto {
  display: flex; align-items: center; min-height: 44px; margin: 0 0 .4em;
  font-size: 14px; color: var(--ink-2); letter-spacing: .02em;
  transition: color .18s ease;
}
.cart-drawer__howto:hover { color: var(--ink); }
.cart-drawer__howto:hover { border-color: var(--ink); }
.cart-drawer__howto:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* ===== S11 送出後的完成畫面（取代整個抽屜內容） ===== */
/* 完成畫面是蓋在抽屜上的覆蓋層，不取代抽屜內容（取代會把結帳表單的 DOM 砍掉，
   關掉再開就一片空白）。is-done 時把面板的其他子元素藏起來，只留這一層。 */
.cart-drawer__panel.is-done > *:not(.cart-done) { display: none !important; }
.cart-done { display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; flex: 1; gap: .2em; }
.cart-done__icon {
  width: 72px; height: 72px; border-radius: 50%; background: #3a5a40; color: #fff;
  display: flex; align-items: center; justify-content: center; font-size: 38px; margin: 0 0 .4em;
}
.cart-done__title { font-size: 26px; letter-spacing: .06em; margin: 0 0 .5em; }
.cart-done__body { font-size: 19px; line-height: 1.9; color: var(--ink); margin: 0 0 1.2em; }
.cart-done__sub { font-size: 15px; color: var(--ink-2); margin: 0 0 .6em; }
.cart-done__link {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 56px; padding: 0 1.8em; border-radius: 999px;
  background: #06C755; color: #fff; font-size: 19px; letter-spacing: .06em;
}
.cart-done__link:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.cart-done__close {
  min-height: 48px; margin-top: 1em; padding: 0 1.4em; border-radius: 999px;
  border: 1px solid var(--line); background: transparent; color: var(--ink-2);
  font-size: 16px; cursor: pointer;
}
.cart-done__close:hover { border-color: var(--ink); color: var(--ink); }
/* 電腦版：oaMessage 在桌面瀏覽器會被轉去 LINE 官網首頁，改成複製訂單再貼到 LINE。 */
.cart-done--desktop { justify-content: flex-start; padding-top: 1em; overflow-y: auto; }
.cart-done__steps { text-align: left; font-size: 17px; line-height: 1.9; margin: 0 0 .8em; padding-left: 1.4em; }
.cart-done__message {
  width: 100%; box-sizing: border-box; padding: .8em 1em; border-radius: 13px;
  border: 1px solid var(--line); background: var(--card); color: var(--ink);
  font: inherit; font-size: 14px; line-height: 1.7; resize: vertical; margin: 0 0 .9em;
}
.cart-done__copy {
  min-height: 56px; padding: 0 1.8em; border: 0; border-radius: 999px;
  background: #06C755; color: #fff; font: inherit; font-size: 19px; letter-spacing: .06em; cursor: pointer;
  transition: transform .18s ease;
}
.cart-done__copy:active { transform: scale(.98); }
.cart-done__copy:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.cart-done__copy.is-copied { background: #3a5a40; }
.cart-done__friend { margin-top: .9em; font-size: 15px; color: var(--ink-2); text-decoration: underline; min-height: 44px; display: inline-flex; align-items: center; }

@media (max-width: 720px) {
  .checkout__row { flex-direction: column; }
}
@media (prefers-reduced-motion: reduce) {
  .checkout__geo-btn, .checkout__store-btn, .checkout__store-change, .checkout__copy,
  .checkout__qr-btn, .cart-drawer__howto { transition: none; }
}

/* ===== S11 圖文教學頁 /coffee/how-to-order/（2026-09-12） =====
   客群是 40 歲以上的手機使用者：單欄直排、一步一畫面、字級刻意比全站大一階，
   說明文字用 --ink-2 而不是 --muted。每一步都看得到 LINE 求助的出口。 */
.howto-hero { padding: clamp(48px, 9vw, 96px) 0 clamp(24px, 4vw, 40px); }
.howto-hero__inner { max-width: 34em; text-align: center; }
.howto-hero__title { font-size: clamp(30px, 7vw, 46px); letter-spacing: .06em; line-height: 1.4; margin: .3em 0 .2em; }
.howto-hero__sub {
  font-family: var(--display); font-size: clamp(17px, 2.4vw, 20px);
  letter-spacing: .14em; color: var(--ink-2); margin: 0 0 1.2em;
}
.howto-hero__intro { font-size: 18px; line-height: 2; color: var(--ink); margin: 0 0 1.6em; }

.howto-line {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 56px; padding: 0 1.8em; border-radius: 999px;
  background: #06C755; color: #fff; font-size: 18px; letter-spacing: .04em;
  transition: transform .18s ease, box-shadow .18s ease;
}
.howto-line:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(6, 199, 85, .28); }
.howto-line:active { transform: translateY(0) scale(.98); }
.howto-line:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

.howto__wrap { max-width: 40em; }
.howto-step {
  padding: clamp(24px, 4vw, 36px) 0;
  border-top: 1px solid var(--line);
}
.howto-step:first-child { border-top: none; }
.howto-step__head { display: flex; align-items: center; gap: .7em; margin: 0 0 .8em; }
.howto-step__num {
  flex: 0 0 auto; width: 48px; height: 48px; border-radius: 50%;
  background: var(--ink); color: var(--bg);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--display); font-size: 24px; line-height: 1;
}
.howto-step__title { font-size: clamp(22px, 5vw, 28px); letter-spacing: .04em; line-height: 1.45; }
.howto-step__shot { margin: 0 0 1em; }
.howto-step__shot img {
  width: 100%; max-width: 340px; margin: 0 auto;
  border-radius: 14px; border: 1px solid var(--line);
  box-shadow: 0 10px 26px rgba(0, 0, 0, .10);
}
.howto-step__body { font-size: 18px; line-height: 2; color: var(--ink); margin: 0; }

.howto-outro__wrap { max-width: 36em; text-align: center; }
.howto-outro__title { font-size: clamp(22px, 5vw, 28px); letter-spacing: .06em; margin: 0 0 .7em; }
.howto-outro__body { font-size: 18px; line-height: 2; color: var(--ink); margin: 0 0 1.8em; }
.howto-outro__cta { display: flex; flex-wrap: wrap; gap: 1em; align-items: center; justify-content: center; }
.howto-back {
  display: inline-flex; align-items: center; min-height: 56px; padding: 0 1.6em;
  border: 1px solid var(--ink); border-radius: 999px; font-size: 18px; letter-spacing: .04em;
  transition: background-color .18s ease, color .18s ease;
}
.howto-back:hover { background: var(--ink); color: var(--bg); }
.howto-back:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

/* /coffee/ hero 上的教學入口：與「本梯次豆單」並列，但用外框區隔主次 */
.pill--howto { border-style: dashed; }

@media (hover: none) {
  .howto-line:hover, .howto-back:hover { transform: none; box-shadow: none; }
}
@media (prefers-reduced-motion: reduce) {
  .howto-line, .howto-back { transition: none; }
}

/* ===== S12 首購導覽（.wlc-onboard）：長輩導覽疊層，2026-09-12 =====
   服務對象是不太會用手機的長輩，硬規格見 260910 個人官網 spec：
   內文字級不小於全站 body（17px，這裡拉到 18px）、可點目標高度 ≥48px、
   一次只講一件事、不用「結帳」「CTA」這類詞、reduced-motion 不做任何動畫、
   手機單欄不可橫向捲動。
   顏色全部吃本站 :root 變數，不另立一套：卡片 --card、標題與按鈕 --ink、
   說明文字 --ink-2（該變數本來就是為 40 歲以上使用者設的深一階，正好是這層的對象）、
   按鈕比照 .buy__add 的黑底白字加 1px 邊框、圓角比照站台的 10px。
   初版曾用暖色票，但那組是跨專案的通用預設，與本站的黑灰編輯風（Marcellus＋明朝體）
   是兩套，疊上去會像外掛的東西。2026-09-12 改為對齊站台。
   [hidden] 一律加 !important，理由同上面 S9 的 .cartbar[hidden]：
   避免任何一條 display 規則蓋掉隱藏屬性，讓疊層一載入就整片攤開。 */
.wlc-onboard {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 16px;
}
.wlc-onboard[hidden] { display: none !important; }
.wlc-onboard__backdrop { position: absolute; inset: 0; background: rgba(0, 0, 0, .38); }
.wlc-onboard__card {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 420px;
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  margin-bottom: clamp(16px, 4vh, 64px);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .10);
  padding: 20px 22px 18px;
}
.wlc-onboard__progress { margin: 0 0 10px; font-size: 14px; letter-spacing: .04em; color: var(--ink-2); }
.wlc-onboard__body { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 18px; }
.wlc-onboard__avatar { flex: 0 0 auto; width: 56px; height: 56px; border-radius: 50%; object-fit: cover; background: var(--card); }
.wlc-onboard__text { min-width: 0; }
.wlc-onboard__title { font-family: var(--serif); font-size: 20px; line-height: 1.5; color: var(--ink); margin: 0 0 8px; }
.wlc-onboard__desc { font-size: 18px; line-height: 1.8; color: var(--ink); margin: 0; }
.wlc-onboard__outro {
  font-size: 18px; line-height: 1.8; color: var(--ink-2); margin: 14px 0 0;
  padding-top: 12px; border-top: 1px solid var(--line);
}
.wlc-onboard__outro[hidden] { display: none; }
.wlc-onboard__actions { display: flex; flex-direction: column; gap: 10px; }
.wlc-onboard__next {
  min-height: 52px; border: 1px solid var(--ink); border-radius: 999px; background: var(--ink); color: var(--bg);
  font-size: 18px; letter-spacing: .04em; cursor: pointer;
  transition: transform .18s ease, box-shadow .18s ease;
}
.wlc-onboard__next:hover { transform: translateY(-1px); box-shadow: 0 10px 26px rgba(0, 0, 0, .10); }
.wlc-onboard__next:active { transform: translateY(0) scale(.99); }
.wlc-onboard__next:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.wlc-onboard__close {
  min-height: 48px; border: 1px solid var(--line); border-radius: 999px;
  background: transparent; color: var(--ink-2); font-size: 16px; cursor: pointer;
  transition: background-color .18s ease;
}
.wlc-onboard__close:hover { background: rgba(0, 0, 0, .05); }
.wlc-onboard__close:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

/* 指著頁面元素那一步：柔和外框，不挪動版面、不遮住內容 */
.wlc-onboard-highlight { outline: 3px solid var(--ink); outline-offset: 4px; border-radius: 12px; }

/* 常駐入口：隨時可重開導覽 */
.wlc-onboard-reopen {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 20px; margin: 0 0 22px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--card); color: var(--ink); font-size: 17px; letter-spacing: .02em; cursor: pointer;
  box-shadow: 0 10px 26px rgba(0, 0, 0, .10);
  transition: transform .18s ease;
}
.wlc-onboard-reopen:hover { transform: translateY(-1px); }
.wlc-onboard-reopen:active { transform: translateY(0) scale(.99); }
.wlc-onboard-reopen:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

@media (hover: none) {
  .wlc-onboard__next:hover, .wlc-onboard-reopen:hover { transform: none; box-shadow: none; }
}
/* 全站已有 * { transition-duration:.001ms !important } 的 reduced-motion 規則（見上方響應式區），
   這裡不需要重複宣告；scrollIntoView 的 smooth/auto 切換交給 assets/onboarding.js 的
   reduceMotion 判斷處理。 */

@media (max-width: 720px) {
  .wlc-onboard { padding: 0; align-items: flex-end; }
  .wlc-onboard__card { max-width: none; width: 100%; margin: 0; border-radius: 10px 22px 0 0; }
  .wlc-onboard__body { flex-direction: column; }
  .wlc-onboard__avatar { width: 48px; height: 48px; }
}

/* ===== S13 背景氛圍層（.bg-atmos）：和紙呼吸＋空色時辰，2026-09-13 =====
   Vic 從五案中選 A＋B 疊用。設計取捨：
   - 全部是沒有邊緣的軟材質，讀者看不出「有東西在動」，只覺得底色有溫度。
   - 會動的只有三件事，全部只動 transform 類屬性（可交給合成器）：
     光團隨整頁捲動位移（translate，由 atmos.js 在捲動時更新）、光團 11 秒呼吸（scale）。
     兩片雲影已於同日移除：與 S14 水盤漣漪同為會動的淡灰色塊，並存時分不清誰在動。
   - 時辰色溫由 atmos.js 在 <html data-sky> 標記，色塊只換 opacity，底色 --bg 本身不動，
     元件裡引用 var(--bg) 的反白按鈕不受影響。
   - prefers-reduced-motion：呼吸停止，光團停在頁首位置。 */
.bg-atmos {
  position: fixed; inset: 0; z-index: -1;
  overflow: hidden; pointer-events: none;
}
.bg-atmos > div { position: absolute; }
.bg-atmos__sky {
  inset: 0;
  background: radial-gradient(90% 70% at 50% -10%, var(--sky-tint, rgba(250, 250, 246, .8)), rgba(0, 0, 0, 0) 70%);
  transition: background 2.4s ease;
}
:root[data-sky="dawn"]  { --sky-tint: rgba(214, 226, 232, .9); }
:root[data-sky="noon"]  { --sky-tint: rgba(250, 250, 246, .8); }
:root[data-sky="dusk"]  { --sky-tint: rgba(246, 226, 206, .75); }
:root[data-sky="night"] { --sky-tint: rgba(206, 208, 214, .7); }
.bg-atmos__sun {
  width: 110vmax; height: 110vmax; left: -35vmax; top: -45vmax;
  background: radial-gradient(closest-side, rgba(255, 251, 240, .95), rgba(255, 251, 240, 0) 72%);
  will-change: translate, scale;
  animation: bg-atmos-breathe 11s ease-in-out infinite;
}
@keyframes bg-atmos-breathe {
  0%, 100% { scale: 1; opacity: .85; }
  50% { scale: 1.03; opacity: 1; }
}
.bg-atmos__paper {
  inset: 0; opacity: .55;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='320' height='320'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .42  0 0 0 0 .41  0 0 0 0 .38  0 0 0 .22 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='600' height='600'><filter id='f'><feTurbulence type='fractalNoise' baseFrequency='.004 .09' numOctaves='2' seed='7' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .5  0 0 0 0 .49  0 0 0 0 .45  0 0 0 .12 0'/></filter><rect width='100%' height='100%' filter='url(%23f)'/></svg>");
}
@media (prefers-reduced-motion: reduce) {
  .bg-atmos__sun { animation: none; }
}

/* ===== S14 水盤（.bg-atmos__water）：淡花浮在和紙水面，碰到才起漣漪，2026-09-13 =====
   Vic 從「侘寂花影五案」選 D。邏輯全在 assets/suiban.js：
   - 花與漣漪畫在一張固定於視窗的 canvas，疊在和紙之上。
   - 可讀性：每幀把文字、圖片、控制元件、卡片外擴 12px 的範圍擦成透明，花碰到會漂開。
   - 靜止時不跑動畫；減少動態時只畫靜止的花。 */
.bg-atmos > canvas.bg-atmos__water { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* ===== S17／S18 不公開分享頁與技術文章共用排版元件（.unlisted、.article--tech）。
   兩者共用同一份選擇器清單（逗號並列），只維護一份 CSS：複製按鈕（assets/copy.js）、
   圖卡（.card-figure）、可橫向捲動的架構圖容器（.arch-diagram）＝ S17（2026-09-15）；
   目錄（.toc）、標籤頁（.tabs，assets/tabs.js）、輔助框（.callout）、CTA（.cta）、
   小字（.fineprint）＝ S18 技術文章排版（layout: tech，2026-09-15）。
   沿用既有 --ink／--line／--card／--muted 變數與 .glass／--display 字型，不另創新色。 ===== */
.unlisted .prompt-block, .article--tech .prompt-block {
  margin: 2em 0;
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  background: var(--card);
}
.unlisted .prompt-block__head, .article--tech .prompt-block__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1em;
  padding: .8em 1.1em;
  border-bottom: 1px solid var(--line);
  font-family: var(--display);
  font-size: 13px;
  letter-spacing: .06em;
  color: var(--muted);
}
.unlisted .prompt-block__copy, .article--tech .prompt-block__copy {
  min-height: 44px;
  min-width: 44px;
  padding: 0 1em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--ink);
  border-radius: 999px;
  font-size: 13px;
  letter-spacing: .04em;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: background-color .18s ease, color .18s ease;
}
.unlisted .prompt-block__copy:hover, .article--tech .prompt-block__copy:hover { background: var(--ink); color: var(--bg); }
.unlisted .prompt-block__copy:focus-visible, .article--tech .prompt-block__copy:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .unlisted .prompt-block__copy, .article--tech .prompt-block__copy { transition: none; } }
.unlisted .prompt-block pre, .article--tech .prompt-block pre {
  margin: 0;
  padding: 1.1em;
  overflow-x: auto;
  font-size: 14px;
  line-height: 1.7;
  -webkit-overflow-scrolling: touch;
}
.unlisted .prompt-block code, .article--tech .prompt-block code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  letter-spacing: 0;
}

.unlisted .card-figure, .article--tech .card-figure { margin: 2em auto; max-width: 540px; text-align: center; }
.unlisted .card-figure img, .article--tech .card-figure img { width: 100%; border-radius: 14px; }
.unlisted .card-figure video, .article--tech .card-figure video { width: 100%; height: auto; border-radius: 14px; display: block; }
.unlisted .card-figure figcaption, .article--tech .card-figure figcaption { margin-top: .6em; font-size: 13px; color: var(--muted); }
/* 長片的 YouTube 內嵌（youtube-nocookie，CSP frame-src 已放行）＝ Day 06（2026-09-21） */
.unlisted .video-embed, .article--tech .video-embed { margin: 2em auto; max-width: 720px; }
.unlisted .video-embed iframe, .article--tech .video-embed iframe { display: block; width: 100%; aspect-ratio: 16 / 9; height: auto; border: 0; border-radius: 14px; }

.unlisted .arch-diagram, .article--tech .arch-diagram { width: 100%; overflow-x: auto; margin: 2em 0; -webkit-overflow-scrolling: touch; }
/* 架構圖：viewBox 寬 360 已為手機設計，桌面限寬置中 */
.unlisted .arch-diagram svg, .article--tech .arch-diagram svg { display: block; width: 100%; max-width: 480px; height: auto; margin: 0 auto; }
.unlisted .arch-diagram figcaption, .article--tech .arch-diagram figcaption { margin-top: .6em; font-size: 13px; color: var(--muted); text-align: center; }
/* 指令包在手機上要能直接讀：自動換行，複製出去的文字不受影響 */
.unlisted .prompt-block pre, .article--tech .prompt-block pre { white-space: pre-wrap; overflow-wrap: anywhere; }

/* ===== S18 目錄（.toc）：手機是可展開的 <details open>，桌面（≥1200px）轉成固定側欄，
   由 assets/toc.js 用 IntersectionObserver 幫目前章節的連結加 aria-current。
   沒有 JS 時仍是一組可點的錨點清單（見 build_toc_html() 的說明）。===== */
.article--tech .toc {
  margin: 0 0 2.4em;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--card);
  overflow: hidden;
}
.article--tech .toc__summary {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0 1.1em;
  font-family: var(--display);
  font-size: 13px;
  letter-spacing: .08em;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
}
.article--tech .toc__summary:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.article--tech .toc__list {
  list-style: none;
  margin: 0;
  padding: .2em 0 .8em;
}
.article--tech .toc__item a {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0 1.1em;
  font-size: 15px;
  line-height: 1.5;
  color: var(--muted);
  border-left: 3px solid transparent;
  transition: color .18s ease, border-color .18s ease;
}
.article--tech .toc__item--h3 a { padding-left: 2.1em; font-size: 14px; }
.article--tech .toc__item a:hover { color: var(--ink); }
.article--tech .toc__item a:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.article--tech .toc__item a[aria-current="true"] { color: var(--ink); border-left-color: var(--ink); font-weight: 500; }
@media (prefers-reduced-motion: reduce) { .article--tech .toc__item a { transition: none; } }

/* 桌面：目錄脫離文章縱向排列，改成文章右側的固定側欄（不遮正文）。實作刻意不用
   position: fixed／absolute——.article__panel（.glass）在滑鼠可 hover 的桌面寬度會開
   backdrop-filter，而 backdrop-filter 與 filter 一樣，會讓套用的元素變成其內
   fixed／absolute 後代的新 containing block（CSS Filter Effects／Backdrop 規範），
   toc 若巢狀在 .article__panel 底下用 fixed 定位，計算基準會被悄悄換成 panel 的框，
   不再是視窗，算出來的座標在有支援 backdrop-filter 的瀏覽器會整個跑掉。改用
   CSS Grid＋position: sticky：.article--tech 在此斷點加寬到 960px 讓側欄有地方擺，
   .article__body 分兩欄（正文 1fr／目錄 200px），toc 的 grid-row 跨滿正文高度，
   sticky 只負責在該範圍內垂直跟隨捲動，不依賴任何祖先的 containing block。 */
@media (min-width: 1200px) {
  .article--tech { max-width: 960px; }
  .article--tech .article__body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 200px;
    column-gap: 32px;
    align-items: start;
  }
  .article--tech .article__body > .toc {
    grid-column: 2;
    grid-row: 1;
    align-self: start;
    position: sticky;
    top: 100px;
    max-height: calc(100vh - 140px);
    overflow-y: auto;
    margin: 0;
  }
  .article--tech .article__body > :not(.toc) { grid-column: 1; }
  /* 桌面側欄由 toc.js 自動展開；摘要列保留當標題，沒有 JS 時仍可點開 */
  .article--tech .toc__summary { font-size: 13px; }
  .article--tech .toc__list { padding: .6em 0; }
  .article--tech .toc__item a { min-height: 36px; font-size: 13px; padding: .3em 1em; }
  .article--tech .toc__item--h3 a { padding-left: 1.8em; font-size: 12px; }
}

/* ===== S18 標籤頁（.tabs，assets/tabs.js）：role=tablist／tab／tabpanel。
   沒有 JS 時 .tabs__panel::before 用 data-tab 顯示標題、所有 panel 依序顯示；
   JS 產生真正的分頁鈕後（[data-tabs-ready]）改隱藏這個佔位標題，避免重複。===== */
.article--tech .tabs { margin: 2em 0; }
.article--tech .tabs__panel {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  padding: 1.2em 1.3em;
  margin-bottom: 1em;
}
.article--tech .tabs__panel:last-child { margin-bottom: 0; }
.article--tech .tabs__panel > *:last-child { margin-bottom: 0; }
.article--tech .tabs__panel::before {
  content: attr(data-tab);
  display: block;
  font-family: var(--display);
  font-size: 13px;
  letter-spacing: .08em;
  color: var(--muted);
  margin-bottom: .6em;
}
.article--tech .tabs[data-tabs-ready] .tabs__panel::before { display: none; }
.article--tech .tabs[data-tabs-ready] .tabs__panel { margin-bottom: 0; border-radius: 0 10px 10px 10px; }
.article--tech .tabs[data-tabs-ready] .tabs__panel[hidden] { display: none; }
.article--tech .tabs__list {
  display: flex;
  flex-wrap: wrap;
  gap: .4em;
  list-style: none;
  margin: 0 0 -1px;
  padding: 0;
}
.article--tech .tabs__tab {
  min-height: 44px;
  padding: 0 1.2em;
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line);
  border-bottom: none;
  border-radius: 10px 10px 0 0;
  background: var(--bg);
  color: var(--muted);
  font: inherit;
  font-size: 14px;
  letter-spacing: .04em;
  cursor: pointer;
  transition: background-color .18s ease, color .18s ease;
}
.article--tech .tabs__tab[aria-selected="true"] { background: var(--card); color: var(--ink); }
.article--tech .tabs__tab:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
@media (hover: hover) { .article--tech .tabs__tab:hover { color: var(--ink); } }
@media (prefers-reduced-motion: reduce) { .article--tech .tabs__tab { transition: none; } }

/* ===== S18 輔助框（.callout）：提示／注意／踩坑紀錄三色，沿用站台既有低彩度色系
   （庫存徽章的暖色 #9A4B12／#C8722B、已加入按鈕的 #3a5a40、結帳錯誤的 #B3261E），
   不另創鮮豔色。===== */
.article--tech .callout {
  margin: 2em 0;
  padding: 1em 1.2em;
  border: 1px solid var(--line);
  border-left: 4px solid var(--muted);
  border-radius: 12px;
  background: var(--card);
}
.article--tech .callout p:last-child { margin-bottom: 0; }
.article--tech .callout__title {
  margin: 0 0 .5em;
  font-family: var(--display);
  font-size: 13px;
  letter-spacing: .08em;
  font-weight: 500;
  color: var(--ink);
}
.article--tech .callout--tip { border-left-color: #3a5a40; }
.article--tech .callout--tip .callout__title { color: #3a5a40; }
.article--tech .callout--warn { border-left-color: #9A4B12; }
.article--tech .callout--warn .callout__title { color: #9A4B12; }
.article--tech .callout--pitfall { border-left-color: #B3261E; }
.article--tech .callout--pitfall .callout__title { color: #B3261E; }

/* ===== S18 CTA 按鈕（.cta）：沿用 .pill--fill 的視覺語言（實心膠囊、44px 可點區）===== */
.article--tech .cta { margin: 2em 0; text-align: center; }
.article--tech .cta__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 1.6em;
  border-radius: 999px;
  background: var(--ink);
  color: var(--bg);
  font-size: 15px;
  letter-spacing: .06em;
  transition: background-color .18s ease;
}
.article--tech .cta__btn:hover { background: #333; }
.article--tech .cta__btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .article--tech .cta__btn { transition: none; } }

/* ===== S18 小字（.fineprint）===== */
.article--tech .fineprint { font-size: 13px; color: var(--muted); margin: 1.5em 0; }

@media (max-width: 720px) {
  .article--tech .tabs__tab { font-size: 13px; padding: 0 1em; }
}

/* ===== 技術文章：表格、截圖、一般程式碼區塊、參考來源（2026-09-15） ===== */
.article--tech .table-wrap { width: 100%; overflow-x: auto; margin: 1.6em 0; -webkit-overflow-scrolling: touch; }
.article--tech table { width: 100%; min-width: 480px; border-collapse: collapse; font-size: 15px; line-height: 1.7; }
.article--tech th, .article--tech td { padding: .6em .8em; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.article--tech th { font-weight: 600; color: var(--ink-2); background: rgba(0,0,0,.03); }
.article--tech .shot-figure { margin: 2em 0; }
.article--tech .shot-figure img { width: 100%; height: auto; margin: 0; border-radius: 12px; border: 1px solid var(--line); }
.article--tech .shot-figure figcaption { margin-top: .6em; font-size: 13px; color: var(--muted); text-align: center; }
.article--tech .article__body pre:not(.prompt-block pre) { margin: 1em 0; padding: .9em 1.1em; overflow-x: auto; background: var(--card); border: 1px solid var(--line); border-radius: 10px; font-size: 14px; line-height: 1.7; }
.article--tech .article__body code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .9em; }
.article--tech .refs { font-size: 14px; line-height: 1.9; }
.article--tech .refs-note { font-size: 13px; color: var(--muted); }

/* 手機與平板：目錄預設收合、只列章（h2），避免目錄本身佔掉一整個畫面 */
@media (max-width: 1199px) {
  .article--tech .toc__item--h3 { display: none; }
}
/* 技術文章的章節標題要一眼分得出層級：h2 加大並加分隔線，h3 次一級 */
.article--tech .article__body h2 { margin: 3em 0 1em; padding-top: 1.2em; border-top: 1px solid var(--line); font-size: 24px; line-height: 1.5; letter-spacing: .04em; scroll-margin-top: 96px; }
.article--tech .article__body h3 { margin: 2.2em 0 .8em; font-size: 19px; line-height: 1.5; letter-spacing: .04em; scroll-margin-top: 96px; }
@media (max-width: 720px) {
  .article--tech .article__body h2 { font-size: 21px; }
  .article--tech .article__body h3 { font-size: 18px; }
}

/* ===== S18 閱讀節奏修訂（2026-09-15，r5 審稿）：章號色帶、精簡側欄、圖卡縮窄、
   程式碼複製鈕、Q&A 與參考來源收合。只作用在 layout: tech（.article--tech）。
   粗體沿用站台慣例寫 500（Noto Serif TC 只載入 400／500，寫 700 會變假粗體）。
   暖色沿用 .stock--low 的 #9A4B12，淡彩底 #F5EEE6 是同色系的低彩度襯底。===== */

/* 章節標題：淡彩圓角色帶取代上方細線，前面放兩位數章號（與側欄一致） */
.article--tech .article__body h2 {
  display: flex; align-items: baseline; gap: .7em;
  margin: 3.4em 0 1.2em; padding: .7em 1em;
  border-top: 0; border-radius: 14px; background: #F5EEE6;
  font-weight: 500;
}
.article--tech .sec-num {
  flex: 0 0 auto; font-family: var(--serif); font-size: .72em; font-variant-numeric: lining-nums tabular-nums;
  letter-spacing: .08em; color: #9A4B12;
}

/* 目錄：章號＋短標；桌面側欄只列章，目前讀到的章才展開小節（toc.js 加 .toc__item--open） */
.article--tech .toc__item a { gap: .6em; }
.article--tech .toc__num {
  flex: 0 0 auto; min-width: 1.9em; font-family: var(--serif); font-variant-numeric: lining-nums tabular-nums;
  font-size: 12px; letter-spacing: .04em; color: #A8A29A;
}
.article--tech .toc__item a[aria-current="true"] .toc__num,
.article--tech .toc__item--chapter > a .toc__num { color: #9A4B12; }
@media (min-width: 1200px) {
  .article--tech .article__body { grid-template-columns: minmax(0, 1fr) 220px; column-gap: 40px; }
  .article--tech .toc__list { padding: .5em 0 .9em; }
  .article--tech .toc__item a { min-height: 38px; padding: .3em 1em .3em .9em; font-size: 14px; line-height: 1.45; }
  .article--tech .toc__item--h3 { display: none; }
  .article--tech .toc__item--h3.toc__item--open { display: block; }
  .article--tech .toc__item--h3 a { min-height: 32px; padding-left: 3.2em; font-size: 13px; }
  .article--tech .toc__item--chapter > a { color: var(--ink); }
}

/* 對話圖卡在桌面縮窄置中，不再一張佔滿整個螢幕高、切斷正文 */
@media (min-width: 721px) {
  .article--tech .card-figure { max-width: 440px; }
}

/* 一般程式碼區塊的複製鈕（assets/copy.js 以 data-copy 處理） */
.article--tech .code-block { position: relative; margin: 1em 0; }
.article--tech .article__body .code-block > pre:not(.prompt-block pre) { margin: 0; padding-right: 5.6em; }
.article--tech .code-block__copy {
  position: absolute; top: 3px; right: 3px;
  min-height: 44px; min-width: 64px; padding: 0 .9em;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg); color: var(--ink); font-size: 13px; letter-spacing: .06em;
  cursor: pointer; transition: background .18s ease, color .18s ease;
}
.article--tech .code-block__copy:hover { background: var(--ink); color: var(--bg); }
.article--tech .code-block__copy:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* Q&A：每題一個 <details>，點問題展開答案 */
.article--tech .qa { border-bottom: 1px solid var(--line); }
.article--tech h3 + .qa { border-top: 1px solid var(--line); }
.article--tech .qa__q {
  position: relative; display: flex; align-items: center;
  min-height: 52px; padding: .7em 2.4em .7em 0;
  list-style: none; cursor: pointer; font-weight: 500; line-height: 1.6;
}
.article--tech .qa__q::-webkit-details-marker { display: none; }
.article--tech .qa__q::after {
  content: "+"; position: absolute; right: .3em; top: 50%;
  font-family: var(--display); font-size: 22px; line-height: 1;
  transform: translateY(-50%); transition: transform .18s ease;
}
.article--tech .qa[open] > .qa__q::after { transform: translateY(-50%) rotate(45deg); }
.article--tech .qa__q:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.article--tech .qa__a { padding: 0 0 .8em; }
.article--tech .qa__a p:last-child { margin-bottom: 0; }

/* 參考來源：整段收合 */
.article--tech .refs-details { margin: 3.4em 0 1em; border: 1px solid var(--line); border-radius: 14px; background: var(--card); }
.article--tech .refs-details__summary {
  position: relative; display: flex; align-items: center;
  min-height: 52px; padding: .6em 3em .6em 1.1em;
  list-style: none; cursor: pointer; font-size: 15px;
}
.article--tech .refs-details__summary::-webkit-details-marker { display: none; }
.article--tech .refs-details__summary::after {
  content: "+"; position: absolute; right: 1em; top: 50%;
  font-family: var(--display); font-size: 22px; line-height: 1;
  transform: translateY(-50%); transition: transform .18s ease;
}
.article--tech .refs-details[open] > .refs-details__summary::after { transform: translateY(-50%) rotate(45deg); }
.article--tech .refs-details__summary:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
.article--tech .refs-details .refs { margin: 0; padding: 0 1.1em 1.1em 2.4em; }

@media (prefers-reduced-motion: reduce) {
  .article--tech .code-block__copy,
  .article--tech .qa__q::after,
  .article--tech .refs-details__summary::after { transition: none; }
}


/* ===== S19 三語（2026-09-15 i18n 第一階段）：日文字型、語言切換、外語大杯居展示卡 ===== */
/* 日文頁換日文字型：同一個漢字在繁中與日文字型字形不同，只換 token，不動各元件 */
html:lang(ja) {
  --serif: "Noto Serif JP", "Hiragino Mincho ProN", "Yu Mincho", Georgia, serif;
  --display: "Marcellus", "Noto Serif JP", Georgia, serif;
}

/* 頁首語言切換：一顆 44px 圓鈕（跟 .icon-btn 同一套外框），點開三個語言 */
.lang-switch { position: relative; flex: 0 0 auto; }
.lang-switch > summary {
  list-style: none; cursor: pointer;
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--ink); border-radius: 50%; color: var(--ink);
  font-family: var(--display); font-size: 13px; letter-spacing: .04em;
  transition: background-color .18s ease, color .18s ease;
}
.lang-switch > summary::-webkit-details-marker { display: none; }
.lang-switch > summary:hover, .lang-switch[open] > summary { background: var(--ink); color: var(--bg); }
.lang-switch > summary:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.lang-switch__menu {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 30;
  margin: 0; padding: 6px; list-style: none;
  background: var(--card); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .08);
  display: flex; flex-direction: column; min-width: 72px;
}
.lang-switch__menu a {
  min-height: 44px; min-width: 60px; padding: 0 14px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--display); font-size: 14px; letter-spacing: .06em; border-radius: 10px;
}
.lang-switch__menu a:hover { background: rgba(0, 0, 0, .05); }
.lang-switch__menu a[aria-current="true"] { text-decoration: underline; text-underline-offset: 4px; }
.lang-switch__menu a:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
@media (hover: none) { .lang-switch > summary:hover { background: transparent; color: var(--ink); } }
@media (prefers-reduced-motion: reduce) { .lang-switch > summary { transition: none; } }
/* 手機頁首（2026-09-15 第三輪）：用 grid 排兩列，語言鈕跟社群鈕排在第一列，位置同桌機（FB 左邊）。
   第一輪把鈕釘在頁首底線（bottom:0），sticky 頁首往下捲時內文從底線經過，圓鈕看起來像壓在字上。
   第二輪排進導覽列右側，Vic 在 iPhone 看仍像「跳行」，第三輪收回第一列。
   - 第一列：品牌｜語言｜FB｜IG｜Line@訂購；第二列：導覽橫跨整列置中。順序與桌機、DOM、鍵盤 Tab 一致。
   - .site-header__cta 用 display:contents 讓裡面四顆鈕直接成為 grid 子項；DOM 順序不變，鍵盤 Tab 順序照舊。
   - 語言鈕圓圈 36px、::after 往外撐 5px（偽元素從邊框內側起算，1px 邊框要補回），點擊範圍維持 44px。
   - .lang-switch 改 flex：summary 是 inline-flex，放在 block 的 details 裡會沾到行高基線，整顆往下偏 1px。
   - 導覽「TOP」只有約 30px 寬，補 min-width 讓點擊範圍到 44px。 */
@media (max-width: 720px) {
  .site-header__inner {
    display: grid; grid-template-columns: minmax(0, 1fr) auto auto auto auto;
    column-gap: 6px; row-gap: 0; align-items: center;
    height: auto; padding: 6px 14px 0;
  }
  .site-header__cta { display: contents; }
  .site-header__brand { grid-column: 1; grid-row: 1; justify-self: start; min-width: 0; }
  .site-nav { grid-column: 1 / -1; grid-row: 2; justify-self: center; width: auto; }
  .site-header__cta > .lang-switch { display: flex; grid-column: 2; grid-row: 1; }
  .site-nav a { min-width: 44px; justify-content: center; }
  .lang-switch > summary { position: relative; width: 36px; height: 36px; font-size: 12px; }
  .lang-switch > summary::after { content: ""; position: absolute; inset: -5px; border-radius: 50%; }
}
/* 390px 以下（iPhone mini／SE、多數 Android）：一列要放五樣東西，FB／IG 也改 36px 圓圈＋5px 外撐（點擊範圍仍 44px），
   間距 8px 讓相鄰的點擊範圍剛好相接不重疊。 */
@media (max-width: 389px) {
  .site-header__inner { column-gap: 8px; padding-left: 12px; padding-right: 12px; }
  .site-header__cta > .icon-btn { position: relative; width: 36px; height: 36px; flex-basis: 36px; }
  .site-header__cta > .icon-btn::after { content: ""; position: absolute; inset: -5px; border-radius: 50%; }
  .site-header__cta > .icon-btn .icon { width: 16px; height: 16px; }
  .line-cta { margin-left: 0; padding: 0 .8em 0 .65em; }
}
/* 360px 以下：中文「Line@訂購」最寬，收掉膠囊裡的 LINE 圖示、膠囊字級與品牌字距再收一點，品牌字才不會被 FB 圓鈕蓋到。 */
@media (max-width: 359px) {
  .site-header__inner { padding-left: 10px; padding-right: 10px; }
  .site-header__brand { letter-spacing: .04em; }
  .site-header__brand .site-header__mark { margin-right: .3em; }
  .line-cta { padding: 0 .6em; font-size: 12px; letter-spacing: .02em; }
  .line-cta .icon { display: none; }
}

/* 外語列表：該分類還沒有譯文時的一句說明 */
.list-empty { text-align: center; color: var(--muted); margin: clamp(24px, 3vw, 40px) 0 0; }

/* 外語大杯居展示卡：各規格價格平鋪（沒有購物車與規格切換） */
.menu-card__vprices { list-style: none; margin: 0 0 .4em; padding: 0; }
.menu-card__vprices li { font-family: var(--display); font-size: 18px; letter-spacing: .06em; line-height: 1.6; }
.menu-card__vlabel { font-family: var(--serif); font-size: 14px; letter-spacing: .02em; color: var(--ink-2); margin-right: .4em; }
.order-abroad { padding: clamp(20px, 3vw, 36px); text-align: center; }
.order-abroad p { margin: 0 0 1.2em; line-height: 1.9; }
.order-abroad__cta { display: flex; flex-wrap: wrap; gap: .8em; justify-content: center; }

/* ===== 文章觀看數＋按讚（.engage）：首尾各一組，常駐呼吸，2026-09-15 第二輪 =====
   Vic 指定：文章首尾都顯示、常駐日式清新呼吸、不干擾閱讀、視覺權重放大、間距要有節奏。
   - 常駐動效只放在圓盤外的光暈（::before 白色柔光、::after 細環），只動 scale／opacity，
     可交給合成器；圖示與數字本身靜止，閱讀視線不會被拉走。
   - 週期互質且偏慢：觀看 9s、讚 7s，與背景光團 11s、頁首 LINE 鈕 4s 永不同拍。
   - 愛心的 hover 放大與按下彈跳掛在內層 svg 的 transform，呼吸在外層偽元素，兩者不互相打斷。
   - 節奏：日期（小）→ 標題 → 近距離接一列互動（屬於標題的一部分）→ 較大留白 → 正文面板；
     文末：面板 → 大留白 → 一道短縱線（間）→ 置中的互動列。
   - 標題下那一列先保留 44px 高度再顯示，數字晚到不會把正文往下推；文末那一列不保留。 */
.engage[hidden], .engage-views[hidden], .menu-sold[hidden] { display: none !important; }
.engage--top[hidden] { display: flex !important; visibility: hidden; }

.engage {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 22px;
  min-height: 44px;
  color: var(--ink-2, #46463f);
  line-height: 1;
}
.article__title:has(+ .engage--top) { margin-bottom: .75em; }
.engage--top { margin: 0 0 clamp(36px, 5.5vw, 56px); }
.engage--end {
  justify-content: center;
  margin: clamp(48px, 8vw, 88px) 0 clamp(12px, 3vw, 28px);
}
.engage--end::before {
  content: "";
  flex: 0 0 100%;
  height: 40px;
  margin-bottom: clamp(14px, 2.4vw, 22px);
  background: linear-gradient(var(--line), var(--line)) center / 1px 100% no-repeat;
}

.engage__item {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  padding: 0 6px 0 0;
  color: inherit;
}

.engage__disc {
  position: relative;
  isolation: isolate;
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .55);
  border: 1px solid var(--line);
  transition: background-color .4s ease, border-color .4s ease, translate .18s ease;
}
.engage__disc::before,
.engage__disc::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  animation-duration: var(--breath, 9s);
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
}
/* 柔光：沒有邊緣的白色空氣感，像晨光落在和紙上 */
.engage__disc::before {
  inset: -14px;
  z-index: -1;
  background: radial-gradient(closest-side, var(--breath-glow, rgba(255, 255, 255, .95)), rgba(255, 255, 255, 0));
  animation-name: engage-glow;
}
/* 內圈微光：2026-09-16 由細環改成 box-shadow 柔光，尺寸固定，只有亮度在呼吸 */
.engage__disc::after {
  inset: -6px;
  border-radius: 50%;
  box-shadow: 0 0 7px 1px var(--breath-ring, rgba(17, 17, 17, .24));
  animation-name: engage-breathe;
}
/* 兩組呼吸都只動 opacity：不用 scale／inset，圓盤佔位與視覺尺寸全程不變，
   擁擠版型（列表頁、手機）才不會互相重疊。 */
@keyframes engage-breathe {
  0%, 100% { opacity: .12; }
  50%      { opacity: .45; }
}
@keyframes engage-glow {
  0%, 100% { opacity: .18; }
  50%      { opacity: .5; }
}

.engage__icon {
  display: block;
  flex: none;
  width: 20px;
  height: 20px;
}
.engage__views .engage__disc { color: var(--ink-2, #46463f); }

.engage__count {
  min-width: 1ch;
  /* Marcellus 的 1 長得像羅馬數字 I，數字改用明朝體 */
  font-family: var(--serif);
  font-size: 18px;
  letter-spacing: .04em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.engage__like {
  --breath: 7s;
  background: transparent;
  border: none;
  margin: 0;
  font: inherit;
  cursor: pointer;
  border-radius: 999px;
  -webkit-tap-highlight-color: transparent;
}
.engage__like-icon { display: block; width: 21px; height: 21px; }
.engage__like-icon .engage__icon { width: 21px; height: 21px; }

/* 已讚：圓盤染一層櫻色，兩層光暈跟著換色，呼吸節奏不變 */
.engage__like[aria-pressed="true"] {
  --breath-glow: rgba(250, 222, 224, .95);
  --breath-ring: rgba(201, 116, 122, .45);
}
.engage__like[aria-pressed="true"] .engage__disc {
  background: rgba(201, 116, 122, .1);
  border-color: rgba(201, 116, 122, .35);
}
.engage__like[aria-pressed="true"] .engage__icon--heart { color: #c9747a; }

.engage__like:focus-visible {
  outline: 2px solid var(--ink, #111111);
  outline-offset: 4px;
}

.engage__icon--heart { transition: transform .18s ease; }
@media (hover: hover) {
  .engage__like:hover .engage__disc { translate: 0 -2px; }
  .engage__like:hover .engage__icon--heart { transform: scale(1.12); }
}
.engage__like:active .engage__disc { translate: 0 0; }
.engage__like:active .engage__icon--heart { transform: scale(.92); }

@keyframes engage-heart-pop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.28); }
  100% { transform: scale(1); }
}
.engage__like.is-popping .engage__icon--heart { animation: engage-heart-pop .28s ease; }

@media (prefers-reduced-motion: reduce) {
  .engage__disc::before { animation: none; opacity: .45; }
  .engage__disc::after { animation: none; opacity: .3; }
  .engage__disc, .engage__icon--heart { transition: none; }
  .engage__like.is-popping .engage__icon--heart,
  .engage__like:hover .engage__icon--heart,
  .engage__like:active .engage__icon--heart { animation: none; transform: none; }
  .engage__like:hover .engage__disc { translate: none; }
}

/* 列表頁：只顯示「眼睛＋觀看數」，比文章頁的 .engage 更低調一階。 */
.engage-views {
  margin-left: 1em;
  vertical-align: middle;
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  font-size: 13px;
  color: var(--ink-2, #46463f);
  opacity: 0.7;
}

.engage-views .engage__icon {
  width: 14px;
  height: 14px;
}

.engage-views__count {
  font-variant-numeric: tabular-nums;
}

/* 商品已售出份數：純文字佐證，不搶主要價格與規格的視覺權重。 */
.menu-sold {
  font-size: 13px;
  color: var(--ink-2, #46463f);
  opacity: 0.75;
  margin: 0.2em 0 0;
}

/* ===== 首頁「每日動態」卡帶（.stories）：主視覺下方、文章區上方 =====
   2026-09-15 第二版（Vic：尺寸太小、節奏太擠）：
   - 卡片改 4:5 直式大卡，跟圖卡原比例一致；手機 132×165（露出 2.5 張暗示可滑）、桌機 200×250。
   - 標題區沿用 Writing 的語彙（小 eyebrow＋展示字），置中；上方留白與 Writing 同一節奏，
     底部一條短縱線當段落之間的「間」，再進 Writing。
   - 卡片標題最多兩行、行高 1.5，固定兩行高度讓整排底線對齊。
   - 24 小時內的卡片外圈呼吸光環，沿用 engage 動效語言（偽元素只動 opacity，尺寸固定），
     週期 5s 與觀看 9s、讚 7s、背景 11s、LINE 鈕 4s 互質；reduced-motion 停止。
   - 橫向捲動只發生在清單內部；卡片不足一排時置中。
   - 超出一排時慢速自動輪播（16px/s，無縫循環，互動即暫停，見 assets/stories.js）。 */
.stories[hidden] { display: none !important; }
.stories { padding: clamp(56px, 8vw, 104px) 0 0; }
.stories__head { text-align: center; margin-bottom: clamp(20px, 3vw, 36px); }
.stories__eyebrow { margin: 0 0 .5em; }
.stories__display {
  margin: 0;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(24px, 3.2vw, 36px);
  letter-spacing: .32em;
  text-indent: .32em;
  line-height: 1.2;
}
.stories__list {
  --card-w: 200px;
  --card-h: 250px;
  display: flex;
  gap: clamp(20px, 2.4vw, 32px);
  margin: 0 -14px;
  padding: 14px 14px 6px;
  scroll-padding-inline: 14px;
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.stories__list::-webkit-scrollbar { display: none; }
@media (hover: hover) and (pointer: fine) {
  .stories__list { scrollbar-width: thin; padding-bottom: 14px; }
  .stories__list::-webkit-scrollbar { display: block; height: 6px; }
}
.stories__item { flex: 0 0 var(--card-w); scroll-snap-align: start; }
.stories__item:first-child { margin-left: auto; }
.stories__item:last-child { margin-right: auto; }
.stories__link {
  display: grid;
  gap: 12px;
  min-height: 44px;
  color: var(--ink);
  text-decoration: none;
  border-radius: 18px;
}
.stories__link:focus-visible { outline: 2px solid var(--ink); outline-offset: 6px; }
.stories__ring {
  position: relative;
  isolation: isolate;
  display: block;
  width: var(--card-w);
  height: var(--card-h);
  border-radius: 18px;
  /* 緩慢呼吸：13s 與 5s 光環、9s／7s engage、11s 背景、4s LINE 鈕互質；
     每張錯開相位（--i 由 stories.js 設定），整排像海浪一樣輪流起伏，不會同時脈動。 */
  animation: stories-breathe 13s ease-in-out infinite;
  animation-delay: calc(var(--i, 0) * -2.2s);
}
@keyframes stories-breathe {
  0%, 100% { scale: 1; }
  50%      { scale: 1.022; }
}
/* 自動輪播時關掉吸附，否則每一步都會被拉回卡片邊緣 */
.stories__list--auto { scroll-snap-type: none; }
.stories__list--auto .stories__item:first-child { margin-left: 0; }
.stories__list--auto .stories__item:last-child { margin-right: 0; }
.stories__thumb {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 18px;
  border: 1px solid var(--line);
  background: var(--card);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .06);
  transition: translate .3s ease, box-shadow .3s ease;
}
.stories__ext {
  position: absolute;
  right: 8px;
  bottom: 8px;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: rgba(244, 244, 242, .92);
  color: var(--ink);
  font-size: 13px;
  line-height: 1;
}
.stories__item--fresh .stories__ring::before,
.stories__item--fresh .stories__ring::after {
  content: "";
  position: absolute;
  pointer-events: none;
  animation: 5s ease-in-out infinite;
}
.stories__item--fresh .stories__ring::before {
  inset: -12px;
  z-index: -1;
  border-radius: 28px;
  background: radial-gradient(closest-side, rgba(255, 255, 255, .95), rgba(255, 255, 255, 0));
  animation-name: engage-glow;
}
/* 2026-09-16：原本是會放大到 1.14 倍的細環，橫向捲動列裡會壓到隔壁卡片。
   改成固定尺寸的 box-shadow 柔光，只有亮度在呼吸。 */
.stories__item--fresh .stories__ring::after {
  inset: -6px;
  border-radius: 23px;
  box-shadow: 0 0 9px 1px rgba(17, 17, 17, .26);
  animation-name: engage-breathe;
}
.stories__title {
  display: -webkit-box;
  overflow: hidden;
  min-height: 3em;
  padding: 0 2px;
  font-size: 15px;
  line-height: 1.5;
  letter-spacing: .02em;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}
.stories::after {
  content: "";
  display: block;
  width: 1px;
  height: 48px;
  margin: clamp(36px, 5vw, 56px) auto 0;
  background: var(--line);
}
@media (hover: hover) {
  .stories__link:hover .stories__thumb { translate: 0 -4px; box-shadow: 0 12px 26px rgba(0, 0, 0, .1); }
}
@media (max-width: 720px) {
  .stories__list { --card-w: 132px; --card-h: 165px; gap: 16px; }
  .stories__title { font-size: 14px; }
  .stories__ext { width: 24px; height: 24px; right: 6px; bottom: 6px; font-size: 12px; }
}
@media (prefers-reduced-motion: reduce) {
  .stories__ring { animation: none; }
  .stories__item--fresh .stories__ring::before { animation: none; opacity: .45; }
  .stories__item--fresh .stories__ring::after { animation: none; opacity: .3; }
  .stories__thumb { transition: none; }
}
