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

   買頁（商品詳細頁 `/p/{商品編號}`、下架／刪除頁）的樣式。2026-09-02。

   ── 為什麼是新的一支檔，不是併進 a2.css ────────────────────────────────────

   之後一定會有人想把它併回去（「客人端不是只有兩份 CSS 嗎」），所以理由寫在這裡：

   1. **a2.css 從第一行到最後一行都掛在 `.tpl-a2` 底下**（那是它的契約：兩份 CSS
      同時載入，不掛就互相污染）。買頁**沒有版型 class**——購買流程兩套版型共用
      同一個畫面（Kelly 2026-09-01），分岔只在首頁。所以這裡每一條規則都選不中。
   2. 硬要併，就得**在 a2.css 與 b2.css 裡各放一份一模一樣的買頁樣式**，
      然後等它們漂開。⚠️ 那個漂法是靜默的：A2 的店家看不到 B2 的頁，
      **沒有任何一個人的畫面上會同時出現兩個版本**。
   3. 首頁不載 buy.css、買頁不載 a2/b2.css——客人不用下載一份選不中的 CSS。

   ⚠️ **反過來也一樣：不要把買頁的 class 拿去首頁用。** `.product-name`／`.product-price`
   ／`.product-desc`／`.product-meta`／`.product-duration` 在兩邊是**同一個語意、同一個名字**
   （刻意的），但樣式住在兩份互不載入的檔裡。在首頁上改 `.product-name` 不會動到詳細頁，
   反之亦然——**這正是分檔的代價，改字級時兩邊都要看。**

   ── 視覺依據 ───────────────────────────────────────────────────────────────

   `design/customer/p2-buy-b2.html` 的「客 1 方案詳情頁」。色票與字級**逐格抄自
   那份稿子的 `<style>`**（那是設計師給的值，不是我調的）：
   墨黑 #1a1c1a／襯底 #faf9f6／髮絲線 #e6e3dc／次要字 #4a463f／再次要 #6f6a60／
   最淡 #9a958c／LINE 綠 #06c755。全部 Noto Sans TC（黑體，Kelly 2026-10-06 統一；原本標題與金額是宋體）。

   ⚠️ **稿子的 class 自成一套**（`.scr`／`.foot`／`.eb`／`.band`…），這份 CSS 用的是
   **契約的 DOM**（`docs/dom-structure-for-css.md` §7）。是稿子照契約，不是契約照稿子。
   ═══════════════════════════════════════════════════════════════════════════ */

body.ps-buy {
  margin: 0;
  background: #fff;
  color: #1a1c1a;
  font-family: "Noto Sans TC", "PingFang TC", -apple-system, sans-serif;
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  /* 動作條是 sticky 貼在底部的，所以整頁要能捲到它下面 */
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
.ps-buy *, .ps-buy *::before, .ps-buy *::after { box-sizing: border-box; }
.ps-buy h1 { margin: 0; font-family: "Noto Sans TC", sans-serif; line-height: 1.35; }
.ps-buy p { margin: 0; }
.ps-buy a { color: inherit; text-decoration: none; }
.ps-buy button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
/* 破圖時露出的佔位底（跟 a2.css 同一個語彙：看起來是佔位，不是壞掉）。
   真的圖片載入後不透明，蓋掉這層。 */
.ps-buy img {
  background: #f1efea repeating-linear-gradient(135deg, transparent 0 12px, #e4e0d7 12px 13px);
  display: block;
}

/* ── 照片帶 ───────────────────────────────────────────────────────────────
   ⚠️ 沒有照片時這個節點是空的（renderer 一律輸出它），高度不能寫死。
   返回鈕 2026-09-25 搬到頂列（`.list-nav`），不再壓在照片上。 */
.ps-buy .product-gallery {
  position: relative;
  flex: 0 0 auto;
}
.ps-buy .product-gallery > .catalog-tag { left: 12px; top: 12px; max-width: calc(100% - 24px); pointer-events: none; }
/* 沒有照片：標籤回到文字流，排在店名與商品名之間。 */
.ps-buy .product-body > .catalog-tag { position: static; align-self: flex-start; }
/* ⚠️ **3:2 寫在圖片身上，不是寫在這條軌道上。**（2026-09-02 Kelly 回報：疊在一起）
   本來是「軌道 `aspect-ratio:3/2` ＋ 圖片 `height:100%`」——那條百分比高度要靠瀏覽器
   先把「由 aspect-ratio 推導出來的高度」認定成確定值才解得開。**Blink 解得開、WebKit 不一定**，
   而客人端的預覽跑在 WKWebView 上：解不開的時候圖片退回自己的原始高度，
   三張各長各的，於是**疊在一起**。⚠️ 兩邊都寫比例會更糟（同一件事兩個來源，
   對不上時中間多一條縫），所以軌道上那條是**移走不是複製**。 */
.ps-buy .product-track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.ps-buy .product-track::-webkit-scrollbar { display: none; }
.ps-buy .product-shot {
  flex: 0 0 100%;
  width: 100%;
  aspect-ratio: 3 / 2;                 /* 桌機顯示框 3:2，完整圖片置中留白 */
  height: auto;
  object-fit: contain;
  background: #fff;
  scroll-snap-align: start;
}
/* 手機 5:4 顯示框，圖片保留原比例（Kelly 2026-09-25：以手機為準）。 */
@media (max-width: 767px) {
  .ps-buy .product-shot { aspect-ratio: 5 / 4; }
}
/* 頂列（`.list-nav`）的樣式搬到 site.css：商品單頁、會員專區、購物車共用（2026-10-08）。 */
/* ── 內文 ─────────────────────────────────────────────────────────────── */
.ps-buy .product-detail { flex: 1 1 auto; }
.ps-buy .product-body {
  padding: 22px 24px 28px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.ps-buy .eyebrow {
  font: 700 11px/1.2 "Noto Sans TC", sans-serif;
  letter-spacing: .2em;
  color: #9a958c;
}
.ps-buy .product-name {
  font-size: 29px;
  font-weight: 600;
  letter-spacing: -.02em;
}
/* 價格與數量同一列（Kelly 2026-10-06）：價格靠左、數量靠右。外連／LINE 詢問／賣完沒有數量，
   價格自己留在左邊。時間（有填才輸出）在這一列上方另起一行。 */
.ps-buy .product-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 48px;
  padding-bottom: 13px;
  border-bottom: 1px solid #e6e3dc;
}
.ps-buy .product-price {
  flex: 0 0 auto;
  font: 600 20px/1.2 "Noto Sans TC", sans-serif;
  white-space: nowrap;
}
/* 剩餘數量（Kelly 2026-10-11）：價格底下一行，字級顏色照購物車的 `.cart-stock`（13／#6f6a60），
   字樣「剩餘 N 件」也同一句。只有計數量、還買得到的商品才有這一格；有規格時跟著選中的規格換。 */
.ps-buy .product-price-stack { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ps-buy .product-stock { margin: 0; font-size: 13px; line-height: 1.5; color: #6f6a60; }

/* 商品單頁主標 24／500、字距 +0.02em（Kelly 2026-10-07 字重 +100、字距由 −0.02em 改 +0.02em；10-06 是 24／400，原本 29／500）。⚠️ 只限 `.product-body`
   ——`.product-name` 在會員頁等也用，那些不跟著動。價格 600 就是上面的基準（2026-10-06 由 500 調回），
   ⚠️ 600 要在 buyHead 的字型 link 裡，不然會落到 700。 */
.ps-buy .product-body > .product-name { font-size: 24px; font-weight: 500; letter-spacing: .02em; }
/* 標題下的小備註（Kelly 2026-10-06）：時間（時鐘）在上、運費門檻（貨車）在下，
   12px、緊行距、每組一顆 14px 圖示。 */
.ps-buy .product-notes { display: flex; flex-direction: column; gap: 4px; margin-top: -4px; }
.ps-buy .product-notes > * {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  font-size: 12px;
  line-height: 1.5;
  color: #6f6a60;
}
.ps-buy .product-notes svg { flex: 0 0 auto; width: 14px; height: 14px; margin-top: 2px; }
.ps-buy .product-desc {
  font-size: 14.5px;
  line-height: 1.85;
  color: #4a463f;
}
/* 描述圖片（Kelly 2026-10-06）：描述文字底下逐張堆疊，整欄寬、**1:1**。
   App 上傳前已經裁成正方形（1560×1560，桌面 780 欄 @2x 不放大），這裡的
   aspect-ratio／object-fit 是保險：舊資料或外部網址不是正方形時，畫面仍然整齊。
   ⚠️ `display:block` 不能省：`<img>` 預設是 inline，底下會多出一條基線縫，
   兩張圖之間的間距就不是 12 而是 12＋幾 px，每張不一樣。
   圓角跟 `.product-shot` 一樣（沒有）。 */
.ps-buy .product-desc-images {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.ps-buy .product-desc-image {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
}
/* 多種規格（Kelly 2026-10-11）：價格那一列上方一排選擇鈕，眼眉字跟「數量」同一款。
   選中＝墨黑底白字（跟購買鈕同色）；售完＝灰底灰字、後面一個小「售完」，留在原位不藏。
   ⚠️ 高 44 是命中區下限，不要為了看起來精緻縮成 34（/p 篩選鈕那個尺寸是另一種元件）。 */
.ps-buy .product-variants { display: flex; flex-direction: column; gap: 10px; }
.ps-buy .variant-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.ps-buy .variant-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 18px;
  border: 1px solid #e6e3dc;
  border-radius: 999px;
  background: #fff;
  color: #1a1c1a;
  font: 500 14px/1.3 "Noto Sans TC", sans-serif;
  cursor: pointer;
}
.ps-buy .variant-chip[aria-checked="true"] { background: #1a1c1a; border-color: #1a1c1a; color: #fff; }
.ps-buy .variant-chip:disabled { background: #f1efea; border-color: #f1efea; color: #9a958c; cursor: default; }
.ps-buy .variant-chip small { font-size: 11.5px; }
/* 數量：跟價格同一列的右邊。⚠️ 外連與 LINE 詢問的商品**整塊不輸出**
   （沒有我們的訂單就數不出賣了幾份，spec §2.5）——不是灰掉。 */
.ps-buy .product-qty {
  display: flex;
  align-items: center;
  gap: 12px;
}
.ps-buy .product-qty-label {
  font: 700 10.5px/1.2 "Noto Sans TC", sans-serif;
  letter-spacing: .18em;
  color: #9a958c;
}
.ps-buy .qty-stepper {
  display: flex;
  align-items: center;
  height: 44px;
  border: 1px solid #e6e3dc;
  border-radius: 3px;
  overflow: hidden;
}
.ps-buy .qty-stepper button {
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 17px;
  color: #4a463f;
}
.ps-buy .qty-value { min-width: 28px; text-align: center; font: 500 15px/1 "Noto Sans TC", sans-serif; }

/* ── 動作條 ───────────────────────────────────────────────────────────────
   `position: sticky` 貼在畫面底：長描述捲下去之後按鈕還在。
   ⚠️ **`bottom: 0` ＋ `env(safe-area-inset-bottom)`**，不要只寫 padding：
   iPhone 底下那條 home indicator 會壓在按鈕上，而在模擬器與桌機瀏覽器上看不出來。 */
.ps-buy .product-actions {
  position: sticky;
  bottom: 0;
  z-index: 3;
  display: flex;
  /* 外連／LINE／售完都只有一顆鈕（直排讓它撐滿寬）；站內購買改橫排「小計＋鈕」，見下方 [data-product-id]。 */
  flex-direction: column;
  gap: 8px;
  padding: 14px 24px calc(22px + env(safe-area-inset-bottom, 0px));
  background: #fff;
  border-top: 1px solid #e6e3dc;
}
.ps-buy .product-buy,
.ps-buy .gone-home {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 52px;
  border-radius: 999px;
  font: 500 16px/1 "Noto Sans TC", sans-serif;
  letter-spacing: .04em;
  flex: 0 0 auto;
}
.ps-buy .product-buy { background: #1a1c1a; color: #fff; }
/* 站內購買：左邊小計（單價 × 數量，即時更新）、右邊加入購物車（Kelly 2026-10-06）。 */
.ps-buy .product-actions[data-product-id] {
  flex-direction: row;
  align-items: center;
  gap: 16px;
}
.ps-buy .product-actions[data-product-id] .product-buy { flex: 1 1 auto; max-width: 220px; margin-left: auto; padding: 0 20px; }
.ps-buy .product-subtotal {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.ps-buy .product-subtotal span { font-size: 12px; color: #6f6a60; }
/* LINE 綠是 LINE 的品牌色，換成墨黑客人會認不出這顆鈕開的是 LINE。
   ⚠️ 真的要照 LINE 官方品牌規範定稿時（按鈕樣式與最小尺寸有既定值），
   改的是這一條，不是去 renderer 加 class。 */
.ps-buy .product-line { background: #06c755; color: #fff; }
.ps-buy .product-line svg { width: 20px; height: 20px; }
.ps-buy .product-soldout {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 52px;
  border-radius: 999px;
  background: #f1efea;
  color: #6f6a60;
  font: 500 16px/1 "Noto Sans TC", sans-serif;
  letter-spacing: .04em;
}

/* ── 購物車浮動鈕 ─────────────────────────────────────────────────────────
   跟 a2.css 的 `.tpl-a2 .cart-fab` 是**同一顆元件、同一份 markup**（`CART_FAB`），
   所以值跟著它走：58×58、角標 22 高、`#bc5816` ＋ 2px 米白描邊。
   ⚠️ 這裡曾經寫著「值逐條對齊」而實際上沒有（58 vs 52、`#bc5816` vs coral、有無描邊）
   ——症狀是客人在首頁看到一顆、點進商品頁看到另一顆，而**兩頁各自看都很正常**。
   ⚠️ **唯一刻意不同的是 `bottom`**：買頁底部有一條 sticky 的動作區，
   照抄 24px 那顆鈕會被壓在鈕底下（首頁沒有那條，所以它不需要這個偏移）。 */
.ps-buy .cart-fab {
  position: fixed;
  right: 20px;
  /* 預設值只給「沒有動作條」的頁面用。有動作條時由 JS 量它的高度把 toast 推到它上面
     ——寫死一個數字的話，兩顆鈕的動作條會把 toast 蓋在鈕上面（2026-09-24 實測）。 */
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));  /* 動作條在下面，不要疊 */
  z-index: 4;
  width: 58px;
  height: 58px;
  border-radius: 50%;
  background: #1a1c1a;
  color: #faf9f6;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 14px rgba(26, 28, 26, 0.28);
}
.ps-buy .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;
}
.ps-buy .cart-fab[hidden] { display: none; }

/* ── 下架／刪除頁 ─────────────────────────────────────────────────────────
   ⚠️ 這一頁**沒有商品名**（刪掉的商品沒有名字可以印，`url-routes.md` §6），
   所以視覺上只剩店名、一句話、一顆回首頁。不要覺得空就往上加東西。 */
.ps-buy.product-gone { justify-content: center; }
.ps-buy .gone {
  padding: 0 24px calc(24px + env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
}
.ps-buy .gone-title { font-size: 27px; font-weight: 600; letter-spacing: -.02em; }
.ps-buy .gone-home { align-self: stretch; border: 1px solid #1a1c1a; }
.ps-buy .gone-home svg { width: 18px; height: 18px; }

/* ═══════════════════════════════════════════════════════════════════════════
   結帳頁 `/checkout`、訂單狀態頁 `/o/{token}`、會員專區 `/me`  ——  2026-09-10
   ═══════════════════════════════════════════════════════════════════════════

   視覺依據：`design/p2-buy-flow-v1/`（B2 工作室版，設計方 2026-09-10 交付）。
   色票與字級**逐格抄自那份稿子的 `<style>`**，跟上面買頁那一段同一組值。

   ⚠️ **稿子的 class 自成一套**（`.scr`／`.foot`／`.eb`／`.band`／`.krow`…），
   這份 CSS 用的是**契約的 DOM**（`docs/dom-structure-for-css.md` §9）。
   跟上面同一條：**是稿子照契約，不是契約照稿子**。對照表在契約那一節。

   ⚠️ **這四頁沒有版型分岔**（跟 `/p/{編號}` 同一條規則，Kelly 2026-09-01）：
   A2 的店家與 B2 的店家看到同一個購買流程，分岔只在首頁。所以這裡不掛 `.tpl-a2`／
   `.tpl-b2`——加上去等於為了一種店家複製一份，然後等它們漂開。 */

/* ── 頁首：返回 ＋ 標題 ＋（可有可無的）狀態膠囊 ───────────────────────────
   ⚠️ **返回鈕的命中區是 44×44，不是圖示的大小。** 圖示 22px，外面那圈透明的
   padding 才是可以按的地方——只給 22px 的話手機上按不到，而畫面上看不出差別。 */
.ps-buy .buy-nav {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 52px;
  padding: 8px 20px 8px 10px;
  flex-shrink: 0;
}
.ps-buy .buy-nav-back {
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #1a1c1a;
  flex-shrink: 0;
}
.ps-buy .buy-nav-back svg { width: 22px; height: 22px; }
.ps-buy .buy-nav-title {
  margin: 0;
  font-family: "Noto Sans TC", sans-serif;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -.01em;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 返回鈕不存在時（訂單頁沒有上一頁），標題自己補上左邊那 34px */
.ps-buy .buy-nav > .buy-nav-title:first-child { padding-left: 14px; }
.ps-buy .buy-nav .status-tag { margin-left: auto; }

/* ── 內容欄 ─────────────────────────────────────────────────────────────── */
.ps-buy .buy-body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 12px 24px 32px;
  min-width: 0;
  /* 子元素一律不准把這一欄撐寬——上面 `<ol>` 那個坑會再發生，
     但下一次的成因可能是一串沒有斷點的帳號或 email。 */
  overflow-wrap: anywhere;
}
.ps-buy .buy-body > * { min-width: 0; max-width: 100%; }
.ps-buy .buy-body > * { flex-shrink: 0; }

/* ── 四步進度條 ─────────────────────────────────────────────────────────
   ⚠️ **第二步的字跟著收款方式變**（銀行是「匯款」、LINE Pay 是「付款」），
   所以那個字是 renderer 給的，不是寫死在 CSS 的 `::after` 裡。 */
/* ⚠️ **`<ol>` 的預設 `padding-left: 40px` 一定要歸零。** 不歸零的話這一列比容器寬，
   而 `.buy-body` 是 flex column、子元素不收縮，**整頁會往右溢出**——症狀不是
   「進度條有點怪」，是**金額、複製鈕、帳號全部被切在畫面外**，而且只有實際渲染
   才看得出來（2026-09-10 就是這樣紅的第一次）。 */
.ps-buy .flow-steps { display: flex; gap: 5px; margin: 0; padding: 0 0 2px; list-style: none; }
/* ⚠️ 結帳頁一種收款方式一份進度條，沒選到的那幾份掛 `hidden`。
   `display: flex` 會蓋掉瀏覽器對 `hidden` 的預設樣式——少了這一條，
   三份進度條會同時出現在畫面上。 */
.ps-buy .flow-steps[hidden] { display: none; }
.ps-buy .flow-steps > * {
  flex: 1 1 0;
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 5px;
  padding-top: 12px;
  font-size: 12px;
  letter-spacing: .04em;
  color: #9a958c;
  min-width: 0;
}
.ps-buy .flow-steps > *::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 4px;
  border-radius: 999px;
  background: #e6e3dc;
}
.ps-buy .flow-steps b {
  font-family: "Noto Sans TC", sans-serif;
  font-size: 12px;
  font-weight: 600;
}
.ps-buy .flow-steps .done { color: #6f6a60; }
.ps-buy .flow-steps .done::before { background: #1a1c1a; opacity: .32; }
.ps-buy .flow-steps .now { color: #1a1c1a; font-weight: 700; }
.ps-buy .flow-steps .now::before { background: #1a1c1a; }

/* ── 狀態膠囊 ───────────────────────────────────────────────────────────
   ⚠️ **一張訂單的狀態只出現一次**（設計稿 README）。它住在頁首，
   內文裡不要再放第二顆——兩顆的字遲早會不一樣，而且沒有人看得出哪一顆是真的。 */
.ps-buy .status-tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 23px;
  padding: 0 8px;
  border-radius: 3px;
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: .06em;
  flex-shrink: 0;
  white-space: nowrap;
}
.ps-buy .status-tag.wait   { background: #fcf4e4; color: #946a00; }  /* 等你付款／回報 */
.ps-buy .status-tag.check  { background: #fbede5; color: #b93e0c; }  /* 待確認收款・未結清 */
.ps-buy .status-tag.paid   { background: #f4f8de; color: #5c6b00; }  /* 已收款・已結清 */
.ps-buy .status-tag.muted  { background: #f2f0eb; color: #6f6a60; }
.ps-buy .status-tag .dot { width: 6px; height: 6px; border-radius: 999px; background: #b7d600; flex-shrink: 0; }

/* ── 暖紙底塊：這是「要照抄的東西」專用的底色 ─────────────────────────────
   ⚠️ **一屏最多一塊。** 稿子的規則是純白＋髮絲線，給了底色就是最強的訊號；
   給第二塊，兩塊就都不強了。匯款帳號用它、訂單編號用它，不要拿來當卡片。 */
/* 暖紙框只定義這一次（2026-10-07）：對帳、訂單摘要、聯絡店家卡、訂購人／收件資訊都是同一個框，
   各自只留內距與間距。要改框的顏色／圓角改這裡，不要在個別元件上再寫一份。 */
.ps-buy :is(.info-band, .notice-strong, .order-box, .contact-card) {
  background: #faf9f6;
  border: 1px solid #e6e3dc;
  border-radius: 8px;
}
.ps-buy .info-band {
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

/* 一個新段落。⚠️ 不再畫墨黑上線（Kelly 2026-10-07「線條太多」）：段落之間靠留白分，
   跟結帳頁同一套；整頁唯一的墨黑線留給「應付金額」那一條。 */
.ps-buy .rule-block {
  margin-top: 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* ── 三種列高，不要互相代用 ─────────────────────────────────────────────
   `.info-row` 34px：塞在暖紙底塊裡的 key/value，密
   `.detail-row` 44px：內容欄上的一般列，不畫線（2026-10-07）
   `.member-row` 48px：會員資料列，右邊是（未來會變成）輸入框
   ⚠️ 三個都滿足 44×44 的命中區下限**只有 detail-row 與 member-row**；
   `.info-row` 是純顯示、沒有可按的東西，所以 34 是對的。
   拿 `.info-row` 去做可以點的列，檢查會全綠而手機上按不到。 */
.ps-buy .info-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  min-height: 34px;
}
.ps-buy .info-row .k {
  font-size: 12.5px;
  letter-spacing: .06em;
  color: #6f6a60;
  padding-top: 2px;
  flex-shrink: 0;
}
.ps-buy .info-row .v { font-size: 14.5px; font-weight: 500; line-height: 1.45; text-align: right; }
.ps-buy .info-row.ruled { padding-top: 9px; border-top: 1px solid #e6e3dc; }

.ps-buy .detail-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 44px;
  font-size: 15px;
}
.ps-buy .detail-row .k { font-size: 14px; color: #6f6a60; flex-shrink: 0; }
.ps-buy .detail-row a.v { color: #1a1c1a; font-weight: 500; text-decoration: underline; text-underline-offset: 3px; }
.ps-buy .detail-row .v { font-weight: 500; text-align: right; min-width: 0; }

.ps-buy .member-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 48px;
}
.ps-buy .member-row .k { font-size: 14px; color: #6f6a60; flex-shrink: 0; }
.ps-buy .member-row .v { font-size: 15px; font-weight: 500; text-align: right; min-width: 0; overflow-wrap: anywhere; }
/* ⚠️ 唯讀那一版的空值不要留白，會看起來像壞掉的輸入框（spec §9-26：V1 唯讀） */
.ps-buy .member-row .v:empty::after { content: "—"; color: #9a958c; font-weight: 400; }

/* ── 表單欄位：底線式，不是框 ───────────────────────────────────────────── */
.ps-buy .form-field { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* 小標 13／500／次要字色：欄位名稱是指引，不跟填進去的內容搶（2026-10-07 結帳減線） */
.ps-buy .form-label {
  font-size: 13px;
  font-weight: 500;
  color: #4a463f;
  line-height: 1.3;
}
.ps-buy .form-input {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 46px;
  padding: 0 2px;
  border: 0;
  border-bottom: 1px solid #e6e3dc;
  border-radius: 0;
  background: none;
  font: inherit;
  /* ⚠️ 至少 16px：iOS Safari 對小於 16px 的輸入框會在聚焦時自動放大整頁 */
  font-size: 16px;
  color: #1a1c1a;
  width: 100%;
}
.ps-buy .form-input::placeholder { color: #b4afa6; }
.ps-buy .form-input:focus { outline: none; border-bottom-color: #1a1c1a; }
.ps-buy textarea.form-input { min-height: 74px; padding: 11px 12px; background: #faf9f6; border-bottom: 0; border-radius: 3px; line-height: 1.6; resize: vertical; }
/* 唯讀的一格長得跟可填的一樣，只是顏色淡一階——⚠️ 不要做成灰底，那看起來像壞掉 */
.ps-buy .form-input[readonly] { color: #4a463f; }
.ps-buy .form-note { font-size: 13px; line-height: 1.7; color: #6f6a60; padding-top: 5px; }

/* ── 單選：付款方式 ─────────────────────────────────────────────────────
   ⚠️ **這一組是 `<label>` 包 `<input type=radio>`，不是 div。** 稿子畫的是圓點，
   但鍵盤與讀屏要真的 radio；圓點是 `::before` 畫的。用 div 的話**滑鼠測不出問題**。 */
/* 一個選項一張卡，選中的那張框線轉墨黑（選中用 ink）；卡與卡之間靠間距，不畫分隔線。 */
.ps-buy .pay-options { display: flex; flex-direction: column; gap: 8px; }
.ps-buy .pay-option {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  min-height: 56px;
  padding: 14px 16px;
  border: 1px solid #e6e3dc;
  border-radius: 12px;
  cursor: pointer;
}
.ps-buy .pay-option:has(input:checked) { border-color: #1a1c1a; }
.ps-buy .pay-option input { position: absolute; opacity: 0; width: 0; height: 0; }
.ps-buy .pay-mark {
  width: 20px;
  height: 20px;
  margin-top: 2px;
  border-radius: 999px;
  border: 1px solid #c9c2b2;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ps-buy .pay-option input:checked + .pay-mark { border-color: #1a1c1a; }
.ps-buy .pay-option input:checked + .pay-mark::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 999px;
  background: #1a1c1a;
}
.ps-buy .pay-option input:focus-visible + .pay-mark { outline: 2px solid #1a1c1a; outline-offset: 3px; }
.ps-buy .pay-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ps-buy .pay-name { font-size: 16px; font-weight: 500; line-height: 1.4; }
.ps-buy .pay-desc { font-size: 13px; line-height: 1.6; color: #6f6a60; }

/* ── 提示：上下髮絲線的一段藍字，不是色塊 ─────────────────────────────── */
.ps-buy .notice {
  display: flex;
  gap: 10px;
  padding: 13px 0;
  border-top: 1px solid #e6e3dc;
  border-bottom: 1px solid #e6e3dc;
  color: #1b62c4;
}
.ps-buy .notice[hidden] { display: none; }
.ps-buy .notice svg { width: 18px; height: 18px; margin-top: 2px; color: #2477e8; flex-shrink: 0; }
.ps-buy .notice p { font-size: 12.5px; line-height: 1.7; }
.ps-buy .notice b { display: block; font-size: 13px; font-weight: 700; letter-spacing: .04em; color: #2477e8; }
/* 唯一有底色的那一塊：加 LINE（`.notice` 的加強版） */
/* 2026-10-07 改成跟 `.order-box` 同一個暖紙框：整個訂單流程只有一種「框起來的一塊」，
   不再另有一塊藍底。LINE 鈕用 LINE 綠（跟 LINE Pay 那顆同色），客人一眼認得出是 LINE。 */
.ps-buy .notice-strong {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 20px;
  color: #1a1c1a;
}
.ps-buy .notice-strong .notice-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: "Noto Sans TC", sans-serif;
  font-size: 17px;
  font-weight: 600;
  color: #1a1c1a;
}

/* ── 複製鈕 ─────────────────────────────────────────────────────────────
   ⚠️ **金額沒有複製鈕，帳號有**（設計稿 README「金額不提供複製」）。
   金額複製出去會帶著 `NT$` 與千分位，貼進銀行 App 是壞的。 */
.ps-buy .copy-button {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 26px;
  padding: 0 8px;
  border: 1px solid #cfe0fa;
  border-radius: 3px;
  background: none;
  color: #1b62c4;
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  flex-shrink: 0;
  cursor: pointer;
}
.ps-buy .copy-button svg { width: 12px; height: 12px; }
.ps-buy .copy-button:active { background: #f1f6fe; }

/* ── 金額與編號的字 ─────────────────────────────────────────────────────── */
.ps-buy .mono { font-family: ui-monospace, "SF Mono", Menlo, monospace; letter-spacing: .02em; }
.ps-buy .sum-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.ps-buy .sum-row .k { font-size: 12.5px; font-weight: 700; letter-spacing: .08em; }

/* ── 結果屏的細線圈勾 ───────────────────────────────────────────────────── */
.ps-buy .result-mark {
  width: 56px;
  height: 56px;
  border-radius: 999px;
  border: 1px solid #1a1c1a;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.ps-buy .result-mark svg { width: 26px; height: 26px; }
.ps-buy .result { display: flex; flex-direction: column; align-items: center; gap: 12px; padding-top: 6px; text-align: center; }
.ps-buy .result-title { font-family: "Noto Sans TC", sans-serif; font-size: 26px; font-weight: 600; letter-spacing: -.02em; }
.ps-buy .result p { font-size: 13px; line-height: 1.7; color: #6f6a60; }

/* ── 底部動作條 ─────────────────────────────────────────────────────────
   ⚠️ **`position: sticky` 不是 `fixed`。** fixed 在 iOS 上鍵盤跳出來時會被推到
   看不見的地方，而且畫面上只會覺得「按鈕不見了」。 */
.ps-buy .act-bar {
  position: sticky;
  bottom: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 24px calc(26px + env(safe-area-inset-bottom, 0px));
  background: #fff;
  border-top: 1px solid #e6e3dc;
  margin-top: auto;
}
.ps-buy .act-bar > a, .ps-buy .act-bar > button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 52px;
  border-radius: 999px;
  border: 0;
  font: inherit;
  font-size: 16px;
  font-weight: 500;
  letter-spacing: .04em;
  cursor: pointer;
  text-align: center;
}
.ps-buy .act-primary { background: #1a1c1a; color: #fff; }
.ps-buy .act-ghost { background: none; color: #1a1c1a; border: 1px solid #1a1c1a !important; min-height: 44px !important; font-size: 14px !important; }
.ps-buy .act-line { background: #06c755; color: #fff; }
.ps-buy .act-bar > [aria-disabled="true"], .ps-buy .act-bar > :disabled { opacity: .35; cursor: default; }
.ps-buy .act-note { font-size: 13px; line-height: 1.7; color: #6f6a60; text-align: center; }
.ps-buy .act-bar svg { width: 18px; height: 18px; }

/* ── 會員專區 ───────────────────────────────────────────────────────────── */
.ps-buy .member-tabs { display: flex; border-bottom: 1px solid #e6e3dc; margin: 0 24px; flex-shrink: 0; }
.ps-buy .member-tabs a {
  flex: 1 1 0;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: #6f6a60;
  letter-spacing: .02em;
}
.ps-buy .member-tabs a.on { color: #1a1c1a; font-weight: 700; box-shadow: inset 0 -2px 0 #1a1c1a; }
.ps-buy .member-logout { margin-left: auto; font-size: 12px; color: #6f6a60; text-decoration: underline; padding: 8px 0 8px 12px; }

.ps-buy .order-list { display: flex; flex-direction: column; }
.ps-buy .order-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 15px 0;
  border-bottom: 1px solid #e6e3dc;
  color: inherit;
  min-width: 0;
}
.ps-buy .order-row .order-key { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 16px; font-weight: 700; }
.ps-buy .order-row .order-facts { display: flex; flex-direction: column; gap: 7px; min-width: 0; flex: 1 1 auto; }
.ps-buy .order-row .order-tags { display: flex; gap: 6px; flex-wrap: wrap; }
.ps-buy .order-row .order-when { font-size: 12px; color: #6f6a60; }
.ps-buy .order-row .order-end { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex-shrink: 0; margin-left: auto; }
.ps-buy .order-row .order-end svg { width: 19px; height: 19px; color: #c9c2b2; }
.ps-buy .order-row .product-price { font-size: 18px; }
.ps-buy .order-thumb {
  width: 56px;
  height: 56px;
  border-radius: 3px;
  flex-shrink: 0;
  overflow: hidden;
  background: #f1efea repeating-linear-gradient(135deg, transparent 0 12px, #e4e0d7 12px 13px);
}
.ps-buy .order-thumb img { width: 100%; height: 100%; object-fit: contain; background: #fff; }

/* 小結摘要：一張圖 ＋「N 個項目」＋ 金額（結帳頁與匯款頁共用同一顆） */
.ps-buy .order-brief { display: flex; align-items: center; gap: 12px; min-width: 0; }
.ps-buy .order-brief .order-thumb { width: 52px; height: 52px; }
.ps-buy .order-brief .brief-facts { display: flex; flex-direction: column; gap: 3px; flex: 1 1 auto; min-width: 0; }
.ps-buy .order-brief .brief-count { font-family: "Noto Sans TC", sans-serif; font-size: 16px; font-weight: 600; }
.ps-buy .order-brief .brief-names { font-size: 13px; color: #6f6a60; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ps-buy .order-brief .product-price { font-size: 20px; }

/* ── 桌機：跟 `/cart` 同一個上限，置中 ─────────────────────────────────── */
/* 頁尾也跟這一欄同寬（Kelly 2026-10-07：桌機頁尾貼著視窗左邊，跟內容不對齊） */
.ps-buy .buy-nav, .ps-buy .buy-body, .ps-buy .act-bar, .ps-buy .member-tabs, .ps-buy .site-footer { width: 100%; max-width: 780px; margin-left: auto; margin-right: auto; box-sizing: border-box; }

/* ── 桌機再窄一階：結帳／訂單／會員專區（2026-09-10 Kelly「以好看為主」）───────
   780px 下每一種**左右對齊的列**都被拉成長條：`.info-row` 的「銀行」與「國泰世華」
   中間空掉近 700px，眼睛要橫掃一整行才知道那兩個字是一組的；表單底線也長到
   一格輸入框看起來像一條分隔線。這幾頁是照著手機流程做的單欄，桌機該做的是
   **把欄收窄**，不是把每個元件各自加一個上限——後者會讓同一欄裡出現三種寬度。

   ⚠️ **只收這三種頁，不收 `/cart`。** 這條 CSS 是共用的，把上面那個 780 直接改小
   會連購物車一起變，而購物車的桌機版沒有人看過。要動它是另一件事。
   ⚠️ **寫在 `min-width` 的 media query 裡**：手機（390 定案過）一個 byte 都不會變。
   ⚠️ `:is()` 的優先級取括號裡最高的那個（0-2-0），跟上面那條同分，靠**順序在後面**
   贏——這兩條的先後不要對調。 */
@media (min-width: 600px) {
  :is(.checkout-page, .order-page, .member-page) :is(.buy-nav, .buy-body, .act-bar, .member-tabs, .site-footer) {
    max-width: 560px;
  }
}

/* 這幾個是上面三支 renderer 用到的小掛點，跟著它們一起加（2026-09-10） */
.ps-buy .row-copy { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
/* ⚠️ 選擇器要比 `.ps-buy .sum-row .k`（0-3-0）重，不然字級被那條吃掉變 12.5px
   ——畫面上只是「這個標題看起來有點小」，不會有任何錯誤。 */
.ps-buy .sum-row .next-title, .ps-buy .rule-block .next-title, .ps-buy .next-title {
  font-family: "Noto Sans TC", sans-serif;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -.01em;
}
/* LINE Pay 的下一步：綠只出現在這條上邊線與按鈕上，其餘一個字都不換色 */
.ps-buy .line-next { border-top: 2px solid #06c755; }
.ps-buy .line-warning { font-size: 12.5px; line-height: 1.75; color: #12703a; }
/* 匯款／LINE Pay 付款期限那一句（Kelly 2026-10-09）：跟在「下一步」金額底下，灰字、不搶主按鈕。 */
.ps-buy .pay-by { margin: 6px 0 0; font-size: 13px; line-height: 1.7; color: #6f6a60; }
.ps-buy .line-link { font-size: 13px; color: #1b62c4; text-decoration: underline; }
.ps-buy .checkout-form, .ps-buy .report-form, .ps-buy .member-login { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.ps-buy .list-count { font-family: "Noto Sans TC", sans-serif; font-size: 18px; font-weight: 600; letter-spacing: 0; }
.ps-buy .contact-eyebrow { color: #6f6a60; }
/* 「這裡少了一塊東西，你走不下去」的一段：登入查不到、店家沒有匯款帳戶。
   ⚠️ **不給底色。** 一屏最多一塊底色，那塊留給「要照抄的東西」（`.info-band`）；
   這裡用上下髮絲線 ＋ 暖紅字就夠強了。⚠️ 一個類別兩個名字一定會漂，所以登入失敗
   與匯款無帳戶共用這一個 `.state-alert`，不要為了語意各開一個。 */
.ps-buy .state-alert {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 13px; line-height: 1.7; color: #b93e0c;
  padding: 12px 0; border-top: 1px solid #e6e3dc; border-bottom: 1px solid #e6e3dc;
}
.ps-buy .state-alert .state-title { font-family: "Noto Sans TC", sans-serif; font-size: 16px; font-weight: 600; }
/* ⚠️ 上面的 display:flex 會蓋掉 hidden 屬性：沒有錯誤時那塊「還沒出事」的空框照樣畫出上下兩條線
   （2026-10-07 Kelly 在會員專區登入屏看到多兩條線）。結帳、回報、留言的送出失敗框都是同一個。 */
.ps-buy .state-alert[hidden] { display: none; }
.ps-buy .member-page .product-name { font-size: 29px; }

.ps-buy .notice-strong .act-line { display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 52px; border-radius: 999px; font-size: 15px; font-weight: 500; }

/* 唯讀的一格不要有可以打字的暗示（游標與 focus 邊線） */
.ps-buy .form-input[readonly] { cursor: default; }
.ps-buy .form-input[readonly]:focus { border-bottom-color: #e6e3dc; }

/* 訂單聊天室：店家靠左、客人靠右，署名與時間保留。 */
.ps-buy .msg-thread{display:flex;flex-direction:column;gap:16px;min-width:0;margin-top:16px}
.ps-buy .msg-list{display:flex;flex-direction:column;gap:18px;min-width:0}
.ps-buy .msg{display:flex;flex-direction:column;gap:6px;min-width:0;max-width:85%;align-self:flex-start}
.ps-buy .msg-you{align-self:flex-end;align-items:flex-end}
.ps-buy .msg-head{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.ps-buy .msg-you .msg-head{justify-content:flex-end}
.ps-buy .msg-who{font-size:12px;font-weight:500;line-height:1.4;color:#6f6a60}
.ps-buy .msg-when{font-size:11px;color:#6f6a60}
.ps-buy .msg-body{margin:0;padding:12px 16px;border-radius:14px 14px 14px 4px;background:#f2f0eb;color:#1a1c1a;font-size:14px;line-height:1.75;overflow-wrap:anywhere;text-align:left;max-width:100%;box-sizing:border-box}
.ps-buy .msg-you .msg-body{border-radius:14px 14px 4px 14px;background:#1a1c1a;color:#fff}

/* 輸入框 ＋ 送出。⚠️ 這顆鈕**不進 `.act-bar`**：底部那條是「這一屏要你做的
   那件事」（去匯款、去回報），留言是隨時可以做、也可以不做的第二件事。
   放進去會有兩顆主鈕，而客人分不出哪一顆是往前走的那一顆。 */
.ps-buy .msg-form { display: flex; flex-direction: column; gap: 10px; align-items: flex-end; min-width: 0; }
.ps-buy .msg-form .form-input { min-height: 80px; width:100%; box-sizing:border-box; border:1px solid #e6e3dc; border-radius:12px; background:#fff; padding:12px 14px; resize:vertical; }
.ps-buy .msg-send {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 22px;
  border: 1px solid #1a1c1a; border-radius: 999px;
  font-size: 14px; font-weight: 500; line-height: 1;
}
.ps-buy .msg-send:active { background: #f2f0eb; }

/* 會員編號那一行（2026-09-10）。設計稿把它放在分頁列底下第一個位置，
   用一條墨黑線跟底下的資料列分開——它不是一筆「你填過的資料」，是店家給的號碼。
   ⚠️ 稿子上編號右邊那顆「一般客戶」分級標籤**沒有做**（spec §6：會員等級永遠不做），
   所以這一行是單欄不是左右分置。 */
.ps-buy .member-no {
  display: flex; flex-direction: column; gap: 3px;
  padding-bottom: 13px; border-bottom: 1px solid #1a1c1a;
}
.ps-buy .member-no .mono { font-size: 20px; font-weight: 600; }

/* ── 只有讀屏看得到的字 ──────────────────────────────────────────────────
   ⚠️ **圓點與粗體在讀屏上都不存在。** 「有新訊息」這件事只用顏色與字重表達的話，
   讀屏拿到的兩列一模一樣，而畫面上看起來完全正常。⚠️ 不要改成 `display: none`
   或 `visibility: hidden`——那兩個連讀屏也讀不到，等於這段字白寫。 */
.ps-buy .sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* 「有新東西」那顆圓點：分頁列、訂單列、通知列共用同一顆。
   ⚠️ **用這一份已經在用的暖紅（`#b93e0c`，`.state-alert` 那個），不要另外調一個。**
   多一個紅就是多一個訊號，而兩個都偏紅的紅在同一頁上分不出誰比較急。 */
.ps-buy .new-dot { width: 7px; height: 7px; border-radius: 999px; background: #b93e0c; flex-shrink: 0; }
.ps-buy .member-tabs a .new-dot { display: inline-block; margin-left: 5px; vertical-align: middle; }
.ps-buy .order-key .new-dot { display: inline-block; margin-right: 6px; vertical-align: 2px; }

/* ── 店家的回覆（訂單查詢最上面那一段，2026-09-10）──────────────────────
   留言串做好了，但客人不會知道店家回了他——會員專區沒有推播，email 通知（SES）
   還不存在。這一段是目前唯一會告訴他「有人回你」的地方。

   ⚠️ **空的時候整段不渲**（`notifyList()` 回空字串），所以這裡沒有空狀態樣式。
   多數時候店家沒有回任何東西，留一個「目前沒有新訊息」的灰框，對九成的人就是
   每次進來被提醒一次自己沒人理。

   ⚠️ **不做成卡片、不給底色。** 一屏最多一塊底色，而它底下就是訂單列表
   ——兩段長得一樣的話，客人會以為那是兩批不同的訂單。這一段是「誰說了什麼」，
   底下那段是「這張單現在怎樣」。 */
.ps-buy .notify-list { display: flex; flex-direction: column; }
.ps-buy .notify-list > .form-label { display: flex; align-items: center; gap: 5px; padding-bottom: 7px; }
.ps-buy .notify-row {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 12px 0;
  border-bottom: 1px solid #e6e3dc;
  color: inherit;
  min-width: 0;
}
.ps-buy .notify-row:first-of-type { border-top: 1px solid #e6e3dc; }
/* ⚠️ 圓點的位置**固定佔一格**，未讀才填。不留這一格的話，讀過與未讀的兩列
   文字會左右差 16px，看起來像排版壞掉。 */
.ps-buy .notify-mark { width: 7px; flex-shrink: 0; display: flex; justify-content: center; padding-top: 7px; }
.ps-buy .notify-facts { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 auto; }
.ps-buy .notify-from { font-size: 14px; font-weight: 500; line-height: 1.55; }
.ps-buy .notify-row.new .notify-from { font-weight: 700; }
/* 節錄兩行。⚠️ **截字交給 CSS，不要在 renderer 裡切字串**——切在字中間會產生
   半個字，emoji 與組合字更慘，而輸出看起來只是一個正常的省略號。 */
.ps-buy .notify-quote {
  font-size: 13px;
  line-height: 1.65;
  color: #6f6a60;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ps-buy .notify-when { font-size: 11.5px; color: #9a958c; }
.ps-buy .notify-row > svg { width: 19px; height: 19px; color: #c9c2b2; flex-shrink: 0; margin-top: 3px; }

/* ── 期間：一顆按鈕，按下去選（2026-09-10）──────────────────────────────
   ⚠️ **`<details>` ＋ `<summary>`，這一頁沒有可以用的 JS**（只注入了複製鈕與
   進度條切換兩支）。選項是三個 `<a>`，導航一發生頁面重載，選單自然收起來。
   ⚠️ 也不要做成 `<form>`：這一頁上已經有三張沒有去處的表單了。
   ⚠️ `summary` 的預設三角形要兩條才關得掉（`list-style` ＋ WebKit 的私有偽元素），
   少一條在 Safari 上會多出一個跟旁邊那個 caret 打架的三角形。 */
.ps-buy .range-pick { align-self: flex-start; min-width: 0; }
.ps-buy .range-pick > summary {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 15px;
  border: 1px solid #c9c2b2;
  border-radius: 999px;
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  list-style: none;
}
.ps-buy .range-pick > summary::-webkit-details-marker { display: none; }
.ps-buy .range-pick > summary svg { color: #6f6a60; }
.ps-buy .range-pick[open] > summary { border-color: #1a1c1a; }
.ps-buy .range-menu { display: flex; flex-direction: column; padding-top: 8px; }
.ps-buy .range-menu a {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 15px;
  font-size: 14px;
  color: #6f6a60;
  border-bottom: 1px solid #e6e3dc;
}
.ps-buy .range-menu a:first-child { border-top: 1px solid #e6e3dc; }
/* 選中的那一項：⚠️ **勾勾 ＋ 墨黑 ＋ 粗體三個一起**。只靠顏色的話，
   他分不出「現在在看哪一段」與「這一項比較常用」。 */
.ps-buy .range-menu a.on { color: #1a1c1a; font-weight: 700; }
.ps-buy .range-menu .range-check { width: 15px; height: 15px; flex-shrink: 0; display: flex; }

/* Shipping draft UI, shared with the App checkout experience. */
/* 暖紙底＋髮絲框的一塊：訂單已成立、對帳資訊、你回報的內容共用。
   框裡的字跟框外的鍵值列同一套：key 14 次要字、value 15 粗體墨黑；框標題 15／600。 */
.ps-buy .order-box{padding:20px;display:flex;flex-direction:column;gap:12px}
.ps-buy .order-box .box-title{font:600 15px/1.5 "Noto Sans TC",sans-serif;margin:0 0 2px}
.ps-buy .order-box .sum-row > span{font-size:14px;color:#6f6a60;white-space:nowrap;flex-shrink:0}.ps-buy .order-box .sum-row > b{text-align:right;min-width:0}
.ps-buy .match-block + .report-form{margin-top:8px}
.ps-buy .shipping-order-summary .result{align-items:flex-start;text-align:left;padding:0}
.ps-buy .shipping-order-summary .result-title{font-size:27px}
.ps-buy .shipping-total{border-top:1px solid #1a1c1a;padding-top:14px;margin-top:4px}
.ps-buy .shipping-panel,.ps-buy .shipping-recipient,.ps-buy .shipping-summary{display:flex;flex-direction:column;gap:16px}
.ps-buy .shipping-panel:empty{display:none}
.ps-buy .shipping-recipient,.ps-buy .shipping-summary{margin-top:20px}
.ps-buy .shipping-summary{gap:12px;font-size:15px}.ps-buy .shipping-summary .product-price{font-size:22px}
.ps-buy .shipping-match{display:flex;align-items:center;gap:10px;min-height:44px}
.ps-buy .shipping-match input{width:20px;height:20px;accent-color:#1a1c1a}
.ps-buy .shipping-store{padding:16px;border:1px solid #e6e3dc;border-radius:12px;display:flex;flex-direction:column;gap:10px}
.ps-buy .shipping-progress,.ps-buy .shipping-alert{padding:12px 16px;background:#faf9f6;border-radius:8px;font-size:13px;line-height:1.8}
.ps-buy .shipping-alert{background:#fff8f3;color:#843809;border-left:2px solid #b93e0c;border-radius:0 8px 8px 0}
.ps-buy .shipping-dialog{box-sizing:border-box;width:calc(100% - 32px);max-width:440px;border:1px solid #e6e3dc;border-radius:8px;padding:24px;color:#1a1c1a;background:white;font:14px/1.8 'PingFang TC',sans-serif}
.ps-buy .shipping-dialog::backdrop{background:rgba(26,28,26,.4)}
.ps-buy .shipping-dialog button{width:100%;margin-top:16px;min-height:48px}
.ps-buy [data-checkout-submit]:disabled{opacity:.35;cursor:default}

/* 結帳四段（訂購人資料／寄送方式／收件資訊／付款方式）同一層標題；段落之間靠留白分開，不畫線。 */
.ps-buy .section-title{font:600 17px/1.5 "Noto Sans TC",sans-serif;letter-spacing:-.01em;margin:0}
.ps-buy .form-field > .section-title{margin-bottom:6px}
.ps-buy .checkout-form > .pay-block,.ps-buy .checkout-form > .shipping-panel{margin-top:20px}
.ps-buy .pay-block{gap:12px}
.ps-buy [data-shipping-progress]:empty{display:none}

.shipping-progress{display:flex;flex-direction:column;gap:6px}

.ps-buy .appointment-contacts{display:flex;flex-direction:column;gap:8px}.ps-buy .appointment-contacts .act-line{min-height:48px}

/* Compact social links in the member contact section. */
.ps-buy .member-social-icons { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 16px; }
.ps-buy .member-social-icons a { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; color: inherit; border: 1px solid #e6e3dc; border-radius: 50%; text-decoration: none; }
.ps-buy .member-social-icons span { display: flex; }
.ps-buy .member-social-icons a:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }

/* 會員專區「聯絡店家」最下方的反詐騙回報（Kelly 2026-10-07）。按鈕沿用 act-ghost 的外框樣子；act-ghost 的版面本來只寫在 .act-bar 裡，這裡補齊。 */
/* 結帳頁「訂購人資料」下方：登入會員自動帶入（2026-10-07）。連結要 44 高的點擊範圍，所以整行用 flex 置中。 */
.ps-buy .member-prefill { display: flex; align-items: center; flex-wrap: wrap; margin: -8px 0 -4px; }
.ps-buy .member-prefill a { display: inline-flex; align-items: center; min-height: 44px; color: #1a1c1a; font-weight: 500; text-decoration: underline; text-underline-offset: 3px; }
.ps-buy .member-shopping-info { display: flex; gap: 8px; }
.ps-buy :is(.member-shopping-info, .member-fraud) .act-ghost { border-radius: 999px; font-weight: 500; }
.ps-buy .member-shopping-info .act-ghost { flex: 1; cursor: pointer; }
.ps-buy .member-fraud { margin-top: 24px; padding-top: 20px; border-top: 1px solid #e6e3dc; gap: 6px; }
.ps-buy .member-fraud .form-note { margin: 0; }
.ps-buy .member-fraud .act-ghost { display: flex; align-items: center; justify-content: center; margin-top: 8px; text-decoration: none; }

/* Related products use the existing catalog order with a compact, scrollable view. */
.ps-buy .related-products { box-sizing: border-box; width: 100%; max-width: 780px; margin: 0 auto; padding: 24px; border-top: 1px solid #e6e3dc; }
.ps-buy .related-products h2 { margin: 0 0 16px; font-size: 20px; font-weight: 500; }
.ps-buy .related-products-list { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(144px, 42%); gap: 16px; overflow-x: auto; scroll-snap-type: x proximity; list-style: none; margin: 0; padding: 4px 4px 12px; }
.ps-buy .related-product-card { display: block; color: inherit; text-decoration: none; scroll-snap-align: start; }
.ps-buy .related-product-card:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; border-radius: 4px; }
.ps-buy .related-product-photo { aspect-ratio: 1; background: #efede6; overflow: hidden; border-radius: 8px; }
.ps-buy .related-product-photo img { width: 100%; height: 100%; display: block; object-fit: contain; background: #fff; }
.ps-buy .related-product-card h3 { margin: 10px 0 4px; font-size: 15px; font-weight: 500; line-height: 1.5; overflow-wrap: anywhere; }
.ps-buy .related-product-card p { margin: 0; font-size: 14px; line-height: 1.5; }
@media (min-width: 700px) { .ps-buy .related-products-list { grid-auto-columns: calc((100% - 48px) / 4); } }

/* Official directory results inside the checkout store picker. */
.ps-buy .shipping-dialog{max-height:85dvh;overflow-y:auto}
.ps-buy .pickup-store-result{display:flex;flex-direction:column;align-items:flex-start;text-align:left;gap:6px;white-space:normal;margin-block:8px;width:100%;padding:16px;border:1px solid #e6e3dc;border-radius:16px}
.ps-buy .pickup-store-result span{font-weight:400}

.ps-buy .pickup-heading,.ps-buy .pickup-result-heading{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%}
.ps-buy .pickup-heading h2{margin:0}
.ps-buy .pickup-heading button{width:44px;min-width:44px;padding:0}
.ps-buy .pickup-area{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.ps-buy .pickup-area select{width:100%;min-width:0;margin-top:8px}
.ps-buy .pickup-area label{min-width:0}
.ps-buy .pickup-store-result .pickup-store-id{background:#1a1c1a;color:#fff;border-radius:999px;padding:4px 12px;font-weight:600}
.ps-buy .shipping-dialog[open]{display:flex;flex-direction:column;gap:8px}
.ps-buy .shipping-dialog [data-store-results]{overflow-y:auto;min-height:0;flex:1 1 auto;overscroll-behavior:contain}
.ps-buy .shipping-dialog > :not([data-store-results]){flex-shrink:0}
.ps-buy .shipping-dialog .pickup-heading button{margin-top:0;border-radius:50%}
.ps-buy .shipping-dialog [data-store-search]{margin-top:4px}
.ps-buy .shipping-dialog [data-store-cancel]{margin-top:0}
.ps-buy .shipping-dialog [data-store-status]{margin:4px 0}

/* Credit payment deadline and cancellation review. */
.ps-buy .payment-deadline{margin:24px 0;padding:18px 20px;border:1px solid #e6dfcf;border-radius:8px;background:#faf7ef;display:grid;gap:7px}
.ps-buy .payment-deadline>span{font-size:12px;color:#73694f}
.ps-buy .payment-deadline strong{font-size:21px;font-weight:600;font-variant-numeric:tabular-nums}
.ps-buy .payment-deadline small{font-size:11px;font-weight:400;color:#6f6a60}
.ps-buy .payment-deadline p{font-size:12px;line-height:1.7;color:#6f6a60;margin:0}
.ps-buy .payment-deadline.is-ended{background:#f6f6f3;border-color:#e6e3dc}
.ps-buy .act-bar>.payment-cancel-link{background:transparent;color:#6f6a60;min-height:36px;font-size:13px;text-decoration:underline;text-underline-offset:4px}
.ps-buy .payment-cancel-dialog{box-sizing:border-box;width:calc(100% - 40px);max-width:390px;max-height:85dvh;overflow:auto;margin:auto;padding:28px 24px;border:1px solid #e6e3dc;border-radius:16px;color:#1a1c1a;background:#fff}
.ps-buy .payment-cancel-dialog::backdrop{background:rgba(26,28,26,.45)}
.ps-buy .payment-dialog-eyebrow{font-size:12px;color:#6f6a60}
.ps-buy .payment-cancel-dialog h2{font-family:"Noto Sans TC",sans-serif;font-size:23px;line-height:1.5;margin:14px 0}
.ps-buy .payment-cancel-dialog p{font-size:14px;line-height:1.8;margin:12px 0 18px}
.ps-buy .payment-cancel-dialog button{display:block;width:100%;min-height:48px;margin-top:10px;border:0;border-radius:999px;font:inherit;cursor:pointer}
.ps-buy .payment-preview-panel{margin:24px 0;padding:14px 16px;border:1px dashed #d4d0c6;border-radius:8px;font-size:12px;color:#6f6a60}
.ps-buy .payment-preview-panel summary{cursor:pointer;min-height:28px;line-height:28px}
.ps-buy .payment-preview-panel p{line-height:1.7;margin:10px 0}
.ps-buy .payment-preview-links{display:flex;flex-wrap:wrap;gap:8px}
.ps-buy .payment-preview-links a{display:block;padding:8px 12px;border:1px solid #e6e3dc;border-radius:8px;color:#1a1c1a;background:white;text-decoration:none;min-height:40px;box-sizing:border-box}
.ps-buy .payment-preview-links a[aria-current=page]{background:#1a1c1a;color:#fff}
.ps-buy .payment-preview-panel label{display:block;line-height:1.8;margin-top:14px}
.ps-buy .payment-preview-panel select{width:100%;margin-top:6px;min-height:44px;padding:8px;background:white;color:#1a1c1a;border:1px solid #d4d0c6;border-radius:6px;font:inherit}
.ps-buy .payment-cancel-dialog button:focus-visible,.ps-buy .payment-cancel-link:focus-visible,.ps-buy .payment-preview-panel a:focus-visible{outline:2px solid #2477e8;outline-offset:3px}
.ps-buy .payment-preview-links button{padding:8px 12px;min-height:44px;border:1px solid #d4d0c6;border-radius:8px;background:white;color:#1a1c1a;font:inherit;cursor:pointer;margin-bottom:10px}
.ps-buy [data-payment-countdown]{font-variant-numeric:tabular-nums}
.ps-buy .act-bar>[hidden]{display:none}

/* 複製／儲存的回饋（2026-09-24 Kelly：「點下去沒有提醒，不確定有沒有按到」）。
   ⚠️ **原本只有「鈕上的字換成已複製」那一種回饋，而按著的手指正好蓋住那顆鈕**
   ——所以它在手機上等於沒有回饋。字仍然照換（手指移開就看得到），這一條是補給
   「按的當下」看的那一個。
   ⚠️ **浮在動作條上面，不是塞進內容流裡**：塞進去會把版面往下推，那一下的跳動
   看起來就像按錯了。`bottom` 留出動作條與安全區的高度。
   ⚠️ 它只報告「已經發生的事」，不能點也不擋操作——`pointer-events: none`。 */
.ps-buy .ps-toast {
  position: fixed;
  left: 50%;
  /* 預設值只給「沒有動作條」的頁面用。有動作條時由 JS 量它的高度把 toast 推到它上面
     ——寫死一個數字的話，兩顆鈕的動作條會把 toast 蓋在鈕上面（2026-09-24 實測）。 */
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  z-index: 10;
  transform: translate(-50%, 6px);
  padding: 10px 18px;
  border-radius: 999px;
  background: #1a1c1a;
  color: #fff;
  font-size: 13px;
  letter-spacing: .04em;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity .18s ease, transform .18s ease;
}
.ps-buy .ps-toast.is-shown { opacity: 1; transform: translate(-50%, 0); }
@media (prefers-reduced-motion: reduce) {
  .ps-buy .ps-toast { transition: none; }
}

/* Multiple photos: same track, direct thumbnail selection. */
.ps-buy .product-thumbs{display:flex;gap:10px;overflow-x:auto;padding:14px 1px 4px;margin:0 20px}
.ps-buy .product-thumbs button{padding:3px;background:transparent;border:2px solid transparent;border-radius:12px;flex:0 0 66px;height:66px;cursor:pointer}
.ps-buy .product-thumbs button[aria-pressed="true"]{border-color:#38352e}
.ps-buy .product-thumbs img{display:block;width:100%;height:100%;object-fit:cover;border-radius:7px}
.ps-buy .cart-added-toast{position:fixed;z-index:40;top:calc(env(safe-area-inset-top,0px) + 76px);left:50%;transform:translate(-50%,-12px);width:calc(100% - 32px);max-width:460px;box-sizing:border-box;background:#282622;color:#fff;border-radius:16px;padding:12px;display:flex;gap:10px;align-items:center;box-shadow:0 8px 28px #0003;opacity:0;visibility:hidden;transition:opacity .2s,transform .2s,visibility .2s}
.ps-buy .cart-added-toast.is-shown{opacity:1;visibility:visible;transform:translate(-50%,0)}
.ps-buy .cart-added-toast img{width:44px;height:44px;object-fit:cover;border-radius:8px}
.ps-buy .cart-added-toast>div{flex:1;min-width:0}
.ps-buy .cart-added-toast strong{font:500 14px/1.5 "Noto Sans TC",sans-serif}
.ps-buy .cart-added-toast strong span{color:#8ad1ac;margin-right:4px}
.ps-buy .cart-added-toast small{display:block;color:#ccc5ba;font-size:11px;margin-top:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ps-buy .cart-added-toast a{font:400 12px/1.4 "Noto Sans TC",sans-serif;white-space:nowrap;background:#ffffff20;color:#fff;text-decoration:none;border-radius:24px;padding:14px 10px;min-height:44px;box-sizing:border-box}
@media(prefers-reduced-motion:reduce){.ps-buy .cart-added-toast{transition:none}}

.ps-buy .cart-add-error{position:fixed;z-index:40;top:76px;left:50%;transform:translateX(-50%);width:calc(100% - 32px);max-width:460px;box-sizing:border-box;margin:0;padding:16px;border-radius:16px;background:#282622;color:#fff;box-shadow:0 8px 28px #0003;font:400 14px/1.6 "Noto Sans TC",sans-serif}

/* ── 訂購人／收件資訊：名片式（2026-10-07）────────────────────────────────
   一段由上往下讀，不是左右兩欄：主行（人・電話）墨黑 16／500，其餘 14 次要字。
   寄送方式是標題右邊的小標籤，物流單號留在最後一列（`.detail-row`）。 */
/* 底色框（Kelly 2026-10-07「有一些底色讓視覺集中」）：跟 `.order-box` 同一個暖紙框，兩張各自一框。 */
.ps-buy .contact-card { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; min-width: 0; padding: 16px 20px 18px; }
.ps-buy .contact-card + .contact-card { margin-top: 0; }
.ps-buy .contact-card .card-tag { background: #fff; }
.ps-buy .contact-card .section-title { margin-bottom: 6px; }
.ps-buy .card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.ps-buy .card-tag { font-size: 13px; color: #4a463f; padding: 2px 10px; border: 1px solid #e6e3dc; border-radius: 999px; white-space: nowrap; }
.ps-buy .contact-card p { margin: 0; }
.ps-buy .card-main { font-size: 16px; font-weight: 500; line-height: 1.6; }
.ps-buy .card-dot { color: #9a958c; margin: 0 2px; }
.ps-buy .card-line { font-size: 15px; line-height: 1.6; color: #1a1c1a; }
.ps-buy .card-sub { font-size: 14px; line-height: 1.6; color: #6f6a60; }
.ps-buy .card-meta { font-size: 13px; color: #6f6a60; margin-left: 8px; white-space: nowrap; }
.ps-buy .contact-card .detail-row { margin-top: 4px; min-height: 32px; justify-content: flex-start; font-size: 14px; }
.ps-buy .contact-card .detail-row .v { text-align: left; }

/* ── 匯款步驟：帳號下面的編號清單（2026-10-07）──────────────────────────── */
.ps-buy .next-steps { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 14px; counter-reset: step; }
.ps-buy .next-steps li { counter-increment: step; display: grid; grid-template-columns: 24px 1fr; column-gap: 12px; row-gap: 2px; align-items: start; }
.ps-buy .next-steps li::before { content: counter(step); grid-row: span 2; width: 24px; height: 24px; border-radius: 999px; background: #1a1c1a; color: #fff; font-size: 13px; font-weight: 600; display: grid; place-items: center; margin-top: 1px; }
.ps-buy .next-steps b { font-size: 15px; font-weight: 500; line-height: 1.6; }
.ps-buy .next-steps span { font-size: 13px; line-height: 1.6; color: #6f6a60; }

/* ═══════════════════════════════════════════════════════════════════════════
   網站暫停頁（renderSiteClosed，Kelly 2026-10-11）：沿用下架頁的 `.gone`，只補口袋狗與聯絡區塊撐滿寬。 */
.ps-buy .site-closed-dog { display: block; background: none; width: 100%; max-width: 280px; height: auto; align-self: center; margin-bottom: 12px; }
.ps-buy.site-closed .gone { padding-top: 32px; }
.ps-buy.site-closed .gone > section { align-self: stretch; }
