/* ==========================================================================
   GROVYN — 一坪森林 商品頁（pdp-forest.css）
   來源：學習skill/一坪森林/頁面版本-v3/T8-直骨架.html ＋ _tokens.css
   移植日：2026-08-30

   三層結構：
     1. 別名層 —— T8 用無前綴的 --bg / --fg，官網用 --ts-*。這裡做一次映射，
        T8 的 CSS 就一個字都不用改，之後 T8 有更新可以直接重跑轉換。
        深色模式不用另寫：--ts-* 已由 body.grovyn-dark-mode 翻轉，別名自動跟著走。
     2. 元件層 —— _tokens.css 的 .btn / .spec / .scent / .buybar 等
     3. 頁面層 —— T8 頁內的 185 行

   所有選擇器都加了 .pdp-forest scope，keyframes 加 gvf- 前綴，
   避免跟官網既有 CSS（.wrap / .sec / .btn 都是通用名）互相汙染。
   ========================================================================== */

/* ---------- 1. 別名層：T8 變數 → 官網 --ts-* ---------- */
.pdp-forest {
  /* 底與面 */
  --bg:           var(--ts-bg, #EEEAE7);
  --bg-alt:       var(--ts-bg-alt, #E8E5DA);
  --surface:      var(--ts-surface, #F8F6F2);
  --fg:           var(--ts-fg, #282C3C);
  /* ⚠️ 一定要用 --ts-fg-muted 不能用 --ts-ink-mute：
     shop-dark.css 只翻 7 個 semantic 變數（bg / bg-alt / surface / fg / fg-muted /
     border / border-strong），--ts-ink-mute 不在其中，深色模式下會留在淺色用的
     #5A5F6D，深底上直接隱形。2026-08-30 上線後踩到。 */
  --muted:        var(--ts-fg-muted, #5A6172);
  --ink-rule:     var(--ts-fg, #282C3C);
  --line:         var(--ts-border, rgba(40, 44, 60, 0.10));
  --line-strong:  var(--ts-border-strong, rgba(40, 44, 60, 0.22));

  /* 主色 */
  --accent:       var(--ts-forest, #495434);
  --accent-deep:  var(--ts-forest-deep, #2F371F);
  --accent-soft:  var(--ts-forest-soft, rgba(73, 84, 52, 0.12));
  --link:         var(--ts-forest, #495434);
  --focus:        var(--ts-forest, #495434);
  --moss:         var(--ts-moss, #A3AC99);
  --sun:          var(--ts-sun, #EEE78D);
  --peach:        var(--ts-peach, #EDCDC2);
  --warm-fill:    var(--ts-accent-warm, #B96B4D);
  --warm-ink:     var(--ts-accent-warm-ink, #964E31);

  /* 按鈕 */
  --btn-bg:       #EEE78D;  /* 2026-09-01 阿翰：主按鈕改成與底部固定列同一顆黃 */
  --btn-bg-hover: #F4EFA6;
  --btn-fg:       #282C3C;

  /* 陰影 */
  --shadow-sm: var(--ts-shadow-sm, 0 2px 6px rgba(40, 44, 60, 0.07), 0 1px 2px rgba(40, 44, 60, 0.04));
  --shadow-md: var(--ts-shadow-md, 0 6px 18px rgba(40, 44, 60, 0.10), 0 2px 5px rgba(40, 44, 60, 0.05));
  --shadow-lg: var(--ts-shadow-lg, 0 14px 36px rgba(40, 44, 60, 0.14), 0 4px 10px rgba(40, 44, 60, 0.06));

  /* 字體 */
  --font-serif:   var(--ts-font-serif-zh, "Noto Serif TC", "PingFang TC", "Songti TC", serif);
  --font-sans:    var(--ts-font-sans-zh, "Noto Sans TC", "PingFang TC", "Heiti TC", system-ui, sans-serif);
  --font-mono:    var(--ts-font-mono, "JetBrains Mono", "SF Mono", ui-monospace, Menlo, monospace);
  --font-display: var(--ts-font-serif-en-display, "Fraunces", "Iowan Old Style", Georgia, serif);

  /* 字級 */
  --t-xs:   var(--ts-text-xs, 12px);
  --t-sm:   var(--ts-text-sm, 14px);
  --t-base: var(--ts-text-base, 16px);
  --t-md:   var(--ts-text-md, 18px);
  --t-lg:   var(--ts-text-lg, 22px);
  --t-xl:   var(--ts-text-xl, 28px);
  --t-2xl:  var(--ts-text-2xl, 36px);
  --t-3xl:  var(--ts-text-3xl, 48px);

  /* 間距 */
  --sp-1: var(--ts-sp-1, 6px);
  --sp-2: var(--ts-sp-2, 12px);
  --sp-3: var(--ts-sp-3, 20px);
  --sp-4: var(--ts-sp-4, 32px);
  --sp-5: var(--ts-sp-5, 48px);
  --sp-6: var(--ts-sp-6, 64px);
  --sp-7: var(--ts-sp-7, 88px);
  --sp-8: var(--ts-sp-8, 120px);

  /* 圓角 */
  --r-xs:   var(--ts-radius-xs, 2px);
  --r-sm:   var(--ts-radius-sm, 6px);
  --r-md:   var(--ts-radius-md, 12px);
  --r-lg:   var(--ts-radius-lg, 20px);
  --r-full: var(--ts-radius-full, 9999px);

  /* 動態 */
  --ease:      var(--ts-ease-natural, cubic-bezier(0.33, 0.1, 0.25, 1));
  --ease-move: var(--ts-ease-standard, cubic-bezier(0.4, 0, 0.2, 1));
  --quick:     var(--ts-dur-quick, 180ms);
  --base-d:    var(--ts-dur-base, 280ms);
  --breath:    var(--ts-dur-breath, 520ms);

  /* 版面 */
  --gutter:    var(--ts-gutter, clamp(20px, 4vw, 48px));
  --topbar-h:  var(--ts-header-h, 72px);

  /* F1 · 明體管意境，黑體管事實。分工必須跟版面的分區對齊 */
  --font-mood: "Noto Serif TC", "Songti TC", "PingFang TC", serif;
  --font-fact: "Noto Sans TC", "PingFang TC", "Heiti TC", system-ui, sans-serif;
  /* 西文對譯一律斜體襯線（#234：首字母大寫的斜體，不是全大寫無襯線） */
  --font-gloss: "Fraunces", "Noto Serif TC", Georgia, serif;

  /* F3 · 寬字距是中文獨有、西文複製不來的手法 */
  --track-label: .19em;   /* 小標籤（C4：8 張範本 0.08–0.2em） */
  --track-wide:  .34em;   /* 章節標 */
  --track-block: .52em;   /* 兩字撐成塊（#248 約半個字身） */
  --track-full:  .82em;   /* 撐滿一行（#231 接近一個字身） */

  /* F2 · 明體沒有字重可用，級距不可壓到 3:1 以內。這兩級是為了做到 8:1 */
  --t-4xl: clamp(52px, 8.4vw, 96px);
  --t-5xl: clamp(72px, 13.5vw, 164px);

  /* F8 · 骨白，不是純白。壓在照片上的字用這個 */
  --bone: #E9E3D6;
}

/* 深色模式的用色鐵則（官網 CLAUDE.md §5-C #14，阿翰 2026-06-09 訂）：
   「深色模式（背景深藍）文字禁用深綠色 --ts-forest（對比不足隱形），
     強調色用陽光黃 --ts-sun #EEE78D、主文字用米色 --ts-cream。」
   --ts-forest 屬於 palette，shop-dark.css 不翻它，所以這裡要自己換掉，
   否則森林綠 #495434 在 navy #282C3C 上只有 1.72:1，連結、focus、
   選中框全部看不見。 */
body.grovyn-dark-mode .pdp-forest {
  /* 交替區塊的底色：官網全站的深色 --ts-bg-alt 是森林深綠 #2F371F，
     但這一頁的設計是「深藍 → 稍淺的藍」交替（T8 原本 #171A23 → #1C202C，
     明度差 1.069:1）。#2C3143 是在官網深色底 #282C3C 上調亮的同等級距：1.074:1。
     只覆蓋這一頁，不動全站 token。 */
  --bg-alt:      #2C3143;

  --accent:      var(--ts-sun, #EEE78D);
  --accent-deep: var(--ts-sun, #EEE78D);
  --accent-soft: rgba(238, 231, 141, .14);
  --link:        var(--ts-sun, #EEE78D);
  --focus:       var(--ts-sun, #EEE78D);
  --warm-ink:    #D6987E;   /* 萜烯橘的深色版：原色 #964E31 在深底上只有 2.4:1 */
}

/* 註：--bone 與 --deep-band 這兩個 T8 專屬 token 不在上面，
   它們的淺色／深色值都由下方元件層保留的原始 :root 規則提供
   （scope 腳本會把 :root 轉成 .pdp-forest、:root[data-theme="dark"] 轉成
   body.grovyn-dark-mode .pdp-forest）。在這裡重寫一份只會蓋錯值。 */

/* ---------- 1.5 Reset（只取頁面內容需要的，加了 scope） ----------
   來自 _tokens.css 的 Reset 區塊。原版是獨立 HTML，可以直接寫 body / html /
   ::selection / scrollbar；掛進官網後那些會汙染全站，所以只留下這頁版面真的
   依賴的幾條。**漏掉 img 那條會讓 1024px 原圖直接撐爆版面**（2026-08-30 實測踩到）。 */
.pdp-forest,
.pdp-forest *,
.pdp-forest *::before,
.pdp-forest *::after { box-sizing: border-box; }

/* ⚠️ 原版把 color / background / font 設在 body 上。移植時 body 規則被排除
   （會汙染全站），必須改設在容器上，否則整頁文字改成繼承官網的顏色。
   2026-08-30 上線後踩到：淺色模式碰巧同樣是深藍字所以看不出來，
   深色模式下 90 個元素的文字色變成 #282C3C 配 #282C3C 底，整片隱形。 */
.pdp-forest {
  color: var(--fg);
  background: var(--bg);
  font-family: var(--font-sans);
  font-size: var(--t-base);
  line-height: 1.85;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}
.pdp-forest img { max-width: 100%; display: block; height: auto; }
.pdp-forest h1,
.pdp-forest h2,
.pdp-forest h3,
.pdp-forest h4,
.pdp-forest p,
.pdp-forest figure,
.pdp-forest blockquote,
.pdp-forest dl,
.pdp-forest dd { margin: 0; }
.pdp-forest h1,
.pdp-forest h2,
.pdp-forest h3 { text-wrap: balance; }

/* ⚠️ 官網有多支 CSS 直接對 h1–h6 / 表格 / 摘要設 color。「直接設定」永遠贏過
   「繼承」，所以光在容器上設 color 不夠，這些標籤要各自寫回 inherit。
   2026-08-30 上線後踩到：容器修好後仍有 23 個標題在深色下隱形。
   這一段放在元件層與頁面層之前，後面自己設色的規則（例如標語上行的 --muted）
   照樣覆蓋得掉。 */
.pdp-forest h1, .pdp-forest h2, .pdp-forest h3,
.pdp-forest h4, .pdp-forest h5, .pdp-forest h6,
.pdp-forest p, .pdp-forest span, .pdp-forest em, .pdp-forest i,
.pdp-forest b, .pdp-forest strong, .pdp-forest small,
.pdp-forest figcaption, .pdp-forest th, .pdp-forest td,
.pdp-forest summary, .pdp-forest li { color: inherit; }
.pdp-forest p { text-wrap: pretty; }
.pdp-forest a { color: inherit; text-underline-offset: 4px; text-decoration-thickness: 1px; }
.pdp-forest button { font: inherit; color: inherit; }
.pdp-forest :focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: 2px; }
.pdp-forest input,
.pdp-forest textarea { caret-color: var(--accent); }

/* ---------- 2. 元件層（來自 _tokens.css） ---------- */
/* ---------- 圖示（單一線寬 1.6 · currentColor） ---------- */
.pdp-forest .ic { width: 22px; height: 22px; stroke: currentColor; fill: none;
      stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; flex: none; }

/* ---------- 標本標籤（The Specimen Label Rule） ---------- */
.pdp-forest .microlabel {
  font-family: var(--font-mono); font-size: 11px; font-weight: 500;
  letter-spacing: .14em; color: var(--muted);
}
.pdp-forest .tag {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 12px; background: var(--bg-alt); color: var(--fg);
  border-radius: var(--r-full);
  font-family: var(--font-mono); font-size: 11px; font-weight: 500; letter-spacing: .12em;
}

/* ---------- 按鈕 ---------- */
.pdp-forest .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  padding: 15px 30px; border: none; cursor: pointer;
  font-family: var(--font-sans); font-weight: 500;
  font-size: var(--t-base); letter-spacing: .04em;
  border-radius: var(--r-full);
  transition: background-color var(--base-d) var(--ease),
              color var(--base-d) var(--ease),
              border-color var(--base-d) var(--ease),
              box-shadow var(--base-d) var(--ease),
              transform var(--quick) var(--ease-move);
}
.pdp-forest .btn--primary { background: var(--btn-bg); color: var(--btn-fg); }
.pdp-forest .btn--primary:hover { background: var(--btn-bg-hover); box-shadow: var(--shadow-md); transform: translateY(-1px); }
.pdp-forest .btn--primary:active { transform: translateY(0); box-shadow: var(--shadow-sm); }
.pdp-forest .btn--ghost { background: transparent; color: var(--fg); border: 1px solid var(--line-strong); }
.pdp-forest .btn--ghost:hover { background: var(--bg-alt); border-color: var(--accent); transform: translateY(-1px); }
.pdp-forest .quiet-link {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 0; background: none; border: none;
  border-bottom: 1px solid currentColor; border-radius: 0;
  font-weight: 500; cursor: pointer;
  transition: color var(--base-d) var(--ease);
}
.pdp-forest .quiet-link:hover { color: var(--accent); }
.pdp-forest .quiet-link .ic { width: 15px; height: 15px; transition: transform var(--quick) var(--ease-move); }
.pdp-forest .quiet-link:hover .ic { transform: translateX(3px); }

/* ---------- 科學註（摺疊） ---------- */
.pdp-forest details.sci { margin-top: var(--sp-4); border-top: 1px solid var(--line); padding-top: var(--sp-3); }
.pdp-forest details.sci summary {
  cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .14em; color: var(--muted);
  transition: color var(--base-d) var(--ease);
}
.pdp-forest details.sci summary:hover { color: var(--fg); }
.pdp-forest details.sci summary::-webkit-details-marker { display: none; }
.pdp-forest details.sci summary::before {
  content: "＋"; font-family: var(--font-mono); color: var(--accent);
  transition: transform var(--base-d) var(--ease); display: inline-block;
}
.pdp-forest details.sci[open] summary::before { content: "－"; }
.pdp-forest details.sci .sci-body {
  margin-top: var(--sp-3); font-size: var(--t-sm); line-height: 1.9; color: var(--muted);
  max-width: 38em;
}
.pdp-forest details.sci a { color: var(--link); }

/* ---------- 規格表（The Cold Record） ---------- */
.pdp-forest .spec { width: 100%; border-collapse: collapse; font-size: var(--t-sm); }
.pdp-forest .spec th, .pdp-forest .spec td {
  padding: 13px 0; text-align: left; vertical-align: top;
  border-bottom: 1px solid var(--line);
}
.pdp-forest .spec th {
  width: 34%; font-weight: 500; color: var(--muted);
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .1em; padding-top: 16px;
}
.pdp-forest .spec td { font-variant-numeric: tabular-nums; }

/* ---------- 香型 · 完整列 ---------- */
.pdp-forest .scent {
  display: grid; grid-template-columns: 44px 1fr; gap: var(--sp-3); align-items: start;
  padding: var(--sp-4); width: 100%; text-align: left; cursor: pointer;
  background: var(--bg-alt); color: inherit;
  border: 1px solid transparent; border-radius: var(--r-md);
  transition: background-color var(--base-d) var(--ease),
              border-color var(--base-d) var(--ease),
              box-shadow var(--base-d) var(--ease),
              transform var(--quick) var(--ease-move);
}
.pdp-forest .scent:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.pdp-forest .scent[aria-pressed="true"] { border-color: var(--accent); background: var(--surface); }
.pdp-forest .scent__ico {
  width: 44px; height: 44px; display: grid; place-items: center;
  border: 1px solid var(--line-strong); border-radius: var(--r-full);
  color: var(--accent);
  transition: border-color var(--base-d) var(--ease), color var(--base-d) var(--ease);
}
.pdp-forest .scent[aria-pressed="true"] .scent__ico { border-color: var(--accent); }
.pdp-forest .scent__name { font-family: var(--font-serif); font-size: var(--t-lg); font-weight: 500; }
.pdp-forest .scent__mood {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .14em;
  color: var(--warm-ink); margin-left: 10px;
}
.pdp-forest .scent__line { margin-top: var(--sp-2); color: var(--muted); font-size: var(--t-sm); line-height: 1.8; }
.pdp-forest .scent__aroma { margin-top: var(--sp-2); font-size: var(--t-sm); }

/* ---------- 尺寸 · 技術圖 ---------- */
.pdp-forest .dim-figure { max-width: 460px; }
.pdp-forest .dim-figure svg { width: 100%; height: auto; display: block; }
.pdp-forest .dim-figure .d-solid { stroke: var(--accent); fill: var(--accent-soft); }
.pdp-forest .dim-figure .d-ghost { stroke: var(--line-strong); fill: none; stroke-dasharray: 4 4; }
.pdp-forest .dim-figure .d-ground { stroke: var(--line-strong); }
.pdp-forest .dim-figure .d-dim { stroke: var(--muted); }
.pdp-forest .dim-figure text {
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .08em;
  fill: var(--muted);
}
.pdp-forest .dim-figure .d-name { fill: var(--fg); }

/* ---------- 情境（時刻） ---------- */
.pdp-forest .moment__when {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .14em;
  color: var(--warm-ink);
  display: flex; align-items: center; gap: 10px;
}
.pdp-forest .moment__when::after { content: ""; flex: 1; height: 1px; background: var(--line); }

/* ---------- 購買列 ---------- */
.pdp-forest .buybar {
  position: sticky; bottom: 0; z-index: 280;
  background: color-mix(in srgb, var(--surface) 96%, transparent);
  backdrop-filter: blur(6px);
  border-top: 1px solid var(--line);
  padding: var(--sp-3) var(--gutter);
}
.pdp-forest .buybar__in {
  max-width: 1080px; margin: 0 auto;
  display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
}
.pdp-forest .buybar__price {
  font-family: var(--font-serif); font-size: var(--t-lg); font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.pdp-forest .buybar__price small {
  display: block; font-family: var(--font-sans); font-weight: 400;
  font-size: var(--t-xs); color: var(--muted); margin-top: 2px;
}
.pdp-forest .buybar__cta { margin-left: auto; display: flex; gap: 12px; flex-wrap: wrap; }
.pdp-forest .buybar__note {
  width: 100%; font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .1em; color: var(--muted);
}
@media (max-width: 640px) {
  .pdp-forest .buybar__cta { margin-left: 0; width: 100%; }
  .pdp-forest .buybar__cta .btn { flex: 1; padding: 13px 16px; font-size: var(--t-sm); }
}

/* ---------- B2B 細線 ---------- */
.pdp-forest .b2b {
  border-top: 1px solid var(--line);
  padding: var(--sp-5) 0;
  display: flex; justify-content: space-between; align-items: center;
  gap: var(--sp-3); flex-wrap: wrap;
  font-size: var(--t-sm); color: var(--muted);
}
.pdp-forest .b2b b { color: var(--fg); font-weight: 500; }

/* ---------- 進場（單一動作 · 各頁自行掛 .rv） ---------- */
.pdp-forest .rv { opacity: 0; transform: translateY(18px); }
.pdp-forest .rv-in {
  opacity: 1; transform: none;
  transition: opacity var(--breath) var(--ease), transform var(--breath) var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  .pdp-forest *, .pdp-forest *::before, .pdp-forest *::after { animation: none !important; transition: none !important; }
  .pdp-forest .rv { opacity: 1; transform: none; }
  .pdp-forest html { scroll-behavior: auto; }
}

/* ============================================================
   v3 追加層 · 中文排版
   來源：範本共通點.md F1–F8（2026-08-27 新分析的 10 張中文自然系範本）
   T1–T5 完稿審查的第一名問題是「中文標題根本不是我選的字」，
   這一層就是為了修那個問題而存在。
   ============================================================ */

/* F1 的實作：意境區與事實區用不同字族，不靠字級區分 */
.pdp-forest .mood { font-family: var(--font-mood); font-weight: 300; }
.pdp-forest .fact { font-family: var(--font-fact); }

/* F5 · 一道細線同時完成分隔、對齊與裝飾（#231 被四個字切成三段） */
.pdp-forest .hairline { display: flex; align-items: center; gap: var(--sp-3); }
.pdp-forest .hairline::after { content: ""; flex: 1; height: 1px; background: var(--line-strong); }
.pdp-forest .hairline--both::before { content: ""; flex: 1; height: 1px; background: var(--line-strong); }

/* #234 · 中文標題＋斜體襯線英文對譯的配對元件。重複使用、每次改字級與字距 */
.pdp-forest .gloss {
  display: block; margin-top: 10px;
  font-family: var(--font-gloss); font-style: italic; font-weight: 300;
  font-size: var(--t-sm); letter-spacing: .04em; color: var(--muted);
}

/* F6 · 直角引號是中文排版成本最低的層級手段 */
.pdp-forest .quoted::before { content: "「"; }
.pdp-forest .quoted::after { content: "」"; }

/* 🔴 v3 修掉的一個系統性錯誤：JetBrains Mono 沒有中日韓字。
   任何含中文的小標籤只要用 --font-mono，中文就會掉回系統字型，
   跟旁邊的拉丁字母對不齊、字重也不一樣。
   規則：**含中文的標籤一律黑體＋寬字距；--font-mono 只留給純數字與拉丁字。** */
.pdp-forest .microlabel,
.pdp-forest .tag,
.pdp-forest .buybar__note { font-family: var(--font-fact); }
.pdp-forest .microlabel { font-size: 11.5px; letter-spacing: var(--track-label); }
.pdp-forest .tag { letter-spacing: var(--track-label); }
.pdp-forest .buybar__note { font-size: 11px; letter-spacing: .1em; }
.pdp-forest .num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: .08em; }

/* 🔴 v3 抓到的第二個真問題：`--accent-deep` 在兩個主題裡的意思是相反的。
   淺色主題它是「更深的綠」(#2F371F)，深色主題它是「更亮的苔蘚」(#C4CDB8)。
   拿它當「收尾轉深」那一段的底色，深色主題下會變成淺底配骨白字 → 1.29:1，遠低於 AA。
   A5 的收尾深帶必須在兩個主題都是深的，所以另開一個不隨主題翻面的 token。 */
.pdp-forest { --deep-band: #2F371F; }
body.grovyn-dark-mode .pdp-forest  { --deep-band: #1E2417; }


/* ---------- 3. 頁面層（來自 T8 頁內 style） ---------- */
/* ============================================================
   T8 · 直骨架
   這一版刻意不發明結構，只把 19 張範本的電商共識照著蓋一遍。
   它的價值是「最可能真的賣得動，也最好移植到 WooCommerce」。
     A1 外邊界永不改變（欄數三→四→二都可以，邊界不動）
     A2 左右交替 Z 字 · A3 對稱區塊夾在不對稱中間當休止符
     A4 換底色＝換章節，而且差要小 · A5 明度曲線收尾轉深
     C1 襯線管品牌情緒、無襯線管功能事實
     C3 極陡級距（#109 茶行 PDP：巨型標語 12–14×，中間層刻意不存在）
     B2 強調色只給可點擊 · B4 全頁唯一一塊實心＝加入購物車
     E1 縮圖帶用途標籤 · E2 信任列緊貼 CTA · E5 吸附列帶價格 · E6 轉化壓力逐段遞減
   ============================================================ */

.pdp-forest .wrap { max-width: 1160px; margin: 0 auto; padding-inline: var(--gutter); }
.pdp-forest .sec { padding-block: clamp(56px, 9vh, 100px); background: var(--bg); }
.pdp-forest .sec--alt { background: var(--bg-alt); }

/* ---- 淺色模式的章節層次（2026-08-30）----
   問題：淺色只有米白 #EEEAE7 與溫米 #E8E5DA 兩階在交替，對比 1.055:1，
   兩個都是米色系、色相幾乎一樣，整頁看不出換過章節。深色那邊因為
   藍調（#171A23）／綠調（#1E2417）交錯，色相差自己撐起了層次。

   做法：不加新顏色，改用既有三階（表面 → 米白 → 溫米）做極淡的單向漸層，
   模擬側光落在紙面上——這正是「陰翳下的標本室」的北極星。
   相鄰區塊的漸層方向相反，接縫處自然形成明度轉折，就是 A4 的「換底色＝換章節」。

   紅線檢查：禁的是彩虹漸層／霓虹色（03-red-lines.md L23），單色明度漸層不在其列；
   純白 #FFFFFF 全程未使用。深色模式完全不動。

   ⚠️ .sec 那條要排除 .sec--deep：深綠帶的 class 是「sec sec--deep」，
      漸層規則 (0,0,2,1) 會壓過 .sec--deep (0,0,1,0)，把深綠底整個蓋掉。 */
body:not(.grovyn-dark-mode) .pdp-forest .sec:not(.sec--deep) {
  background: linear-gradient(158deg, var(--surface) 0%, var(--bg) 58%, var(--bg) 100%);
}
body:not(.grovyn-dark-mode) .pdp-forest .sec--alt {
  background: linear-gradient(158deg, var(--bg) 0%, var(--bg-alt) 52%, var(--bg-alt) 100%);
}
body:not(.grovyn-dark-mode) .pdp-forest .slogan {
  background: linear-gradient(158deg, var(--bg-alt) 0%, var(--surface) 100%);
}
.pdp-forest .sec--deep { background: var(--deep-band); color: var(--bone); }
.pdp-forest .sec--deep .microlabel { color: color-mix(in srgb, var(--bone) 72%, transparent); }
/* 共用元件 .b2b 寫死了 --muted（淺色主題的灰），放進深色帶會掉到 2:1。深色帶內一律繼承 */
.pdp-forest .sec--deep .b2b { color: color-mix(in srgb, var(--bone) 86%, transparent); border-color: color-mix(in srgb, var(--bone) 24%, transparent); }
.pdp-forest .sec--deep .b2b b, .pdp-forest .sec--deep .quiet-link { color: var(--bone); }
/* 深色模式的 --deep-band #1E2417 對頁面底 #171A23 只有 1.09:1 —— 等於沒換底色，A4 失效。
   改成「浮起的面」：深色模式裡強調的方向是變亮，不是變暗。
   #2A2F40 對 --bg 是 1.31:1（章節看得出來但差很小），--bone 文字在它上面 10.4:1。
   淺色模式維持原本的深綠帶，不動。 */
body.grovyn-dark-mode .pdp-forest .sec--deep { background: var(--bg); padding-block: clamp(40px, 7vh, 72px); }
body.grovyn-dark-mode .pdp-forest .sec--deep > .wrap { background: #2A2F40;
  padding: clamp(32px, 5vw, 56px) clamp(24px, 4vw, 48px); }

/* 淺色模式的 B2B 收尾段（阿翰 2026-08-30 兩輪選定的結果）：
   整段翻成表面色，內容卡改暗一階＋細描邊，明暗關係跟原本的深帶反過來。
   ⚠️ 這等於在淺色模式取消了 A5 的「明度曲線收尾轉深」——
      收尾層次改由卡片的溫米底＋描邊承擔，不再靠整段深帶。
      _tokens.css 檔尾那個「不隨主題翻面」的 --deep-band 現在只有深色模式在用。
   文字一律翻深：底層 .sec--deep 的 color 是 --bone（米白），淺底上會看不見。 */
body:not(.grovyn-dark-mode) .pdp-forest .sec--deep { background: var(--surface); color: var(--fg); }
body:not(.grovyn-dark-mode) .pdp-forest .sec--deep > .wrap {
  background: var(--bg-alt);
  border: 1px solid rgba(40, 44, 60, .10);
  padding: clamp(28px, 4vw, 48px);
}
body:not(.grovyn-dark-mode) .pdp-forest .sec--deep .b2b,
body:not(.grovyn-dark-mode) .pdp-forest .sec--deep .b2b b,
body:not(.grovyn-dark-mode) .pdp-forest .sec--deep .quiet-link { color: var(--fg); }
body:not(.grovyn-dark-mode) .pdp-forest .sec--deep .b2b p { opacity: 1; }
body:not(.grovyn-dark-mode) .pdp-forest .sec--deep .microlabel { color: var(--muted); }
body:not(.grovyn-dark-mode) .pdp-forest .sec--deep .quiet-link { border-bottom-color: var(--line-strong); }

/* 章節標：襯線，中等；巨型標語另有其位 */
.pdp-forest .st { font-family: var(--font-serif); font-weight: 400; font-size: clamp(22px, 2.7vw, 30px); letter-spacing: .05em; line-height: 1.6; }
.pdp-forest .body { line-height: 2.15; max-width: 34em; }
.pdp-forest .body p + p { margin-top: 1.2em; }
.pdp-forest .body strong { font-weight: 500; }
.pdp-forest .mute { color: var(--muted); }

/* ---- A2 · 左右交替（Z 字） ---- */
.pdp-forest .zz { display: grid; gap: var(--sp-5); align-items: center; }
@media (min-width: 900px) {
  .pdp-forest .zz { grid-template-columns: 1fr 1fr; gap: var(--sp-6); }
  .pdp-forest .zz--flip > :first-child { order: 2; }
}
.pdp-forest .zz img { width: 100%; aspect-ratio: 4/3; object-fit: cover; }

/* ---- 主購買區（左圖右資訊） ---- */
.pdp-forest .pdp { display: grid; gap: var(--sp-5); padding-top: clamp(28px, 5vh, 52px); }
@media (min-width: 940px) {
  .pdp-forest .pdp { grid-template-columns: 1.1fr .9fr; gap: var(--sp-6); align-items: start; }
  /* 右欄的元件比左欄長，圖庫黏住才不會留下一大塊空白 */
  .pdp-forest .pdp > :first-child { position: sticky; top: calc(var(--topbar-h) + 20px); }
}
.pdp-forest .gal__main { width: 100%; aspect-ratio: 16/10; object-fit: cover; background: var(--bg-alt); }
/* E1 · 縮圖帶用途標籤：告訴使用者每張圖回答什麼問題，而非讓他自己猜 */
.pdp-forest .thumbs { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-2); margin-top: var(--sp-2); }
.pdp-forest .thumb { padding: 0; border: 1px solid transparent; background: none; cursor: pointer; text-align: left; color: inherit; }
/* 六格統一 1:1 滿版，裁切點一律往上移到主體：置中會把直立畫框的頂端切掉 */
.pdp-forest .thumb img { width: 100%; aspect-ratio: 1/1; object-fit: cover; object-position: 50% 42%; }
.pdp-forest .thumb span { display: block; margin-top: 6px; font-family: var(--font-fact); font-size: 11px;
  letter-spacing: .1em; color: var(--muted); line-height: 1.6; }
.pdp-forest .thumb[aria-pressed="true"] { border-color: var(--accent); }
.pdp-forest .thumb[aria-pressed="true"] span { color: var(--fg); }

.pdp-forest .buy__name { font-family: var(--font-serif); font-weight: 400; font-size: clamp(26px, 3.4vw, 38px); letter-spacing: .06em; }
.pdp-forest .buy__line { margin-top: var(--sp-2); color: var(--muted); line-height: 2; }
.pdp-forest .buy__price { margin-top: var(--sp-4); display: flex; align-items: baseline; gap: var(--sp-3); flex-wrap: wrap; }
.pdp-forest .buy__price b { font-family: var(--font-mono); font-size: var(--t-2xl); font-weight: 500; font-variant-numeric: tabular-nums; }
.pdp-forest .buy__price s { color: var(--muted); font-family: var(--font-mono); font-size: var(--t-md); }
.pdp-forest .opt { margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: 1px solid var(--line); }
.pdp-forest .opt > p { font-family: var(--font-fact); font-size: 11.5px; letter-spacing: var(--track-label); color: var(--muted); }
.pdp-forest .sku { display: grid; gap: var(--sp-2); margin-top: var(--sp-2); }
.pdp-forest .sku button { display: flex; gap: var(--sp-2); align-items: baseline; flex-wrap: wrap;
  padding: 14px var(--sp-3); background: transparent; border: 1px solid var(--line-strong);
  cursor: pointer; color: inherit; text-align: left; transition: border-color var(--base-d) var(--ease), background-color var(--base-d) var(--ease); }
.pdp-forest .sku button:hover { border-color: var(--accent); }
.pdp-forest .sku button[aria-pressed="true"] { border-color: var(--accent); background: var(--surface); }
.pdp-forest .sku em { font-style: normal; flex: 1 1 auto; font-weight: 500; }
.pdp-forest .sku i { font-style: normal; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.pdp-forest .sku small { flex-basis: 100%; color: var(--muted); font-size: var(--t-xs); line-height: 1.8; }
.pdp-forest .picks { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: var(--sp-2); margin-top: var(--sp-2); }
.pdp-forest .pick { padding: 12px 8px; border: 1px solid var(--line-strong); background: transparent; cursor: pointer;
  color: inherit; font-family: var(--font-serif); font-size: var(--t-md); letter-spacing: .24em; text-indent: .24em;
  transition: border-color var(--base-d) var(--ease), background-color var(--base-d) var(--ease); }
.pdp-forest .pick:hover { border-color: var(--accent); }
.pdp-forest .pick[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-soft); }
.pdp-forest .cta { margin-top: var(--sp-4); display: grid; gap: var(--sp-2); }
.pdp-forest .cta .btn { width: 100%; }

/* E2 · 信任列緊貼 CTA 下方（#24 疑慮在決策瞬間被攔截） */
.pdp-forest .trust { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--sp-3); margin-top: var(--sp-4);
  padding-top: var(--sp-3); border-top: 1px solid var(--line); }
@media (min-width: 620px) { .pdp-forest .trust { grid-template-columns: repeat(4, 1fr); } }
.pdp-forest .trust div { display: flex; flex-direction: column; gap: 6px; }
.pdp-forest .trust b { font-family: var(--font-mono); font-size: var(--t-md); font-weight: 500; font-variant-numeric: tabular-nums; color: var(--accent); }
.pdp-forest .trust span { font-family: var(--font-fact); font-size: 11.5px; letter-spacing: .08em; color: var(--muted); line-height: 1.7; }

/* ---- C3 · 巨型標語（極陡級距的頂點，中間層刻意不存在） ---- */
.pdp-forest .slogan { padding-block: clamp(72px, 14vh, 168px); background: var(--bg-alt); text-align: center; }
.pdp-forest .slogan h2 { font-family: var(--font-serif); font-weight: 200;
  font-size: clamp(38px, 8.4vw, 116px); line-height: 1.28; letter-spacing: .1em; text-indent: .1em; }
/* 雙行對比標語：上行是前提（退為灰），下行是轉折。
   兩行都要壓過上面 .slogan h2 的 font-size，所以綁 h2.。 */
.pdp-forest .slogan h2.slogan__pair { line-height: 1.4; }
.pdp-forest .slogan h2.slogan__pair span { display: block; font-size: clamp(29px, 5.9vw, 80px); letter-spacing: .09em; text-indent: .09em; }
.pdp-forest .slogan h2.slogan__pair span:first-child { color: var(--muted); }
.pdp-forest .slogan h2.slogan__pair span:last-child { margin-top: .24em; }
.pdp-forest .slogan p { margin-top: var(--sp-4); font-family: var(--font-fact); font-size: 11.5px;
  letter-spacing: var(--track-label); color: var(--muted); }
/* A3 休止符：置中是刻意的，但要有上下界線宣告它是一段停頓。
   放在 .slogan 之後才壓得過它的 padding-block。
   留白刻意非對稱：上窄下寬，標語承接上一段，再把讀者推向下一段。 */
.pdp-forest .slogan--rest { padding-top: clamp(28px, 5vh, 56px); padding-bottom: clamp(52px, 9vh, 108px); }
.pdp-forest .slogan--rest .wrap { border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  padding-top: var(--sp-4); padding-bottom: var(--sp-5); }

/* ---- A3 · 對稱區塊：四款四等分，夾在兩個不對稱之間當休止符 ---- */
.pdp-forest .four { display: grid; gap: var(--sp-3); margin-top: var(--sp-5); }
@media (min-width: 700px) { .pdp-forest .four { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1020px) { .pdp-forest .four { grid-template-columns: repeat(4, 1fr); } }
.pdp-forest .card4 { display: flex; flex-direction: column; gap: var(--sp-2); padding: var(--sp-4);
  background: var(--bg); border: 1px solid var(--line-strong); text-align: left; cursor: pointer; color: inherit;
  transition: border-color var(--base-d) var(--ease); }
.pdp-forest .card4:hover { border-color: var(--accent); }
.pdp-forest .card4[aria-pressed="true"] { border-color: var(--accent); background: var(--surface); }
/* 從下方卡片選香型時，購買區在兩個畫面外。讓永遠可見的吸附列閃一下當回執。
   一次、很短、只動邊線——不是裝飾動畫，是「你剛剛的動作有被收到」 */
.pdp-forest .buybar--ack { animation: gvf-ack calc(var(--beat, 90ms) * 8) var(--ease) 1; }
@keyframes gvf-ack {
  0%   { border-top-color: var(--accent); }
  55%  { border-top-color: var(--accent); }
  100% { border-top-color: var(--line); }   /* 收在 .buybar 原本的 --line，動畫結束不會跳 */
}
@media (prefers-reduced-motion: reduce) { .pdp-forest .buybar--ack { animation: none; } }
.pdp-forest .card4 h3 { font-family: var(--font-serif); font-weight: 300; font-size: clamp(28px, 3.6vw, 38px);
  letter-spacing: var(--track-block); text-indent: var(--track-block); line-height: 1.2; }
.pdp-forest .card4 .ar { font-family: var(--font-fact); font-size: var(--t-sm); color: var(--muted); letter-spacing: .04em; }
.pdp-forest .card4 .mt { display: flex; flex-direction: column; gap: 5px; margin-top: 2px; }
.pdp-forest .card4 .mt span { display: flex; align-items: center; gap: 7px; font-family: var(--font-fact); font-size: 11px; letter-spacing: .1em; color: var(--muted); }
.pdp-forest .card4 .mt i { display: flex; gap: 3px; font-style: normal; }
.pdp-forest .card4 .mt i b { width: 5px; height: 5px; border-radius: 50%; background: var(--line-strong); }
.pdp-forest .card4 .mt i b.on { background: var(--accent); }
.pdp-forest .card4 .nt { font-size: var(--t-sm); line-height: 1.95; }
.pdp-forest .card4 .wh { margin-top: auto; padding-top: var(--sp-3); border-top: 1px solid var(--line);
  font-size: var(--t-sm); line-height: 1.95; color: var(--muted); }
.pdp-forest .card4 .df { font-family: var(--font-fact); font-size: 10.5px; letter-spacing: .16em; color: var(--warm-ink); }
/* 選中香型時，卡片內各層依序漂入 —— 品牌動畫規範的「碎形散開」，stagger 40ms。
   規範禁 spring／彈跳／ease-in，所以走官方的 --ease（自然呼吸曲線）。 */
@keyframes gvf-scent-drift {
  from { opacity: 0; transform: translateY(13px); }
  to   { opacity: 1; transform: none; }
}
.pdp-forest .card4[aria-pressed="true"] > * { animation: gvf-scent-drift 400ms var(--ease) both; }
.pdp-forest .card4[aria-pressed="true"] > *:nth-child(1) { animation-delay: 0ms; }
.pdp-forest .card4[aria-pressed="true"] > *:nth-child(2) { animation-delay: 40ms; }
.pdp-forest .card4[aria-pressed="true"] > *:nth-child(3) { animation-delay: 80ms; }
.pdp-forest .card4[aria-pressed="true"] > *:nth-child(4) { animation-delay: 120ms; }
.pdp-forest .card4[aria-pressed="true"] > *:nth-child(5) { animation-delay: 160ms; }
@media (prefers-reduced-motion: reduce) { .pdp-forest .card4[aria-pressed="true"] > * { animation: none; } }

/* ---- 三情境（三等分） ---- */
.pdp-forest .moments { display: grid; gap: var(--sp-5); }
@media (min-width: 880px) { .pdp-forest .moments { grid-template-columns: repeat(3,1fr); gap: var(--sp-4); } }
.pdp-forest .moment img { width: 100%; aspect-ratio: 4/3; object-fit: cover; }
.pdp-forest .moment h3 { margin-top: var(--sp-3); font-family: var(--font-fact); font-size: 11.5px;
  letter-spacing: var(--track-label); color: var(--warm-ink); font-weight: 400; }
.pdp-forest .moment div { margin-top: var(--sp-2); font-size: var(--t-sm); line-height: 2.05; }
.pdp-forest .moment div p + p { margin-top: 1em; }

/* ---- 規格：左欄欄位名、右欄內容 ---- */
.pdp-forest .two { display: grid; gap: var(--sp-5); }
@media (min-width: 900px) { .pdp-forest .two { grid-template-columns: 1fr 1fr; gap: var(--sp-6); align-items: start; } }
.pdp-forest .three { display: grid; gap: var(--sp-4); }
@media (min-width: 820px) { .pdp-forest .three { grid-template-columns: repeat(3,1fr); gap: var(--sp-5); } }
.pdp-forest .three > div { border-top: 1px solid var(--line-strong); padding-top: var(--sp-3); }
.pdp-forest .three h4 { font-weight: 500; font-size: var(--t-md); }
.pdp-forest .three p { margin-top: 8px; font-size: var(--t-sm); color: var(--muted); line-height: 2; }

.pdp-forest .ledger { width: 100%; border-collapse: collapse; font-family: var(--font-mono); font-size: var(--t-sm); }
.pdp-forest .ledger td { padding: 11px 0; border-bottom: 1px solid var(--line); font-variant-numeric: tabular-nums; }
.pdp-forest .ledger td:last-child { text-align: right; }
.pdp-forest .ledger tr.sum td { border-bottom: 1px solid var(--line-strong); font-weight: 500; }
.pdp-forest .ledger tr.save td { border-bottom: none; color: var(--warm-ink); }

.pdp-forest .gap-note { margin-top: var(--sp-3); padding: 12px 16px; border: 1px dashed var(--line-strong);
  font-family: var(--font-fact); font-size: 11.5px; letter-spacing: .08em; color: var(--muted); line-height: 2; }

/* ---- 吸附列改品牌深林藍底（阿翰 2026-08-30 從四個品牌深色裡選的）----
   基礎樣式在 _tokens.css:313（淺色 surface 96%），這裡整個覆蓋成深底。
   ⚠️ 一起換掉的還有「加入購物車」：森林綠 #495434 在 #282C3C 上只有 1.72:1，
      遠低於 WCAG 對 UI 元件的 3:1，按鈕會沉進背景。換成晨光黃 #EEE78D 後 10.86:1。
      深色背景強調色用陽光黃是專案鐵則（官網 CLAUDE.md §5-C #14）。
   幽靈按鈕與說明字同步翻米白，否則深底上讀不到。兩個主題共用同一組值。 */
/* 上下留白：官網 server 上的 ts-tokens.css 少了 --ts-gutter，原本 .buybar 的
   padding: var(--sp-3) var(--gutter) 會整條被丟棄變 0，按鈕直接貼齊上緣。
   這裡寫死一組不依賴 --gutter 的值，下方比上方多一階讓說明字有呼吸空間。 */
.pdp-forest .buybar { padding: var(--sp-3) clamp(20px, 4vw, 48px) var(--sp-4);
  background: color-mix(in srgb, #282C3C 96%, transparent);
  border-top-color: rgba(238, 234, 231, .16); backdrop-filter: blur(8px); }
.pdp-forest .buybar .buybar__price { color: #EEEAE7; }
.pdp-forest .buybar .buybar__price small { color: rgba(238, 234, 231, .72); }
.pdp-forest .buybar .buybar__note { color: rgba(238, 234, 231, .62); }
.pdp-forest .buybar .btn--primary { background: #EEE78D; color: #282C3C; }
.pdp-forest .buybar .btn--primary:hover { background: #F4EFA6; }
.pdp-forest .buybar .btn--ghost { color: #EEEAE7; border-color: rgba(238, 234, 231, .34); }
.pdp-forest .buybar .btn--ghost:hover { background: rgba(238, 234, 231, .10); border-color: #EEE78D; }

/* ═══ 手機可讀性：把「必須讀懂的資訊」拉到 12px 以上（2026-09-01）═══
   只動 ≤640px 斷點，桌機一個字都不改。
   小字 + 寬字距是這頁刻意的設計語言，所以不做全面放大，
   只提升「客人漏看會出事」的那幾類：預購/出貨說明、選購建議、
   信任聲明、縮圖說明。純裝飾性的 mono 標籤（.df 等）維持原樣。
   實測前：手機有 15 處 < 14px，最小 11.5px。 */
@media (max-width: 640px) {
  .pdp-forest .microlabel,
  .pdp-forest .opt > p,
  .pdp-forest .slogan p,
  .pdp-forest .moment h3 { font-size: 13px; }

  /* 這兩個空間較擠（sticky 購買列、三欄縮圖），只微調不硬撐 */
  .pdp-forest .trust span,
  .pdp-forest .buybar__note { font-size: 12.5px; }
  .pdp-forest .thumb span { font-size: 12px; }
}
