/*
 * onsite.css — BL-069 階段 E 第二包 WO-E2b-1
 * 來源檔：sales-redeem-flow/mockup/style.css（無法取得 git commit——sales-redeem-flow
 *         資料夾本身未受任何 git 版控；來源檔以檔案系統 mtime 為準，見轉換腳本執行紀錄）。
 * 轉換日期：2026-09-20
 * 本檔是「一次性轉換產物」，不是手改對象——要改樣式請先改 mockup/style.css，
 * 再重跑 sales-redeem-flow/onsite-css-tools/transform-css.cjs 重新產生本檔（用法見該
 * 資料夾 README.md）。
 *
 * 六類機械轉換（外觀值零改，只做下列六種轉換；2026-09-20 二次複核新增 (f)）：
 * (a) 作用域：每個一般規則的每個選擇器前加 .srf-root。:root 併入 .srf-root。裸 html/body
 *     規則的宣告逐條篩選：只留對容器仍有意義的（font-family／-webkit-font-smoothing／
 *     color；2026-09-20 複核後把 background 也移出保留清單——套在 .srf-root 這個
 *     嵌入頁面的容器上會蓋掉 mockup 原本沒有的底色，造成與 mockup 對照組不一致，見隔離
 *     重設層說明），其餘（margin/padding/min-height/background 等整頁 reset）略過，見下方
 *     「已略過清單」。含 body 類別修飾的複合選擇器（如 body.dp-site-shell、
 *     body:not(.cu-page)）把開頭 html/body token 換成 .srf-root，其餘不動——這些是
 *     mockup 自己 demo 用的預覽切換，production 目前未接，保留規則本身不刪。
 * (b) 單位：全篇 rem 依 mockup 16px 基準換算成 px（×16），含 calc()／變數值內的。
 * (c) 字型：.srf-root 另掛 font-family（design-rules §1.3）／font-size:16px／line-height。
 * (d) 安全區：所有 env (safe-area-inset-*) 改成固定值（取 calc() 內原有的基礎值；官網
 *     viewport 無 viewport-fit=cover，這些值在官網環境本來就會算成 0）。逐處原值見下表。
 * (e) 層級：mockup 三個真浮層（.overlay／.scan-camera-layer／.srf-toast）原 z-index 平移到
 *     600–1000 之間、保持相對順序，避開官網漢堡選單（500）與 Bootstrap modal（1055，
 *     來源：spec 2026-09-16 拍板／P2 報告 §4）；其餘 z-index（0/1/2/20/50）是元件內部
 *     堆疊（卡片層、頁首相對定位），不與官網頁面層級競爭，維持原值：
 *       .overlay              100 → 650
 *       .scan-camera-layer    200 → 700
 *       .srf-toast            999 → 950
 * (f) class 改名：每個 class 選擇器 token 一律加 srf- 前綴（.card→.srf-card、
 *     .form-label→.srf-form-label、.mt-8→.srf-mt-8……狀態類／工具類／元件類一視同仁，
 *     不挑）。已經以 srf- 開頭的不重複加（.srf-root／.srf-toast 等）。由來：僅加祖先
 *     作用域（.srf-root .xxx）防不了「同名 class」滲入——Bootstrap 間距工具類帶
 *     !important、且同名 class 上「mockup 沒宣告但官網有宣告」的屬性（如 .form-label
 *     的 color／margin-bottom、.card 經 CSS 變數設的 border-radius）我方規則根本沒
 *     宣告該屬性、無從蓋過。只有 class 名稱本身不撞名才能根治，2b 共同規定 2 原文
 *     「加作用域前綴」其實就是指這個，先前只做了祖先選擇器是誤讀。id 選擇器不動
 *     （mockup 只用了三個：#app／#header／#sheet-holder，均為結構性 id 非工具/元件
 *     class，不撞名風險低，維持不變）；[class*=] 一類屬性選擇器經查證來源檔 0 處，
 *     不需處理。
 *
 * env (safe-area-inset-*) 逐處原值 → 新值：
 *   calc(14px + env (safe-area-inset-top, 0px)) → 14px
 *   calc(14px + env (safe-area-inset-bottom, 0px)) → 14px
 *   calc(22px + env (safe-area-inset-bottom, 0px)) → 22px
 *   calc(8px + env (safe-area-inset-bottom, 0px)) → 8px
 *   env (safe-area-inset-top, 0px) → 0px
 *   env (safe-area-inset-bottom, 0px) → 0px
 *
 * 已略過（原為 html/body 的宣告，套在 .srf-root 容器上無意義或可能與官網頁面衝突，
 * 施工方判斷，未上鎖，待使用者需要時再議）：
 *   原為 html/body 的 margin: 0
 *   原為 html/body 的 padding: 0
 *   原為 html/body 的 background: var(--gray-100)
 *   原為 body 的 min-height: 100vh
 *   原為 body 的 min-height: 100dvh
 *
 * 為什麼不進官網 webpack 打包：見 stage-E2-workorders.md 2b 共同規定 1（全站走 webpack mix，
 * 新增入口會讓全站既有程式包重編、波及舊頁，且有打包舊債 BL-073）。
 *
 * ---------------------------------------------------------------------------
 * 隔離重設層（2026-09-20 主 session 複核後補；由來：browse 殼截圖與 mockup 並排比對，
 * 肉眼看出官網全域樣式滲進 .srf-root——字距變寬、標題變襯線、標籤字級跑掉）。
 *
 * 官網對基本元素下的全域規則（逐一查證，來源：public/assets/css/app/style.css／
 * add_style.css／maps/style.css／public/vendors/sandbox/css/style.css）：
 *   body                       letter-spacing: 0.05em（style.css:699）
 *   h1–h6, .h1–.h6             font-family: "Noto Serif TC","Noto Serif JP",serif
 *                              （add_style.css，把標題變成襯線體、非 mockup 的無襯線標題）
 *   h1–h6, .h1–.h6             font-weight:700／margin/line-height 各級不同／
 *                              word-spacing:0.1 rem／letter-spacing:-0.01 rem／
 *                              color:#343f52（sandbox style.css，Bootstrap 風格主題預設）
 *   p, table, blockquote,
 *   address, pre, iframe,
 *   form, figure, dl           margin: 0（style.css normalize 區）
 *   ul, ol                     margin/padding: 0; list-style: none（style.css）
 *   ol, ul                     padding-left: 2 rem；margin-top/bottom: 1 rem（sandbox，
 *                              與上一條疊加時視載入順序而定，不可預期）
 *   a                          color: inherit; text-decoration: none（style.css，mockup
 *                              自己也有這條、不衝突）
 *   label                      display: inline-block（sandbox）
 *   button, input, optgroup,
 *   select, textarea           color:inherit; background:transparent; padding:0;
 *                              margin:0; border-radius:0; text-align/text-transform:
 *                              inherit（style.css normalize 區）
 *   table                      border-collapse: collapse（style.css／sandbox 兩處）
 *   th                         text-align:left; font-weight:bold（style.css）／
 *                              text-align:-webkit-match-parent（sandbox，較晚載入者贏）
 *   td, th                     padding: 0（style.css）
 *   small, .small              font-size: 80%（style.css）／0.6 rem（sandbox）
 *
 * 對策：在 mockup 轉換規則「之前」插入一層隔離重設——(1) .srf-root 本身重設字距／字重／
 * 行高／顏色等會被繼承的屬性回到「mockup body 若不設就是瀏覽器預設」的值；(2) 對每個
 * 基本元素寫一條 .srf-root <tag> {...}（特異度 0,1,1），把上表官網會改到的屬性設回
 * inherit（讓它們從 .srf-root 的重設值往下繼承，不管官網原本設的是什麼值都被蓋掉）。
 * 不用 :where()（特異度 0，壓不過官網任何元素選擇器）。這層排在 mockup 自己的
 * .srf-root .xxx 規則之前，mockup 有另外定義樣式的元素（.page_title／.btn／.form-label
 * 等）之後會被 mockup 規則覆蓋，行為不變；mockup 沒特別定義的基本元素則落回這層重設值。
 *
 * h1–h6／small 的 font-size 選擇：查證 mockup 正式頁（customer.js／staff.js／common.js）
 * 沒有任何一處使用裸 <h1>–<h6> 或 <small>（全部經由 .page_title／.section-title／
 * .s1-entry-title 等 class 設字級），故字級不依賴瀏覽器預設值，一律 inherit 最簡單也最
 * 不會踩雷；margin 則沿用瀏覽器預設（避免大量 margin:0 讓需要天然留白的地方塌陷）。
 * ---------------------------------------------------------------------------
 */

.srf-root {
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: normal;
  font-weight: normal;
  font-style: normal;
  letter-spacing: normal;
  word-spacing: normal;
  text-transform: none;
  text-indent: 0;
  color: var(--gray-600);
}
/* text-align 不在 .srf-root 統一設值：mockup body 本身沒設 text-align，維持瀏覽器初始值
   （容器類元素初始值 start，在 LTR 頁面視覺等同 left；若寫死 left 反而在 <button> 等
   UA 預設值不是 start 的元素上失真，見下方 button/input 用 revert 還原 UA 預設的理由）。 */

.srf-root h1, .srf-root h2, .srf-root h3, .srf-root h4, .srf-root h5, .srf-root h6 {
  font-family: inherit; font-size: inherit; font-weight: bold; font-style: inherit;
  letter-spacing: inherit; word-spacing: inherit; line-height: inherit; color: inherit;
  text-transform: inherit; margin: 1em 0;
}
.srf-root small {
  font-family: inherit; font-size: inherit; font-weight: inherit; font-style: inherit;
  letter-spacing: inherit; line-height: inherit; color: inherit;
}
.srf-root strong, .srf-root b {
  font-family: inherit; font-weight: bolder; font-style: inherit; color: inherit;
}
.srf-root p, .srf-root blockquote, .srf-root figure {
  font-family: inherit; font-size: inherit; font-weight: inherit; font-style: inherit;
  letter-spacing: inherit; word-spacing: inherit; line-height: inherit; color: inherit;
  text-transform: inherit; margin: 1em 0;
}
.srf-root a {
  font-family: inherit; font-size: inherit; font-weight: inherit; font-style: inherit;
  letter-spacing: inherit; word-spacing: inherit; line-height: inherit;
  text-transform: inherit; text-decoration: inherit;
}
.srf-root ul, .srf-root ol {
  font-family: inherit; font-size: inherit; font-weight: inherit; letter-spacing: inherit;
  line-height: inherit; color: inherit; text-transform: inherit;
  margin: 1em 0; padding-left: 40px; list-style: initial;
}
.srf-root li {
  font-family: inherit; font-size: inherit; font-weight: inherit; letter-spacing: inherit;
  line-height: inherit; color: inherit;
}
.srf-root label {
  font-family: inherit; font-size: inherit; font-weight: inherit; letter-spacing: inherit;
  line-height: inherit; color: inherit; text-transform: inherit; display: inline-block;
}
.srf-root button, .srf-root input, .srf-root select, .srf-root textarea {
  font-family: inherit; font-weight: inherit; font-style: inherit;
  letter-spacing: inherit; word-spacing: inherit; line-height: inherit; color: inherit;
  text-transform: inherit; margin: 0; border-radius: 0; background: transparent;
  /* font-size 同 text-align 一樣用 revert：mockup 沒有任何一條裸 button/input/select/
     textarea 規則設過 font-size，代表它依賴瀏覽器表單元件 UA 預設值（Chromium 對這幾個
     元素的 UA 預設 font-size 本來就不是「跟隨父層」，用 inherit 會跟 mockup 真實表現
     不同）；mockup 需要特定字級的欄位（如 .form-control）都各自有 class 規則明寫
     font-size，特異度更高，不受這裡影響。 */
  font-size: revert;
  /* text-align 官網 normalize 強制改 inherit（本來 <button> UA 預設是 center，
     inherit 後端看祖先才決定）——mockup 完全沒動過這個屬性，代表它假設 button 維持
     UA 預設；用 revert 撤回「官網的 inherit」這個 author 層宣告，讓它退回 UA 預設，
     不是讓它 inherit 自 .srf-root（.srf-root 沒設 text-align，inherit 也會拿到別的
     祖先值，不等於 UA 預設，兩者不同，需要 revert 而非 inherit）。 */
  text-align: revert;
}
.srf-root table {
  font-family: inherit; font-size: inherit; letter-spacing: inherit; color: inherit;
  border-collapse: collapse;
}
.srf-root th, .srf-root td {
  font-family: inherit; font-size: inherit; font-weight: inherit; letter-spacing: inherit;
  line-height: inherit; color: inherit; padding: 0;
}
.srf-root td { text-align: revert; }
.srf-root th { text-align: left; font-weight: bold; }

/*
 * style.css — 共用視覺系統（v3 全面改版）
 * 色彩取自 design/frontend-guideline.md 的 primary teal 色階（app/assets/css/main.css @theme）
 * 字型：Noto Sans TC（內文）／Noto Serif TC（標題）— 透過 Google Fonts CDN 載入（各 html <head> 已加 link）。
 *       粉圓體 jf-openhuninn 前提已推翻（見 design-review-2026-08-15.md §〇），不引進。
 * 店員端＝方向 B「官網延伸風」（見 directions.html #dir-b）：ticket-card／ticket-tabs／rounded-pill btn-sm／
 *       灰 badge、襯線 section 標題、嚴格兩階 teal。
 * 客人端＝完整網站頁外殼（簡化 navbar＋襯線 page title＋footer），視覺貼齊官網 my/tickets.blade.php 既有 class 語彙
 *       （ticket-tabs / ticket-card / ticket-remain-num / ticket-badge-ended / ticket-loadmore 等，命名已對齊實測結果）。
 * 玻璃語言＝折衷：白底扁平為骨，玻璃只用於浮層與強調區塊（sheet、QR 出示區），整頁不鋪玻璃。
 * 破壞性動作＝灰階降級＋強制二次確認，不用紅、不用品牌色（拍板 2026-08-15）。
 */.srf-root {
  --primary-50: #effbfc;
  --primary-100: #d7f3f6;
  --primary-200: #b5e7ec;
  --primary-300: #81d4df;
  --primary-400: #3eb5c7;
  --primary-500: #2b9caf;
  --primary-600: #267e94;
  --primary-700: #256779;
  --primary-800: #265564;
  --primary-900: #244855;
  --primary-950: #132e39;

  --gray-50: #f9fafb;
  --gray-100: #f3f4f6;
  --gray-150: #eef0f2;
  --gray-200: #e5e7eb;
  --gray-300: #d1d5db;
  --gray-400: #9aa0a6;
  --gray-500: #6b7280;
  --gray-600: #4b5563;
  --gray-700: #374151;
  --gray-800: #1f2937;
  --gray-900: #111827;

  --radius-card: 12px;
  --radius-btn: 10px;
  --radius-pill: 999px;
  --shadow-card: 0 1px 2px rgba(20, 66, 82, 0.06), 0 12px 24px -14px rgba(20, 66, 82, 0.22);
  /* 店員端統一陰影（Figma 三件式的兩層 drop shadow；背景模糊只留白 pill 主鈕，見下方註解） */
  --shadow-stf: 0 1px 2px rgba(20, 66, 82, 0.1), 0 12px 18px -8px rgba(20, 66, 82, 0.4);
  --shadow-pop: 0 4px 24px rgba(20, 66, 82, 0.12), 0 24px 48px -24px rgba(20, 66, 82, 0.35);

  --font-sans: 'Noto Sans TC', 'PingFang TC', 'Microsoft JhengHei', 'Heiti TC', system-ui, -apple-system, sans-serif;
  --font-serif: 'Noto Serif TC', 'PingFang TC', 'Microsoft JhengHei', serif;
}.srf-root * { box-sizing: border-box; }.srf-root { color: var(--gray-600); font-family: var(--font-sans); -webkit-font-smoothing: antialiased;}.srf-root { /* 已略過：見檔頭略過清單 */ }
/* 行動版工具列收合／展開會讓 100vh 跳動（見 .phone-shell 同款註解），body 也補一行 dvh
   退路，支援的瀏覽器蓋掉上一行，不支援的忽略整條不會壞。2026-09-19 BL-069 手機 Safari
   走查修批。 */.srf-root { /* 已略過：見檔頭略過清單 */ }.srf-root a { color: inherit; text-decoration: none; }.srf-root button { font-family: inherit; }

/* ===================== 手機框（店員／客人共用） ===================== */.srf-root .srf-phone-shell {
  max-width: 430px;
  min-height: 100vh;
  /* 行動瀏覽器的網址列會讓 100vh 比實際可視高度多出一截（收起前量到的是含網址列的
     高度），底部釘住的內容因此會落在可視範圍外，要滑動一下（網址列收起）才看得到。
     100dvh 是「當下真的看得到多少」，支援的瀏覽器會用這行蓋掉上面那行；不支援的
     瀏覽器把這行當非法值整條忽略，保留 100vh，不會壞。2026-09-07 使用者實機回饋。 */
  min-height: 100dvh;
  margin: 0 auto;
  background: #fff;
  position: relative;
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-card);
}
@media (min-width: 560px) {.srf-root .srf-phone-shell {
    min-height: calc(100vh - 32px);
    min-height: calc(100dvh - 32px);
    margin: 16px auto;
    border-radius: 32px;
    overflow: hidden;
    border: 1px solid var(--gray-200);
    box-shadow: var(--shadow-pop);
    /* 2026-09-07：只在桌面預覽（有手機外框那層視覺時）需要——讓 .phone-shell 自己變成
       position:fixed 子元素的定位基準（CSS 規定：祖先只要有 transform 就會變成 fixed
       後代的「定位參照物」，fixed 後代從此相對這個祖先算位置，不再相對整個瀏覽器視窗）。
       這樣 .cu-flow-bg 的 fixed 底圖在桌面上才會乖乖待在手機外框裡，不會滿版整個瀏覽器
       視窗（跟外框的圓角、陰影打架）。手機上（<560px）沒有這層外框視覺，底圖就該直接
       相對真正的瀏覽器視窗定位，所以這行只寫在這個 media query 裡，不搬到外面。
       translateZ(0) 是最小副作用的寫法，不改變任何看得見的東西，純粹只為了觸發這個
       CSS 規則。 */
    transform: translateZ(0);
  }
}
@media (min-width: 860px) {
  /* 客人可能用平板：容器跟著放寬一階，貼近 Bootstrap container 斷點精神（§二-16） */.srf-root .srf-phone-shell { max-width: 600px; }
}

/* #app 必須自己是 flex column 且吃滿剩餘高度，.app-body{flex:1} 才會真的把底部動作條頂到底
   （v2 缺這條規則，#app 不是 flex，導致底部動作條浮在畫面中間，見 design-review §一-33） */.srf-root #app {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

/* ===================== 品牌流動漸層底圖（客人端＋店員端共用） ===================== */
/* 配色與演算法照官網 WN_landingpage/app/components/FlowBackground.vue，2026-09-05 起不再是
   「唯讀取值的近似」，而是把該元件的 shader／uniform／resize／動態全部逐字移植成純 JS
   （見 flow-bg.js），這裡的容器只負責定位與「WebGL 起不來時」的備援底色。
   STOPS = #DBF7FF / #A8ECFF / #7BC9DE，漸層角度與停止點照官網原檔 264 行 CSS fallback 數值，
   一個字都沒改。2026-09-07 起店員端也鋪同一支（見 R227 milestone 1），這裡不再分客人／
   店員；上面這句舊註解原寫「只用在客人端」已過期，一併更正。
   .cu-shell { position: relative; } 這行原本是給下面 position:absolute 當定位基準，
   2026-09-07 改 position:fixed 後其實用不到了（.phone-shell 基底本來就有 position:relative，
   對 fixed 元素也沒有作用），但其他規則可能還依賴這個 class 存在，故意保留不刪。 */.srf-root .srf-cu-shell { position: relative; }.srf-root .srf-cu-flow-bg {
  /* 2026-09-07 使用者實機回饋「背景看起來被限制了、沒有夥伴頁單店頁那麼滿版」：查證
     官網元件是 position:fixed（註解寫「全頁固定底圖」，永遠精準貼合當下那一屏，捲動時
     底圖不跟著移動）；這裡原本抄成 position:absolute，會跟著 .phone-shell 一起變高——
     頁面內容比一屏長時（例如展開很多商品的組單頁），底圖被拉伸鋪滿整個很長的頁面，
     同一屏內看到的只是拉稀釋過的一小段，視覺上就是「變小、不飽滿」。改回 fixed，
     跟官網一致：不論頁面多長，底圖永遠精準貼合當下畫面。
     手機上（<560px，這支 mockup 實際會被使用的寬度）沒有「桌面外框」這層東西，
     fixed 直接相對瀏覽器視窗定位，效果等同官網。桌面預覽（≥560px）想保留「背景不
     超出手機外框」的既有觀感，用 .phone-shell 加 transform 讓它自己變成 fixed 子元素
     的定位基準（見下面 560px 那段），兩邊都不用另外分流程式碼。 */
  position: fixed; inset: 0; z-index: 0;
  overflow: hidden; pointer-events: none;
  /* WebGL2 不支援、或 shader 編譯／連結失敗時，flow-bg.js 直接 return，畫面留這層，不會壞 */
  background: linear-gradient(150deg, #DBF7FF 9.2%, #A8ECFF 30.9%, #7BC9DE 71.7%);
}.srf-root .srf-cu-flow-canvas {
  display: block;
  width: 100%;
  height: 100%;
}.srf-root .srf-cu-shell > #header,
.srf-root .srf-cu-shell > #app,
.srf-root .srf-cu-shell > .srf-cu-site-footer { position: relative; z-index: 1; }

/* 客人端內容一律裝進白色實面卡片再浮在漸層上（骨架仍扁平，字要好讀，見對比度自檢） */.srf-root .srf-cu-panel {
  background: #fff; border-radius: var(--radius-card);
  box-shadow: var(--shadow-stf); padding: 20px;
}

/* ===================== 客人端站台外殼（navbar／footer，全站常駐） ===================== */
/* BL-069 UX 同步修批 F7（2026-09-19 使用者拍板）：頁首固定 52px，與官網 #header.header_fixed／
   本檔 .dp-site-header 同高（見下方 2130 行附近「dp-site-*：官網殼」段落）；logo 尺寸／位置
   直接照 .dp-site-header .dp-site-logo 抄（left 13.5px、top 10.4px、168.9×32.2）。原本的
   safe-area-inset-top 動態內距與右上〔出示給店員〕小鈕（.cu-header-qr-btn，C05／F8 兩批舊
   修批）已隨這次改版整組移除——「做事頁」頁首與「逛的頁」頁首現在共用同一組尺寸基準，不再
   各自量各自的。 */.srf-root #header.srf-cu-header {
  flex-shrink: 0;
  background: #fff;
  border-bottom: 1px solid var(--gray-150);
  position: relative;
  height: 52px;
  box-sizing: border-box;
}.srf-root .srf-header_logo { margin: 0; }.srf-root .srf-cu-header-logo {
  position: absolute; left: 13.5px; top: 10.4px;
  width: 168.9px; height: 32.2px; display: block;
  cursor: pointer;
}

/* 概念稿階段簡化為單行版權字；官網 footer.blade.php 另含關於我們／隱私權政策連結＋公司登記資訊，
   正式開發需比照官網補齊連結，不視為終版（component-audit-2026-08-17 部分對齊 5） */.srf-root .srf-cu-site-footer {
  flex-shrink: 0;
  background: #fff;
  text-align: center;
  padding: 16px 18px;
  font-size: 11.2px;
  color: var(--gray-300);
  border-top: 1px solid var(--gray-100);
}

/* 客人端頁首（每個 C 畫面用）：骨架貼齊官網 page_heading/page_main_visual/page_title/main_jp
   （my/tickets.blade.php 等全站共用結構）；返回鍵／QR 捷徑是本工具的操作型擴充，
   官網靜態頁沒有，維持 cu- 前綴命名（component-audit-2026-08-17 §四-2） */.srf-root .srf-page_heading { padding: 18px 20px 4px; }.srf-root .srf-page_main_visual { }.srf-root .srf-cu-pagehead-top { display: flex; align-items: center; justify-content: space-between; min-height: 30px; }.srf-root .srf-cu-back-btn {
  border: 0; background: transparent; color: var(--gray-400);
  display: inline-flex; align-items: center; justify-content: center;
  /* C07（BL-069 品質事故修批）：可點擊範圍撐到 44×44（Apple HIG／WCAG 建議的最小觸控目標），
     圖示本身大小不變（UI.icon() 內部仍是原本的 size 參數）——用外框撐大，不是放大圖形。 */
  width: 44px; height: 44px; margin: -7px; border-radius: var(--radius-pill); cursor: pointer;
}.srf-root .srf-cu-back-btn:hover { color: var(--primary-500); background: var(--gray-50); }.srf-root .srf-cu-pagehead-right { display: flex; align-items: center; }.srf-root .srf-page_title {
  font-family: var(--font-serif);
  font-size: clamp(24.8px, 6.5vw, 31.2px); font-weight: 600; color: var(--gray-600);
  letter-spacing: 0.04em; line-height: 1.3;
  text-align: center; margin: 8px 0 0;
}.srf-root .srf-cu-pagehead-sub { text-align: center; font-size: 12.8px; color: var(--gray-500); margin-top: 8px; letter-spacing: 0.06em; line-height: 1.7; }
/* ===================== 店員端頁首（app-topbar，方向 B：官網分頁節奏） ===================== */.srf-root .srf-app-topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  background: #fff;
  border-bottom: 1px solid var(--gray-150);
  /* BL-069 第四輪修批 F7：staff.html 同 customer.html 一樣有 viewport-fit=cover＋
     black-translucent（見 staff.html，支援加到主畫面），加入主畫面後頁首會被瀏海／動態島蓋住。
     比照 .cu-header（上方 C05 修批）既有寫法補上 env (safe-area-inset-top)；非 notch 裝置／
     一般瀏覽器分頁模式下 env() 算出 0，不影響現有外觀。 */
  padding: 14px 18px 14px;
  display: flex;
  align-items: center;
  gap: 10px;
}.srf-root .srf-app-topbar .srf-tb-title {
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 17.28px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}.srf-root .srf-app-topbar .srf-tb-btn {
  border: 0;
  background: transparent;
  color: var(--gray-600);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* C07：同 .cu-back-btn，可點擊範圍撐到 44×44，圖示視覺大小不變，負 margin 抵銷撐大的外框
     避免把 topbar 其他元素的排版擠開。 */
  width: 44px;
  height: 44px;
  margin: -5px;
  border-radius: var(--radius-pill);
  cursor: pointer;
}.srf-root .srf-app-topbar .srf-tb-btn:hover { background: var(--gray-100); color: var(--primary-500); }.srf-root .srf-app-topbar .srf-tb-sub { font-size: 12px; color: var(--gray-400); }.srf-root .srf-app-body { flex: 1; padding: 18px 18px 90px; }.srf-root .srf-phone-shell:not(.srf-cu-shell) .srf-bottom-action-bar { background: rgba(238, 243, 245, 0.82); }
/* 客人端動作條＝完全透明，只有按鈕本身（2026-09-03 使用者拍板：不要任何色幕／墊層）。
   代價是內容捲到按鈕底下時會從玻璃按鈕透出來——這是「只要單純按鈕」的必然結果，
   不再用任何遮蔽層去補。 */.srf-root .srf-cu-shell .srf-bottom-action-bar {
  background: transparent;
  border-top: 0;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}.srf-root .srf-app-body.srf-no-pad-bottom { padding-bottom: 18px; }

/* 底部動作條（送出／確認等主要 CTA），跨畫面共用（C9／C3 第一步／S9 三處，見 customer.js／staff.js）。
   2026-08-24 走查補漏：組單／自助購買頁的「合計」原本在整頁最下面，只勾一項就要往下捲兩百多
   像素才看得到，勾選當下完全不知道花了多少錢。底部固定列補一行即時金額（詳細表格留在原位）。 */.srf-root .srf-bottom-total-row { display: flex; align-items: baseline; justify-content: space-between; width: 100%; padding: 2px 2px 8px; }.srf-root .srf-bottom-total-row .srf-bt-label { font-size: 13.12px; color: var(--gray-500); }.srf-root .srf-bottom-total-row .srf-bt-value { font-size: 17.92px; font-weight: 700; color: var(--gray-900); font-variant-numeric: tabular-nums; }

/* 2026-09-19 使用者拍板（BL-069）：拿掉 position:sticky，改接在內容最後面（捲到底才看得到），
   跟 S2 送出區、C3／C9 同意書動作區同一個節奏。不用另外處理「內容不滿一屏時鈕要沉到底」——
   這條本來就是靠 #app{flex:column;flex:1} + .app-body{flex:1}（見上方 #app 規則的註解）把這個
   flex 兄弟頂到容器底部，position:sticky 只負責「內容捲動時鈕黏在視窗底」這一件事，拿掉不影響
   短內容沉底的行為。背景／框線／陰影本來就已經是 transparent（客人端 .cu-shell 269 行、店員端
   .stf-shell 863 行），這裡不用跟著改。 */.srf-root .srf-bottom-action-bar {
  background: rgba(255, 255, 255, 0.34);
  backdrop-filter: blur(20px) saturate(1.4);
  -webkit-backdrop-filter: blur(20px) saturate(1.4);
  border-top: 1px solid rgba(255, 255, 255, 0.85);
  box-shadow: 0 -8px 24px rgba(20, 66, 82, 0.07);
  /* 客人端底下有漸層可透（A 真玻璃鈕）；店員端整頁白底，改鋪極淺灰藍讓 E 白 pill 浮得出來 */
  padding: 14px 18px 14px;
  display: flex; gap: 10px;
}.srf-root .srf-bottom-action-hint {
  text-align: center; font-size: 12.8px; color: var(--gray-400);
  padding: 10px 0;
}

/* ===================== S1 儀表板 v2（Figma 3364:5，2026-09-06） =====================
   S1（無進行中）取代舊版「單一大卡＋今日統計行＋直接新客購買文字連結」，改兩張並排入口
   小卡＋英文「More」清單標題。統計行與文字連結拿掉，功能改由右卡〔開啟〕承接
   （見 staff.js renderS1，onclick 沿用原 Staff.startNewCustomer）。

   底圖：店員端這次一起掛上與客人端同一套 flow-bg.js。掛載容器沿用同一支 flow-bg.js
   （它 querySelector('.cu-flow-bg') 是通用選擇器，本來就沒綁死 .cu-shell，不用修 JS）；
   但定位／z-index 規則另立 .stf-shell（不直接掛 .cu-shell class），避免連帶套用上面
   「客人端站台外殼」那批刻意用 .cu-shell 限定的專屬覆寫（page_title 襯線化、ticket-tabs、
   hint-text 二階色等——那些規則的存在理由就是「店員端也在用同名 class，故限定客人端」，
   見該段落開頭註解）。頂欄 .app-topbar 本身是不透明白底，不需要另外處理就會維持白底。 */.srf-root .srf-stf-shell { position: relative; background: transparent; }
/* #app 是 .stf-shell 唯一的直接子節點（topbar／app-body 都在 #app 裡面由 staff.js
   mount() 整段換血），只要 #app 蓋過流動底圖即可；.app-topbar 本身已是不透明白底，
   不需要另外拉 z-index。 */.srf-root .srf-stf-shell > #app { position: relative; z-index: 1; }

/* 兩張並排入口小卡 */.srf-root .srf-s1-entry-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 22px;
  margin-bottom: 17px;
}.srf-root .srf-s1-entry-card {
  position: relative;
  height: 148px;
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  cursor: pointer;
  overflow: hidden;
  /* 2026-09-06 Figma 回寫：入口卡內不再有 pill 子鈕，整張卡是唯一可點目標。
     卡片本身要能被鍵盤聚焦＋Enter 觸發，所以 staff.js 改用 <button>；這裡把瀏覽器
     預設按鈕外觀洗掉，可見外觀仍由 .card（右卡）／.is-scan（左卡）提供。 */
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
  text-align: left;
  appearance: none;
  -webkit-appearance: none;
}
/* 2026-09-07 修正 1（使用者實機對照 Figma 3374:4）：卡片的 color 就是「這張卡的前景色」，
   標題與右下角線稿 icon **都**吃它——icon 的 SVG 用 stroke="currentColor"，所以只要卡片
   設一次 color，兩者必然同色，不可能再各自漂移。原本 color 只寫在 .s1-entry-title 上，
   icon 拿不到、退回瀏覽器 button 預設色（深灰），才會出現「圖示顏色跟文字不一樣」。 */
/* 左卡「掃描顧客 QR」：實心底色，不掛 .card（.card 的白 80% 底會蓋掉這裡要的實心色）。
   2026-09-19 還原：9/18 第四輪審查為對比度改成 primary-500，違反使用者 2026-09-15「色彩對比整批不處理」裁決（design-rules §七），已退回原色。 */.srf-root .srf-s1-entry-card.srf-is-scan { background: #7FCBE0; color: #fff; }
/* 右卡「新客購買」：白底沿用既有 .card（rgba(255,255,255,.8)，2026-09-03 已拍板的白），
   標記自身不重複宣告背景——.card 的 border/box-shadow/overflow 與 .s1-entry-card 同值，
   兩者疊加不衝突。 */.srf-root .srf-s1-entry-card.srf-is-new { color: #3EB5C7; }

/* 標題＝兩行大字（Figma 3374:4／3374:45／3374:98 三格同值）。左右卡的 top 不同是 Figma
   原樣（左卡 17.4／右卡 8），沒有自行對齊。 */.srf-root .srf-s1-entry-title {
  position: absolute;
  left: 15px;
  margin: 0;
  font-size: 30px;
  line-height: 35px;
  font-weight: 500;
  letter-spacing: 3px;
  white-space: nowrap;
}.srf-root .srf-s1-entry-title .srf-is-sm { font-size: 24px; }   /* 「QR-CODE」那一行 */
/* 標題不自己宣告顏色，一律繼承卡片的 color（見上方修正 1 註解）；這裡只留 Figma 的 top。 */.srf-root .srf-s1-entry-card.srf-is-scan .srf-s1-entry-title { top: 17.4px; }.srf-root .srf-s1-entry-card.srf-is-new .srf-s1-entry-title { top: 8px; }

/* 角落 44px 線稿 icon：Figma 匯出的 arrow-down-right／plus 原樣內嵌（路徑座標未改寫，
   見 staff.js S1_ICON_*）。右卡的 plus 在 Figma 就是切齊卡片右下角（inset 0），
   視覺留白由 glyph 自身的內縮提供，不是版面失誤。 */.srf-root .srf-s1-entry-icon { position: absolute; display: block; }.srf-root .srf-s1-entry-card.srf-is-scan .srf-s1-entry-icon { right: 13px; bottom: 7px; }.srf-root .srf-s1-entry-card.srf-is-new .srf-s1-entry-icon { right: 0; bottom: 0; }

/* 「More」標題（英文為刻意設計，2026-09-06 使用者拍板）：Figma 指定 Noto Sans
   ExtraCondensed Bold（可變寬度 wdth 62.5）。字型檔沒載窄體版時，font-stretch 在多數瀏覽器
   對非可變字體無效，會安靜退回一般寬度粗體——接受（spec 原文載明的退場方案）。 */.srf-root .srf-s1-more-title {
  font-family: 'Noto Sans', 'Noto Sans TC', sans-serif;
  font-weight: 700;
  font-stretch: 62.5%;
  font-size: 16.8px;  /* 16.8px */
  line-height: 1.5;    /* 24px */
  color: #6A6A6A;
  margin: 0 0 10px;
}
/* More 清單（紀錄／店員管理）文字改青色 500（原本是深色 700，僅限這個清單——
   .pick-row.is-menu-row 只有 moreRow() 這一處在用，見 staff.js，不影響 S6 等其他清單）。 */.srf-root .srf-pick-row.srf-is-menu-row .srf-pr-title { color: #3EB5C7; font-weight: 500; }

/* ===================== S2 組單（Figma Page 4「S2 組單」七格，2026-09-06 回寫） =====================
   全段一律以 `.stf-shell .stf-s2` 起手，作用域＝店員端 S2 這一個畫面：
     - `.stf-shell` 擋掉客人端（customer.html 是 .cu-shell，一個像素都不會被動到）
     - `.stf-s2` 擋掉同在店員端的 S1／S3／S6／S9（那幾格 Figma 這次沒改，工單也寫明只動 S2）
     - 浮層（切換店員／重複單警示）掛在 #sheet-holder，位於 .stf-shell 之外，因此
       Figma 38 的浮層樣式自動維持現狀，不需要另外排除
   共同改動來自 figma-export/s2-apply*-rules.md 四輪：深灰→中灰、品名金額改中等字重、
   卡片與列的框線移除、勾選色改亮青、選中列白底＋2px 青框＋18px 青字。

   2026-09-19（使用者要求 C9「完全對齊、共用元件」）：勾選列這一組（白卡、列、勾選框、
   品名／金額、數量「－ 數字 ＋」、立即兌換子行、徽章、淡入動畫、選中陰影）改以
   `.phone-shell .pick-card` 起手——S2 與客人端 C9 的清單卡都掛 .pick-card，吃同一組規則；
   HTML 與動畫由 common.js UI.pickRow 產生。起手兩個 class 換兩個 class，權重不變，
   S2 改前改後逐像素比對為 0。S2 專屬的頁面層（折讓、金額表、送出區、區塊標題、
   收合列「＋加購服務」的左內距）仍是 `.stf-shell .stf-s2`。 */

/* 版面：送出鈕改成流內元素（原本的 .bottom-action-bar 白霧底條已整組拿掉），
   內容短時用 margin-top:auto 沉到底部——Figma 的 06／14／18 三格 frame 高度剛好是
   844（＝視窗高、內容不滿一頁），鈕都貼在距底 29.8px 處，就是這個行為。 */
/* 底部留白分兩段：頁面本身留 10（＝Figma 底部提示距 frame 底 10），送出鈕再自己多留 20
   （鈕下緣距 frame 底 29.8）。兩種收尾各自對得上，不用在 JS 裡分岔。 */.srf-root .srf-stf-shell .srf-stf-s2 { display: flex; flex-direction: column; padding-bottom: 10px; }
/* 2026-09-07 修正 4：送出鈕與說明文字外包一層 .s2-foot（id=s2-footer），沉底用的
   margin-top:auto 從內層上移到這一層——盒子尺寸完全不變（外層無 padding／無邊框），
   但「送出鈕 ↔ 說明文字」的切換就能只換這一層的 innerHTML，不必整頁重畫。 */.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-foot { margin-top: auto; }
/* 2026-09-07 修正 4（使用者實機回饋）：「請至少選擇一項…」這句提示如果也吃
   margin-top:auto，會被推到整欄最底部——手機瀏覽器網址列還沒收起時 100vh 比實際
   可視高度多一截（見 .phone-shell 的 100dvh 修正），提示就落在可視範圍外，不滑動
   看不到。這句提示的用途是告訴店員「現在為什麼按不了」，該貼著清單，不必釘在
   畫面最底部——跟送出鈕（真的該固定在底部的主要動作）分開處理：footer 裡裝的是
   提示而不是送出鈕時，改用固定間距接在清單／折讓區後面。 */.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-foot:has(.srf-bottom-action-hint) { margin-top: 24px; }.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-send { margin-top: 0; padding: 10px 0 20px; }.srf-root .srf-stf-shell .srf-stf-s2 .srf-bottom-action-hint { margin-top: 0; padding: 0; }

/* 白卡：不透明白、無框線、只留（比通用 .card 更重的）Figma 陰影。
   卡寬 339 而列寬 354——選中列刻意突出卡片左右各 7px，Figma 四輪都維持這個關係，
   所以 overflow 要放行，否則突出的部分會被卡片圓角切掉。 */.srf-root .srf-stf-shell .srf-stf-s2 .srf-card,
.srf-root .srf-phone-shell .srf-card.srf-pick-card {
  background: #fff;
  border: 0;
  box-shadow: var(--shadow-stf);
  /* Figma 這張卡標了 backdrop-blur 5px，這裡刻意不套：卡片填色是不透明白，
     背後糊不糊完全看不到（零視覺差）。而且只要樣式表裡出現 backdrop-filter，
     Chromium 就會把整份文件切到不同的合成／點陣化路徑——實測會讓客人端 C3
     確認鈕的圓角反鋸齒差 30 個像素（客人端沒有任何元素吃到這條規則，純粹是
     全域合成副作用）。工單要求客人端逐像素零差異，所以不留這兩行。 */
  margin-left: 7px;
  margin-right: 7px;
  overflow: visible;
}

/* 列：列與列之間不再有框線，靠留白分列（Figma 未選列高 51、兌換列高 72） */.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row {
  border: 0;
  border-radius: 12px;
  /* 2026-09-07 修正 3（使用者實機回饋）：右內距原本是 7px，跟左內距 13px 不一樣——
     勾選框左緣到卡片左邊的留白，明顯比金額右緣到卡片右邊的留白寬。改成左右都 13px，
     兩側對稱。未選列高 51＝13+21+17，跟左右內距無關，不受影響。 */
  padding: 13px 13px 17px 13px;   /* 未選列高 51＝13+21+17，品名落在列頂 +13 */
  gap: 0;
  align-items: flex-start;
  position: relative;
}
/* 直接子選擇器很重要：不加 `>` 的話這條（4 個 class＋1 個屬性選擇器）會連
   「立即兌換」那顆巢狀小勾選框一起吃掉，把它的 margin-right 撐成 15px。 */.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row > input[type="checkbox"] {
  margin: 1px 15px 0 0; accent-color: var(--primary-400);
}.srf-root .srf-phone-shell .srf-pick-card .srf-pr-main { flex: 1; min-width: 0; }
/* .pr-title 改成 flex 容器（裝品名文字＋「新客限定」徽章兩個手足），本身不吃字級。
   2026-09-07 修正 2（使用者實機回饋：勾選/取消時徽章大小會跳、跟品名太近）：
   舊寫法徽章是品名文字裡的 inline span，FLIP 用 transform:scale() 放大品名字級時，
   整個 inline box（含徽章）被視覺一起放大，勾選那一刻徽章跟著「跳」一下尺寸；
   又因為兩者同一行文字，只能用 vertical-align 硬湊、負 margin 頂開高度差，代價是
   間距被吃掉、貼太近。改成手足關係後，字級動畫只套在 .pr-title-text 這個文字節點
   上，徽章不受影響；間距與對齊改用 flex 的 gap／align-items 控制，不再需要那組
   vertical-align／負 margin 補丁（見下面 .badge 規則）。 */.srf-root .srf-phone-shell .srf-pick-card .srf-pr-title {
  /* 必須是 flex（區塊級），不能是 inline-flex——.pr-title 原本是區塊級的 <div>，
     跟同層的 .form-check-tap／.pr-sub 各自佔一行（列高算式靠這個堆疊關係）。
     改成 inline-flex 會讓它變成行內級，跟著後面的內容擠到同一行，量出來的列高
     會跟著跑掉（實測 95→98）。flex 一樣有 gap／align-items，只是仍佔滿一整行。 */
  display: flex; align-items: center; gap: 8px; min-width: 0;
}.srf-root .srf-phone-shell .srf-pick-card .srf-pr-title-text,
.srf-root .srf-phone-shell .srf-pick-card .srf-pr-amt {
  font-weight: 500; font-size: 14.72px; line-height: 21px; color: var(--gray-600);
}
/* .pr-title-text 的 min-width:0（允許被壓縮）已有全域規則（見「排版基礎」段），S2 不重寫 */.srf-root .srf-phone-shell .srf-pick-card .srf-pr-amt { margin-left: auto; padding-top: 0; }.srf-root .srf-phone-shell .srf-pick-card .srf-pr-sub { color: var(--gray-400); }

/* 選中列：白底不透明、2px 亮青框、品名與金額 18px 青字。
   margin 負 7 讓它長回 354 寬（突出白卡）；padding 已扣掉 2px 邊框，所以內容
   仍落在 Figma 的 x=38（品名 x=72）與金額右緣 x≈357。 */.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row.srf-is-checked {
  background: #fff;
  border: 2px solid var(--primary-400);
  margin-left: -7px;
  margin-right: -7px;
  /* 加上 2px 邊框後：品名落在列頂 +14、內容 x=38、金額右緣 x≈357。
     兌換的已選列（品名＋副標、無「立即兌換」子行）高度＝2+12+21+3+18+14+2＝72；
     購買的已選列另由 .form-check-tap 的上下 margin（13／11）補到 95。 */
  padding: 12px 13px 14px 18px;
}
/* 2026-09-07 修正 2（使用者拍板）：選中態**不再變粗**——font-weight 從這裡拿掉，
   兩態同吃上面那條 .stf-s2 .pr-title/.pr-amt 的 500，選中只靠「變大＋變青」表達。
   字級與顏色的過渡由 staff.js s2SwapRow() 現場設行內樣式（見該處 FLIP 註解）：
   字級走 transform: scale()（不佔版面、不推鄰列），顏色走 transition: color。 */.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row.srf-is-checked .srf-pr-title-text,
.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row.srf-is-checked .srf-pr-amt {
  font-size: 18px; color: var(--primary-400);
}
/* 有數量控制時，品名欄固定 125px 寬——Figma 的「－ 數字 ＋」在每一格都釘在 x=197，
   不隨金額字數浮動，用固定 basis 才對得上（38+19+15+125 = 197）。 */.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row.srf-is-checked.srf-has-qty .srf-pr-main { flex: 0 1 125px; }
/* 停用列（此手機號已使用過）：依工單只把外框拿掉，其餘淡化行為維持既有 */.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row.srf-is-disabled { border-color: transparent; }

/* 數量：－ 數字 ＋（取代原本的 <select> 下拉，行為仍走 Staff.setQuantity） */.srf-root .srf-phone-shell .srf-pick-card .srf-pr-qty {
  display: flex; align-items: center; flex-shrink: 0;
  font-size: 18px; font-weight: 700; line-height: 21px; color: var(--primary-400);
  /* 2026-09-07 修正 4：加減鈕支援長按連發，按住期間不可以反白選字、也不要吃到
     行動瀏覽器的雙擊縮放延遲。 */
  -webkit-user-select: none; user-select: none;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}.srf-root .srf-phone-shell .srf-pick-card .srf-pr-qty-n { min-width: 10px; text-align: center; }.srf-root .srf-phone-shell .srf-pick-card .srf-pr-qty-btn {
  display: flex; align-items: center; justify-content: center;
  width: 12px; height: 12px; padding: 0; border: 0; background: none;
  color: var(--gray-600); cursor: pointer; position: relative; flex-shrink: 0;
  -webkit-user-select: none; user-select: none;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
/* 12px 的加減鈕遠低於 44px 觸控門檻——用透明 ::after 外推可點範圍，可見像素不變
   （同 .btn-sm::after 既有手法）。 */.srf-root .srf-phone-shell .srf-pick-card .srf-pr-qty-btn::after {
  content: ''; position: absolute; left: -8px; right: -8px; top: -16px; bottom: -16px;
}.srf-root .srf-phone-shell .srf-pick-card .srf-pr-qty-btn:disabled { opacity: 0.3; cursor: default; }.srf-root .srf-phone-shell .srf-pick-card .srf-pr-qty-gap-l { width: 12px; }.srf-root .srf-phone-shell .srf-pick-card .srf-pr-qty-gap-r { width: 13px; }

/* 立即兌換子行：16px，未勾中灰＋12px 小框，已勾亮青＋19px 實心框（兩態大小不同是
   Figma 原樣，見 s2-apply3-rules §判斷與存疑 5，未自行統一）。
   2026-09-07 修正 2（使用者實機回饋「勾起來就換行」）：兩個成因各修一個——
     (a) 勾選框從 12px 變 19px 時整行變寬 → 佔位盒固定 19px（＝已勾尺寸），未勾時
         只用 transform 把「裡面的圖形」縮到 12px 呈現。視覺大小差照 Figma 保留，
         但版面寬度兩態相同，勾選那一刻不會有任何寬度變化。
     (b) 這一行住在 .pr-main 裡，而選中又有數量控制時 .pr-main 被釘成 125px（Figma 的
         「－ 數字 ＋」必須落在 x=197），寬度本來就不夠一行放完 → 這一行改成不折行、
         允許往右溢出。它在品名的下一行，右邊同高度的位置是空的（數量與金額都靠列頂
         對齊），所以溢出不會壓到任何東西，也不會撐出橫向捲動。 */.srf-root .srf-phone-shell .srf-pick-card .srf-form-check-tap {
  min-height: 0; padding: 0; margin: 13px 0 11px; align-items: center;
  font-size: 16px; line-height: 20px; color: var(--gray-600); gap: 7px; position: relative;
  white-space: nowrap;
}.srf-root .srf-phone-shell .srf-pick-card .srf-form-check-tap::after {
  content: ''; position: absolute; left: -8px; right: -8px; top: -12px; bottom: -12px;
}
/* 文字不准被 flex 壓縮（壓縮＝又會折行） */.srf-root .srf-phone-shell .srf-pick-card .srf-form-check-tap > span { flex: 0 0 auto; }.srf-root .srf-phone-shell .srf-pick-card .srf-form-check-tap .srf-form-check-input {
  width: 19px; height: 19px; margin: 0 0 0 4px; flex-shrink: 0;
  accent-color: var(--primary-400);
  transform: scale(0.631579);   /* 12 ÷ 19 —— 未勾時看起來就是 12px */
  transform-origin: center;
}.srf-root .srf-phone-shell .srf-pick-card .srf-form-check-tap.srf-is-on { color: var(--primary-400); }.srf-root .srf-phone-shell .srf-pick-card .srf-form-check-tap.srf-is-on .srf-form-check-input { transform: none; }

/* 2026-09-07 修正 4：勾選時該列平滑長高。高度的起訖值必須現場量（內容長度不定），
   所以 height 的 transition 由 staff.js s2SwapRow() 設在 inline style；這裡只負責
   「新出現的內容淡入」。取消勾選時內容已先移除，高度過渡本身即為反向動作。 */
@keyframes srf-pickRowFadeIn { from { opacity: 0; } to { opacity: 1; } }.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row.srf-is-row-anim .srf-pr-qty,
.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row.srf-is-row-anim .srf-form-check-tap,
.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row.srf-is-row-anim .srf-pr-sub {
  animation: srf-pickRowFadeIn 200ms ease-out both;
}
@media (prefers-reduced-motion: reduce) {
  /* JS 端已經整段跳過動畫；這裡再擋一層，確保就算 inline transition 被設上去也不生效 */.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row { transition: none !important; }.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row.srf-is-row-anim .srf-pr-qty,
.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row.srf-is-row-anim .srf-form-check-tap,
.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row.srf-is-row-anim .srf-pr-sub { animation: none !important; }
  /* 2026-09-07 修正 2：字級／顏色的過渡與 FLIP 縮放同樣直接切換、不留任何 transform */.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row .srf-pr-title,
.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row .srf-pr-amt { transition: none !important; transform: none !important; }
  /* 2026-09-07 修正 1：折讓區的展開／收合也直接切換 */.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-fold,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-fold,
.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-fold-inner,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-fold-inner { transition: none !important; }
}

/* 徽章「新客限定」：底色變淡、字重降回一般。
   2026-09-07 修正 2：徽章現在是 .pr-title（flex 容器）的手足，不再是品名文字裡的
   inline span，靠 align-items:center／gap 對齊留白（見上面 .pr-title 規則），不需要
   vertical-align 或負 margin 這組舊補丁——徽章外高 22px 比品名行高 21px 只多 1px，
   flex 置中下這點差異可忽略。 */.srf-root .srf-phone-shell .srf-pick-card .srf-badge {
  background: #f6f6f6; font-weight: 400; padding: 3px 14px; line-height: 16px;
}

/* 區塊標題「兌換」「購買」改英文 REDEEM／BUY（Figma 3377:4「11 格」為樣式範本，2026-09-07
   回寫）：與 S1「More」、DISCOUNT 共用同一份 .s1-more-title 規則（見該規則段落註解），不另寫
   一份；這裡只補 S2 專屬的垂直間距（原本掛在 .section-title 上的 margin-bottom:12px，換 class
   後要重新掛一次）。原本這條規則鎖定的 .section-title 在 S2 只有這兩處在用，已隨標題換成
   .s1-more-title 一起搬過來，不留孤兒規則。 */.srf-root .srf-stf-shell .srf-stf-s2 .srf-s1-more-title { margin-bottom: 12px; }
/* 收合態「＋加購服務」列：沒有勾選框，左內距照 Figma 縮到 8（文字落在 x=33） */.srf-root .srf-stf-shell .srf-stf-s2 .srf-pick-row.srf-is-borderless { padding-left: 8px; }

/* 金額小計：深墨字與分隔線改中灰（總計不再用品牌色）。
   上方間距由折讓槽位的 margin-bottom 負責，這裡把 .mt-16 歸零避免兩段相加
   （app-body 是 flex 容器，相鄰 margin 不會合併）。 */.srf-root .srf-stf-shell .srf-stf-s2 .srf-table-order { color: var(--gray-600); }.srf-root .srf-stf-shell .srf-stf-s2 .srf-table-order.srf-mt-16 { margin-top: 0; }.srf-root .srf-stf-shell .srf-stf-s2 .srf-table-order .srf-text-dark { color: var(--gray-600); }.srf-root .srf-stf-shell .srf-stf-s2 .srf-table-order tr.srf-mt-total td {
  border-top: 1px solid var(--gray-600); padding-top: 16px;
}.srf-root .srf-stf-shell .srf-stf-s2 .srf-table-order tr.srf-mt-total .srf-price { color: var(--gray-600); }

/* ===================== 折讓區（2026-09-15 使用者拍板改版；提案 artifact 166d9db8）=========
   折讓從「整單一個數字」改成一行一筆的清單（金額＋原因）。
     收合態  整區只有一顆「＋ 折讓」文字鈕（不是每一單都會用，預設不展開）
     展開態  DISCOUNT 標題＋右邊向上箭頭（收起）＋白卡；卡內一行一筆，下面「＋ 新增一筆折讓」，
             最後一列折讓合計
   拍板細節：兩處的 ＋ 都**不加圓外框**；金額欄不要瀏覽器的上下微調鈕。
   顏色／字級／白卡／陰影全部沿用原本那一版的實測值，變的只有結構。

   展開收合用 grid-template-rows 0fr→1fr（同客人端流水帳 .tk-fold）：行數不固定、高度沒辦法
   寫死，交給瀏覽器算。舊版寫死 94px 的那套與「打完金額直接按送出」的高度恆定保證一併作廢——
   現在打字只改金額顯示與折讓合計的文字，不重建節點也不改高度，那一下點擊照樣成立；真正會
   改變高度的是「新增／刪除一行」與「展開／收起」，都是明確的點擊動作，不會跟送出撞在一起。 */.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-discount,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-discount { margin: 21px 0 20px; }
/* 收合態的「＋ 折讓」：純文字鈕，沒有底色也沒有外框，左緣切齊白卡（白卡有 margin-left:7） */.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-add,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-add {
  display: inline-flex; align-items: center; gap: 7px;
  margin-left: 7px; padding: 8px 2px;
  border: 0; background: none; cursor: pointer;
  color: var(--primary-500); font-family: inherit; font-size: 14.72px; font-weight: 700;
}.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-plus,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-plus { font-size: 16.96px; line-height: 1; font-weight: 400; }.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-discount.srf-is-open .srf-s2-dc-add,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-discount.srf-is-open .srf-s2-dc-add { display: none; }
/* 面板：節點一直掛著，靠 0fr→1fr 收合，所以收合動畫有東西可以動 */.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-fold,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-fold {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 200ms cubic-bezier(0.22, 0.61, 0.36, 1);
}.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-discount.srf-is-open .srf-s2-dc-fold,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-discount.srf-is-open .srf-s2-dc-fold { grid-template-rows: 1fr; }.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-fold-inner,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-fold-inner {
  min-height: 0; overflow: hidden; opacity: 0;
  transition: opacity 200ms cubic-bezier(0.22, 0.61, 0.36, 1);
}.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-discount.srf-is-open .srf-s2-dc-fold-inner,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-discount.srf-is-open .srf-s2-dc-fold-inner { opacity: 1; }
/* 標題列：DISCOUNT 左、收起箭頭右；左緣切齊白卡 */.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-head,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-head {
  display: flex; align-items: center; margin: 0 7px 6px;
}.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-title,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-title {
  font-family: 'Noto Sans', 'Noto Sans TC', sans-serif;
  font-weight: 700; font-stretch: 62.5%;
  font-size: 16.8px;   /* 16.8px */
  line-height: 1.5;     /* 25.2px */
  color: #6A6A6A; margin: 0;
}.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-collapse,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-collapse {
  margin-left: auto; display: inline-flex; align-items: center;
  border: 0; background: none; padding: 2px; cursor: pointer; color: var(--primary-500);
  position: relative; /* 撐大可點範圍用，見下方 ::after（同 .btn-sm 既有手法） */
}
/* 2026-09-18 第四輪 G6／B7-1（實測約 22×22，低於 44×44）：同 .btn-sm::after 手法，
   透明 ::after 負值 inset 撐到 44×44，不改變可見圖示大小。 */.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-collapse::after,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-collapse::after {
  content: ''; position: absolute; inset: -11px;
}
/* 白卡沿用 .card（位置／圓角／白底／陰影一次到位，與同畫面其他白卡同一套外觀） */.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-card,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-card { padding: 4px 14px 2px; }.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-row,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-row {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 0; min-width: 0;
}.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-row + .srf-s2-dc-row,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-row + .srf-s2-dc-row { border-top: 1px solid var(--gray-150); }.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-cur,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-cur {
  flex-shrink: 0;
  font-size: 14.72px; font-weight: 700; line-height: 21px; color: var(--primary-400);
}
/* 金額欄與事由欄：底線刻意**不用 border-bottom**——Chromium 會把 border 寬度取整成整數
   CSS 像素（1.5 → 1），畫不出指定的 1.5px。改用貼在下緣的線性漸層當底線，不受那道取整限制。 */
/* 2026-09-15 使用者回報「原因的提示字太貼底線」：原本 21px 行高塞在 22.5px 的盒子裡，
   文字幾乎壓在底線上。把行高放到 26（盒子 27.5＝26＋1.5 底線），多出來的行距由上下均分，
   文字與底線之間就有約 5px 的呼吸。**金額欄一起放大**是必要的：兩欄在同一列裡靠
   align-items:center 對齊，只放大其中一欄會讓兩條底線一高一低。 */.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-amt,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-amt,
.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-note,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-note {
  font-family: inherit; font-size: 14.72px; line-height: 26px;
  height: 27.5px; box-sizing: border-box;
  padding: 0; background-color: transparent; border: 0;
  border-radius: 0; box-shadow: none;
  background-repeat: no-repeat; background-position: left bottom; background-size: 100% 1.5px;
}.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-amt,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-amt {
  width: 62px; flex-shrink: 0; font-weight: 700; color: var(--primary-400);
  appearance: textfield; -moz-appearance: textfield;
  background-image: linear-gradient(var(--primary-400), var(--primary-400));
}
/* 數字欄不要瀏覽器自帶的上下微調鈕（2026-09-15 拍板）：現場是用鍵盤打金額，
   那兩顆只會擠掉欄寬又容易誤按。 */.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-amt::-webkit-outer-spin-button,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-amt::-webkit-outer-spin-button,
.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-amt::-webkit-inner-spin-button,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-amt::-webkit-inner-spin-button { appearance: none; -webkit-appearance: none; margin: 0; }.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-note,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-note {
  flex: 1 1 auto; min-width: 0;
  /* 2026-09-15 使用者拍板：這一欄的字置中（欄很寬，靠左的短字會像是被丟在角落）。
     CSS 沒辦法只對 placeholder 設對齊，所以打進去的原因也跟著置中。 */
  text-align: center;
  font-weight: 500; color: var(--gray-600);
  background-image: linear-gradient(var(--gray-300), var(--gray-300));
}.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-note:focus,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-note:focus {
  background-image: linear-gradient(var(--primary-400), var(--primary-400));
}.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-note::placeholder,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-note::placeholder { color: var(--gray-300); }.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-amt:focus,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-amt:focus,
.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-note:focus,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-note:focus { outline: none; }
/* 刪除：只剩一行時換成同寬的空位，不讓那一行的欄位跟著左右跳 */.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-del,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-del {
  flex-shrink: 0; width: 24px; height: 24px; padding: 0;
  border: 0; background: none; border-radius: 50%; cursor: pointer;
  color: var(--gray-300); font-size: 16.96px; line-height: 1;
  position: relative; /* 撐大可點範圍用，見下方 ::after（同 .btn-sm 既有手法） */
}
/* 2026-09-18 第四輪 G6／B7-1（24×24，低於 44×44）：同 .btn-sm::after 手法（-10px，
   與 .btn-sm 本身完全同值），透明 ::after 撐到 44×44，不改變可見圖示大小。 */.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-del::after,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-del::after {
  content: ''; position: absolute; inset: -10px;
}.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-del.srf-is-blank,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-del.srf-is-blank { cursor: default; }
/* 新增：與收合鈕同款的純文字＋裸 ＋，在面板內置中（2026-09-15 使用者拍板） */.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-addrow,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-addrow {
  display: flex; align-items: center; justify-content: center; gap: 7px; width: 100%;
  padding: 11px 0; border: 0; border-top: 1px solid var(--gray-150);
  background: none; cursor: pointer;
  color: var(--primary-500); font-family: inherit; font-size: 13.76px; font-weight: 700;
}.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-sum,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-sum {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 0 9px; border-top: 1px solid var(--gray-150);
  font-size: 13.12px; font-weight: 700; color: var(--gray-400);
}.srf-root .srf-stf-shell .srf-stf-s2 .srf-s2-dc-sum-v,
.srf-root .srf-stf-shell .srf-stf-s9 .srf-s2-dc-sum-v { font-size: 14.72px; color: var(--gray-600); }

/* ===================== 店員端 S3／S6／S9 里程碑同步（M1，2026-09-07）=====================
   來源＝Figma Page 4 店員端現況（rules-s3-20260907.md／rules-s6s9-20260907.md／
   rules-shadow-20260907.md／rules-checkbox-20260907.md ＋ 2026-09-07 對齊拍板）。
   作用域一律 `.stf-shell` 起手；S3／S6d／S9 三個畫面另掛 `.stf-detail`（外加各自的
   `.stf-s3`／`.stf-s6d`／`.stf-s9`），S2 的既有規則因此完全不受影響——一個畫面不可能
   同時是 .stf-s2 與 .stf-detail，兩批規則沒有交集，不必比誰的權重高。
   客人端零影響：本段每一條都帶 `.stf-shell` 或 `body:not(.cu-page)`（customer.html 的
   <body> 掛 cu-page，staff.html 沒有），浮層那兩條靠後者擋。 */

/* ── 陰影：店員端白底元件統一「三件式」的兩層 drop shadow ────────────────────────────
   Figma 基準＝白 pill 主鈕 3381:57 的 effects：
     0 1px 2px  #144252@0.10（貼地層）
     0 12px 18px -8px #144252@0.40（主層）
     BACKGROUND_BLUR 10
   **偏離 Figma 一項（刻意）**：第三件「背景模糊」在 mockup 只保留原本就有的白 pill 主鈕
   （.btn-primary 基底自帶 backdrop-filter: blur(10px)），卡片／列／浮層／膠囊一律不加
   backdrop-filter。兩個理由：(a) 同一畫面出現多個 backdrop-filter，iOS Safari 會錯層
   （gotcha-mockup 已記）(b) 這些元件填的是白 80%～100%，背後糊不糊看不出來，而只要樣式表
   出現 backdrop-filter，Chromium 就會把整份文件切到不同的合成路徑（見 .stf-s2 .card 註解）。 */.srf-root .srf-stf-shell .srf-card,
.srf-root .srf-stf-shell .srf-live-card,
.srf-root .srf-stf-shell .srf-stf-s6 .srf-visit-card,
.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row.srf-is-checked,
.srf-root:not(.srf-cu-page) #sheet-holder .srf-sheet:not(.srf-sheet--glass) { box-shadow: var(--shadow-stf); }
/* 白 pill 主鈕與 S8 的外框鈕：Figma 也吃同一組基準（rules-shadow §2 待問四項全數套用）。
   權重靠 body 這個元素選擇器壓過後面的 `.phone-shell:not(.cu-shell) .btn-*`，不靠先後順序。 */.srf-root:not(.srf-cu-page) .srf-stf-shell :is(.srf-card, .srf-sheet) .srf-btn-primary,
.srf-root:not(.srf-cu-page) .srf-stf-shell .srf-btn-outline,
.srf-root:not(.srf-cu-page) #sheet-holder .srf-btn-primary { box-shadow: var(--shadow-stf); }

/* 主鈕文字色（原 #267E94 → #3EB5C7，S3 R20／S6-S9 S7）：2026-09-14 起白底 pill 的共用規則
   本身就是 --primary-400，兩端同值，這條店員端專屬覆寫已無作用，移除。 */

/* ── 勾選框：未選 12×12、已選 19×19（rules-checkbox-20260907）────────────────────────
   佔位盒兩態都是 19px，未選只用 transform 把「看得見的圖形」縮成 12px——跟「立即兌換」
   子勾選框同一招（見 .stf-s2 .form-check-tap .form-check-input 註解）。勾選那一刻版面寬度
   完全不變，不會推動品名或讓它折行。 */.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row > input[type="checkbox"] {
  transform: scale(0.631579);   /* 12 ÷ 19 */
  transform-origin: center;
}.srf-root .srf-phone-shell .srf-pick-card .srf-pick-row.srf-is-checked > input[type="checkbox"] { transform: none; }

/* ── 「立即兌換」膠囊（2026-09-07 拍板）：72×22、圓角 11、青底白字、離品名 10 ──────────
   只認 .is-redeemnow，其餘 soft 徽章（×N 份、新客限定…）不連坐。
   高度 22 ＝ 3（上內距）＋16（行高）＋3；寬度由字自己撐（4 字 × 11.2 ＋ 27 內距 ≈ 72）。 */.srf-root .srf-stf-shell .srf-badge.srf-bg-label-primary.srf-is-redeemnow {
  background: var(--primary-400);
  color: #fff;
  border-radius: 11px;
  padding: 3px 13.5px;
  font-size: 11.2px;
  font-weight: 400;
  line-height: 16px;
  vertical-align: middle;
}

/* ── 提醒 .notice：文字 Medium 500／中灰；驚嘆號縮到 16 貼左；升級提示改 14px 笑臉並置中 ── */.srf-root .srf-stf-shell .srf-notice { gap: 6px; }
/* icon 對齊「第一行文字的中線」，不是整段文字的中線——Figma 19 格的提示是兩行，
   icon（3521:71 y=564）對的是第一行（文字 y=559、行高約 23）的中心，不是整塊的中心。
   margin-top ＝（行高 23.1 − icon 高）÷ 2。 */.srf-root .srf-stf-shell .srf-notice-mark {
  width: 16px; height: 16px; margin-top: 3.5px;
  box-shadow: inset 0 0 0 1.5px var(--primary-400);
  color: var(--primary-400);
  font-family: var(--font-sans);
  font-size: 9.6px;
}.srf-root .srf-stf-shell .srf-notice-text { font-weight: 500; color: var(--gray-600); }
/* 升級提示（Figma 19／21）：笑臉 icon 14、與文字距 6、整行置中 */.srf-root .srf-stf-shell .srf-notice--icon { justify-content: center; align-items: flex-start; }.srf-root .srf-stf-shell .srf-notice--icon .srf-notice-mark { width: 14px; height: 14px; margin-top: 4.5px; box-shadow: none; }.srf-root .srf-stf-shell .srf-notice--icon .srf-notice-mark svg { width: 14px; height: 14px; display: block; }.srf-root .srf-stf-shell .srf-notice--icon .srf-notice-text { flex: 0 1 auto; }

/* ── S3／S6d／S9 共用：卡頭、明細列、合計、狀態句、應收金額 ────────────────────────── */.srf-root .srf-stf-shell .srf-card-header { color: var(--gray-600); }
/* 本次內容摘要列（S3 R6–R11、S9 S20）：金額亮青粗體（數字類，不套三層字級系統）；
   品名 2026-09-10 比照全站三層字級系統「中標」改為 Medium（原本跟金額一樣寫死粗體，
   是三層系統回寫 mockup 時的漏網之魚——色號原本就對，被色號盤點的抓漏方法跳過）。
   兌換列右側「N 堂」只換色，字級 12.8／Regular 照 Figma 不動。 */.srf-root .srf-stf-shell .srf-stf-detail .srf-sum-row .srf-sum-name { color: var(--primary-400); font-weight: 500; }.srf-root .srf-stf-shell .srf-stf-detail .srf-sum-row .srf-sum-amt { color: var(--primary-400); font-weight: 700; }.srf-root .srf-stf-shell .srf-stf-detail .srf-card .srf-sum-row .srf-sum-count { color: var(--primary-400); }
/* 品名容器排成一列：讓「立即兌換」膠囊與品名**中線**對齊（inline 排版對 CJK 會偏低 2px 多） */.srf-root .srf-stf-shell .srf-stf-detail .srf-sum-row .srf-sum-name,
.srf-root .srf-stf-shell .srf-stf-detail .srf-card .srf-pr-title { display: flex; align-items: center; }
/* 唯讀清單卡與紀錄詳情卡的品名／金額（S9 S2／S4、S6d S14／S17）：
   金額維持粗體（數字類）；品名 2026-09-10 改 Medium，理由同上方 .sum-name。 */.srf-root .srf-stf-shell .srf-stf-detail .srf-card .srf-pr-title { color: var(--primary-400); font-weight: 500; }.srf-root .srf-stf-shell .srf-stf-detail .srf-card .srf-pr-amt { color: var(--primary-400); font-weight: 700; }
/* 詳情卡的客人／時間／店員、備註等灰字往深走一階（S6-S9 S15／S16） */.srf-root .srf-stf-shell .srf-stf-detail .srf-card .srf-hint-text { color: var(--gray-600); }
/* 但 S9 唯讀兌換列右側的「剩 N → M」屬於次數，跟著品名走亮青（S6-S9 S3） */.srf-root .srf-stf-shell .srf-stf-s9 .srf-card .srf-item-block .srf-hint-text { color: var(--primary-400); }
/* 合計：分隔線與標籤中灰、金額亮青（S3 R13–R15） */.srf-root .srf-stf-shell .srf-stf-detail .srf-table-order .srf-text-dark { color: var(--gray-600); }.srf-root .srf-stf-shell .srf-stf-detail .srf-table-order tr.srf-mt-total td { border-top-color: var(--gray-600); }.srf-root .srf-stf-shell .srf-stf-detail .srf-table-order tr.srf-mt-total .srf-price { color: var(--primary-400); }
/* 狀態句與應收金額：一律中灰（S3 R16／R17／R18） */.srf-root .srf-stf-shell .srf-stf-detail .srf-state-line { color: var(--gray-600); }.srf-root .srf-stf-shell .srf-stf-detail .srf-amount-display .srf-amount-label,
.srf-root .srf-stf-shell .srf-stf-detail .srf-amount-display .srf-amount-value { color: var(--gray-600); }
/* 底部白霧動作條整條拿掉，主鈕直接浮在漸層上（S6-S9 S6，做法同 S2）。
   注意：.bottom-action-bar 在 staff.js 是 .app-body 的**兄弟節點**（不在裡面），
   所以這裡不能用 .stf-s9 當前綴；店員端目前也只有 S9 這一處還在用它。 */.srf-root:not(.srf-cu-page) .srf-stf-shell .srf-bottom-action-bar {
  background: transparent;
  border-top: 0;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* ── 舊版 S6 清單／詳情的規則（.stf-s6 .pick-row 家族、.stf-s6d .card .pr-title）已於
   2026-09-15 刪除：紀錄頁改成「一趟一張卡」之後，markup 換成 .vc-* 與 .vd-*，那幾條規則
   已經沒有任何元素可以命中（/simplify 抓到），留著只會讓人以為它們還生效。
   下面的 .rec-tags 與 .pr-title-text 仍在用（S2 與新版 S6 都有），不刪。 */
/* 狀態小標籤群（異議處理中／未收款）：離品名 18，彼此 6 */.srf-root .srf-rec-tags { display: inline-flex; align-items: center; gap: 6px; margin-left: 18px; flex-shrink: 0; }.srf-root .srf-pr-title-text { min-width: 0; }

/* ── 一趟到店的卡片（2026-09-14 改版）────────────────────────────────────────
   清單的單位從「一條動作」改成「一趟到店」，所以卡片內部從單列變成「標頭＋數列＋結尾」。
   外觀刻意跟原本的單列卡完全一樣（實色白、圓角 10、同一組三件式陰影、左右內距 15），
   拍板時看到的就是這個——改的是資訊怎麼分組，不是視覺。 */.srf-root .srf-stf-shell .srf-stf-s6 .srf-visit-card {
  background: #fff;
  border-radius: 10px;
  box-shadow: var(--shadow-stf);
  padding: 13px 0 13px;
  cursor: pointer;
}
/* 標頭：客人靠左、時間靠右、箭頭最右（Figma 24 的欄間距 11 沿用） */.srf-root .srf-stf-shell .srf-stf-s6 .srf-vc-head {
  display: flex; align-items: center; gap: 11px;
  padding: 0 15px 9px;
}.srf-root .srf-stf-shell .srf-stf-s6 .srf-vc-who { font-size: 14.72px; font-weight: 700; color: var(--gray-600); }.srf-root .srf-stf-shell .srf-stf-s6 .srf-vc-time { margin-left: auto; font-size: 12.48px; color: var(--gray-400); }.srf-root .srf-stf-shell .srf-stf-s6 .srf-vc-arrow { display: inline-flex; align-items: center; color: var(--primary-500); flex-shrink: 0; }
/* 一條動作一列：品名（可壓縮）＋右側數字 */.srf-root .srf-stf-shell .srf-stf-s6 .srf-vc-line {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 5px 15px;
}.srf-root .srf-stf-shell .srf-stf-s6 .srf-vc-label {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center;
  font-size: 14.72px; font-weight: 500; color: var(--primary-400);
}.srf-root .srf-stf-shell .srf-stf-s6 .srf-vc-line .srf-pr-amt,
.srf-root .srf-stf-shell .srf-stf-s6 .srf-vc-line .srf-pr-amt.srf-is-note-alt {
  flex-shrink: 0; font-size: 14.72px; font-weight: 700; color: var(--primary-400);
}.srf-root .srf-stf-shell .srf-stf-s6 .srf-vc-note { padding: 0 15px 3px; }
/* 結尾的未收款：整趟沒收到的錢加總，跟上面的動作列用一條分隔線隔開 */.srf-root .srf-stf-shell .srf-stf-s6 .srf-vc-foot {
  display: flex; align-items: center;
  margin: 8px 15px 0; padding-top: 10px;
  border-top: 1px solid var(--gray-150);
}.srf-root .srf-stf-shell .srf-stf-s6 .srf-vc-foot-amt {
  margin-left: auto; font-size: 14.72px; font-weight: 700; color: var(--gray-700);
}
/* 今天以前的一趟：壓成一行摘要（客人＋做了什麼＋未收款） */.srf-root .srf-stf-shell .srf-stf-s6 .srf-visit-card.srf-is-slim { padding: 0; }.srf-root .srf-stf-shell .srf-stf-s6 .srf-vc-slim {
  display: flex; align-items: center; gap: 11px;
  padding: 13px 15px;
}.srf-root .srf-stf-shell .srf-stf-s6 .srf-vc-slim-who { font-size: 13.76px; font-weight: 700; color: var(--gray-600); flex-shrink: 0; }.srf-root .srf-stf-shell .srf-stf-s6 .srf-vc-slim-sum {
  flex: 1 1 auto; min-width: 0;
  font-size: 12.8px; color: var(--gray-400);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}.srf-root .srf-stf-shell .srf-stf-s6 .srf-vc-slim .srf-rec-tags { margin-left: 0; }

/* 紀錄詳情卡（Figma 25／39／43／44）：跟通用 .card 的差異只有這兩項——通用 .card 是
   80% 白＋teal 8% 邊框，漸層底圖會透出來讓白帶一點藍；這裡改實色無框對齊 Figma 端
   「所有卡片都不該有邊框」的拍板（2026-09-08）。陰影已由 792 行的共用規則給
   var(--shadow-stf)，這裡不重複宣告。
   範圍刻意只框 S6：S3／S9／S1／客人端的 .card 目前仍是舊的 80%＋有框版本，若要一併
   改成同樣的不透明白無框，需要另外一輪同步——這裡先不動，避免這次改動範圍悄悄擴大。 */.srf-root .srf-stf-shell .srf-stf-s6d .srf-card {
  background: #fff;
  border: 0;
}

/* ── 紀錄詳情＝一趟的完整帳（2026-09-14 改版）──────────────────────────────
   頁首一行「客人　時間」，之後 BUY／SERVICE 兩區；BUY 區一張單一張小卡，各自帶自己的
   時間與「確認已收款」。字級與顏色沿用詳情頁原本的品名／金額（16px 500／700 亮青）。 */.srf-root .srf-stf-shell .srf-stf-s6d .srf-vd-head { margin: 0 0 14px 2px; }.srf-root .srf-stf-shell .srf-stf-s6d .srf-vd-card-head {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 8px;
}.srf-root .srf-stf-shell .srf-stf-s6d .srf-vd-time { font-size: 12.48px; color: var(--gray-400); }.srf-root .srf-stf-shell .srf-stf-s6d .srf-vd-card-head .srf-rec-tags { margin-left: auto; }.srf-root .srf-stf-shell .srf-stf-s6d .srf-vd-item {
  display: flex; align-items: baseline; gap: 10px;
  padding: 5px 0;
}.srf-root .srf-stf-shell .srf-stf-s6d .srf-vd-item-name {
  flex: 1 1 auto; min-width: 0;
  font-size: 16px; font-weight: 500; color: var(--primary-400);
}
/* 2026-09-15：原本買多份時在品名與金額之間插一段灰字「$6,240／份」，已改成把算式直接
   寫在金額欄（$6,240 × 2），.vd-item-unit 沒有人用了，移除。
   SERVICE 的時間已改成與 BUY 同款、放在小卡標頭（.vd-card-head），不再塞在列首。 */
/* 2026-09-15 使用者拍板：詳情頁品項列右側的值改中等字重（原 700）。下方合計那張
   .table-order 維持粗體不動——一張卡裡只留一個最重的數字，合計才跳得出來。
   兌換列的「3 → 2」吃同一條規則（同一欄同一個位置，分開設會左右不齊）。 */.srf-root .srf-stf-shell .srf-stf-s6d .srf-vd-item-amt { flex-shrink: 0; font-size: 16px; font-weight: 500; color: var(--primary-400); }.srf-root .srf-stf-shell .srf-stf-s6d .srf-vd-item .srf-rec-tags { margin-left: 0; }.srf-root .srf-stf-shell .srf-stf-s6d .srf-vd-item-note { margin: -2px 0 4px; }

/* ===================== 排版基礎 ===================== */.srf-root .srf-section-title {
  font-family: var(--font-serif);
  font-size: 16.8px;
  font-weight: 700;
  color: var(--gray-600);
  margin: 0 0 10px;
}.srf-root .srf-hint-text { font-size: 12.8px; color: var(--gray-400); line-height: 1.7; letter-spacing: 0.03em; }.srf-root .srf-stack { display: flex; flex-direction: column; gap: 12px; }.srf-root .srf-row-between { display: flex; align-items: center; justify-content: space-between; gap: 10px; }.srf-root .srf-mt-8 { margin-top: 8px; }.srf-root .srf-mt-12 { margin-top: 12px; }.srf-root .srf-mt-16 { margin-top: 16px; }.srf-root .srf-mt-24 { margin-top: 24px; }.srf-root .srf-mb-8 { margin-bottom: 8px; }.srf-root .srf-mb-12 { margin-bottom: 12px; }.srf-root .srf-mb-16 { margin-bottom: 16px; }

/* ===================== 按鈕（rounded-pill，取自現行網站 btn-primary 語彙） ===================== */.srf-root .srf-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  padding: 12px 22px;
  font-size: 14.72px;
  font-weight: 600;
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: all 0.15s ease;
  line-height: 1.2;
  position: relative;
}.srf-root .srf-btn:active { transform: scale(0.97); }.srf-root .srf-btn:disabled { opacity: 0.45; cursor: not-allowed; pointer-events: none; }.srf-root .srf-btn-block { width: 100%; }
/* 2026-09-14（主鈕高度統一 43.66）：按鈕內的 icon 不准把行高撐高。log-in 這種 18px 的 icon
   比文字行高（0.92 rem × 1.2 ＝ 17.66）還高，會把登入頁那兩顆撐成 44，跟其他主鈕差 0.34。
   夾成與文字同高、寬高一起夾避免變形；.btn-sm 的 icon（堆疊收起的 chevron 等）不在此限。 */.srf-root .srf-btn:not(.srf-btn-sm) > svg { max-width: 1.2em; max-height: 1.2em; }
/* .btn-lg（16px 24px／1 rem，算出來 53.19 高）於 2026-09-14 使用者拍板「主鈕高度統一 43.66」後整組移除，
   全站主鈕一律吃 .btn 基底的 12px 22px／0.92 rem。要再做大尺寸鈕請重新定義，不要復活這個 class。 */.srf-root .srf-btn-sm { padding: 8px 16px; font-size: 12.8px; border-width: 2px; position: relative; }
/* BL-069 第四輪修批 F8：.btn-sm（含店員「掃描」鈕，實測約 35px 高）低於 Apple HIG／WCAG
   建議的 44px 最小觸控目標。嚴禁改變可見大小／間距／字級（外觀變更需使用者過目，本批不做）
   ——改用透明 ::after 絕對定位負值 inset 把可點範圍撐到 ≥44px 高，不影響任何可見像素
   （同一手法比照上面 .cu-back-btn／.app-topbar .tb-btn 既有的「外框撐大、圖形不變」原則，
   差別是那兩個用實際 width/height＋負 margin，這裡的按鈕本身寬度不固定不適用同招，改用
   ::after 覆蓋整個按鈕寬度＋上下各外推，見下方共用寫法彙總）。 */.srf-root .srf-btn-sm::after {
  content: '';
  position: absolute;
  left: 0; right: 0; top: -10px; bottom: -10px;
}

/* 主鈕＝真玻璃（2026-09-03 三修拍板：官網「前往預約」原始配方原封不動——近透明、白字、
   0.5px 受光棱邊；只用在有漸層可透的情境。白底情境（卡片內、白 sheet）另有霜面淡染變體，
   見下方 scoped 覆寫——真玻璃在純白上會隱形，霜面保住玻璃質感與可讀性。
   2026-09-13 修正：原本白底情境還包含「整個店員端」（`.phone-shell:not(.cu-shell)`），
   理由寫的是「店員端整頁白底」——但 2026-09-06 店員端已改掛與客人端同一套 flow-bg 漸層底圖，
   那個前提三天後就不成立了。現在店員端裸露在漸層上的主鈕一律走真玻璃，只有白卡／白 sheet
   裡的主鈕才吃下面的白 pill 變體，判斷依據回到「背後是不是白的」而不是「哪一端」。 */.srf-root .srf-btn-primary {
  background: radial-gradient(257.58% 534.44% at 24.23% 3.03%,
    rgba(255, 255, 255, 0.028) 0%, rgba(151, 151, 151, 0.118) 100%);
  color: #fff;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 1px 2px rgba(20, 66, 82, 0.06), 0 10px 16px -7px rgba(20, 66, 82, 0.22);
}.srf-root .srf-btn-primary::before {
  /* inset:-1px＝蓋到 border-box——.btn 基底有 1px 透明邊框，用 inset:0 棱邊會縮在
     真正邊界內側 1px，遠看像兩層邊（2026-09-03 使用者截圖抓到） */
  content: ''; position: absolute; inset: -1px; border-radius: inherit; padding: 0.5px; pointer-events: none;
  background: linear-gradient(180deg, #ffffff 0%, #999999 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}.srf-root .srf-btn-primary:hover { background: radial-gradient(257.58% 534.44% at 24.23% 3.03%,
    rgba(255, 255, 255, 0.06) 0%, rgba(151, 151, 151, 0.2) 100%); }
/* 白底情境變體（2026-09-03 使用者拍板「漸層用 A、白卡用 E」）：官網選中膠囊——
   實心白 pill＋品牌色字＋浮起雙層陰影（取自夥伴頁縣市篩選選中態實測值）。
   兩端共用：只看背後是不是白的（白卡／白 sheet／面板），不分客人端店員端。 */.srf-root .srf-card .srf-btn-primary,
.srf-root .srf-sheet .srf-btn-primary,
.srf-root .srf-cu-panel .srf-btn-primary {
  background: #fff;
  /* 2026-09-14 對齊 Figma：白底 pill 的字色 --primary-600(#267E94) → --primary-400(#3EB5C7)。
     店員端本來就另外覆寫成 400，這次把兩端收斂成同一個值，下面那條店員端專屬覆寫因此拿掉。 */
  color: var(--primary-400);
  box-shadow: 0 1px 2px rgba(20, 66, 82, 0.1), 0 12px 18px -8px rgba(20, 66, 82, 0.4);
}.srf-root .srf-card .srf-btn-primary::before,
.srf-root .srf-sheet .srf-btn-primary::before,
.srf-root .srf-cu-panel .srf-btn-primary::before { display: none; }.srf-root .srf-card .srf-btn-primary:hover,
.srf-root .srf-sheet .srf-btn-primary:hover,
.srf-root .srf-cu-panel .srf-btn-primary:hover { background: var(--primary-50); }.srf-root .srf-btn-outline {
  background: rgba(255, 255, 255, 0.78);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  border-color: var(--primary-300); color: var(--primary-600);
  box-shadow: 0 1px 2px rgba(20, 66, 82, 0.05);
}.srf-root .srf-btn-outline:hover { background: var(--primary-50); border-color: var(--primary-400); }
/* 白底情境（配 E 主鈕）：次動作降成灰框灰字，避免比白 pill 主鈕更搶眼
   （2026-09-03 A+E 套用後目檢抓到層級倒置：券卡「查看紀錄」比「兌換」強） */.srf-root .srf-card .srf-btn-outline,
.srf-root .srf-sheet .srf-btn-outline,
.srf-root .srf-cu-panel .srf-btn-outline,
.srf-root .srf-phone-shell:not(.srf-cu-shell) .srf-btn-outline {
  border-color: var(--gray-300); color: var(--gray-600); background: #fff; box-shadow: none;
}.srf-root .srf-card .srf-btn-outline:hover,
.srf-root .srf-sheet .srf-btn-outline:hover,
.srf-root .srf-cu-panel .srf-btn-outline:hover,
.srf-root .srf-phone-shell:not(.srf-cu-shell) .srf-btn-outline:hover { background: var(--gray-50); border-color: var(--gray-400); color: var(--gray-800); }.srf-root .srf-btn-ghost { background: transparent; color: var(--gray-600); border-color: transparent; }.srf-root .srf-btn-ghost:hover { background: var(--gray-100); color: var(--primary-600); }.srf-root .srf-btn-ghost.srf-is-open { color: var(--primary-600); }

/* 破壞性動作：灰階降級，不用紅、不用品牌色（拍板 2026-08-15） */.srf-root .srf-btn-destructive { background: var(--gray-700); color: #fff; }.srf-root .srf-btn-destructive:hover { background: var(--gray-800); }

/* ===================== 卡片 ===================== */
/* 2026-09-14 對齊 Figma：白卡從「白 80% 半透明＋青色 8% 細框」改成「實心白、無框」。
   使用者 2026-09-12 已在 Figma 把 Card 元件的半透明／不透明兩個變體統一成不透明那版，
   mockup 這邊的基底一直沒跟上（style.css 2026-09-08 就記過這條拍板但當時擱置）。
   S1 右邊那張入口卡沒有自己宣告底色、直接吃這裡，所以會一併跟著變實心。 */.srf-root .srf-card {
  background: #fff;
  border: 0;
  border-radius: var(--radius-card);
  /* 2026-09-19 依 design-sync/design-value-changes.md #4 改回 Figma 母版重陰影
     （使用者 2026-09-12 拍板：客人端卡片統一成不透明店員端那套視覺，含重陰影）。
     店員端另有 .stf-shell .card 覆寫同值，此處實際只影響客人端卡片。 */
  box-shadow: var(--shadow-stf);
  overflow: hidden;
}.srf-root .srf-card-pad { padding: 16px; }.srf-root .srf-card-header {
  padding: 12px 16px;
  font-weight: 700;
  font-size: 14.4px;
  color: var(--gray-600);
}

/* ===================== 券卡片（class 名對齊官網 my/tickets.blade.php 實測結果） ===================== */.srf-root .srf-ticket-tabs-wrap { display: flex; justify-content: center; margin: 4px 0 18px; }.srf-root .srf-ticket-tabs { display: inline-flex; gap: 4px; background: var(--gray-100); border-radius: var(--radius-pill); padding: 5px; }.srf-root .srf-ticket-tab {
  border: 0; background: transparent; border-radius: var(--radius-pill);
  padding: 8px 24px; font-size: 13.6px; color: var(--gray-400); cursor: pointer; font-family: inherit;
  transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease;
  position: relative; /* F8：見下方 ::after，撐大可點範圍用 */
}
/* BL-069 第四輪修批 F8（一般變體約 34-35px、.is-sm 變體亦約 35px，皆低於 44px）：同 .btn-sm
   手法，但外推幅度縮到 6px——.ticket-tab 的父層 .ticket-tabs 只有 5px padding（見上方），
   外推太多會超出膠囊容器範圍、有機會跟上下相鄰區塊（section-title／券卡片列表）新增重疊；
   6px 略大於驗收測的「邊界外 5px」，留 1px 安全餘裕，同時把超出容器 padding 的量壓到最低。 */.srf-root .srf-ticket-tab::after {
  content: '';
  position: absolute;
  left: 0; right: 0; top: -6px; bottom: -6px;
}.srf-root .srf-ticket-tab.srf-active { background: #fff; color: var(--primary-500); font-weight: 700; font-size: 15.2px; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12); transform: scale(1.03); }
/* 小尺寸修飾（S6 篩選 pill 重用，取代原自建的 .tab-pills/.tab-pill 平行家族，
   component-audit-2026-08-17 部分對齊 3） */
/* 2026-09-14：.ticket-tabs.is-sm 的小尺寸變體是給 S6 的 ALL／BUY／USED 分頁用的，
   那組分頁已隨紀錄頁改版整組拿掉，規則一併移除（.ticket-tab 現在只剩客人端券夾在用）。 */.srf-root .srf-ticket-pane { animation: srf-ticketPaneIn 0.2s ease; }
@keyframes srf-ticketPaneIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }.srf-root .srf-ticket-card { display: flex; flex-direction: column; position: relative; }
/* 視覺重繪（2026-09-03 拍板）：券卡改官網排版邏輯——襯線名稱、淡化細節。
   2026-09-14 使用者拍板拆除：原本卡底有一條 1.5px 的線，hover／tap 時由左畫出
   （抄自官網夥伴頁 PartnerStoreCard 的同款微互動）。連帶拆掉的還有觸控版那段
   「攔截點擊→加 class→240ms 後才真的放行」的動效處理，見 common.js installTapFx
   ——線沒了以後那段只剩延遲、沒有任何可見效果。 */.srf-root .srf-ticket-card.srf-is-ended { background: #fafafa; box-shadow: none; border-color: var(--gray-150); }.srf-root .srf-ticket-loadmore-wrap { text-align: center; margin-top: 14px; }.srf-root .srf-ticket-loadmore {
  border: 0; background: transparent; color: var(--gray-500);
  border-radius: var(--radius-pill); padding: 9px 20px;
  font-size: 13.12px; font-weight: 700; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  position: relative; /* 撐大可點範圍用，見下方 ::after（同 .btn-sm 既有手法） */
}
/* 2026-09-18 第四輪 G6／B7-3（實測約 34px 高，低於 44px；同批 .btn-sm／.ticket-tab 已用
   同手法補過，這顆是漏網的一顆；.cu-header-qr-btn 曾是同批之一，已隨 F7 整顆刪除）：
   同 .btn-sm::after，-10px。
   .ticket-loadmore-wrap 只有這一顆子元素、上有 margin-top:14px 緩衝，外推不會撞到別的控制項。 */.srf-root .srf-ticket-loadmore::after {
  content: ''; position: absolute; left: 0; right: 0; top: -10px; bottom: -10px;
}.srf-root .srf-ticket-loadmore:hover { color: var(--primary-600); background: var(--primary-50); }.srf-root .srf-ticket-loadmore svg { transition: transform 0.15s ease; }.srf-root .srf-ticket-loadmore:hover svg { transform: translateY(2px); }

/* ===================== 券卡 v3（2026-09-04 定案）=====================
   決議全文：sales-redeem-flow/visual-decisions-2026-09-04.md
   這一段是「取代」不是「疊加」——v2 的規則整段換掉，不留舊值在下面打架。
   五階字級 22／15／26／12／10；兩欄格線（內容 1fr ／ 動作欄 82px）；
   表面＝正式站預約頁的厚玻璃（純白保留給「被選中」的語意，不當卡片底色）；
   點狀進度退場（10 堂需 116px、動作欄只有 82px，且與「數字當主角」重複表達）。
   tk-* 與 ticket-card 皆為客人端專用（店員端零引用，已 grep 確認），故不需前綴。 */.srf-root {
  --fs-title: 22px; --fs-name: 14px; --fs-num: 24px; --fs-sub: 12px;
  --fs-btn: 12px; --fs-tag: 10px;
  --cu-ink: #333;                        /* 主文字。底圖上 6.77–11.29 */
  --cu-ink-2: var(--gray-600);           /* 次要。2026-09-10 收斂進全站三層字級系統的目標灰，取代原本獨立的 rgba(51,51,51,.85) */
  /* 2026-09-08 對齊 Figma（使用者手改樣板 01）：券卡改用跟全站一致的主色青，
     取代原本因白底對比度另外挑的深青（#256779，見下方保留的舊值註解）。
     這是使用者在這輪明確、重複做的選擇（店員端這次也把好幾處 #256779/#267e94
     都改回 #3eb5c7），視為蓋過舊的對比度考量，不再另外挑色。
     舊值僅供對照：#256779（官網 #3eb5c7 在白底對比度只有 2.43，未達 WCAG AA 4.5:1）。 */
  --cu-action: var(--primary-400);
  --tk-glass: rgba(255, 255, 255, 0.5);
  --tk-blur: blur(28px) saturate(1.6);
  --tk-edge: rgba(255, 255, 255, 0.88);
  --tk-radius: 18px;
  --act-col: 82px;
}

/* 表面：2026-09-08 對齊 Figma——拿掉厚玻璃，改跟其他卡片一樣的不透明白＋標準陰影
   （不加 backdrop-filter，理由同全站其他卡片：iOS Safari 多層 backdrop-filter 會錯層，
   見 M1 milestone 大段註解）。--tk-glass/--tk-blur/--tk-edge 三個變數不再被這裡引用，
   保留只因怕還有別處引用；已 grep 確認只有這裡用，可視為死變數。 */.srf-root .srf-ticket-card.srf-card {
  background: #fff;
  border: 0;
  border-radius: var(--tk-radius);
  box-shadow: var(--shadow-stf);
}.srf-root .srf-tk { position: relative; padding: 14px 15px; }

/* 2026-09-12 拍板：狀態標記（異議處理中／已升級正式）從名稱上方那一列移到說明文字右側，
   跟它的說明本來就是一組；原本的 .tk-top 列已無人使用，整條移除。 */.srf-root .srf-tk-status-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* 2026-09-12 拍板：加值／體驗標籤從服務名稱上方移到名稱右側，跟名稱同一列、保持安全間距，
   不再佔用獨立的 .tk-top 列——沒有這類標籤時名稱位置才能跟其他卡片對齊、卡片高度才能一致。 */.srf-root .srf-tk-name-row { display: flex; align-items: center; gap: 8px; }.srf-root .srf-tk-name-row .srf-tk-name { min-width: 0; }
/* 2026-09-08 對齊 Figma：原本黑色實框直角小標籤，改成青色細框膠囊，用主色青，
   不用 rgba(0,0,0,..) 這種跟品牌色無關的灰黑框。 */.srf-root .srf-tk-kind {
  font-size: var(--fs-tag); font-weight: 600; letter-spacing: 0.12em; line-height: 1;
  color: var(--cu-action); border: 1px solid var(--cu-action);
  border-radius: 999px; padding: 4px 7px; flex-shrink: 0;
}

/* 兩欄格線：動作欄固定寬，剩餘堂數與按鈕共用同一組左右邊界 */.srf-root .srf-tk-body {
  display: grid; grid-template-columns: 1fr var(--act-col);
  column-gap: 14px; align-items: start;
}.srf-root .srf-tk-main { min-width: 0; }
/* 2026-09-08 對齊 Figma：字重 600(SemiBold)→500(Medium)、色 --cu-ink(黑)→--cu-action(青)。
   跟到期日／門市之間的間距也拉開（原 7px，Figma 量出來約 27px），呼吸感更接近樣板。
   2026-09-10：字體襯線體→無襯線體、15px→14px，比照全站三層字級系統「中標」收斂
   （盤點發現這裡跟 Figma 現況早就不一致，襯線體是舊規格殘留）。 */.srf-root .srf-tk-name { font-family: var(--font-sans); font-size: var(--fs-name); font-weight: 500;
  color: var(--cu-action); line-height: 1.4; }.srf-root .srf-tk-meta { font-size: var(--fs-sub); color: var(--cu-ink-2); margin-top: 27px;
  letter-spacing: 0.02em; line-height: 1.65; }

/* 2026-09-13 對齊 Figma（使用者手改的 C4-01 為基準，量測 C4-02／06／09 三張完全一致）：
   右欄不再是「從上往下排、固定 12px 間距」，而是**上下各自貼齊自己的那一條線**——
   「剩 N 堂」跟服務名稱同一條線、「兌換」跟最後一行 meta（可用門市）同一條線。
   做法：這一格 align-self:stretch 撐滿整列（.tk-body 是 grid 且 align-items:start，
   只有這一格要例外），再用 space-between 把兩個子元素推到頭尾。 */.srf-root .srf-tk-right { display: flex; flex-direction: column; align-items: stretch;
  align-self: stretch; justify-content: space-between; width: var(--act-col); }
/* 2026-09-14：狀態徽章（已用畢／已收回／已過期）改成「縮到剛好、靠右」。
   右欄是 align-items:stretch，小孩預設撐滿 82px——「剩 N 堂」與「兌換」本來就要滿欄沒問題，
   但徽章只需要 55.6px（文字 33.6＋左右內距各 11），被一起撐開會多出 26.4px 空白。
   用 align-self 單獨把徽章退出 stretch，右緣仍與上面兩者對齊成一直線。 */.srf-root .srf-tk-right > .srf-badge { align-self: flex-end; }
/* -12.6px 不是魔數：襯線大數字的 line box（24px Noto Serif TC，行高 35）上緣有一段留白，
   glyph 只佔中間。扣掉這段留白，數字才會跟左邊的服務名稱對齊——Figma 量到的
   數字文字框上緣正好在卡片頂端 +1.4px，也就是內距上緣再往上 12.6px。 */.srf-root .srf-tk-remain { display: flex; align-items: baseline; justify-content: flex-end; gap: 3px;
  margin-top: -12.6px; }.srf-root .srf-tk-remain-txt { font-size: 11px; color: var(--cu-ink-2); letter-spacing: 0.02em; }
/* 襯線體只留 Noto Serif TC。Noto Serif Display 是為 60px 以上設計的，
   18px 時細筆畫會糊掉——那正是原本這個數字不夠有份量的原因。
   2026-09-08：大數字色 --cu-ink(黑)→--cu-action(青)，對齊 Figma。 */
/* 2026-09-13 對齊 Figma（使用者手改的 C4-01 第一張為基準）：字重 600→500、字級 26→24（見 --fs-num）。 */.srf-root .srf-tk-remain-txt b { font-family: var(--font-serif); font-weight: 500;
  font-size: var(--fs-num); color: var(--cu-action); font-variant-numeric: tabular-nums; }
/* 2026-09-08 對齊 Figma：「兌換」從實心按鈕改成文字＋箭頭連結（見 .tk-redeem-link，
   customer.js ticketCardHtml/ticketStackHtml 已改用這個 class 取代 .btn.btn-primary.btn-sm）。
   舊的按鈕規則留著給還沒轉過去的地方相容，不刪。 */.srf-root .srf-ticket-card .srf-btn-primary.srf-btn-sm {
  width: 100%; padding: 8px 0; font-size: var(--fs-btn); font-weight: 600;
  letter-spacing: 0.04em; background: #fff; color: var(--cu-action);
  border-color: transparent;
  box-shadow: 0 1px 2px rgba(20, 66, 82, 0.08), 0 8px 14px -7px rgba(20, 66, 82, 0.28);
}
/* 2026-09-13：撐到跟 meta 一行等高（同一組 font-size × line-height），再靠 .tk-right 的
   space-between 貼齊底部——這樣「兌換」的視覺中心就跟「可用門市」那一行的中心同一條線，
   不必寫死像素；meta 變成三行時也自動跟著最後一行走。 */.srf-root .srf-tk-redeem-link {
  display: flex; align-items: center; justify-content: flex-end; gap: 6px;
  min-height: calc(var(--fs-sub) * 1.65);
  font-size: var(--fs-btn); font-weight: 700; color: var(--cu-action);
  background: none; border: 0; padding: 0; cursor: pointer;
}
/* 2026-09-11 對齊 Figma（C4 canonical 樣板文字與箭頭間距量測約 7.5px、icon 18x18）：
   gap 2px→6px、icon 16px→18px。 */.srf-root .srf-tk-redeem-link svg { width: 18px; height: 18px; flex-shrink: 0; }

/* 已結束：2026-09-08 使用者拍板改成跟使用中同一套顏色（不再用「表面變淡」表達結束），
   狀態改全靠 .tk-right 的「已收回／已用畢／已過期」徽章傳達。 */

/* 堆疊：後面兩層只露邊；展開時退場 */.srf-root .srf-stack-wrap { position: relative; }
/* 2026-09-14 對齊 Figma：露邊薄片改實心白＋白框、圓角 18→10（Figma 量測 338x20／320x20 r=10 sw=1）。 */.srf-root .srf-stack-layer { position: absolute; height: 20px; background: #fff;
  border: 1px solid #fff; border-radius: 10px;
  box-shadow: none;
  /* 收合時較晚才滑回來——讓子券先退場，露邊最後才「長回去」，收尾才像反向動作 */
  transition: transform 0.34s cubic-bezier(0.16, 1, 0.3, 1) 0.16s, opacity 0.3s ease 0.16s; }.srf-root .srf-stack-layer.srf-l1 { left: 8px; right: 8px; bottom: -6px; z-index: 1; }.srf-root .srf-stack-layer.srf-l2 { left: 17px; right: 17px; bottom: -12px; z-index: 0; opacity: 0.7; }.srf-root .srf-stack-wrap { margin-bottom: 8px; }.srf-root .srf-stack-wrap > .srf-ticket-card { position: relative; z-index: 2; }.srf-root .srf-stack-wrap.srf-is-open .srf-stack-layer {
  opacity: 0;
  transition: transform 0.38s cubic-bezier(0.16, 1, 0.3, 1) 0s, opacity 0.34s ease 0s; }.srf-root .srf-stack-wrap.srf-is-open .srf-stack-layer.srf-l1 { transform: translateY(14px); }.srf-root .srf-stack-wrap.srf-is-open .srf-stack-layer.srf-l2 { transform: translateY(22px); }
/* 2026-09-12 拍板：收合態不放展開箭頭（露出堆疊層次本身已是足夠的可展開暗示）；
   展開態的收合箭頭移到子券清單最下方置中，比照「這些紀錄有問題？」的置中收尾按鈕手法。 */.srf-root .srf-stack-collapse-btn { padding: 6px; }.srf-root .srf-stack-collapse-btn svg { display: block; }

/* ═══ 展開／收合動效（2026-09-14 使用者拍板：提案 C「抽出」＋收合走反向動作）═══
   共同做法：高度用 grid-template-rows 0fr→1fr 讓瀏覽器自己算，不寫死數字——券數與
   紀錄筆數都會變，寫死就會有內容被切掉或留一截空白。
   收合**不是一次收到位**：子項先反向逐一退場（最後一張先走），容器高度稍晚才跟著收，
   看起來像被推回去而不是被關掉。正向用 :nth-child 排序、反向用 :nth-last-child，
   同一組規則自然對稱。
   節奏（提案 C）：展開 460／子項 380・每張差 90；收合 340／子項 260・每張差 70。 */.srf-root .srf-stack-children { display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 0.34s cubic-bezier(0.4, 0, 0.7, 1) 0.11s; }.srf-root .srf-stack-wrap.srf-is-open .srf-stack-children {
  grid-template-rows: 1fr;
  transition: grid-template-rows 0.46s cubic-bezier(0.16, 1, 0.3, 1) 0s; }.srf-root .srf-stack-children-inner { overflow: hidden; }
/* 2026-09-14 對齊 Figma（使用者手改的 C4-07）：左側那條階層直線整條拿掉，子券列往左拉寬到
   與卡片內容同一組邊界——Figma 量到子券 x=33 寬 325，卡片是 18..372，也就是左內距 15、右內距 14。
   原本左內距 30 是為了讓出畫直線的空間，線拿掉後就沒有理由再縮。 */.srf-root .srf-stack-child-list { display: flex; flex-direction: column; gap: 8px;
  padding: 10px 14px 14px 15px; position: relative; }.srf-root .srf-stack-child { background: rgba(255, 255, 255, 0.8); border: 1px solid rgba(38, 126, 148, 0.08);
  border-radius: var(--radius-btn); cursor: pointer;
  /* 收起來的樣子＝被收回卡片底下：往上縮一段並略微縮小 */
  opacity: 0; transform: translateY(-18px) scale(0.96);
  transition: opacity 0.26s ease, transform 0.26s cubic-bezier(0.4, 0, 0.7, 1); }.srf-root .srf-stack-wrap.srf-is-open .srf-stack-child {
  opacity: 1; transform: none;
  transition: opacity 0.38s cubic-bezier(0.16, 1, 0.3, 1), transform 0.38s cubic-bezier(0.16, 1, 0.3, 1); }
/* 展開：由上往下一張一張出來 */.srf-root .srf-stack-wrap.srf-is-open .srf-stack-child:nth-child(1) { transition-delay: 0.09s; }.srf-root .srf-stack-wrap.srf-is-open .srf-stack-child:nth-child(2) { transition-delay: 0.18s; }.srf-root .srf-stack-wrap.srf-is-open .srf-stack-child:nth-child(3) { transition-delay: 0.27s; }.srf-root .srf-stack-wrap.srf-is-open .srf-stack-child:nth-child(4) { transition-delay: 0.36s; }.srf-root .srf-stack-wrap.srf-is-open .srf-stack-child:nth-child(n+5) { transition-delay: 0.45s; }
/* 收合：反向——最後一張先走，第一張最後走（:nth-last-child 天然就是倒數） */.srf-root .srf-stack-wrap:not(.srf-is-open) .srf-stack-child:nth-last-child(1) { transition-delay: 0s; }.srf-root .srf-stack-wrap:not(.srf-is-open) .srf-stack-child:nth-last-child(2) { transition-delay: 0.07s; }.srf-root .srf-stack-wrap:not(.srf-is-open) .srf-stack-child:nth-last-child(3) { transition-delay: 0.14s; }.srf-root .srf-stack-wrap:not(.srf-is-open) .srf-stack-child:nth-last-child(4) { transition-delay: 0.21s; }.srf-root .srf-stack-wrap:not(.srf-is-open) .srf-stack-child:nth-last-child(n+5) { transition-delay: 0.28s; }.srf-root .srf-sc-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 13px; }.srf-root .srf-sc-main { min-width: 0; }.srf-root .srf-sc-no { font-size: 12.8px; font-weight: 500; color: var(--gray-600);
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
/* 2026-09-14 對齊 Figma：底色 --primary-50（淺青）→ --gray-100、字色 --primary-600（深青）→ --primary-400，
   與現行 Badge 的 Tone=Next 同一組值（#f3f4f6 底、#3eb5c7 字）。字級與內距本來就相符，不動。 */.srf-root .srf-sc-next { font-size: 10.24px; font-weight: 500; letter-spacing: 0.04em; color: var(--primary-400);
  background: var(--gray-100); border-radius: var(--radius-pill); padding: 2px 8px; }.srf-root .srf-sc-meta { font-size: 11.36px; color: rgba(51, 51, 51, 0.55); margin-top: 3px; }
/* 2026-09-13 對齊 Figma（使用者手改的 C4-07 第一張子券列為基準）：標籤 0.74 rem→10px、數字字重 600→500、字級 17→20px。 */.srf-root .srf-sc-remain { font-size: 10px; color: var(--gray-600); flex-shrink: 0; }.srf-root .srf-sc-remain b { font-family: var(--font-serif); font-weight: 500; font-size: 20px; color: var(--cu-ink); font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) {.srf-root .srf-stack-children,
.srf-root .srf-stack-child,
.srf-root .srf-stack-layer,
.srf-root .srf-tk-fold,
.srf-root .srf-tk-fold .srf-timeline-row,
.srf-root .srf-tk-fold .srf-card-pad.srf-has-divider-top::before { transition: none !important; }
}

/* ===================== Badge（骨架貼齊官網 Bootstrap badge/bg-label-*，配色維持克制策略：
   僅 primary + 灰階，不用紅綠橘；component-audit-2026-08-17 部分對齊 2） ===================== */.srf-root .srf-badge {
  display: inline-flex; align-items: center;
  border-radius: var(--radius-pill);
  padding: 3px 11px;
  font-size: 11.2px;
  font-weight: 700;
  white-space: nowrap;
}.srf-root .srf-badge.srf-bg-label-secondary { background: var(--gray-100); color: var(--gray-500); }
/* 2026-09-19 依 design-sync #7 改回 Figma 母版字重 Medium（顏色不動）。 */.srf-root .srf-badge.srf-bg-label-secondary.srf-is-dim { color: var(--gray-400); font-weight: 500; }.srf-root .srf-badge.srf-bg-label-primary { background: var(--primary-50); color: var(--primary-600); }.srf-root .srf-badge.srf-bg-primary { background: var(--primary-400); color: #fff; font-weight: 400; }
/* 2026-09-19 依 design-sync #6 改回 Figma 母版字重 Medium。 */.srf-root .srf-badge.srf-bg-outline { background: #fff; border: 1px solid var(--gray-300); color: var(--gray-600); font-weight: 500; }.srf-root .srf-badge.srf-bg-dark { background: var(--gray-700); color: #fff; }

/* 「立即兌換」膠囊離品名的間距：兩端共用同一條（2026-09-14 使用者拍板 10px）。
   客人端原本沒設間距、只靠一個空白字元，看起來比店員端緊——現在兩邊同值。
   掛這個 class 的地方前面都不留空白字元，留了會變成 10＋空白寬。 */.srf-root .srf-badge.srf-is-redeemnow { margin-left: 10px; }

/* S6 紀錄列副標「客人　時間」：同類附註並排，不用符號分隔，間距 10px
   （2026-09-14 使用者拍板，與「立即兌換」膠囊同一個間距值）。 */.srf-root .srf-pr-sub-gap { margin-left: 10px; }

/* 並排資訊之間的分隔（2026-09-14 使用者拍板「全改成 10px 間距」）：原本用間隔點「・」的地方
   一律改成這個固定寬度的行內空白，見 UI.sepGap()。 */.srf-root .srf-sep-gap { display: inline-block; width: 10px; }

/* 數量標記（×N）：改為純文字，不用徽章外框（2026-09-10 拍板，比照 .badge 同字級但字重改 Regular，無底色） */.srf-root .srf-qty-mark { font-size: 11.2px; font-weight: 400; color: var(--primary-400); }

/* ===================== 表單（骨架貼齊官網 checkout.blade.php form-group/form-label/form-control，
   component-audit-2026-08-17 自造④） ===================== */.srf-root .srf-form-group { display: flex; flex-direction: column; gap: 6px; }
/* .staff-switch-name 已於 2026-09-12 隨切換店員功能移除（原與 .form-label 視覺相同，見 BL-082） */.srf-root .srf-form-label { font-size: 13.12px; font-weight: 500; color: var(--gray-600); }.srf-root .srf-form-control {
  border: 1px solid var(--gray-200);
  border-radius: var(--radius-btn);
  padding: 11px 13px;
  font-size: 14.72px;
  font-family: inherit;
  color: var(--gray-600);
  background: #fff;
  width: 100%;
}.srf-root .srf-form-control:focus {
  outline: none;
  border-color: var(--primary-400);
  box-shadow: 0 0 0 3px rgba(62, 181, 199, 0.18);
}

/* 勾選列（骨架貼齊官網 redeem/confirm.blade.php 同意書勾選 form-check-input，
   component-audit-2026-08-17 自造⑤） */.srf-root .srf-form-check { display: flex; align-items: flex-start; gap: 9px; font-size: 13.76px; color: var(--gray-600); }.srf-root .srf-form-check-input { margin-top: 3px; width: 17px; height: 17px; accent-color: var(--primary-500); flex-shrink: 0; }
/* 2026-08-24 走查補漏：卡片內的子勾選框（「立即兌換 1 堂（當場用）」）原本是 <span>，
   點文字完全沒反應（死區），整塊高度只有 23px，往下偏 4–6px 就會打到外層卡片、把整張卡連同
   金額靜默取消掉。改成 <label> 讓文字連動勾選，並把可點高度撐到 44px 的行動裝置門檻。 */.srf-root .srf-form-check-tap { min-height: 44px; align-items: center; padding: 4px 6px; margin-left: -6px; cursor: pointer; }.srf-root .srf-form-check-tap .srf-form-check-input { margin-top: 0; width: 20px; height: 20px; }.srf-root input[type="radio"] { accent-color: var(--primary-500); }

/* ===================== 選項列（勾選券／品項；改用 label 包裹，原生行為取代手動 stopPropagation） ===================== */.srf-root label.srf-pick-row,
.srf-root .srf-pick-row {
  display: flex; align-items: flex-start; gap: 12px;
  border: 1px solid var(--gray-150);
  border-radius: var(--radius-btn);
  padding: 13px 14px;
  cursor: pointer;
}.srf-root .srf-pick-row.srf-is-checked { border-color: var(--primary-400); background: var(--primary-50); }.srf-root .srf-pick-row.srf-is-disabled { opacity: 0.5; cursor: not-allowed; pointer-events: none; }.srf-root .srf-pick-row input[type="checkbox"],
.srf-root .srf-pick-row input[type="radio"] {
  width: 19px; height: 19px; accent-color: var(--primary-500); flex-shrink: 0; margin-top: 1px;
}.srf-root .srf-pick-row .srf-pr-main { flex: 1; min-width: 0; }.srf-root .srf-pick-row .srf-pr-title { font-weight: 500; font-size: 14.72px; }.srf-root .srf-pick-row .srf-pr-sub { font-size: 12.48px; color: var(--gray-400); margin-top: 3px; }.srf-root .srf-pick-row .srf-pr-amt { font-variant-numeric: tabular-nums; font-weight: 700; font-size: 14.72px; color: var(--gray-800); flex-shrink: 0; padding-top: 1px; }.srf-root .srf-pick-row .srf-pr-arrow { font-weight: 700; color: var(--primary-500); flex-shrink: 0; }

/* ===================== 金額明細表（骨架貼齊官網 checkout.blade.php table.table-order，
   四畫面統一：S2/S3/C3/S6d 皆需總計；component-audit-2026-08-17 自造③） ===================== */.srf-root .srf-table-order { width: 100%; border-collapse: collapse; font-size: 14.08px; }.srf-root .srf-table-order td { padding: 6px 0; }
/* 折讓明細列（2026-09-15）：一筆折讓一列、原因當標籤。縮排＋字小一級＋灰，
   跟「售價／折讓」兩條主列分層，不會被誤讀成另一筆獨立金額。 */.srf-root .srf-table-order tr.srf-mt-sub td { padding: 2px 0 2px 12px; font-size: 12.8px; color: var(--gray-400); }.srf-root .srf-table-order tr.srf-mt-sub td:last-child { padding-left: 0; }.srf-root .srf-table-order tr.srf-mt-sub .srf-price { color: var(--gray-400); font-weight: 400; }.srf-root .srf-table-order .srf-text-end { text-align: right; font-variant-numeric: tabular-nums; }.srf-root .srf-table-order .srf-price { margin: 0; }.srf-root .srf-table-order .srf-text-dark { color: var(--gray-800); }.srf-root .srf-table-order .srf-fw-bold { font-weight: 700; }.srf-root .srf-table-order tr.srf-mt-total td { border-top: 1.5px solid var(--gray-800); padding-top: 12px; }.srf-root .srf-table-order tr.srf-mt-total .srf-price { font-size: 18.4px; color: var(--primary-400); }.srf-root .srf-item-block + .srf-item-block { margin-top: 10px; }

/* ===================== 時間軸 ===================== */
/* ═══ 流水帳展開／收合（2026-09-14 提案 C，與堆疊同一套節奏）═══
   .tk-fold 一直存在，只是高度收成 0——這樣收合才有過程可以動（原本是整段從 DOM 拿掉）。
   視覺一個像素都沒改：分隔線還是原本那條，只是從 border-top 換成可以橫掃的一層。 */.srf-root .srf-tk-fold { display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows 0.3s cubic-bezier(0.4, 0, 0.7, 1) 0.09s; }.srf-root .srf-tk-fold.srf-is-open { grid-template-rows: 1fr;
  transition: grid-template-rows 0.42s cubic-bezier(0.16, 1, 0.3, 1) 0s; }.srf-root .srf-tk-fold-inner { overflow: hidden; }

/* 分隔線：展開時由左橫掃出來，收合時往回收（最後才走） */.srf-root .srf-tk-fold .srf-card-pad.srf-has-divider-top { border-top: 0; position: relative; }.srf-root .srf-tk-fold .srf-card-pad.srf-has-divider-top::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 1px;
  background: var(--gray-150); transform: scaleX(0); transform-origin: left;
  transition: transform 0.2s cubic-bezier(0.4, 0, 0.7, 1) 0.12s;
}.srf-root .srf-tk-fold.srf-is-open .srf-card-pad.srf-has-divider-top::before {
  transform: scaleX(1);
  transition: transform 0.26s cubic-bezier(0.16, 1, 0.3, 1) 0s;
}

/* 紀錄列：展開由上往下錯開，收合反向（最後一列先走） */.srf-root .srf-tk-fold .srf-timeline-row {
  opacity: 0; transform: translateY(-10px);
  transition: opacity 0.24s ease, transform 0.24s cubic-bezier(0.4, 0, 0.7, 1);
}.srf-root .srf-tk-fold.srf-is-open .srf-timeline-row {
  opacity: 1; transform: none;
  transition: opacity 0.38s cubic-bezier(0.16, 1, 0.3, 1), transform 0.38s cubic-bezier(0.16, 1, 0.3, 1);
}.srf-root .srf-tk-fold.srf-is-open .srf-timeline-row:nth-child(1) { transition-delay: 0.10s; }.srf-root .srf-tk-fold.srf-is-open .srf-timeline-row:nth-child(2) { transition-delay: 0.17s; }.srf-root .srf-tk-fold.srf-is-open .srf-timeline-row:nth-child(3) { transition-delay: 0.24s; }.srf-root .srf-tk-fold.srf-is-open .srf-timeline-row:nth-child(4) { transition-delay: 0.31s; }.srf-root .srf-tk-fold.srf-is-open .srf-timeline-row:nth-child(n+5) { transition-delay: 0.38s; }.srf-root .srf-tk-fold:not(.srf-is-open) .srf-timeline-row:nth-last-child(1) { transition-delay: 0s; }.srf-root .srf-tk-fold:not(.srf-is-open) .srf-timeline-row:nth-last-child(2) { transition-delay: 0.06s; }.srf-root .srf-tk-fold:not(.srf-is-open) .srf-timeline-row:nth-last-child(3) { transition-delay: 0.12s; }.srf-root .srf-tk-fold:not(.srf-is-open) .srf-timeline-row:nth-last-child(4) { transition-delay: 0.18s; }.srf-root .srf-tk-fold:not(.srf-is-open) .srf-timeline-row:nth-last-child(n+5) { transition-delay: 0.24s; }.srf-root .srf-timeline { display: flex; flex-direction: column; }.srf-root .srf-timeline-row { display: flex; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--gray-100); }.srf-root .srf-timeline-row:last-child { border-bottom: none; }.srf-root .srf-timeline-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--primary-400); margin-top: 6px; flex-shrink: 0; }.srf-root .srf-timeline-dot.srf-is-cancelled { background: var(--gray-300); }.srf-root .srf-timeline-main { flex: 1; min-width: 0; }.srf-root .srf-timeline-title { font-weight: 500; font-size: 14.08px; color: var(--gray-600); }.srf-root .srf-timeline-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }.srf-root .srf-timeline-sub { font-size: 12.16px; color: var(--gray-400); margin-top: 5px; line-height: 1.6; }.srf-root .srf-timeline-row.srf-is-cancelled .srf-timeline-title { color: var(--gray-400); text-decoration: line-through; }

/* ===================== QR 展示（強調區塊：折衷玻璃只用在這裡＋sheet） ===================== */.srf-root .srf-qr-display-zone {
  background: linear-gradient(180deg, var(--primary-50), #fff 65%);
  border-radius: 24px;
  padding: 30px 20px 22px;
  display: flex; flex-direction: column; align-items: center;
}
/* C01（BL-069 品質事故修批）：出示 sheet 上原本 .overlay + .sheet--glass + .qr-frame 三層
   backdrop-filter 疊在一起（毛玻璃疊毛玻璃），視覺糊成一片還拖效能。玻璃語彙收斂成「只留
   sheet 本體一層」——.qr-frame 改實色，不再自己疊一層 blur；QR 需要乾淨的白底才好掃描，
   實色對這裡反而更合適，不只是退讓。 */
/* 2026-09-03 使用者拍板：QR 直接放在半透明底上，不再墊白卡。
   兩層白都要拿掉——這個外框，以及 qrcode.js 產的 svg 自帶的白底方塊（見下方 svg rect 規則）。 */.srf-root .srf-qr-frame {
  background: transparent;
  border: 0;
  box-shadow: none;
  border-radius: 20px;
  padding: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: 100%;
  box-sizing: border-box;
}
/* 藍底頁面上的 QR 保留白底（2026-09-03 使用者指定）：漸層底色深、QR 直接畫上去對比不足，
   白底同時給掃描留餘裕。浮層（.sheet）內的 QR 不套用，維持直接透出玻璃。 */.srf-root .srf-cu-shell .srf-app-body .srf-qr-frame {
  background: #fff;
  border-radius: 20px;
  padding: 22px;
  box-shadow: 0 8px 24px rgba(17, 24, 39, 0.08);
}

/* C03：QR 尺寸自適應（見 common.js renderQR 註解）——.qr-responsive 用 min() 限制絕不超過
   理想尺寸、也絕不超過容器可用寬；裡面的 svg（qrcode.js 已用 scalable:true 產生、不帶自己的
   width/height 屬性）撐滿 wrapper，320px 窄螢幕（iPhone SE 等）不會再讓整頁或 sheet 橫向溢出。 */.srf-root .srf-qr-responsive { display: block; width: min(var(--qr-size, 220px), 100%); }.srf-root .srf-qr-responsive svg { display: block; width: 100%; height: auto; }
/* qrcode.js 會在 svg 內先畫一塊 100%×100% 的白底 rect；QR 要直接透出底下的玻璃／漸層，
   把它關掉（QR 模組本身是 <path>，不受影響）。 */.srf-root .srf-qr-responsive svg > rect { fill: none; }.srf-root .srf-qr-status-row { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 16px; }.srf-root .srf-qr-countdown { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--gray-500); }
/* 2026-09-19 還原：9/18 第四輪審查為對比度改成 gray-700，違反使用者 2026-09-15「次要灰字整批仍用 gray-400」裁決，已退回。 */.srf-root .srf-qr-explain { text-align: center; font-size: 12.16px; color: var(--gray-400); margin-top: 8px; line-height: 1.6; }.srf-root .srf-pulse-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--primary-500); display: inline-block; animation: srf-cuPulse 1.4s infinite ease-in-out; }
@keyframes srf-cuPulse { 0%, 100% { opacity: 0.3; } 50% { opacity: 1; } }

/* 級聯保護（storyboards 分鏡三）：資料層仍會擋（findActiveReferencer），但 UI 不再引導逐步解鎖——
   有牽連的紀錄詳情頁直接不給取消按鈕，改一行提示文字（見 staff.js renderS6Detail），
   故不再需要「兩步清單＋進度」的 cascade-* 樣式。 */

/* 應收金額大字（完成畫面／核對與收款畫面共用；見通用元件「完成畫面」「S9 核對確認」）；
   字級沿用 .ticket-remain-num 既有慣例（2.1 rem，非另起字級），component-audit-2026-08-17 部分對齊 6 */.srf-root .srf-amount-display { text-align: center; margin: 18px 0 4px; }.srf-root .srf-amount-display .srf-amount-label { font-size: 12.8px; color: var(--gray-400); }.srf-root .srf-amount-display .srf-amount-value {
  font-size: 33.6px; font-weight: 700; color: var(--gray-800);
  font-variant-numeric: tabular-nums; line-height: 1.25; margin-top: 2px;
}

/* 「加折讓」低頻角落文字鈕（S9 核對與收款畫面專用）已改用 .btn.btn-ghost.btn-sm（見上方按鈕系統
   ＋ .btn-ghost.is-open 開啟態修飾），不再另立 .discount-corner-btn 家族
   （component-audit-2026-08-17 部分對齊 7） */

/* 處理中轉圈（客人「出示畫面」被掃到後：QR 消失、轉圈，見通用元件） */.srf-root .srf-spinner {
  width: 34px; height: 34px; border-radius: 50%;
  border: 3px solid var(--primary-100); border-top-color: var(--primary-500);
  animation: srf-srfSpin 0.85s linear infinite; margin: 0 auto;
}
@keyframes srf-srfSpin { to { transform: rotate(360deg); } }

/* ===================== 空狀態 / 提示 / 條（含灰階危險級：破壞性動作不用紅） ===================== */
/* 等同官網 text-center py-12 灰字慣例（my/orders.blade.php／ticket-redeems.blade.php），
   數值維持原樣，影響極小不強改（component-audit-2026-08-17 部分對齊 8） */.srf-root .srf-empty-state { text-align: center; color: var(--gray-400); padding: 40px 12px; font-size: 13.76px; }
/* 提示／通知橫幅：骨架貼齊官網 app/components/alert.blade.php 的 .alert/.alert-danger/.alert-success/
   .alert-warning（role="alert" 一併補在標記處），配色維持既有克制策略（is-warning 用灰、is-danger 用深灰，
   不用紅黃綠——2026-08-15 已驗證可行的視覺決定，本次只換骨架命名不動配色，component-audit-2026-08-17 自造①） */.srf-root .srf-alert {
  border-radius: var(--radius-btn);
  padding: 12px 14px;
  font-size: 13.12px;
  color: var(--primary-700);
  line-height: 1.6;
  display: flex;
  gap: 10px;
  align-items: flex-start;
}.srf-root .srf-alert svg { flex-shrink: 0; margin-top: 1px; }

/* ===================== 訊息四角色（2026-09-03 拍板，取代單一 .alert 通用框） =====================
   盤點（notice-audit-2026-09-03.md）結論：20 處 alert 其實在做四件不同的事。
   ①狀態與原因 → 標題徽章＋深色粗體狀態句（不用框）②入口 → 可點的進行中卡片
   ③紀錄內容 → 併進紀錄本體 ④真提醒 → 保留並加重（空心品牌色驚嘆號）。 */

/* ① 狀態句：畫面上唯一交代「現在是什麼狀態」的一行，要有正文重量，不是灰註腳 */
/* 命名注意：demo 面板另有一個 .status-line（灰色小字），定義在本檔更後面會蓋掉這裡，
   所以狀態句改用 .state-line／.state-note（2026-09-03 實測撞名後改名） */.srf-root .srf-state-line { font-size: 14.08px; font-weight: 500; color: var(--gray-600); line-height: 1.7; }.srf-root .srf-state-line.srf-is-dim { color: var(--gray-600); font-weight: 500; }
/* 狀態句下方的補充（為什麼、怎麼辦）：可以輕，但不能比狀態句重 */.srf-root .srf-state-note { font-size: 12.8px; color: var(--gray-500); line-height: 1.75; margin-top: 4px; }

/* topbar／pageHead 的狀態徽章與倒數 */.srf-root .srf-tb-badge { font-size: 10.08px; letter-spacing: 0.1em; padding: 3px 9px; border-radius: var(--radius-pill);
  background: var(--primary-50); color: var(--primary-700); border: 1px solid var(--primary-200);
  white-space: nowrap; flex-shrink: 0; }.srf-root .srf-tb-badge.srf-is-dim { background: var(--gray-100); color: var(--gray-600); border-color: var(--gray-200); }.srf-root .srf-tb-countdown { font-size: 13.76px; font-weight: 600; color: var(--gray-700);
  font-variant-numeric: tabular-nums; flex-shrink: 0; }

/* ④ 真提醒：會改變交易結果或要求動作，全站只剩 6 處，所以可以重
   驚嘆號用空心品牌色（拍板）——這是提醒不是錯誤，深墨在藍綠畫面裡會讀成「出事了」 */.srf-root .srf-notice { display: flex; gap: 11px; align-items: flex-start; }
/* 2026-09-14 對齊 Figma：圈 26→16px、環 2px 內陰影→1.5px 實框、色 --primary-600→--primary-400、
   字改無襯線 9.6px（Figma 量測：圈 16x16 r=8 sw=1.5 #3EB5C7、驚嘆號 Noto Sans TC Bold 9.6 #3EB5C7）。 */.srf-root .srf-notice-mark { flex-shrink: 0; width: 16px; height: 16px; border-radius: 50%;
  /* 2026-10-09 BL-098（使用者拍板）：圓圈與文字第一行垂直置中。margin-top＝（文字行高 13.6×1.7＝23.12 − 圓圈 16）÷ 2 ≈ 3.5，
     同店員殼 .srf-stf-shell 那條既有算法；量測差由 −3px 降到 +0.5px。 */
  margin-top: 3.5px;
  border: 1.5px solid var(--primary-400); color: var(--primary-400);
  font-family: var(--font-sans); font-weight: 700; font-size: 9.6px;
  display: flex; align-items: center; justify-content: center; line-height: 1; }.srf-root .srf-notice-text { font-size: 13.6px; font-weight: 500; color: var(--gray-600); line-height: 1.7; }.srf-root .srf-notice-text .srf-hint-text { font-weight: 400; }.srf-root .srf-notice-actions { margin-left: auto; flex-shrink: 0; }

/* S2 升級提示改用 Figma 匯出的 smile 線稿 icon（19 格 3380:4，2026-09-07 回寫）取代原本
   CSS 畫的驚嘆號圓框——圖示本身已經是完整的圓＋笑臉（見 staff.js S2_ICON_SMILE），不需要
   再疊一層 box-shadow 畫的圓，所以拿掉圓框、縮到 Figma 量到的 24px、改用圖示原色。
   只有 noticeHtml() 第三參數帶了 icon 才會掛 .notice--icon，其餘三處呼叫（S6 補光提示／
   店員切換未成立提示／S3 進行中提示，含 customer.js 自己那份 noticeHtml）完全不受影響。 */.srf-root .srf-notice--icon .srf-notice-mark {
  box-shadow: none;
  /* 2026-10-09 BL-098：icon 款不吃上面基底的 3.5px；24px 圖示對第一行中線＝（23.12 − 24）÷ 2 ≈ −0.5。 */
  margin-top: -0.5px;
  /* 2026-09-14：基底 .notice-mark 的圓框從 box-shadow 改成真 border（對齊 Figma），
     這個變體本來就不要圓框（圖示自帶圓），所以 border 要跟 box-shadow 一起歸零——
     不歸零的話 border 會吃掉 border-box 的內容區，把 14px 的笑臉圖示擠成 12px。 */
  border: 0;
  width: 24px; height: 24px;
  color: var(--primary-400);
}

/* ② 進行中卡片（儀表板入口）：左欄倒數、右邊內容，中間不畫線（拍板）；文字規格照 Figma 3364-45（2026-09-06） */
/* 2026-09-08 對齊 Figma：原本 80% 白＋舊版陰影，跟店員端 .stf-shell .live-card（見上方
   共用陰影規則）已經用的新版三件式陰影不一致，改成同款不透明白＋新陰影＋無框線。 */.srf-root .srf-live-card { display: flex; align-items: stretch; background: #fff;
  border-radius: var(--radius-card); overflow: hidden;
  box-shadow: var(--shadow-stf); cursor: pointer; }.srf-root .srf-live-card { margin-bottom: 12px; }.srf-root .srf-live-card + .srf-live-card { margin-top: -4px; }
/* 2026-09-19 依 design-sync #8 改回 Figma 母版：時鐘／剩餘欄靠左（原為置中）。 */.srf-root .srf-live-clock { flex-shrink: 0; width: 74px; padding: 12px 6px; text-align: center;
  display: flex; flex-direction: column; justify-content: center; gap: 1px; }.srf-root .srf-live-clock .srf-n { font-size: 18.88px; font-weight: 700; color: #49ACBA;
  font-variant-numeric: tabular-nums; line-height: 1.15; }.srf-root .srf-live-clock .srf-u { font-size: 9.6px; font-weight: 500; letter-spacing: 0.1em; color: var(--gray-500); }.srf-root .srf-live-main { flex: 1; min-width: 0; padding: 12px 13px; }
/* 2026-09-19 依 design-sync #8 改回 Figma 母版：名字色 #4B5563（原 #000）、行高 23（原無宣告，
   瀏覽器預設約 20）；卡片整體高度 69.69→66.69 的落差即由行高 -3 這裡回補。 */.srf-root .srf-live-who { font-size: 14px; font-weight: 500; color: #4B5563; }.srf-root .srf-live-sub { font-size: 11.68px; color: var(--gray-500); margin-top: 4px; line-height: 1.6; }

/* ===================== Modal / Sheet（折衷玻璃：僅浮層用） ===================== */
/* C01：overlay 改純半透明色，不再自己疊一層 blur——毛玻璃收斂成只留 .sheet--glass 本體一層
   （見下方 .sheet--glass 與上方 .qr-frame 註解），同一畫面同時出現的 backdrop-filter 元素
   數量降到最多 1 個。 */.srf-root .srf-overlay {
  position: fixed; inset: 0;
  background: rgba(17, 24, 39, 0.55);
  animation: srf-srfOverlayIn 0.22s ease;
  display: flex; align-items: flex-end; justify-content: center;
  z-index: 650;
}
@media (min-width: 560px) {.srf-root .srf-overlay { align-items: center; } }.srf-root .srf-sheet {
  background: #fff;
  animation: srf-srfSheetUp 0.32s cubic-bezier(0.34, 1.15, 0.64, 1);
  width: 100%;
  max-width: 430px;
  max-height: 88vh;
  /* 工具列收合／展開會讓 88vh 跳動（同 body／.phone-shell 款式），補一行 dvh 退路。
     2026-09-19 BL-069 手機 Safari 走查修批。 */
  max-height: 88dvh;
  overflow-y: auto;
  overscroll-behavior: contain; /* C02：捲到底／頂不再把捲動傳到底下的頁面（iOS 尤其明顯的橡皮筋外溢) */
  border-radius: 20px 20px 0 0;
  padding: 22px 20px 22px;
}
@media (min-width: 560px) {.srf-root .srf-sheet { border-radius: 20px; } }.srf-root .srf-sheet-title { font-family: var(--font-serif); font-weight: 700; font-size: 17.28px; margin: 0 0 12px; }

/* 2026-09-14 使用者拍板更正：**浮層一律毛玻璃**，白底扁平不再是預設。
   （原註解寫「僅會員 QR sheet 等疊玻璃、其餘維持白底扁平」，已不符現行設計，整條改寫。）
   要注意的是「浮層」與「浮層上的按鈕」分開看：浮層毛玻璃、上面的主鈕維持白 pill，
   見上方 `.card .btn-primary, .sheet .btn-primary, .cu-panel .btn-primary`。 */.srf-root .srf-sheet--glass {
  /* 濃度歷程：0.66/0.44（太透，券卡的字穿過 QR）→ 0.86/0.72（使用者：太濃）→ 現值。 */
  background: radial-gradient(140% 180% at 24% 3%,
    rgba(255, 255, 255, 0.66) 0%, rgba(255, 255, 255, 0.44) 100%);
  backdrop-filter: blur(28px) saturate(1.5);
  -webkit-backdrop-filter: blur(28px) saturate(1.5);
  border-top: 0;
  /* 棱邊改 inset shadow（捲動容器內偽元素會跟著捲走，不能用 ::before 配方） */
  /* 2026-09-12 試做：外層陰影加深加大一點，做出「真的貼在畫面上」的接觸感（liquid_glass_easy
     套件的 multiply 貼合陰影因為捲動容器限制沒辦法直接照搬，改用加強一般陰影逼近） */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.92), inset 0 -0.5px 0 rgba(153, 153, 153, 0.35),
    0 -10px 36px rgba(17, 24, 39, 0.2);
}
@media (min-width: 560px) {.srf-root .srf-sheet--glass { border: 1px solid rgba(255, 255, 255, 0.85); } }
/* 2026-09-12 玻璃按鈕試做已撤回：查證 Apple Liquid Glass 官方指引「不要在內容層中使用
   Liquid Glass、玻璃疊玻璃會造成視覺層次混亂」，浮層本身玻璃即可，裡面的按鈕改回沿用
   .sheet .btn-primary 的白底 pill 預設樣式（不再另外覆寫），故此處無覆寫規則。 */

/* 同意書（2026-09-03 改法三）：條款直接排在頁面上，不再包白卡與內層捲動框——
   原本框內捲動與整頁捲動疊在一起，iOS 上容易捲錯對象。捲到底才解鎖勾選的規則不變，
   改由條款末尾的 .consent-end 哨兵進入畫面時觸發（見 customer.js wireConsentScroll）。 */.srf-root .srf-consent-terms {
  background: rgba(255, 255, 255, 0.55);
  border-radius: var(--radius-card);
  padding: 16px;
  font-size: 12.48px;
  color: var(--gray-600);
  line-height: 1.9;
  white-space: pre-line;
}
/* 浮層（白底 sheet）內不需要再鋪一層白，改為極淡灰底與現有卡片語彙一致 */.srf-root .srf-sheet .srf-consent-terms { background: var(--gray-50); border: 1px solid var(--gray-150); }.srf-root .srf-consent-end { height: 1px; }
/* BL-090（2026-09-29）：照片使用二選一（插在條款內），純排版——與周圍條款文字
   同列、換行時自然堆疊，無底色／邊框／陰影／裝飾。逐字對齊提案 artifact v3
   .rc-photo-consent-line（scratchpad consent-proposal/index.html）。 */
.srf-root .srf-consent-choice { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-top: 8px; }
/* BL-090 修正單第 1 項（使用者回報：圓框跟文字沒有垂直置中）：.srf-form-check
   共用規則預設 align-items:flex-start（給長文案勾選框用，見上方 1339 行），本區
   內兩顆單選圓框跟「同意」「不同意」文字改置中對齊；範圍只限
   .srf-consent-choice 內，不影響其他勾選框（照片段落 .srf-form-check-input
   本身無 margin-top 的必要，改成 0 讓 accent-color 圓點跟一行文字同高）。 */
.srf-root .srf-consent-choice .srf-form-check { align-items: center; }
.srf-root .srf-consent-choice .srf-form-check-input { margin-top: 0; }
/* 同意書步驟的動作區：不吸底、接在條款之後（2026-09-04）——長文頁面吸底的按鈕會讓
   條款文字從它底下穿過去；接在文末剛好對上「捲到底才解鎖」的節奏。 */.srf-root .srf-consent-actions {
  padding: 18px 0 8px;
  display: flex; flex-direction: column; gap: 10px;
}.srf-root .srf-consent-actions .srf-bottom-action-hint { padding: 0; }

/* ===================== 相機掃描取景層（BL-069，2026-08-17）=====================
   浮層：背景是即時相機畫面本身（不加玻璃，玻璃在鏡頭直出影像上沒有意義），
   只有浮在畫面上的控制項（取消鈕、提示文字）套用既有玻璃語彙（沿用 .qr-frame／
   .sheet--glass 的 blur+saturate+白邊配方），符合「玻璃只用於浮層」鐵則。 */.srf-root .srf-scan-camera-layer { position: fixed; inset: 0; z-index: 700; background: #000; overflow: hidden; }.srf-root .srf-scan-camera-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }.srf-root .srf-scan-camera-scrim {
  position: relative; z-index: 1; height: 100%;
  display: flex; flex-direction: column; align-items: center;
  padding: calc(0px + 16px) 16px calc(0px + 16px);
}.srf-root .srf-scan-camera-topbar { width: 100%; display: flex; justify-content: flex-end; }.srf-root .srf-scan-camera-cancel {
  background: rgba(17, 24, 39, 0.55);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  color: #fff; border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: var(--radius-pill);
  padding: 8px 18px; font-size: 13.76px; font-weight: 500;
  position: relative; /* F8：見下方 ::after，撐大可點範圍用 */
}
/* BL-069 第四輪修批 F8（實測約 38px 高）：同 .btn-sm 手法。.scan-camera-scrim 上下 padding
   各 ≥16px，-10px 外推仍在安全範圍內，不會跟 .scan-frame 或畫面邊緣重疊。 */.srf-root .srf-scan-camera-cancel::after {
  content: '';
  position: absolute;
  left: 0; right: 0; top: -10px; bottom: -10px;
}.srf-root .srf-scan-frame {
  margin: auto;
  width: min(68vw, 280px); height: min(68vw, 280px);
  border: 2px solid rgba(255, 255, 255, 0.92);
  border-radius: 20px;
  box-shadow: 0 0 0 999px rgba(0, 0, 0, 0.4);
}.srf-root .srf-scan-camera-hint {
  margin-top: 18px;
  background: rgba(17, 24, 39, 0.55);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  color: #fff; font-size: 13.44px; text-align: center;
  padding: 8px 16px; border-radius: var(--radius-pill);
}.srf-root .srf-scan-camera-bottom { margin-top: auto; padding-top: 18px; }.srf-root .srf-scan-camera-bottom a { color: rgba(255, 255, 255, 0.82); font-size: 12.8px; text-decoration: underline; text-underline-offset: 3px; }

/* ===================== Toast（bottom 提高，避開各畫面 sticky 動作條；§一-13） ===================== */.srf-root .srf-toast {
  position: fixed;
  left: 50%; bottom: 88px;
  transform: translateX(-50%) translateY(12px);
  background: var(--gray-800);
  color: #fff;
  padding: 10px 18px;
  border-radius: var(--radius-pill);
  font-size: 13.12px;
  opacity: 0;
  pointer-events: none;
  transition: all 0.2s ease;
  z-index: 950;
  max-width: 90vw;
  text-align: center;
}.srf-root .srf-toast.srf-is-visible { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ===================== S6 紀錄：日期分段 ===================== */.srf-root .srf-records-date-group { margin-bottom: 18px; }.srf-root .srf-records-date-label { font-size: 12.16px; font-weight: 700; color: var(--gray-400); margin: 0 0 8px 2px; letter-spacing: 0.02em; }
/* 2026-09-14：原本的 .visit-group（同一次到店的群組容器）整組拿掉——清單的單位已經
   改成「一趟到店」，每一趟本身就是一張卡（樣式見 S6 段落的 .visit-card），不再需要
   「卡片裡再包一層群組」這種盒中盒。 */

/* ===================== 身份分流（首頁，供實機雙人測試點選進入） ===================== */.srf-root .srf-role-picker-shell { max-width: 1080px; margin: 0 auto; padding: 28px 20px 0; }.srf-root .srf-role-picker-title { font-family: var(--font-serif); font-size: 17.6px; font-weight: 700; color: var(--gray-700); margin: 0 0 12px; }.srf-root .srf-role-picker-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; }.srf-root .srf-role-card {
  display: flex; align-items: center; gap: 14px;
  background: #fff; border: 0; border-radius: var(--radius-card);
  box-shadow: var(--shadow-stf); padding: 18px 20px;
  text-decoration: none; color: var(--gray-800);
  transition: transform 0.15s ease;
}.srf-root .srf-role-card:active { transform: scale(0.97); }.srf-root .srf-role-card-icon {
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 48px; height: 48px; border-radius: var(--radius-pill);
  background: var(--primary-50); color: var(--primary-500);
}.srf-root .srf-role-card-text { display: flex; flex-direction: column; gap: 2px; }.srf-root .srf-role-card-label { font-family: var(--font-serif); font-size: 16.8px; font-weight: 700; color: var(--gray-600); }.srf-root .srf-role-card-desc { font-size: 12.48px; color: var(--gray-500); }

/* ===================== Demo 面板專用（桌面測試用：劇本載入／雙窗，非分流按鈕） ===================== */.srf-root .srf-demo-shell { max-width: 1080px; margin: 0 auto; padding: 12px 20px 60px; }.srf-root .srf-demo-banner {
  background: var(--gray-800);
  color: #fff;
  padding: 10px 18px;
  border-radius: var(--radius-btn);
  font-size: 12.8px;
  margin-bottom: 22px;
  text-align: center;
  letter-spacing: 0.02em;
}.srf-root .srf-demo-title { font-family: var(--font-serif); font-size: 24px; font-weight: 700; margin: 0 0 4px; }.srf-root .srf-demo-sub { color: var(--gray-500); font-size: 14.08px; margin: 0 0 24px; }.srf-root .srf-demo-toolbar { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 26px; }.srf-root .srf-demo-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 16px; }.srf-root .srf-scenario-card {
  background: #fff;
  border: 1px solid var(--gray-150);
  border-radius: var(--radius-card);
  padding: 18px;
  box-shadow: var(--shadow-card);
  display: flex; flex-direction: column; gap: 10px;
}.srf-root .srf-scenario-card h3 { margin: 0; font-size: 16px; font-family: var(--font-serif); }.srf-root .srf-scenario-card .srf-sc-summary { font-size: 13.12px; color: var(--gray-500); line-height: 1.6; }.srf-root .srf-scenario-card ol { margin: 0; padding-left: 18px; font-size: 12.48px; color: var(--gray-600); line-height: 1.7; }.srf-root .srf-scenario-card .srf-sc-actions { display: flex; gap: 8px; margin-top: 4px; }.srf-root .srf-status-line { font-size: 12.48px; color: var(--gray-400); margin-top: 6px; }

/* 補登整包（含官網後台示意頁）已於 v4 移除，見 storyboards.md 範圍註記（BL-070 暫緩）。*/

/* ===================== BL-069 mockup simplify（2026-09-03）：行內樣式收斂為 class =====================
   目的：畫面不變，只把散落在 customer.js/staff.js/common.js/demo.js 的 style="..." 收進這裡統一管理，
   為接下來的整體視覺重繪先清好地。以下 utility 一律只新增屬性或用 modifier class 補足 specificity，
   逐條已核對不會改變任何既有畫面的實際渲染結果（見 component-audit-2026-08-17 同批施工紀錄）。 */.srf-root .srf-text-center { text-align: center; }.srf-root .srf-v-hidden { visibility: hidden; }.srf-root .srf-is-clickable { cursor: pointer; }.srf-root .srf-pl-0 { padding-left: 0; }.srf-root .srf-self-start { align-self: flex-start; }.srf-root .srf-mt-2 { margin-top: 2px; }.srf-root .srf-mt-4 { margin-top: 4px; }.srf-root .srf-mt-6 { margin-top: 6px; }.srf-root .srf-mt-10 { margin-top: 10px; }.srf-root .srf-text-primary { color: var(--primary-500); }.srf-root .srf-text-gray-300 { color: var(--gray-300); }

/* 字級走 token 化 utility（取代逐處寫死 font-size）。
   注意：.pr-title 本身「不」補統一預設值——它在 .pick-row 情境內有 0.92 rem（既有規則），
   但在其他情境（item-block／獨立卡片標題等）原本完全依賴外層繼承字級（多半是 16px），
   兩者互不相同。2026-09-03 施工中一度加了一條 bare `.pr-title{font-size:.92 rem}` 圖方便，
   結果把所有「原本靠繼承、從未設過字級」的 .pr-title（如 S6d 詳情頁主標題）誤改成 14.72px，
   截圖比對抓到才發現並改回——教訓是「补統一預設」這類看似無害的簡化，對「原本就沒有規則、
   靠繼承」的元素等同於新增一條會變更計算值的規則，不算純粹的收斂。改法：不加 bare 規則，
   原本就是 .92 rem 的獨立情境（item-block 內）逐處補 .fs-92，其餘情境維持原樣不動。 */.srf-root .srf-fs-88 { font-size: 14.08px; }.srf-root .srf-fs-90 { font-size: 14.4px; }.srf-root .srf-fs-92 { font-size: 14.72px; }.srf-root .srf-fs-95 { font-size: 15.2px; }.srf-root .srf-fs-100 { font-size: 16px; }.srf-root .srf-fs-105 { font-size: 16.8px; }

/* 元件一次性版面覆寫，用 modifier class 承接（selector specificity 逐條核對過，足以覆蓋各自的基底規則） */.srf-root .srf-app-body.srf-is-centered-vh { display: flex; flex-direction: column; justify-content: center; min-height: 70vh; }.srf-root .srf-app-body.srf-is-loading { text-align: center; padding: 36px 0; }.srf-root .srf-app-body.srf-is-loading-connect { text-align: center; padding: 40px 0; }.srf-root .srf-app-body.srf-is-loading-lg { text-align: center; padding: 60px 0; }.srf-root .srf-app-body.srf-is-scan-instruction { text-align: center; padding-top: 48px; }.srf-root .srf-cu-panel.srf-is-loading { text-align: center; padding: 36px 0; }.srf-root .srf-page_title.srf-mt-0 { margin-top: 0; }.srf-root .srf-hint-text.srf-has-divider { border-top: 1px solid var(--gray-200); padding-top: 12px; }
/* overflow-wrap:anywhere（2026-09-15 第三輪體檢）：信箱是不可斷行的長字串，沒有這一行時
   字級放大到 200%（視力不好的人常這樣設）或窄螢幕會把整頁撐出橫向捲動、信箱後半段跑出卡片。
   這一頁存在的唯一目的就是讓客人核對自己的信箱。 */.srf-root .srf-hint-text.srf-is-email-display { padding: 10px 0; color: var(--gray-600); font-size: 14.72px; overflow-wrap: anywhere; }.srf-root .srf-hint-text.srf-is-inline-center { display: flex; align-items: center; justify-content: center; gap: 6px; }.srf-root .srf-card-pad.srf-has-divider-top { border-top: 1px solid var(--gray-150); }.srf-root .srf-bottom-action-bar.srf-is-stacked { flex-direction: column; }.srf-root .srf-qr-frame.srf-is-inline { margin: 0 auto; width: fit-content; }.srf-root .srf-form-control.srf-is-compact { padding: 7px 9px; font-size: 13.6px; }.srf-root .srf-pick-row.srf-is-menu-row { border: 0; border-radius: 0; }.srf-root .srf-pick-row.srf-is-borderless { border: 0; }.srf-root .srf-pick-row .srf-pr-title.srf-fs-88 { font-size: 14.08px; }.srf-root .srf-pick-row .srf-pr-amt.srf-is-note { font-weight: 400; color: var(--gray-500); font-size: 13.12px; }.srf-root .srf-pick-row .srf-pr-amt.srf-is-note-alt { font-weight: 400; color: var(--gray-400); font-size: 12.8px; }.srf-root .srf-app-topbar .srf-tb-btn.srf-is-wide { width: auto; padding: 5px 10px; gap: 5px; }.srf-root .srf-sheet-footer-action { padding: 0 18px 20px; text-align: center; }.srf-root .srf-w-110 { width: 110px; }.srf-root .srf-spacer-8 { height: 8px; }.srf-root .srf-spacer-30 { width: 30px; height: 30px; display: inline-block; }.srf-root .srf-cust-name-lg { font-size: 18.4px; font-weight: 500; color: var(--gray-600); }.srf-root .srf-op-detail-toggle { cursor: pointer; flex: 1; }.srf-root .srf-op-alert-row { display: flex; align-items: flex-start; gap: 8px; width: 100%; }.srf-root .srf-demo-footnote { font-size: 12.48px; color: var(--gray-400); line-height: 1.7; }.srf-root .srf-qr-fallback { box-sizing: border-box; display: flex; align-items: center; justify-content: center; text-align: center; font-size: 11.52px; color: var(--gray-400); padding: 8px; width: min(var(--qr-size, 220px), 100%); height: min(var(--qr-size, 220px), 60vw); }



/* ===================== 視覺重繪動效層（2026-09-03，抄自官網 Nuxt 前台實測值） ===================== */
@keyframes srf-srfOverlayIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes srf-srfSheetUp { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: none; } }
/* 換畫面進場（僅 hash 換頁時由 mount() 加 .view-enter，state 同步的重繪不重播） */
@keyframes srf-srfViewIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }.srf-root #app.srf-view-enter .srf-app-body,
.srf-root #app.srf-view-enter .srf-page_heading {
  animation: srf-srfViewIn 0.42s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
}.srf-root #app.srf-view-enter .srf-app-body { animation-delay: 0.05s; }

/* 逐字上滑換字（官網 flip：每字錯開 33ms；單份文字用兩段 keyframe 模擬上出下進，
   不複製文字節點——innerText 保持與畫面文案一字不差） */.srf-root .srf-flip-wrap { display: inline-block; white-space: nowrap; }.srf-root .srf-fch { display: inline-block; }
@keyframes srf-srfFchFlip {
  0% { transform: translateY(0); opacity: 1; }
  45% { transform: translateY(-115%); opacity: 0; }
  50% { transform: translateY(115%); opacity: 0; }
  100% { transform: translateY(0); opacity: 1; }
}.srf-root .srf-btn-primary:hover .srf-fch,
.srf-root .srf-btn-primary.srf-tap-hover .srf-fch {
  animation: srf-srfFchFlip 0.5s cubic-bezier(0.075, 0.82, 0.165, 1) both;
}.srf-root .srf-flip-wrap .srf-fch:nth-child(2) { animation-delay: 33ms; }.srf-root .srf-flip-wrap .srf-fch:nth-child(3) { animation-delay: 66ms; }.srf-root .srf-flip-wrap .srf-fch:nth-child(4) { animation-delay: 99ms; }.srf-root .srf-flip-wrap .srf-fch:nth-child(5) { animation-delay: 132ms; }.srf-root .srf-flip-wrap .srf-fch:nth-child(6) { animation-delay: 165ms; }.srf-root .srf-flip-wrap .srf-fch:nth-child(7) { animation-delay: 198ms; }.srf-root .srf-flip-wrap .srf-fch:nth-child(8) { animation-delay: 231ms; }.srf-root .srf-flip-wrap .srf-fch:nth-child(9) { animation-delay: 264ms; }.srf-root .srf-flip-wrap .srf-fch:nth-child(10) { animation-delay: 297ms; }

@media (prefers-reduced-motion: reduce) {.srf-root #app.srf-view-enter .srf-app-body,
.srf-root #app.srf-view-enter .srf-page_heading,
.srf-root .srf-sheet,
.srf-root .srf-overlay { animation: none !important; }.srf-root .srf-fch { animation: none !important; }
  /* 2026-09-15 第三輪體檢補漏：這兩個是實測時唯一沒被任何一個關閉區塊蓋到的動畫——
     客人端分頁切換的滑入（.ticket-pane）與「出示給店員」等待畫面一閃一閃的圓點（.pulse-dot）。
     後者是無限重複，對前庭敏感的人影響最大。 */.srf-root .srf-ticket-pane { animation: none !important; }.srf-root .srf-pulse-dot { animation: none !important; opacity: 1; }
}

/* 玻璃 sheet 上的次要文字對比補強（round1 目檢） */.srf-root .srf-sheet--glass .srf-hint-text,
.srf-root .srf-sheet--glass .srf-qr-explain { color: var(--gray-600); }.srf-root .srf-sheet--glass .srf-qr-countdown { color: var(--gray-700); }

/* ═════ 2026-09-04 定案 — 客人端其餘部分 ═════
   以下 class 店員端也在用，故一律 .cu-shell / .cu-page 限定。
   店員端是否一併改＝尚未決議，不碰。 */

/* 頁標題：五階字級的頂階 */.srf-root .srf-cu-shell .srf-page_title { font-size: var(--fs-title); line-height: 1.3;
  letter-spacing: 0.03em; color: var(--cu-ink); }

/* 分頁：改成兩顆獨立的細框藥丸、左對齊。選中＝實心白＋品牌色＋浮起，
   沿用正式站三處逐字相同的「被選中」配方（膠囊／日期卡／時段卡）。 */.srf-root .srf-cu-shell .srf-ticket-tabs-wrap { justify-content: flex-start; margin: 4px 0 20px; }.srf-root .srf-cu-shell .srf-ticket-tabs { background: transparent; padding: 0; gap: 8px; }.srf-root .srf-cu-shell .srf-ticket-tab {
  font-size: 13px; font-weight: 600; padding: 8px 18px;
  color: var(--cu-ink-2); border: 1px solid rgba(0, 0, 0, 0.16);
}.srf-root .srf-cu-shell .srf-ticket-tab.srf-active {
  background: #fff; color: var(--cu-action); border-color: transparent;
  box-shadow: 0 1px 2px rgba(20, 66, 82, 0.08), 0 8px 14px -7px rgba(20, 66, 82, 0.3);
}
/* BL-093 設計調整（2026-10-01，使用者原話「跟我的服務上面那組長得不一樣」，比對後
   拍板比照「我的服務」）：店員紀錄頁不在 .srf-cu-shell 底下、吃不到上面那組覆寫，
   只能看到最舊的灰軌道樣式。以下逐條照抄上面 .srf-cu-shell 那組的原值，選擇器換成
   紀錄頁專屬的 .srf-stf-s6（見 records.blade.php 的 shell-class），不影響其他店員頁、
   不動 .srf-cu-shell 原規則、沒有新增或改任何顏色／字級／陰影數值。 */.srf-root .srf-stf-s6 .srf-ticket-tabs-wrap { justify-content: flex-start; margin: 4px 0 20px; }.srf-root .srf-stf-s6 .srf-ticket-tabs { background: transparent; padding: 0; gap: 8px; }.srf-root .srf-stf-s6 .srf-ticket-tab {
  font-size: 13px; font-weight: 600; padding: 8px 18px;
  color: var(--cu-ink-2); border: 1px solid rgba(0, 0, 0, 0.16);
}.srf-root .srf-stf-s6 .srf-ticket-tab.srf-active {
  background: #fff; color: var(--cu-action); border-color: transparent;
  box-shadow: 0 1px 2px rgba(20, 66, 82, 0.08), 0 8px 14px -7px rgba(20, 66, 82, 0.3);
}

/* 其餘文字色：gray-400 / gray-500 退出文字角色 */.srf-root .srf-cu-shell .srf-hint-text,
.srf-root .srf-cu-shell .srf-qr-explain,
.srf-root .srf-cu-shell .srf-timeline-sub,
.srf-root .srf-cu-shell .srf-amount-display .srf-amount-label,
.srf-root .srf-cu-shell .srf-cu-panel.srf-empty-state,
.srf-root .srf-cu-shell .srf-cu-site-footer { color: var(--cu-ink-2); }
/* 2026-09-19 依 design-sync #5 改回 Figma Tone=Dim-S2（客人端「已完成」「新客限定」等
   淡灰徽章）：Regular／#9AA0A6，取代先前誤沿用 Dim-Staff 深灰粗字。 */.srf-root .srf-cu-shell .srf-badge.srf-bg-label-secondary { color: var(--gray-400); font-weight: 400; }.srf-root .srf-cu-shell .srf-badge.srf-bg-label-primary { color: var(--cu-action); }

/* 浮層：#sheet-holder 是 .cu-shell 的兄弟節點（不在裡面），上面那批規則吃不到。
   customer.html 的 <body> 掛 cu-page 當客人端識別；staff.html 沒有，故店員端不受影響。 */.srf-root .srf-cu-page .srf-hint-text,
.srf-root .srf-cu-page .srf-pr-sub,
.srf-root .srf-cu-page .srf-qr-explain { color: var(--cu-ink-2); }

/* 鎖住的選項：不能點的是「控制項」，但「為什麼不能點」必須讀得到。
   原本整列 opacity .5 把原因字壓到 1.56:1，等於把唯一的說明藏起來。 */.srf-root .srf-cu-page .srf-pick-row.srf-is-disabled { opacity: 1; }.srf-root .srf-cu-page .srf-pick-row.srf-is-disabled .srf-pr-title { opacity: 0.5; }.srf-root .srf-cu-page .srf-pick-row.srf-is-disabled input[type="checkbox"] { opacity: 0.45; }.srf-root .srf-cu-page .srf-pick-row.srf-is-disabled .srf-pr-sub { color: var(--cu-ink-2); opacity: 1; }

/* 客人端其餘勾選列（C4 兌換浮層的加選清單、儀表板 More 列等）：2026-09-08 當初是為 C9
   寫的「半對齊」版本，選擇器沒限定頁面，一併套到了這些列。
   2026-09-19：C9 已改用與店員端 S2 共用的勾選列元件（common.js UI.pickRow＋上方
   `.phone-shell .pick-card` 那一組規則），這一段用 :where(:not(.pick-card > .pick-row))
   把共用元件排除在外——:where() 不增加權重，其餘客人端勾選列的外觀與改版前完全相同。 */.srf-root .srf-cu-page .srf-pick-row:where(:not(.srf-pick-card > .srf-pick-row)) {
  border: 0;
  border-radius: 12px;
  background: transparent;
  box-shadow: none;
}.srf-root .srf-cu-page .srf-pick-row:where(:not(.srf-pick-card > .srf-pick-row)) > input[type="checkbox"] {
  transform: scale(0.631579); /* 12 ÷ 19，佔位盒仍是 19px */
  transform-origin: center;
}.srf-root .srf-cu-page .srf-pick-row.srf-is-checked:where(:not(.srf-pick-card > .srf-pick-row)) > input[type="checkbox"] { transform: none; }.srf-root .srf-cu-page .srf-pick-row:where(:not(.srf-pick-card > .srf-pick-row)) .srf-pr-title,
.srf-root .srf-cu-page .srf-pick-row:where(:not(.srf-pick-card > .srf-pick-row)) .srf-pr-amt { font-weight: 500; font-size: 14.72px; color: var(--gray-600); }.srf-root .srf-cu-page .srf-pick-row.srf-is-checked:where(:not(.srf-pick-card > .srf-pick-row)) {
  background: #fff;
  border: 2px solid var(--primary-400);
}.srf-root .srf-cu-page .srf-pick-row.srf-is-checked:where(:not(.srf-pick-card > .srf-pick-row)) .srf-pr-title,
.srf-root .srf-cu-page .srf-pick-row.srf-is-checked:where(:not(.srf-pick-card > .srf-pick-row)) .srf-pr-amt { font-size: 18px; font-weight: 700; color: var(--primary-400); }

/* =====================================================================================
   儀表板（2026-09-17 從 dashboard-proposal 快照搬進正式 mockup；2026-09-15/16 提案拍板）

   規矩：本段只准出現 `dp-` 前綴的新 class，數值一律從既有規則照抄，不自訂新的視覺語彙。
   會需要這幾條，是因為要沿用的既有元件原本只在「另一端的外殼」底下才成立——
   把同一組數值在新的外殼裡寫一次，而不是另外做一套長得像的東西。
   ===================================================================================== */

/* ① 單張入口方塊佔整列（客人未連線時只有〔我的服務〕一張）。
      .s1-entry-grid 是兩欄 grid，一張卡時讓它跨滿兩欄，卡片高度與圓角維持 .s1-entry-card 原值。 */.srf-root .srf-dp-entry-full { grid-column: 1 / -1; }

/* ② 客人儀表板入口方塊的角落圖示內縮。
      店員端兩張卡的 icon 是 Figma 匯出的 44 viewBox 專屬資產，右卡 .is-new 的 plus 靠
      glyph 自身內縮所以 inset 0；客人端改用 common.js ICON_PATHS（24 viewBox 等比放大），
      沒有那圈內縮，會直接切齊卡角。兩張一律改用左卡 .s1-entry-card.is-scan .s1-entry-icon
      的既有數值（right 13 / bottom 7），不另訂數字。 */.srf-root .srf-dp-dash .srf-s1-entry-card .srf-s1-entry-icon { right: 13px; bottom: 7px; }

/* ②-2 客人儀表板入口方塊的標題起始位置。
      店員端兩張卡的 top 不同是內容形狀決定的：左卡是「30px＋24px」兩行（整塊較矮，
      所以 17.4），右卡是「30px＋30px」兩行（所以 8）。客人端這兩張都是 30px＋30px，
      形狀與右卡相同，因此兩張一律吃右卡 .s1-entry-card.is-new .s1-entry-title 的既有值。
      （不是為了對齊而自訂數字——是把既有規則套在對的內容形狀上。） */.srf-root .srf-dp-dash .srf-s1-entry-card .srf-s1-entry-title { top: 8px; }

/* ③ 客人儀表板 More 列的文字＝店員端 S1 More 列的文字。
      客人端站台外殼在檔尾另有一批 `.cu-page .pick-row` 覆寫（那是給 C9 選購勾選列用的），
      會蓋掉 More 列的青字與 .fs-88 字級。這裡把既有數值原樣寫回：色與字重照抄
      `.pick-row.is-menu-row .pr-title`，字級照抄 `.pick-row .pr-title.fs-88`。 */.srf-root .srf-cu-page .srf-dp-dash .srf-pick-row.srf-is-menu-row .srf-pr-title {
  color: #3EB5C7;
  font-weight: 500;
  font-size: 14.08px;
}

/* ④ 店員端連線碼頁（#S-CODE）的白底大 QR 卡。
      客人端是靠 `.cu-shell .app-body .qr-frame` 得到白底卡（藍底頁面上的 QR 保留白底，
      2026-09-03 使用者指定），該規則吃不到店員端外殼。數值逐項照抄那一條。 */.srf-root .srf-dp-linkcode .srf-qr-frame {
  background: #fff;
  border-radius: 20px;
  padding: 22px;
  box-shadow: 0 8px 24px rgba(17, 24, 39, 0.08);
}

/* ==========================================================================
   dp-site-*：官網殼（2026-09-16 拍板「殼的切法 B」）
   「逛的頁」（客人儀表板 C0 三態／我的服務 C4／帳戶資訊／訂購紀錄）套正式站的頁首與
   完整站尾；「做事的頁」（C6 送出等待、C9 到期、出示底板）維持 mockup 自己的殼。
   以下數值全部照本機正式站 http://whiteningnet-eng.test/privacy 在 390×844 量到的
   computed style 抄寫，不是憑印象畫（量測表見交付回報）。
   全部選擇器帶 dp-site- 前綴或掛在 body.dp-site-shell 下，不碰任何共用選擇器。
   ========================================================================== */

/* 套官網殼時，藏掉 mockup 自己的品牌字頁首與一行版權 */.srf-root.srf-dp-site-shell .srf-cu-shell > #header.srf-cu-header,
.srf-root.srf-dp-site-shell .srf-cu-shell > .srf-cu-site-footer { display: none; }

/* --- 頁首：正式站 #header.header_fixed（h 52 / bg #fff / position fixed z50）---
   正式站是 fixed 覆蓋在內容上方，內容自 y=0 起算、靠 .page_title 的 80px 上內距
   讓開它。這裡用 absolute 達成同一個疊法（phone-shell 就是視窗），初次渲染逐像素相同。 */.srf-root .srf-dp-site-header {
  position: absolute; top: 0; left: 0; right: 0; height: 52px;
  background: #fff; z-index: 50; pointer-events: none;
}.srf-root .srf-dp-site-header .srf-dp-site-logo {
  position: absolute; left: 13.5px; top: 10.4px;
  width: 168.9px; height: 32.2px; display: block;
}
/* 漢堡：正式站 .openbtn1 三條 26×1px，色 #000，top 16.1 / 24.9 / 34.3，left 348.4。
   2026-09-19 還原：9/18 第四輪審查未經使用者同意拿掉漢堡，已恢復顯示。 */.srf-root .srf-dp-site-header .srf-dp-site-burger { position: absolute; left: 348.4px; top: 16.1px; width: 26px; height: 19.2px; }.srf-root .srf-dp-site-header .srf-dp-site-burger span { position: absolute; left: 0; width: 26px; height: 1px; background: #000; display: block; }.srf-root .srf-dp-site-header .srf-dp-site-burger span:nth-child(1) { top: 0; }.srf-root .srf-dp-site-header .srf-dp-site-burger span:nth-child(2) { top: 8.8px; }.srf-root .srf-dp-site-header .srf-dp-site-burger span:nth-child(3) { top: 18.2px; }

/* --- 頁面標題：正式站 .page_title（padding 80/16/32、margin-bottom 48、20px/600/lh28/ls.4、
   色 #1F2937、Noto Serif TC、置中）。整塊 .page_heading 高 140。--- */
/* mockup 的 .page_heading 自帶 18/20/4 的內距，正式站是 0——套官網殼時歸零，
   讓 .page_title 的 80/16/32 直接落在正式站的位置上。 */.srf-root.srf-dp-site-shell .srf-cu-shell .srf-page_heading { padding: 0; }.srf-root.srf-dp-site-shell .srf-cu-shell .srf-page_heading .srf-page_title {
  padding: 80px 16px 32px; margin: 0 0 48px; text-align: center;
  font-family: "Noto Serif TC", "Noto Serif JP", serif;
  font-size: 20px; font-weight: 600; line-height: 28px; letter-spacing: 0.4px; color: #1F2937;
}.srf-root.srf-dp-site-shell .srf-cu-shell .srf-page_heading .srf-cu-pagehead-top { display: none; }

/* --- 站尾：正式站 footer（bg #F3F4F5、h 207.9）--- */.srf-root .srf-dp-site-footer { background: #F3F4F5; width: 100%; position: relative; z-index: 1; }.srf-root .srf-dp-site-footer .srf-dp-site-wrapper { margin: 0 15.61px 0 15.59px; }.srf-root .srf-dp-site-footer .srf-dp-site-fbottom { padding: 41.6px 0; }.srf-root .srf-dp-site-footer .srf-dp-site-fleft { width: 260.9px; margin: 30.68px auto 0; text-align: center; }.srf-root .srf-dp-site-footer .srf-dp-site-fnav {
  list-style: none; margin: 0; padding: 0;
  display: flex; justify-content: center; gap: 39.5px; height: 15.5px;
}.srf-root .srf-dp-site-footer .srf-dp-site-fnav span {
  font-size: 12.48px; font-weight: 300; line-height: 12.48px;
  color: rgba(0, 0, 0, 0.5); text-decoration: none;
}.srf-root .srf-dp-site-footer .srf-dp-site-fsmall {
  display: block; margin: 31.72px 0 0;
  font-size: 10.4px; font-weight: 300; line-height: 15.6px; color: rgba(0, 0, 0, 0.3);
}.srf-root .srf-dp-site-footer .srf-dp-site-fsmall span { color: rgba(0, 0, 0, 0.3); text-decoration: none; }

/* ==========================================================================
   dp-back-tc：返回鍵（2026-09-16 提案原有三案六種做法，2026-09-17 拍板只留④c
   標題列 chevron・貼齊內容區左緣，且不再靠旗標切換——這是「我的服務」頁返回鍵的
   唯一做法，unconditional 套用，不掛在 body class 下）。
   版面：三欄 grid（1fr / auto 標題 / 1fr、grid-template-rows:28px、左右內距 18px）——
   兩側 1fr 欄寬相等，標題（中欄 auto）不受影響，一樣整頁置中、字級不動。
   圖示：common.js 既有的 chevron-right（More 清單那支），用 CSS scaleX(-1) 鏡射成向左，
   無穿梭動效；第一欄 justify-self 改 start（不置中），讓命中框貼齊欄位起點＝容器
   padding-left 18px，正是內容區左緣。命中框 44×44（比照 .cu-back-btn「外框撐大」慣例），
   圖示用 justify-content:flex-start 貼在框內左緣，框左緣與圖示視覺左緣因此同落在 18px。
   align-items:center 讓 44 高的命中框在 28 高的列裡上下溢出、垂直居中對齊標題文字中心。
   z-index 必要：.page_heading 帶進場動畫（#app.view-enter），且在 DOM 上排在 chevron 之後，
   不墊 z-index 會被那塊透明標題框蓋住點擊。 --- */.srf-root.srf-dp-site-shell .srf-cu-shell .srf-page_heading .srf-page_title.srf-dp-back-tc-mid {
  display: grid; grid-template-columns: 1fr auto 1fr;
  grid-template-rows: 28px; align-items: center;
  padding-left: 18px; padding-right: 18px;
}.srf-root .srf-page_title.srf-dp-back-tc-mid .srf-main_jp { white-space: nowrap; }.srf-root .srf-dp-back-tc {
  position: static; z-index: 2; justify-self: start;
  display: inline-flex; align-items: center; justify-content: flex-start;
  width: 44px; height: 44px; min-width: 0; /* min-width:0 防 1fr 軌道被固定寬度撐開不等寬 */
  color: #1F2937; text-decoration: none;
}.srf-root .srf-dp-back-tc .srf-dp-back-tc-glyph { transform: scaleX(-1); flex: none; } /* chevron-right 鏡射成向左 */
@media (hover: hover) {.srf-root .srf-dp-back-tc:hover { color: var(--primary-500); } /* 同 .cu-back-btn:hover 的色，無底色墊層 */
}

/* --- 兩個逛的頁（訂購紀錄 .order-card／帳戶資訊 .acct-card）=====================
   2026-09-18 改版：原本的 .dp-ord-* / .dp-acct-* 是照正式站版面 1:1 抄的（灰色縮圖方塊、
   hr 分段、表單框線堆疊），整組換掉，不留舊值在下面打架。
   這兩張卡刻意跟 .ticket-card.card（C4 券卡）共用同一組表面與節奏值，讓三頁看起來是同一套：
     表面 = 純白 + var(--tk-radius) 18px + var(--shadow-stf)   ← 逐值同 .ticket-card.card
     內距 = 14px 15px                                          ← 逐值同 .tk
     卡距 = 12px                                               ← 沿用 .stack，不另寫 margin
     字級 = --fs-name 14px 青（品名階）／--fs-sub 12px 灰（說明階）／--fs-num 24px 襯線青（主數字）
   這裡不重新宣告那些數值的來源，直接吃同一批變數；C4 調值時這兩頁自動跟著走。 */.srf-root .srf-order-card.srf-card,
.srf-root .srf-acct-card.srf-card {
  background: #fff;
  border: 0;
  border-radius: var(--tk-radius);
  box-shadow: var(--shadow-stf);
}.srf-root .srf-oc,
.srf-root .srf-ac { padding: 14px 15px; }

/* 訂購紀錄 ---------------------------------------------------------------- */
/* 卡頭：單號（說明階灰）在左、狀態徽章在右。徽章只用 UI.badge 既有的兩階灰
   （dim = 已完成／outline = 處理中），不新增第三種樣式、不引入第二個色系。 */.srf-root .srf-oc-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }.srf-root .srf-oc-no {
  font-size: var(--fs-sub); color: var(--cu-ink-2);
  letter-spacing: 0.06em; font-variant-numeric: tabular-nums;
}
/* 品項列：列＝品項，多一個品項只是多一列，版面不變（不是一列並排多欄）。
   上下兩個區塊間距同值（head→items 與 items→foot 都是 14px），卡內節奏才一致。 */.srf-root .srf-oc-items { margin-top: 14px; }.srf-root .srf-oc-item { display: flex; align-items: baseline; gap: 12px; }.srf-root .srf-oc-item + .srf-oc-item { margin-top: 8px; }
/* 逐條對齊 .tk-name：同字體、同字級、同字重、同色、同行高——這是「同一套語言」最直接的一處。 */.srf-root .srf-oc-item-name {
  flex: 1 1 auto; min-width: 0;
  font-family: var(--font-sans); font-size: var(--fs-name); font-weight: 500;
  color: var(--cu-action); line-height: 1.4;
}.srf-root .srf-oc-item-name .srf-qty-mark { margin-left: 6px; }
/* 金額欄寫成「$6,240 × 2」：與店員端紀錄詳情品項列同一個寫法（見 .vd-item-amt 註解）。
   這一欄刻意留在說明階（12px 灰），一張卡裡只讓「訂單金額」那個數字最重。 */.srf-root .srf-oc-item-amt {
  flex: 0 0 auto;
  font-size: var(--fs-sub); color: var(--cu-ink-2);
  letter-spacing: 0.02em; font-variant-numeric: tabular-nums; white-space: nowrap;
}.srf-root .srf-oc-foot {
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--gray-150);
  /* BL-093 Y 第 14 項設計調整（2026-10-01）：有折讓時右側 .srf-oc-total 變兩行，
     align-items 從 baseline 改 flex-end，讓左側日期與右側下行（實收大字）的
     底部對齊——只改排版，不動顏色／字級／字型。 */
  display: flex; align-items: flex-end; justify-content: space-between; gap: 10px;
}.srf-root .srf-oc-date { font-size: var(--fs-sub); color: var(--cu-ink-2); letter-spacing: 0.02em; }.srf-root .srf-oc-total { display: flex; align-items: baseline; gap: 6px; }
/* BL-093 Y 第 14 項設計調整（2026-10-01）：有折讓時右側兩行堆疊、靠右對齊——
   只加排版屬性（display／flex-direction／align-items／gap），不新增顏色、
   字級、字型；無折讓的 .srf-oc-total 不帶這個 class，維持原本單行樣式不變。 */
.srf-root .srf-oc-total.srf-oc-total-stacked { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
/* 「訂單金額 $12,480」的兩截處理逐值同 .tk-remain / .tk-remain-txt（「剩 3 堂」那一組）：
   標籤 11px 灰、數字襯線 --fs-num 青。 */.srf-root .srf-oc-total-label { font-size: 11px; color: var(--cu-ink-2); letter-spacing: 0.02em; }.srf-root .srf-oc-total b {
  font-family: var(--font-serif); font-weight: 500;
  font-size: var(--fs-num); color: var(--cu-action); font-variant-numeric: tabular-nums;
}

/* 帳戶資訊 ---------------------------------------------------------------- */
/* 身分列：頭像 + 姓名。姓名是這一頁的標題階，比品名階再大一階（--fs-title 的下一級），
   用 16px／600；頭像用主色淡底 + 既有 users icon，不放實心灰圓。 */.srf-root .srf-ac-id { display: flex; align-items: center; gap: 12px; }.srf-root .srf-ac-avatar {
  width: 40px; height: 40px; border-radius: 50%; flex: 0 0 40px;
  display: flex; align-items: center; justify-content: center;
  background: var(--primary-50); color: var(--cu-action);
}.srf-root .srf-ac-name { font-size: 16px; font-weight: 600; color: var(--cu-ink); min-width: 0; overflow-wrap: anywhere; }
/* 標籤＋值一行一項。標籤固定寬（不是 1fr），值靠左起排：值很長（長 Email）時會自己換行，
   標籤不會被擠掉。值不用 word-break:break-all（會從中文字中間硬切），用 overflow-wrap:anywhere。 */.srf-root .srf-ac-rows { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--gray-150); }.srf-root .srf-ai-row { display: grid; grid-template-columns: 56px 1fr; column-gap: 12px; align-items: baseline; }.srf-root .srf-ai-row + .srf-ai-row { margin-top: 10px; }.srf-root .srf-ai-label { font-size: var(--fs-sub); color: var(--cu-ink-2); letter-spacing: 0.02em; }.srf-root .srf-ai-value {
  font-size: var(--fs-name); color: var(--cu-ink); line-height: 1.5;
  min-width: 0; overflow-wrap: anywhere;
}
/* 變更密碼卡的段標：與 .ac-name 同階但收斂成說明色，不用 .section-title（那支是襯線 1.05 rem，
   放在卡內會比卡裡任何一行都重）。 */.srf-root .srf-ac-sec-title { font-size: var(--fs-name); font-weight: 600; color: var(--cu-ink); }.srf-root .srf-ac .srf-form-label { font-size: var(--fs-sub); color: var(--cu-ink-2); }

/* 2026-09-19 使用者拍板（C9 對齊 S2 後的兩處）：
   1. 購買頁（.pick-card）鎖住列照店家端整列變淡——蓋掉上方 .cu-page .pick-row.is-disabled 的「原因字維持深色」
      （那組只留給 C4 兌換浮層的列）。
   2. 選項列裡的「新客限定」徽章兩端一律細字（400）。 */.srf-root .srf-cu-page .srf-phone-shell.srf-cu-shell .srf-pick-card .srf-pick-row.srf-is-disabled { opacity: 0.5; }.srf-root .srf-cu-page .srf-phone-shell.srf-cu-shell .srf-pick-card .srf-pick-row.srf-is-disabled .srf-pr-title,
.srf-root .srf-cu-page .srf-phone-shell.srf-cu-shell .srf-pick-card .srf-pick-row.srf-is-disabled input[type="checkbox"] { opacity: 1; }.srf-root .srf-cu-page .srf-phone-shell.srf-cu-shell .srf-pick-card .srf-pr-sub { color: var(--gray-400); }.srf-root .srf-cu-page .srf-phone-shell.srf-cu-shell .srf-pick-card .srf-pick-row.srf-is-disabled .srf-pr-sub { opacity: 1; }.srf-root .srf-phone-shell .srf-pick-card .srf-badge.srf-bg-label-secondary.srf-is-dim { font-weight: 400; }

/* ===================== 服務轉讓（BL-027 概念稿快照新增；只用既有 primary＋灰階，無側邊色條） ===================== */
/* 展開區底下的「轉讓堂數 →」入口：連結本身沿用 .tk-redeem-link（同「兌換 →」），這裡只負責列的位置 */.srf-root .srf-tk-transfer-entry { display: flex; justify-content: flex-end; border-top: 1px solid var(--gray-100); margin-top: 2px; padding-top: 10px; }
/* 轉讓管理頁：全碼（大字）與碼卡 */.srf-root .srf-tm-fresh { text-align: center; }.srf-root .srf-tm-code { font-family: var(--font-serif); font-size: 28px; font-weight: 500; letter-spacing: 0.14em; color: var(--cu-action); line-height: 1.4; word-break: break-all; user-select: all; }.srf-root .srf-tm-code-sm { font-family: var(--font-serif); font-size: 16.8px; font-weight: 500; letter-spacing: 0.1em; color: var(--cu-action); }.srf-root .srf-tm-mask { color: var(--gray-300); }.srf-root .srf-tm-who { font-size: 14.72px; font-weight: 500; color: var(--gray-600); }.srf-root .srf-tm-code-card.srf-is-done .srf-tm-who { color: var(--gray-400); }.srf-root .srf-tm-code-card { overflow: hidden; max-height: 640px;
  transition: opacity 0.3s ease, max-height 0.3s ease, padding 0.3s ease, margin 0.3s ease; }.srf-root .srf-tm-code-card.srf-is-leaving { opacity: 0; max-height: 0; padding-top: 0; padding-bottom: 0; margin-top: -6px; }.srf-root .srf-tm-code-card.srf-is-clickable { cursor: pointer; }.srf-root .srf-tm-code-card.srf-is-open .srf-tm-code-sm { font-size: 20.8px; }
/* QR 為主、碼為輔：QR 約 160px 置中，碼小一級，兩顆文字鈕並排置中 */.srf-root .srf-tm-qr { display: flex; justify-content: center; margin: 0 auto 4px; }.srf-root .srf-tm-code.srf-tm-code-md { font-size: 20.8px; text-align: center; }.srf-root .srf-tm-copy-row { display: flex; justify-content: center; gap: 8px; margin-top: 10px; }.srf-root .srf-tm-code-card.srf-is-open .srf-tm-code-md { font-size: 20.8px; }.srf-root .srf-tm-enter-link { font-size: 12.8px; color: var(--cu-action); text-decoration: none; letter-spacing: 0.03em; }
