/* ═══════════════════════════════════════════════════════════════════════════
   ⚠️⚠️⚠️  暫 代 C S S  ——  設計方交付正式 a2.css 後【整檔替換】，DOM 不動  ⚠️⚠️⚠️
   ═══════════════════════════════════════════════════════════════════════════

   2026-08-30 為了 App 內 WKWebView 真預覽（M0 E 段 Phase 1）而寫。
   正式的 a2.css 由 Kelly／外部設計方提供（test/README.md），不在我們手上。

   這份的規則：
   · 只認 docs/dom-structure-for-css.md 的 class 契約——§3 藏顯表、§4 product-card
     grid 重排、§2.1 頁首 logo 兩態，都照契約做，所以正式 CSS 進來時只換皮不動骨
   · 每一條都掛在 .tpl-a2 底下（契約 §1：a2/b2 兩份同時載入，不掛會互相污染）
   · 字型：內文 Noto Sans TC（思源黑）、**標題與價格 Noto Serif TC（宋體）**
     ——renderer 的 <head> 自己有連 Google Fonts，線上吃得到；系統字留在 stack 最後，
     WKWebView 離線時安靜退過去，這份 CSS 不另外連字型。
     ⚠️ **標題 2026-09-01 從 LXGW WenKai TC（手寫體）改成宋體**（Kelly），
     而且**不再把 PingFang TC 墊在 Noto 前面**——墊前面等於有蘋方的機器一律用蘋方
   · <img> 都墊灰斜紋底：fixture 的圖是 assets/… 相對路徑，App bundle 裡沒有檔案，
     破圖時露出的就是這層底——跟線框的 .ph 佔位同一個語彙，看起來是佔位不是壞掉

   視覺依據：design/wireframe/templates.mjs 的 A2（卡片式）。
   色票：墨黑 #1a1c1a（2026-08-30 跟設計師成品稿，原 #1f1d1a）／米白 #faf9f6（2026-08-30 跟設計師成品稿的 surface，原 #fbfaf7）／襯底 #f4f1ea／邊線 #e3dfd4／次要字 #6f6a60。
   ⚠️ qa/PLAN.md §5 的「a2.css 出現就開頁首擠爆檢查」對這份先不開（PLAN 內有註記）。
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 基底 ─────────────────────────────────────────────────────────────────── */
body.tpl-a2 {
  margin: 0;
  background: #faf9f6;
  color: #1a1c1a;
  font-family: "Noto Sans TC", "PingFang TC", -apple-system, sans-serif;
  font-size: 15px;
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
}
.tpl-a2 *, .tpl-a2 *::before, .tpl-a2 *::after { box-sizing: border-box; }
/* 標題＝**宋體**（2026-09-01 Kelly：「主標記得改宋體，第一順序宋體 Noto Serif TC、
   第二思源黑，都用 Google 的」）。
   ⚠️ **在這之前是 `LXGW WenKai TC`（手寫體）**——那是 08-30 照設計師成品稿設的，
      不是壞掉，是被推翻了。⚠️ **`docs/dom-structure-for-css.md` §6 那條「A2 標題
      LXGW WenKai TC」要一起改**，不然外部設計方拿到的規格書還是舊的。
   ⚠️ **不再墊 `PingFang TC` 在 Noto 之前**：墊在前面的話，任何一台有蘋方的機器都會
      直接用蘋方——而那正是 Kelly 看到的「還是蘋方」。系統 fallback 留在最後就好。 */
.tpl-a2 h1, .tpl-a2 h2, .tpl-a2 h3 {
  margin: 0;
  font-family: "Noto Serif TC", "Noto Sans TC", serif;
  line-height: 1.3;
}
.tpl-a2 p { margin: 0; }
.tpl-a2 a { color: inherit; text-decoration: none; }
.tpl-a2 button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
/* 破圖時露出的佔位底（理由見檔頭）。真的圖片載入後不透明，蓋掉這層。 */
.tpl-a2 img {
  background: #e9e8e5 repeating-linear-gradient(135deg, transparent 0 14px, #dcdbd7 14px 15px);
}
.tpl-a2 .eyebrow {
  font-size: 13px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #1a1c1a;
}

/* ── 頁首（logo 規則整段照 dom-structure-for-css.md §2.1，不要改動） ──────── */
/* 2026-08-30 Kelly 拍板：header 改 sticky 毛玻璃（設計師成品稿的做法），
   原本的「不 sticky 待決格」關閉。
   ⚠️ 毛玻璃一定要做在 ::before 上，不能把 backdrop-filter 加在 .site-header 本體：
   漢堡選單（.menu，position: fixed）住在 header 裡面，祖先一帶 filter／backdrop-filter，
   fixed 的定位基準就從視窗變成 header——選單會縮在頂上那 64px 裡，而且不報錯。
   偽元素不是祖先，沒有這個問題。 */
.tpl-a2 .site-header {
  display: flex;
  align-items: center;      /* ⚠️ 不要拿掉：flex 預設 stretch 會把 logo 拉變形（§2.1-4） */
  gap: 12px;
  /* 上下 3：漢堡 48 命中區＋6＝54，跟 /p、商品單頁頂列同高（Kelly 2026-10-06：原本 16／80 高）。 */
  padding: 3px 20px;
  position: sticky;
  top: 0;
  /* z-index 在 site.css（兩套皮共用，選單疊層的理由寫在那裡） */
  box-shadow: 0 1px 8px rgba(0, 0, 0, 0.04);
}
.tpl-a2 .site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(250, 249, 246, 0.8);
  -webkit-backdrop-filter: blur(24px);
  backdrop-filter: blur(24px);
}
.tpl-a2 .site-header .brand-logo {
  max-height: 32px;         /* ⚠️ max-height 不是 height：height＋max-width 會橫向壓扁（§2.1-1） */
  max-width: 160px;
  width: auto;
  height: auto;
  object-fit: contain;
  flex: 0 0 auto;           /* logo 不讓步（Kelly 2026-08-29 拍板） */
}
.tpl-a2 .site-header .brand {
  flex: 0 1 auto;
  min-width: 0;             /* ⚠️ 拿掉店名就不截字、會把漢堡推出畫面（§2.1-3） */
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 17px;
  font-weight: 500;   /* 成品稿全站只有兩處不是 400：這裡（品牌名 500）跟購物車角標（700） */
  letter-spacing: 0.02em;
}
.tpl-a2 .site-header .brand ~ .menu-open { margin-left: auto; }
/* 只顯示 logo（預設）：放開 160 上限。⚠️ :has() 這條只放寬不收緊（§2.1-6） */
.tpl-a2 .site-header:has(.brand.off) .brand-logo {
  max-width: 100%;
  min-width: 0;
  flex: 0 1 auto;
}
.tpl-a2 .brand-logo.off, .tpl-a2 .brand.off { display: none; }
/* 2026-08-30 Kelly：漢堡不要外框——裸的三條線（成品稿也是裸圖示）。
   48×48 是透明的命中區，看起來只有圖示、按起來還是一整塊。關閉的 × 跟它是
   同一對控制項，一起裸掉（開著沒框、關著有框會像兩個不同的東西）。 */
.tpl-a2 .menu-open {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;              /* 可點區最小 48（契約 §6） */
  height: 48px;
}

/* ── 選單（抽屜寬度與左側進場動畫由 site.css 共用） ────────────────────────────── */
.tpl-a2 .menu { position: fixed; inset: 0; z-index: 50; }
.tpl-a2 .menu[hidden] { display: none; }
.tpl-a2 .menu-scrim { position: absolute; inset: 0; background: rgba(26, 28, 26, 0.5); }
.tpl-a2 .menu-sheet {
  position: relative;
  display: flex;
  flex-direction: column;
  background: #faf9f6;
  border-radius: 26px;
  margin: 6px 10px;
  max-height: calc(100dvh - 12px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 20px 20px 28px;
  box-shadow: 0 12px 28px rgba(26, 28, 26, 0.2);
}
.tpl-a2 .menu-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 16px;
}
.tpl-a2 .menu-head .brand { font-size: 17px; font-weight: 500; letter-spacing: 0.02em; }   /* 跟 header 的品牌名同字重 */
.tpl-a2 .menu-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
}
.tpl-a2 .menu-item {
  display: flex;
  align-items: center;
  min-height: 48px;
  font-size: 17px;
  font-weight: 400;
  letter-spacing: 0.04em;
}
.tpl-a2 .menu-no { display: none; }   /* §3：編號只有 B2 顯示 */

/* ── hero（4:5，標題疊圖上貼左下，點列疊圖下緣） ─────────────────────────── */
.tpl-a2 .hero { position: relative; }
.tpl-a2 .hero-media {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: #8c8b87;
}
/* 輪播是原生橫向捲動（2026-08-30 Kelly：「希望輪播可以有滑動感」）：
   圖排在 .hero-track 上讓瀏覽器自己捲，慣性與吸附都是原生的，JS 只同步點點。
   scroll-snap-stop: always ＝ 一次滑一張，快甩不會跳過中間的圖。 */
.tpl-a2 .hero-track {
  position: absolute;
  inset: 0;
  display: flex;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x mandatory;
}
/* 藏捲軸（手機本來就沒有可見捲軸，桌機露一條很醜）。⚠️ 兩個橫向捲動的地方
   共用這一條：分開寫的話第三個出現時會有三份。 */
.tpl-a2 .hero-track,
.tpl-a2 .product-filters { scrollbar-width: none; }
.tpl-a2 .hero-track::-webkit-scrollbar,
.tpl-a2 .product-filters::-webkit-scrollbar { display: none; }
.tpl-a2 .hero-img {
  width: 100%;
  height: 100%;
  flex-shrink: 0;
  object-fit: cover;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}
/* 裝飾性 scrim，讓白字疊在任何照片上都讀得到（偽元素只做裝飾，契約 §1 允許）。
   只壓主標那一段（Kelly 2026-10-07：原本蓋到 55%，太多）：主標區塊手機／電腦都是
   底部往上 120，所以用固定 220px 而不是百分比——4:5 跟 4:3 兩種高度暗的範圍一樣。 */
.tpl-a2 .hero-media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(26, 28, 26, 0.55), rgba(26, 28, 26, 0) 220px);
  pointer-events: none;
}
.tpl-a2 .hero-text {
  position: absolute;
  left: 24px;
  right: 24px;
  bottom: 44px;
  z-index: 1;
  color: #faf9f6;
  display: flex;
  flex-direction: column;
  gap: 8px;
  /* 標題疊在輪播上，不吃手勢——沒有這條，從標題那塊起手的拖曳會滑不動圖。 */
  pointer-events: none;
}
.tpl-a2 .hero-title { font-size: 32px; font-weight: 400; line-height: 1.25; }
.tpl-a2 .hero-sub { font-size: 16px; }
.tpl-a2 .hero-strip {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 16px;
  z-index: 1;
  display: flex;
  justify-content: center;
}
.tpl-a2 .hero-caption { display: none; }   /* §3：照片說明只有 B2 顯示 */
.tpl-a2 .dots { display: flex; gap: 8px; align-items: center; }
.tpl-a2 .dots i {
  width: 6px;
  height: 6px;
  border-radius: 3px;
  background: rgba(250, 249, 246, 0.4);
  cursor: pointer;
}
.tpl-a2 .dots i.on { width: 24px; background: #faf9f6; }

/* ── 區塊共通 ─────────────────────────────────────────────────────────────── */
.tpl-a2 .sec {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 48px 20px;
}
.tpl-a2 .rule { display: none; }          /* §3：短黑槓只有 B2 顯示 */
.tpl-a2 .sec-title { font-size: 26px; font-weight: 400; }
.tpl-a2 .sec-text { font-size: 15px; line-height: 1.75; }
.tpl-a2 .sec-photo {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: 12px;
  border: 1px solid #e3dfd4;
}
.tpl-a2 .sec-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
/* 2026-08-30 Kelly：「左右滑 →」要跟 eyebrow 同一列置右（Gallery 與 Video 都是），
   所以「eyebrow 獨佔一行」只留給 Products——它下面那行是區塊大標，不是提示字。 */
.tpl-a2 .sec-products .sec-head .eyebrow { flex-basis: 100%; }
/* 2026-08-30 Kelly：英文 eyebrow 跟中文大標要靠近（成品稿是 gap-2＝8px）。
   區塊的 gap 是 24，負 margin 收 16 → 有效間距 8。⚠️ 只抓 .sec 的**直接**子元素：
   Products 的標題住在 .sec-head 裡（gap 已是 8），抓進來會疊成負的。
   用 ~ 不用 +：About 的 eyebrow 和標題中間隔著一條 B2 才顯示的 .rule。
   ⚠️ 這條負 margin 是「跟 gap 24 配對」的值——區塊自己的 gap 不是 24 的，
   要跟著給一條配對的覆寫（下面 FAQ 那條），不然有效間距會各組不一樣
   （08-30 量出 FAQ 是 0、其他 8，Kelly 一眼看出來）。 */
.tpl-a2 .sec > .eyebrow ~ .sec-title { margin-top: -16px; }
/* FAQ 的 gap 是 16：16−8＝8，跟大家一致。
   ⚠️ 選擇器要跟上面那條長得一樣（同權重、寫在後面才蓋得過）——
   少寫 .eyebrow ~ 會輸在 specificity，而且畫面上只是「怎麼還是 0」。 */
.tpl-a2 .sec-faq > .eyebrow ~ .sec-title { margin-top: -8px; }
.tpl-a2 .hint { font-size: 14px; color: #6f6a60; }

/* ── Gallery（橫向捲動，右緣出血提示「還有更多」） ───────────────────────── */
.tpl-a2 .sec-gallery { background: #f4f1ea; padding-right: 0; }
.tpl-a2 .sec-gallery .sec-head { padding-right: 20px; }
.tpl-a2 .gallery-scroller {
  display: flex;
  gap: 16px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-right: 20px;
  /* 2026-08-30 Kelly：跟設計師成品稿加 snap，滑動吸附到每張卡（video 同一組）。 */
  scroll-snap-type: x mandatory;
}
.tpl-a2 .gallery-img {
  /* 2026-08-30 Kelly：第一畫面要看得到一點點第二張（成品稿的出血提示）。
     卡寬跟著視口算：60 ＝ 左 padding 20 ＋ gap 16 ＋ 露出 24（成品稿 390 實測）。
     ⚠️ 不要改回定值——寫死 332 在 390 有 22px 露出，但 App 預覽的 WKWebView
     視口約 366，第二張的起點剛好掉出畫面，露出變 0 而且沒有任何錯誤。
     cap 332 是給寬視口的：桌機上卡不會跟著螢幕長到滿版（video 同一組值）。 */
  width: min(calc(100vw - 60px), 332px);
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: 12px;
  border: 1px solid #e3dfd4;
  flex-shrink: 0;
  scroll-snap-align: center;
}

/* ── Products：唯一要 grid 重排的一塊（契約 §4，價格從 .product-meta 搬到名稱旁） ─ */
.tpl-a2 .sec-products { gap: 24px; }
.tpl-a2 .product-card {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "photo    photo"
    "name     price"
    "duration duration"
    "desc     desc"
    "open     open";
  background: #fff;
  border: 1.5px solid #e3dfd4;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 1px 2px rgba(26, 28, 26, 0.05);
  position: relative;       /* 商品標籤壓在照片左上角（site.css `.catalog-tag`） */
}
.tpl-a2 .product-photo {
  grid-area: photo;
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: contain;
  background: #fff;
}
/* 首頁商品卡：手機 5:4 顯示框，圖片保留原比例（Kelly 2026-09-25）；桌機 3:2。 */
@media (max-width: 767px) {
  .tpl-a2 .product-photo { aspect-ratio: 5 / 4; }
}
.tpl-a2 .product-name {
  grid-area: name;
  margin: 20px 0 0 20px;
  font-size: 20px;
  /* ⚠️ **維持 400 是沿用原本的視覺，不再是字型的限制**（2026-09-01）：
     這條原本寫的是「手寫體只有 400，寫 700 是瀏覽器偽造的粗體」——標題換成
     Noto Serif TC 之後 500／700 都是真的字重（`<head>` 那條 link 有帶）。
     **要不要變粗是設計決定，不是順手改**。 */
  font-weight: 400;
}
.tpl-a2 .product-meta { display: contents; }  /* §4：讓 duration／price 直接成為 grid item */
.tpl-a2 .product-price {
  grid-area: price;
  /* 2026-08-30 Kelly：價格要跟方案名稱平行——margin-top 跟 .product-name 同一個 20，
     line-height 也收成跟 h3 通則同一個 1.3（不寫的話吃 body 的 1.75，
     字盒高出 8px，看起來就是價格往下掉）。成品稿是 items-start 的頂對齊。 */
  margin: 20px 20px 0 16px;
  /* 價格走襯線（成品稿的 font-tabular-price＝Noto Serif TC），跟內文的黑體分開。 */
  font-family: "Noto Serif TC", "PingFang TC", serif;
  font-size: 18px;
  font-weight: 400;   /* 它是 <b>，不壓回 400 會是 700——稿子上價格沒有加粗 */
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.tpl-a2 .product-duration {
  grid-area: duration;
  margin: 12px 20px 0;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  color: #6f6a60;
}
.tpl-a2 .product-desc {
  grid-area: desc;
  margin: 12px 20px 20px;
  font-size: 14px;
  line-height: 1.75;
  display: -webkit-box;
  -webkit-line-clamp: 2;                   /* §3：A2 截 2 行 */
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.tpl-a2 .product-rule, .tpl-a2 .product-cta { display: none; }   /* §3：A2 整卡可點、不放鈕 */
/* 卡底那條「看方案內容 →」（08-25 拍板的系統固定列，暫代 CSS 一直漏做，
   2026-08-30 Kelly 對設計師成品稿抓到）。它不是按鈕——整張卡本來就可點，
   這一列只是把「可以點」說出來。B2 藏（B2 用 .product-cta 膠囊鈕）。 */
.tpl-a2 .product-open,
.tpl-a2.product-list .product-cta {
  grid-area: open;
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* 上緣不再自己加 margin：描述的 margin-bottom 20 就是跟框線的距離
     （2026-08-30 Kelly 對稿抓到 20＋20 疊成 40，稿子只有 20）。 */
  padding: 16px 20px;
  border-top: 1.5px solid #e3dfd4;
  font-size: 15px;
}

/* ── FAQ（白卡＋展開收合；第一題 renderer 給 .open） ─────────────────────── */
.tpl-a2 .sec-faq { gap: 16px; }
.tpl-a2 .faq-item {
  background: #fff;
  border: 1.5px solid #e3dfd4;
  border-radius: 12px;
  padding: 4px 16px;
  box-shadow: 0 1px 2px rgba(26, 28, 26, 0.05);
}
.tpl-a2 .faq-q {
  display: flex;
  /* 2026-08-30 Kelly：＋要跟問題上下置中（成品稿是 items-center）。
     原本 flex-start 是替折行的長問題著想，但單行時＋會掉到字的下緣。 */
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  min-height: 48px;
  padding: 12px 0;
  text-align: left;
}
/* FAQ 問題是黑體不是手寫體（成品稿）：h1–h3 的手寫體通則到這裡要讓路——
   問題是資訊不是標題字，手寫體 15px 在灰底上會糊。 */
.tpl-a2 .faq-q h3 { font-family: "Noto Sans TC", "PingFang TC", sans-serif; font-size: 15px; font-weight: 400; line-height: 1.5; }
/* line-height 1（不是 1.5）：字盒跟字同高，置中才置得準。
   顏色收成墨黑——#8a857a 是 08-28 之前的舊說明字色，稿上這顆是 on-surface。 */
.tpl-a2 .faq-toggle { flex-shrink: 0; font-size: 20px; line-height: 1; color: #1a1c1a; }
.tpl-a2 .faq-toggle::after { content: "+"; }
.tpl-a2 .faq-item.open .faq-toggle::after { content: "\2212"; }
.tpl-a2 .faq-a { display: none; }
.tpl-a2 .faq-item.open .faq-a { display: block; font-size: 14px; padding: 0 0 14px; }

/* ── 影片 ──────────────────────────────────────────── */
/* 2026-08-30 Kelly：影片改橫滑，跟 gallery 同一種右緣出血節奏（卡寬也取同一個 332）。 */
.tpl-a2 .sec-video { padding-right: 0; }
.tpl-a2 .sec-video .sec-head { padding-right: 20px; }
.tpl-a2 .video-scroller {
  display: flex;
  gap: 16px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-right: 20px;
  scroll-snap-type: x mandatory;
}
/* 2026-08-31 影片改成真的 iframe embed（縮圖與播放都由 YouTube 給）。
   ⚠️ 這一組現在只剩**共用的盒子**：卡寬、16:9、圓角、snap——iframe 與 fallback 都吃。
   斜線灰底與播放圓鈕搬到 .video-fallback，**不要搬回來**：那層底會從 iframe 的邊緣
   露出來一圈，而那看起來只是「這支影片的邊框怪怪的」。 */
.tpl-a2 .video-item {
  /* 跟 .gallery-img 同一組值與理由（60 的組成、為什麼不能寫死）——見那邊的註解。 */
  width: min(calc(100vw - 60px), 332px);
  flex-shrink: 0;
  scroll-snap-align: center;
  aspect-ratio: 16 / 9;
  border-radius: 12px;
  border: 1px solid #e3dfd4;
}
/* ⚠️ iframe 預設是 inline，底下會多一條 baseline 的縫（看起來像卡片沒對齊）。 */
.tpl-a2 iframe.video-item { display: block; background: #e9e8e5; }
/* 解析不出 YouTube id 的退路（**只有 App 草稿預覽走得到**，發佈路徑在 render() 就 throw）。
   這就是 08-31 之前所有影片的長相：斜線灰底＋一顆播放圓鈕。 */
.tpl-a2 .video-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #e9e8e5 repeating-linear-gradient(135deg, transparent 0 14px, #dcdbd7 14px 15px);
}
.tpl-a2 .video-fallback svg {
  box-sizing: content-box;
  padding: 16px;
  border-radius: 50%;
  background: rgba(26, 28, 26, 0.75);
  color: #faf9f6;
}

/* ── 社群與連結（白灰鍵帽，置中文字與兩側圖示） ───────────────────────── */
.tpl-a2 .sec-links { background: #f4f1ea; }
.tpl-a2 .links-list { display: flex; flex-direction: column; gap: 18px; }
.tpl-a2 .link-item {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr) 20px;
  align-items: center;
  gap: 12px;
  min-height: 64px;
  padding: 16px 22px;
  background: #fff;
  color: #303030;
  border: 1px solid #b6b6b6;
  border-radius: 999px;
  box-shadow: 0 4px 0 #a1a1a1, 0 5px 0 #b6b6b6;
}
.tpl-a2 .link-label { min-width: 0; text-align: center; overflow-wrap: anywhere; font-size: 15px; font-weight: 500; }
.tpl-a2 .link-item > svg { color: #707070; }
.tpl-a2 .link-item:active { transform: translateY(3px); box-shadow: 0 1px 0 #a1a1a1, 0 2px 0 #b6b6b6; }

/* ── 購物車浮動鈕（一定在 DOM，JS 控顯隱） ───────────────────────────────── */
.tpl-a2 .cart-fab {
  position: fixed;
  right: 20px;
  bottom: 24px;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 58px;
  height: 58px;
  border-radius: 50%;
  background: #1a1c1a;
  color: #faf9f6;
  box-shadow: 0 4px 14px rgba(26, 28, 26, 0.28);
}
.tpl-a2 .cart-fab[hidden] { display: none; }
.tpl-a2 .cart-count {
  position: absolute;
  top: -3px;
  right: -3px;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border-radius: 11px;
  background: #bc5816;
  color: #faf9f6;
  border: 2px solid #faf9f6;
  font-size: 12px;
}

/* ── 頁尾（付款回報入口＋版權行） ────────────────────────────────────────── */
.tpl-a2 .site-footer {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 32px 20px 40px;
}
.tpl-a2 .copyright { text-align: center; font-size: 13px; color: #6f6a60; }

/* ═══════════════════════════════════════════════════════════════════════════
   商品總覽 `/p`（2026-09-02）——依據設計方交付的 `p2-products-a2.html`
   ═══════════════════════════════════════════════════════════════════════════
   ⚠️ 這一段跟整份檔一樣是**暫代**：正式 a2.css 進來時整檔替換、DOM 不動。
   ⚠️ **`/p` 是第二套版面**（Kelly 2026-09-02 拍板，推翻 url-routes §3.3 舊條）：
      它有自己的頁首（返回＋店名）、標題、分類篩選。**卡片本身仍然是同一顆
      `.product-card`**，所以上面那整段 grid 重排在這裡原封不動生效——
      ⚠️ 不要為列表頁另外寫一套卡片樣式，那會變成同一批卡片有兩種長相。
   ⚠️ **兩種掛法，分界是「這條規則有沒有在覆寫首頁已經有的 class」：**
      · `/p` 專屬的 class（`.list-nav`／`.product-filter…`）→ `.tpl-a2 .list-nav`，
        它們只存在於這一頁，不用再限定頁
      · **覆寫首頁既有 class 的**（`.sec-title`／`.product-open`／`.product-cta`）
        → `.tpl-a2.product-list …`，不限定頁就會把首頁一起改掉
      ⚠️ **`.tpl-a2.product-list` 中間沒有空格**（兩個 class 都在 `<body>` 上）。
      寫成 `.tpl-a2 .product-list` 是後代選擇器，一條都選不中。 */

.tpl-a2 .list-nav {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 54px;
  padding: 0 16px 0 8px;
  background: #fff;
  border-bottom: 1px solid #e3dfd4;
}
/* ⚠️ 視覺 22、命中區 44（跟 App 那邊同一條）：把 44 寫成視覺會把整條列撐高。 */
.tpl-a2 .list-back {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  color: #1a1c1a;
}
/* ⚠️ **四條截字保護不能省**（跟首頁 `.site-header .brand` 同一組，§2.1-3）：
   少了它們，長店名會把返回鍵擠出畫面——而那在示範資料上看不出來。 */
.tpl-a2 .list-nav .brand {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* 跟首頁 header 的店名同一組：黑體 500（Kelly 2026-09-25） */
  font-family: "Noto Sans TC", "PingFang TC", sans-serif;
  font-size: 17px;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0.02em;
}
.tpl-a2 .list-body {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 20px 20px 28px;
}
/* 外層已提供首頁同樣的 20px 留白，避免商品區重複縮窄卡片。 */
.tpl-a2 .list-body > .sec-products { padding-inline: 0; }
/* 標題那一組沿用首頁的 `.sec-head`／`.eyebrow`／`.sec-title`，只在這一頁改字級——
   ⚠️ 這一頁的標題是 `<h1>` 不是 `<h2>`（它是這一頁的主標，不是首頁的一個區塊）。 */
.tpl-a2.product-list .sec-head { display: flex; flex-direction: column; gap: 4px; }
/* 字型、字級、字重在 site.css 的 `.product-list.tpl-a2 .sec-title`（黑體 26／400，2026-10-06）。 */
.tpl-a2.product-list .sec-title {
  margin: 0;
  letter-spacing: -0.015em;
}

/* ── 分類篩選 ─────────────────────────────────────────────────────────────
   ⚠️ **橫向可捲、不換行**（`overflow-x: auto`）：換行的話分類一多，篩選器會把
      第一張商品卡推到螢幕外，而客人進這一頁是為了看商品。
   ⚠️ 捲軸藏起來但**保留捲動**——手機上本來就沒有可見捲軸，桌機露出一條會很醜。 */
.tpl-a2 .product-filters {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  margin: 0 -20px;      /* 出血到螢幕邊：捲到底時最後一格不會卡在 20px 的邊界裡 */
  padding: 2px 20px;    /* 2px 讓膠囊的陰影／外框不被裁掉 */
}
.tpl-a2 .product-filter {
  display: flex;
  align-items: center;
  gap: 5px;
  height: 36px;
  padding: 0 14px;
  flex-shrink: 0;
  border: 1px solid #e3dfd4;
  border-radius: 999px;
  background: #fff;
  color: #4a463f;
  font: inherit;
  font-size: 13.5px;
  cursor: pointer;
}
.tpl-a2 .product-filter.on {
  background: #1a1c1a;
  border-color: #1a1c1a;
  color: #fff;
  font-weight: 500;
}
/* 數量。⚠️ 用 tabular-nums：不然「1」跟「11」會讓膠囊寬度跳動。 */
.tpl-a2 .product-filter-count { font-style: normal; font-variant-numeric: tabular-nums; opacity: 0.65; }

/* ── 卡底那一行：`/p` 印商品自己的按鈕文字，首頁印系統固定字 ──────────────
   ⚠️ **兩個節點一直都在，只是各頁顯示不同的那一個**（契約 §1：用 display 藏、不要刪）。
      首頁：`.product-open`（「看內容」）；`/p`：`.product-cta`（店家寫的「我要報名」）。
   ⚠️ 這仍然**不是按鈕**——整張卡可點，這一列只是把「按下去會怎樣」說出來。 */
.tpl-a2.product-list .product-open { display: none; }
/* ⚠️ **它跟 `.product-open` 是同一個元件的兩個狀態，不是兩個元件**（同一格版面、
   同一件事，只是印的字不同）——所以盒模型跟著 `.product-open` 那一條走，
   這裡只覆寫真的不一樣的（靠右、gap、字重）。各寫一份的話，卡底那條分隔線
   改粗細要改兩個地方，而漏掉一邊只有把兩頁並排才看得出來。 */
.tpl-a2.product-list .product-cta {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
  font-weight: 500;
  letter-spacing: 0.04em;
}
/* 純裝飾的箭頭（契約 §1 允許裝飾性偽元素）。⚠️ 不要在這裡用 content 塞真資料。 */
.tpl-a2.product-list .product-cta::after {
  content: "";
  width: 7px;
  height: 7px;
  border: 1.6px solid currentColor;
  border-left: 0;
  border-bottom: 0;
  transform: rotate(45deg);
}

/* ── 售完（首頁與 /p 都標，Kelly 2026-09-02） ─────────────────────────────
   ⚠️ **照片是淡出不是蓋一層紗。** 稿子上是 62% 的紙色遮罩，效果一樣，
      但遮罩要一個能覆蓋整個照片格的節點，而照片是 3:2 自適應高度的 `<img>`
      ——淡出一行就做完，而且不會在圓角上露出直角。
   ⚠️ **標記不能只換 CTA 的字**：A2 的首頁卡不顯示 `.product-cta`，只換字的話
      A2 的店家在首頁完全看不出哪一個賣完了。 */
.tpl-a2 .product-card.is-soldout .product-photo { opacity: 0.38; }
.tpl-a2 .product-card.is-soldout .product-name,
.tpl-a2 .product-card.is-soldout .product-price { color: #6f6a60; }
/* 售完的標記（`.product-card-soldout`）2026-09-25 起跟其他商品標籤同一個樣子，
   壓在照片左上角——樣式在 site.css 的 `.catalog-tag`。這裡只剩照片變淡、字變灰。 */

/* Member access is a separate action at the bottom of the menu card. */
.tpl-a2 .menu-sheet { background: #fff; padding-bottom: calc(22px + env(safe-area-inset-bottom, 0px)); }
.tpl-a2 .menu-links { flex-shrink: 0; }
.tpl-a2 .menu-links .menu-item { min-height: 54px; border-bottom: 1px solid #e3dfd4; }
.tpl-a2 .menu-links .menu-item:last-child { border-bottom: 0; }
.tpl-a2 .menu-footer { margin-top: 20px; flex-shrink: 0; }
.tpl-a2 .menu-footer .member-entry { justify-content: center; min-height: 50px; padding: 12px 20px; border-radius: 999px; background: #1a1c1a; color: #fff; font: 500 15px/1.5 "Noto Sans TC", sans-serif; letter-spacing: .06em; }
