/* my 後台 — 冰白玻璃皮（版型 C：頂欄加抽屜）
 *
 * ⛔⛔ 這支的規矩：**不改任何一頁的 HTML**，只接管既有的 op-* class。
 *    所以 14 頁換皮零風險 —— 拿掉這支 <link> 就整個回到 OP 原色，一秒可回滾。
 *
 * ⛔ 必須放在每頁自己的 <style> **之後**（也就是 </head> 前最後一支），
 *    否則頁面內 style 會蓋掉這裡（症狀是「只有一半換到新樣式」）。
 *
 * tokens 跟 my逛逛 同一套，兩邊講同一種視覺語言。
 */
:root{
  --ink:#17181c; --ink-2:rgba(23,24,28,.72);
  /* ⛔ --ink-3 不可以再淡 —— 實測 .5 在玻璃底上只有 3.28:1，未達 WCAG AA 的 4.5。
     表頭、提示文字、手機浮島標籤都吃這個色。.62 約 4.6:1。 */
  --ink-3:rgba(23,24,28,.62);
  /* ⛔ --ink-4 只給邊框與裝飾，**不可以拿來寫字**（1.83:1，等於看不見）。 */
  --ink-4:rgba(23,24,28,.28); --line:rgba(23,24,28,.09);
  --bg:#eef0f4;
  --glass:linear-gradient(rgba(255,255,255,.72),rgba(255,255,255,.5));
  --solid:linear-gradient(rgba(255,255,255,.93),rgba(255,255,255,.84));
  --hi:inset 0 1px 0 rgba(255,255,255,.9);
  --sh:0 8px 24px rgba(23,24,28,.06); --sh-lg:0 18px 44px rgba(23,24,28,.10);
  --pink:#ff3b30;                     /* ⛔ 只給金額與強調，不當按鈕底色 */
  --ok:#1f9d6b; --warn:#b8860b; --info:#2c6fb5;
  --r:14px; --r-sm:9px; --nav-w:228px; --hdr:54px;

  /* OP 原本的變數留著 —— 有些頁面直接用 var(--op-xxx)，改掉會變透明看不見 */
  --op-primary:#17181c; --op-primary-h:#26272c;
  --op-success:#1f9d6b; --op-info:#2c6fb5; --op-warning:#b8860b; --op-danger:#e5533d;
  --op-bd:rgba(23,24,28,.09); --op-bg:#eef0f4; --op-text:#17181c;
  /* ⛔ hover 色與這兩個也要接管 —— 漏掉的話 OP 舊色會從變數縫裡漏回來
     （實測 dashboard 的 chip 邊框就是漏回 #53bee6 亮藍、卡片上緣是 #8fa9bd）。 */
  --op-success-h:#1a8a5e; --op-info-h:#255f9c; --op-warning-h:#9c7209;
  --op-danger-h:#c9432f; --op-teal:#17181c; --op-head:rgba(23,24,28,.28);
}

html,body{margin:0;padding:0}
body{
  background:var(--bg)!important; color:var(--ink);
  font:14px/1.65 -apple-system,"Segoe UI","Noto Sans TC","PingFang TC","Microsoft JhengHei",sans-serif;
  -webkit-font-smoothing:antialiased; min-height:100dvh;
}
body::before{                        /* 粉彩微光，固定不隨捲動 */
  content:''; position:fixed; inset:0; z-index:-2; pointer-events:none;
  background:
    radial-gradient(58vw 46vw at 12% -6%, rgba(173,196,255,.50), transparent 62%),
    radial-gradient(52vw 44vw at 92% 4%,  rgba(255,214,189,.45), transparent 60%),
    radial-gradient(48vw 40vw at 68% 96%, rgba(198,224,255,.38), transparent 62%);
}
/* ⛔ 顆粒要疊在**最上層**（my逛逛 是 z-index:90）。放 -1 的話只蓋到背景，
   面板（畫面上最大的面積）完全沒有顆粒 —— 那正是它要消掉的塑膠感來源。 */
body::after{
  content:''; position:fixed; inset:0; z-index:9999; pointer-events:none;
  opacity:.05; mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter><rect width='160' height='160' filter='url(%23n)'/></svg>");
}

/* ── 舊頂列交給 shell.js 重建，這裡先藏起來 ── */
.op-nav{display:none!important}
.op-testbar{
  background:linear-gradient(90deg,rgba(255,59,48,.14),rgba(255,59,48,.06))!important;
  color:#8e2b22!important; border:0!important; border-bottom:1px solid rgba(255,59,48,.18)!important;
  font-size:12.5px!important; padding:7px 16px!important; text-align:center;
  position:sticky; top:0; z-index:80; backdrop-filter:blur(20px);
}

/* ── 版面骨架（shell.js 建出來的） ── */
.sk-hd{
  position:sticky; top:0; z-index:60; display:flex; align-items:center; gap:11px;
  padding:0 16px; height:var(--hdr); background:var(--solid);
  backdrop-filter:blur(30px) saturate(1.8); -webkit-backdrop-filter:blur(30px) saturate(1.8);
  box-shadow:var(--hi),var(--sh);
}
/* ⛔ 不可以寫死高度 —— 測試條在手機上會換成兩行（實測 31px → 50px），
   寫死的話 sticky 頂欄會被壓在它下面切掉一半，而且畫面不報錯。
   實際高度由 shell.js 量出來寫進 --tb-h。 */
body.has-testbar .sk-hd{top:var(--tb-h, 31px)}
/* 跳到主內容：平常收在畫面外，Tab 到才浮出來。 */
.sk-skip{
  position:fixed; left:10px; top:-60px; z-index:9998;
  background:var(--ink); color:#fff; padding:9px 15px; border-radius:var(--r-sm);
  font-size:13px; text-decoration:none; transition:top .16s;
}
.sk-skip:focus{top:10px; outline:2px solid #fff; outline-offset:2px}
.sk-main:focus{outline:none}
.sk-brand{font-family:"Playfair Display",Georgia,serif; font-size:17px; letter-spacing:.045em}
.sk-body{display:flex; min-height:calc(100dvh - var(--hdr))}
.sk-side{
  width:var(--nav-w); flex:none; padding:14px 11px; position:sticky; top:var(--hdr);
  height:calc(100dvh - var(--hdr)); overflow-y:auto;
  transition:margin-left .24s cubic-bezier(0,0,.2,1);
}
body.sk-fold .sk-side{margin-left:calc(var(--nav-w) * -1)}
.sk-main{flex:1; min-width:0}

.sk-i{
  display:flex; align-items:center; gap:10px; padding:8px 12px; border-radius:10px;
  color:var(--ink-2); text-decoration:none; font-size:13.5px; white-space:nowrap;
  transition:background .12s,color .12s;
}
.sk-i svg{width:16px;height:16px;flex:none;stroke:currentColor;fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
.sk-i:hover{background:rgba(255,255,255,.62); color:var(--ink)}
.sk-i.on{background:var(--ink); color:#fff; box-shadow:0 4px 14px rgba(23,24,28,.22)}
.sk-sec{font-size:10.5px; letter-spacing:.14em; color:var(--ink-4); padding:15px 12px 5px; font-weight:600}
.sk-av{width:30px;height:30px;border-radius:50%;background:var(--ink);color:#fff;
  display:grid;place-items:center;font-size:12px;flex:none}

/* ⛔⛔ 頂欄的圖示鈕要自己一條 —— 底下 .btn 的 padding 帶 !important，
   會**蓋掉 inline style**（!important 的優先級高於行內樣式）。
   實測後果：32px 寬的方鈕扣掉左右各 13px，SVG 只剩 4px 寬 → 漢堡整個消失，
   而且畫面不報錯，看起來只是「那裡有個空按鈕」。 */
.sk-hd .btn{padding:0 12px!important}
.sk-hd .btn svg{width:16px!important; height:16px!important; flex:none;
  stroke:currentColor; fill:none; stroke-width:2; stroke-linecap:round}
#sk-burger{width:32px; padding:0!important; justify-content:center}

/* 手機底部浮島 —— 跟 my逛逛 同一個做法 */
.sk-tabs{
  position:fixed; left:11px; right:11px; bottom:calc(11px + env(safe-area-inset-bottom));
  height:58px; display:none; align-items:center; z-index:70; border-radius:18px;
  background:var(--solid); backdrop-filter:blur(30px) saturate(1.8);
  -webkit-backdrop-filter:blur(30px) saturate(1.8); box-shadow:var(--hi),var(--sh-lg);
}
.sk-tab{flex:1; display:flex; flex-direction:column; align-items:center; gap:3px;
  font-size:10.5px; color:var(--ink-3); text-decoration:none; padding:6px 0}
.sk-tab svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
.sk-tab.on{color:var(--ink)}

/* ── 內容容器 ── */
.op-wrap{padding:20px 24px 40px!important; max-width:none}
.op-title{
  font-family:"Noto Serif TC",serif; font-size:19px!important; font-weight:600!important;
  letter-spacing:-.01em; color:var(--ink)!important; margin:0 0 16px!important;
  padding:0!important; border:0!important; display:flex; align-items:center; gap:9px;
}
.op-title svg{opacity:.42}
.op-title-bar{margin-bottom:14px!important}

/* ── 面板＝玻璃卡 ── */
/* ⭐ 玻璃的「厚度」來自三樣：1px 白邊、下緣 inset 白線、分層外陰影。
   少了就只是一塊半透明白方塊（跟 my逛逛 的 .glass 對齊）。 */
.op-panel{
  background:var(--glass)!important; backdrop-filter:blur(30px) saturate(1.8);
  -webkit-backdrop-filter:blur(30px) saturate(1.8);
  border:1px solid rgba(255,255,255,.8)!important; border-radius:var(--r)!important;
  box-shadow:0 1px 2px rgba(23,24,28,.05), 0 14px 40px rgba(23,24,28,.10),
             inset 0 1px 0 rgba(255,255,255,.95),
             inset 0 -1px 0 rgba(255,255,255,.25)!important;
  margin-bottom:14px!important;
}
.op-panel-head{
  background:transparent!important; border:0!important;
  border-bottom:1px solid var(--line)!important;
  padding:13px 18px!important; font-size:13.5px!important; font-weight:600!important;
  color:var(--ink)!important; border-radius:var(--r) var(--r) 0 0!important;
}
.op-panel-body{padding:16px 18px!important}
.op-filters{
  background:transparent!important; border:0!important; padding:0!important;
  display:flex; gap:8px; flex-wrap:wrap; align-items:center;
}

/* ── 表格：資料密度高，玻璃要收斂 ── */
.op-tw{overflow-x:auto; border-radius:var(--r-sm); background:transparent!important}
.op-table{background:transparent!important; font-size:13px!important}
.op-table th{
  background:rgba(255,255,255,.55)!important; border:0!important;
  border-bottom:1px solid var(--line)!important;
  color:var(--ink-3)!important; font-size:11.5px!important; font-weight:600!important;
  letter-spacing:.06em; padding:10px 12px!important; text-align:left; white-space:nowrap;
  /* ⛔ 這裡不要寫 position:sticky —— .op-tw 的高度是 auto，垂直方向永遠不捲，
     sticky 從來不會觸發（實測 clientHeight === scrollHeight），是死碼。
     真要做得給 .op-tw 一個 max-height，而且 top 要閃開 sticky 頂欄。 */
  backdrop-filter:blur(12px);
}
.op-table td{
  border:0!important; border-bottom:1px solid var(--line)!important;
  color:var(--ink-2)!important; padding:11px 12px!important; white-space:nowrap;
}
.op-table td.wrap,.op-table td[data-wrap]{white-space:normal}
/* ⛔ 關掉 OP 的斑馬紋 —— `nth-child(odd){background:#f9f9f9}` 是**不透明**的，
   壓在半透明玻璃面板上會把它切成一條條白線，玻璃感直接消失。
   行的區隔交給下面那條 1px var(--line) 就夠。 */
.op-table tbody tr:nth-child(odd){background:transparent!important}
.op-table tbody tr{transition:background .1s}
.op-table tbody tr:hover{background:rgba(255,255,255,.55)!important}
.op-table tbody tr:last-child td{border-bottom:0!important}

/* ── 表單 ── */
/* ⛔ 用排除法不要列舉 —— 原本只列 text/number/date/search/email，
   漏掉 tel/password 讓 login.html 整頁保留 OP 樣式。 */
.op-inp,.op-sel,textarea,select,
input:not([type=checkbox]):not([type=radio]):not([type=button]):not([type=submit]):not([type=hidden]):not([type=file]){
  height:32px; padding:0 11px!important; border:1px solid var(--line)!important;
  border-radius:var(--r-sm)!important; background:rgba(255,255,255,.78)!important;
  font-size:13px!important; color:var(--ink)!important; outline:none; max-width:100%;
  font-family:inherit; transition:border-color .12s,background .12s;
}
textarea{height:auto; padding:9px 11px!important; line-height:1.6}
.op-inp:focus,.op-sel:focus,input:focus,select:focus,textarea:focus,.op-ta:focus{
  border-color:var(--ink-4)!important; background:#fff!important;
  /* ⛔ 一定要覆蓋 box-shadow —— op.css 的 focus 光暈是 OP 亮藍 rgba(102,175,233,.4)，
     只改 border-color 的話按下去還是會亮出一圈藍。 */
  box-shadow:0 0 0 3px rgba(23,24,28,.08)!important;
}
.op-inp-xs{height:27px!important; font-size:12px!important}
.op-sel{padding-right:26px!important}
input[type=checkbox],input[type=radio]{accent-color:var(--ink); width:15px; height:15px}

/* ── 按鈕：主 CTA 一律墨黑，⛔ 不用粉紅 ── */
.btn{
  display:inline-flex; align-items:center; gap:6px; height:32px; padding:0 13px!important;
  border:1px solid var(--line)!important; border-radius:var(--r-sm)!important;
  background:rgba(255,255,255,.72)!important; color:var(--ink)!important;
  font-size:13px!important; line-height:1; cursor:pointer; text-shadow:none!important;
  box-shadow:none!important; transition:.12s; white-space:nowrap; font-family:inherit;
}
.btn:hover{background:#fff!important; box-shadow:var(--sh)!important}
.btn-primary,.btn-teal{background:var(--ink)!important; color:#fff!important; border-color:var(--ink)!important}
.btn-primary:hover,.btn-teal:hover{background:#26272c!important; color:#fff!important}
.btn-success{background:rgba(31,157,107,.12)!important; color:var(--ok)!important; border-color:rgba(31,157,107,.26)!important}
.btn-info{background:rgba(44,111,181,.12)!important; color:var(--info)!important; border-color:rgba(44,111,181,.26)!important}
.btn-warning{background:rgba(184,134,11,.13)!important; color:var(--warn)!important; border-color:rgba(184,134,11,.28)!important}
.btn-danger{background:rgba(229,83,61,.11)!important; color:#c0392b!important; border-color:rgba(229,83,61,.26)!important}
.btn-sm{height:29px!important; font-size:12.5px!important; padding:0 11px!important}
.btn-xs{height:25px!important; font-size:12px!important; padding:0 9px!important}
.btn[disabled],.btn:disabled{opacity:.42; cursor:not-allowed}

/* ── 狀態標籤 ── */
.st{
  display:inline-flex; align-items:center; height:22px; padding:0 9px!important;
  border-radius:99px!important; font-size:11.5px!important; font-weight:600;
  background:rgba(23,24,28,.07)!important; color:var(--ink-2)!important; border:0!important;
}
.st-ok{background:rgba(31,157,107,.13)!important; color:var(--ok)!important}
.st-sub{color:var(--ink-3)!important; font-size:11px!important}

/* ── 提示文字 ── */
.op-hint,.op-note,.op-tip,.op-help{
  color:var(--ink-3)!important; font-size:12px!important; background:transparent!important;
  border:0!important;
}
.op-note,.op-tip{
  background:rgba(255,255,255,.5)!important; border-radius:var(--r-sm)!important;
  padding:10px 13px!important; line-height:1.7; border-left:2px solid var(--ink-4)!important;
}
.op-thumb{border-radius:7px!important; border:1px solid var(--line)!important}
.op-pager{display:flex; gap:5px; align-items:center; padding:12px 0 0!important}

/* 金額用品牌紅 —— 這是全站唯一用紅的地方 */
.money,.op-money,td.money{color:var(--pink)!important; font-weight:600}
.num,td .num{font-variant-numeric:tabular-nums}

/* ── modal ── */
.op-modal-head{
  border:0!important; border-bottom:1px solid var(--line)!important;
  padding:14px 18px!important; font-weight:600; background:transparent!important;
}
.op-modal-body{padding:16px 18px!important}

/* ══════════════════════════════════════════════════════════════════
 *  各頁自己定義的元件
 *  ⛔ 這一區是「換到一半」最集中的地方 —— 上面接管的是 op.css 的共用 class，
 *     但每一頁的 <style> 還各自定義了 chip / tabs / card / modal / tag …
 *     不接管的話那些元件會留著 Bootstrap 3 的舊色與方角。
 *  ⭐ 全部只靠 CSS，不動任何 HTML（維持「拿掉兩行即回滾」的性質）。
 * ══════════════════════════════════════════════════════════════════ */

/* ── 篩選 chip（dashboard / shop）── */
.op-chip{
  display:inline-flex; align-items:center; gap:5px; height:28px; padding:0 12px!important;
  border-radius:99px!important; font-size:12.5px!important;
  background:rgba(255,255,255,.7)!important; border:1px solid var(--line)!important;
  color:var(--ink-2)!important; cursor:pointer; transition:.12s;
}
.op-chip:hover{background:#fff!important}
.op-chip.on,.op-chip.active{
  background:var(--ink)!important; color:#fff!important; border-color:var(--ink)!important;
}

/* ── 分頁籤（dashboard / members / payments / settings / shop）
      ⛔ Bootstrap 3 的 nav-tabs 是「選中頁籤用白色下邊框騙出缺口」，
         在玻璃底上那條白線會很明顯 → 改成底線式。 ── */
.op-tabs{
  background:transparent!important; border:0!important;
  border-bottom:1px solid var(--line)!important; display:flex; gap:2px; padding:0!important;
}
.op-tab{
  background:transparent!important; border:0!important; border-radius:0!important;
  padding:9px 14px!important; font-size:13.5px!important; color:var(--ink-3)!important;
  cursor:pointer; position:relative; transition:color .12s;
}
.op-tab:hover{color:var(--ink)!important}
.op-tab.on,.op-tab.active{
  color:var(--ink)!important; font-weight:600; background:transparent!important;
}
.op-tab.on::after,.op-tab.active::after{
  content:''; position:absolute; left:10px; right:10px; bottom:-1px; height:2px;
  background:var(--ink); border-radius:2px;
}

/* ── 卡片（dashboard / bonus / members）── */
.op-card,.op-cards > *{
  background:var(--glass)!important; backdrop-filter:blur(30px) saturate(1.8);
  -webkit-backdrop-filter:blur(30px) saturate(1.8);
  border:1px solid rgba(255,255,255,.8)!important; border-radius:var(--r)!important;
  box-shadow:0 1px 2px rgba(23,24,28,.05),0 8px 24px rgba(23,24,28,.06),
             inset 0 1px 0 rgba(255,255,255,.95)!important;
}
/* ⛔ OP 用「卡片上緣一條彩色帶」區分類型，那是它的色票語彙 → 收斂成墨色細線 */
.op-card::before,.op-card::after{background:var(--ink-4)!important}
.op-card-head,.op-card-foot{background:transparent!important; border-color:var(--line)!important}
.op-card-head{border-bottom:1px solid var(--line)!important}
.op-card-foot{border-top:1px solid var(--line)!important}

/* ── 彈窗（accounts / groups / invoices / payments / refunds / settings / shop）── */
.op-mask,.op-modal-mask{
  background:rgba(23,24,28,.34)!important;
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
}
.op-modal,.op-modal-box,.op-modal > .box{
  background:linear-gradient(rgba(255,255,255,.94),rgba(255,255,255,.88))!important;
  backdrop-filter:blur(30px) saturate(1.6); -webkit-backdrop-filter:blur(30px) saturate(1.6);
  border:1px solid rgba(255,255,255,.8)!important; border-radius:var(--r)!important;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.95),0 18px 44px rgba(23,24,28,.18)!important;
}
.op-modal-foot{background:transparent!important; border-top:1px solid var(--line)!important;
  padding:14px 18px!important}

/* ── 狀態標籤：等級/檔期/badge（bonus / campaigns / orders）
      ⛔ 一律低飽和底 + 深色字，不要 Bootstrap 的實心色塊 ── */
.op-tag,.op-tt,.badge,.day-tag,.pill{
  display:inline-flex; align-items:center; height:22px; padding:0 10px!important;
  border-radius:99px!important; font-size:11.5px!important; font-weight:600;
  background:rgba(23,24,28,.07)!important; color:var(--ink-2)!important; border:0!important;
}
.pill.now,.badge.now,.op-tag.on{           /* 「進行中」—— 唯一該亮起來的狀態 */
  background:rgba(31,157,107,.14)!important; color:var(--ok)!important;
}
.badge.live,.pill.live{background:rgba(255,59,48,.12)!important; color:var(--pink)!important}
.tag.mall,.op-tag.mall{
  background:rgba(184,134,11,.13)!important; color:var(--warn)!important; border:0!important;
}
.cp-code,.op-code,code{
  background:rgba(23,24,28,.06)!important; color:var(--ink-2)!important;
  border-radius:6px!important; padding:1px 6px!important; border:0!important;
  font-variant-numeric:tabular-nums;
}

/* ── 全功能選單的模組磚（index）── */
.mod{
  background:var(--glass)!important; backdrop-filter:blur(30px) saturate(1.8);
  -webkit-backdrop-filter:blur(30px) saturate(1.8);
  border:1px solid rgba(255,255,255,.8)!important; border-radius:var(--r)!important;
  box-shadow:var(--hi),var(--sh)!important; transition:transform .16s,box-shadow .16s;
}
.mod:hover{transform:translateY(-2px); box-shadow:var(--hi),var(--sh-lg)!important;
  border-color:rgba(255,255,255,.95)!important}

/* ── 其餘散落的淺色底（統一換成玻璃）── */
.op-fn,.op-payicon,.op-bulk,.bulkbar,.op-up,.op-toolbar,.op-fold-head,
.op-batch,.op-warn,.op-demo-note,.op-acc{
  background:rgba(255,255,255,.55)!important; border-color:var(--line)!important;
  color:var(--ink-2)!important; border-radius:var(--r-sm)!important;
}
.op-alert-danger{
  background:rgba(255,59,48,.08)!important; border:0!important;
  border-left:2px solid var(--pink)!important; color:#8e2b22!important;
  border-radius:var(--r-sm)!important; padding:11px 14px!important;
}

/* ── 金額用品牌紅 ──
   ⛔ 全站沒有任何 class="money"，所以只靠 .money 那條規則命中 0 個元素。
      表格裡的金額欄實際是 .num，各頁 inline 還寫死 #c9302c（Bootstrap 深紅）。 */
.op-table td.num,.op-table td .num{color:var(--pink)!important; font-weight:600}
.op-table td.ctr .num,.op-table th .num{color:inherit!important; font-weight:inherit}

/* ── 登入頁（login.html 原本整頁沒換到）── */
.box{
  background:var(--glass)!important; backdrop-filter:blur(30px) saturate(1.8);
  -webkit-backdrop-filter:blur(30px) saturate(1.8);
  border:1px solid rgba(255,255,255,.8)!important; border-radius:var(--r)!important;
  box-shadow:0 1px 2px rgba(23,24,28,.05),0 18px 44px rgba(23,24,28,.10),
             inset 0 1px 0 rgba(255,255,255,.95)!important;
}
.box h1{font-family:"Noto Serif TC",serif; font-weight:600; color:var(--ink)}
.sub{background:var(--ink)!important; color:#fff!important; border:0!important;
  border-radius:var(--r-sm)!important}
.sub:hover{background:#26272c!important}

/* ── toast ──
   ⛔ 各頁自己定的位置跟新骨架打架：
      invoices 的 top:60px 落在 sticky 頂欄帶內（頂欄底緣 54~85）直接壓在頂欄上；
      accounts/groups 的 bottom:16px 在手機會壓到底部浮島（浮島 z-index 70）。
   ⭐ 統一改成「桌機右下、手機浮島上方」，並確保 z-index 在浮島之上。 */
.op-toast{
  top:auto!important; left:auto!important; right:18px!important;
  bottom:calc(18px + env(safe-area-inset-bottom))!important; z-index:9500!important;
  background:linear-gradient(rgba(255,255,255,.94),rgba(255,255,255,.88))!important;
  backdrop-filter:blur(24px) saturate(1.6); -webkit-backdrop-filter:blur(24px) saturate(1.6);
  border:1px solid rgba(255,255,255,.8)!important; border-radius:var(--r-sm)!important;
  color:var(--ink)!important;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.95),0 12px 32px rgba(23,24,28,.16)!important;
  padding:11px 16px!important; font-size:13px!important;
  /* ⛔ 一定要接管 transform —— bonus.html 用 translateX(-50%) 置中，
     我改了 left/right 卻不管 transform 的話，那顆 toast 會往左偏半個寬度。
     各頁的顯示狀態 class 不統一（accounts 用 .is-on、bonus 用 .on），兩個都收。 */
  transform:translateY(10px)!important;
}
.op-toast.on,.op-toast.is-on,.op-toast.show{transform:translateY(0)!important}

/* ⚠️ 註記：.op-panel 有 backdrop-filter，會成為獨立的堆疊環境 ——
   之後若有人在面板裡放 position:fixed 的東西，它會被關在面板裡出不來。 */

/* ── 手機 ── */
/* ══════════════════════════════════════════════════════════════════
   手機底欄：分組面板 ＋ 長按加入最愛（2026-09-09 亮拍板）
   ⛔ 只新增，沒有改動上面任何一條既有規則。
   ⛔ 桌機不存在這一組 —— 側欄本來就看得到全部 17 項，面板是多餘的。
   ══════════════════════════════════════════════════════════════════ */
.sk-sheet{
  display:none;                                   /* 桌機不存在，手機才 block */
  position:fixed; left:11px; right:11px; z-index:80;
  /* ⛔ 面板要停在**底欄上方**，不可以蓋住它 —— 蓋住的話手機上唯一的關法
     就只剩「點上方那一小條遮罩」（沒有 Esc 鍵）。停在上面的話「更多」
     一直看得見，再按一次就收，跟打開時是同一顆鈕。
     58(底欄高) + 11(底欄 bottom) + 10(間距) = 79 */
  bottom:calc(79px + env(safe-area-inset-bottom));
  border-radius:20px; background:var(--solid); box-shadow:var(--hi),var(--sh-lg);
  backdrop-filter:blur(30px) saturate(1.8); -webkit-backdrop-filter:blur(30px) saturate(1.8);
  padding:14px 13px 12px; overflow:auto;
  /* ⛔ 高度要扣掉**頂欄 ＋ 測試條**，不能寫死一個數字 ——
     實測寫 62px 時面板頂端頂到 y=62，而測試條佔到 56px、頂欄再 54px，
     結果面板蓋住頂欄、遮罩可點區只剩 16px（幾乎按不到）。
     ⭐ `--tb-h` 是 shell.js 實際量出來的測試條高度（它會換行變兩倍高），
        正式上線沒有測試條時 fallback 0px，同一條式子兩種情境都對。 */
  /* 最後那個 44px 是**留給遮罩的可點區** —— 手指的最小觸控目標就是 44px。
     ⛔ 我一開始留 16px，實測「點面板上方關掉」那一下幾乎按不到（會點到頂欄）。
     面板本來就要捲，多捲 28px 無感，但那 44px 是唯一的容錯出口。 */
  /* ⛔ `100dvh` 不是 `100vh` —— 手機網址列收合時 vh **不會變**，
     面板會比實際可視高度多算 60~80px，底部被切掉一截。 */
  max-height:calc(100dvh - 79px - var(--hdr) - var(--tb-h, 0px) - 44px
                  - env(safe-area-inset-bottom));
  transform:translateY(calc(100% + 82px));        /* 收起來時要連底欄一起讓過去 */
  transition:transform .26s cubic-bezier(0,0,.2,1);
}
.sk-sheet.up{transform:translateY(0)}
.sk-grab{width:36px;height:4px;border-radius:9px;background:var(--ink-4);margin:0 auto 12px}
.sk-stip{
  font-size:11px; color:var(--ink-3); background:rgba(23,24,28,.05);
  border-radius:9px; padding:6px 10px; margin-bottom:11px; line-height:1.5;
  text-align:center;                                /* 只有一句話，置中比較安靜 */
}
.sk-stip b{color:var(--ink)}
.sk-sgrp{font-size:10.5px; font-weight:800; color:var(--ink-3); letter-spacing:.08em;
  margin:12px 0 7px}
.sk-sgrp:first-of-type{margin-top:0}
.sk-sgrid{display:grid; grid-template-columns:1fr 1fr; gap:7px}
.sk-sitem{
  display:flex; align-items:center; gap:8px; padding:10px; border-radius:11px;
  background:rgba(255,255,255,.62); border:1px solid var(--line);
  font-size:12.5px; color:var(--ink); text-decoration:none; min-width:0;
  position:relative; overflow:hidden;
  /* ⛔ 長按會叫出系統的「複製／分享」選單，一定要關掉，不然長按等於沒用 */
  -webkit-user-select:none; user-select:none; -webkit-touch-callout:none;
  touch-action:manipulation; transition:transform .12s, border-color .16s;
}
.sk-sitem svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round;flex:none;color:var(--ink-3)}
.sk-sitem span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sk-sitem.fav{border-color:var(--ink); background:rgba(255,255,255,.92)}
.sk-sitem.fav svg{color:var(--ink)}
.sk-sitem .sk-dot{margin-left:auto;width:6px;height:6px;border-radius:99px;
  background:var(--ink);flex:none}
.sk-sitem.press{transform:scale(.965)}
.sk-sitem .sk-prog{position:absolute;left:0;bottom:0;height:2.5px;width:0;
  background:var(--ink);border-radius:0 3px 3px 0}
.sk-sitem.press .sk-prog{width:100%;transition:width .55s linear}
.sk-scrim{
  display:none; position:fixed; inset:0; z-index:75; background:rgba(23,24,28,.24);
  /* ⛔ 遮罩不可以蓋到底欄 —— 蓋住的話底欄「看得見但點不到」：
     想從面板直接跳去「訂單」會點在遮罩上，結果只是把面板關掉。
     ⚠️ 這種 bug 用座標檢查看不出來（z-index 不影響 getBoundingClientRect），
        要用 document.elementFromPoint() 實際問「這個點會打到誰」才抓得到。
     69 = 58(底欄高) + 11(底欄 bottom) */
  bottom:calc(69px + env(safe-area-inset-bottom));
  backdrop-filter:blur(2px); -webkit-backdrop-filter:blur(2px);
  opacity:0; pointer-events:none; transition:opacity .22s;
}
.sk-scrim.on{opacity:1; pointer-events:auto}
.sk-toast{
  display:none; position:fixed; left:14px; right:14px; z-index:88;
  bottom:calc(82px + env(safe-area-inset-bottom));
  background:var(--ink); color:#fff; border-radius:11px; padding:10px 13px;
  font-size:11.5px; line-height:1.55; box-shadow:var(--sh-lg);
  opacity:0; transform:translateY(8px); pointer-events:none; transition:.2s;
}
.sk-toast.on{opacity:1; transform:translateY(0)}
@media(max-width:860px){
  .sk-sheet, .sk-scrim, .sk-toast{display:block}
}

@media(max-width:860px){
  .sk-side{
    position:fixed; left:0; top:var(--hdr); z-index:75; background:var(--solid);
    backdrop-filter:blur(30px) saturate(1.8); -webkit-backdrop-filter:blur(30px) saturate(1.8);
    box-shadow:var(--hi),var(--sh-lg); border-radius:0 var(--r) var(--r) 0;
    margin-left:calc(var(--nav-w) * -1);
  }
  body.sk-open .sk-side{margin-left:0}
  /* ⛔ top 推下去，height 也要跟著扣 —— 不扣的話抽屜比視窗高，
     最底下的「登出」會被推出畫面，捲不到也點不到（實測 375x667 差 17px）。 */
  body.has-testbar .sk-side{top:calc(var(--hdr) + var(--tb-h, 31px));
    height:calc(100dvh - var(--hdr) - var(--tb-h, 31px))}
  .sk-tabs{display:flex}
  /* ⛔ 浮島的 bottom 有 env(safe-area)，內容的 padding 也要有，
     否則瀏海機上浮島會壓到最後一列（safe-area ≈34px > 預留的 92-69=23px）。 */
  .op-wrap{padding:14px 12px calc(92px + env(safe-area-inset-bottom))!important}
  /* 手機：toast 要停在底部浮島**之上**，不然會被浮島壓住看不到 */
  .op-toast{left:12px!important; right:12px!important;
    bottom:calc(80px + env(safe-area-inset-bottom))!important}

  /* ⛔ 篩選區在窄螢幕會錯位 —— HTML 是「標籤 span、輸入框」平鋪，
     flex-wrap 一換行就把標籤跟它的欄位拆到不同行（看起來像標錯欄位）。
     解法：標籤一律獨佔整行，欄位滿寬。
     ⛔ 欄位上有 inline 的 min-width:148px，所以這裡要 !important 才蓋得過。 */
  .op-filters{display:grid!important; grid-template-columns:1fr 1fr; gap:7px;
    align-items:center}
  .op-filters > .op-hint{grid-column:1/-1; font-size:11.5px; margin:2px 0 -2px}
  .op-filters > .op-inp,.op-filters > .op-sel,.op-filters > input,.op-filters > select{
    width:100%!important; min-width:0!important}
  .op-filters > .btn{width:100%}
  .op-filters > span[style*="margin-left:auto"]{display:none}   /* 桌機用的推擠器 */
  .op-panel-body{padding:13px 13px!important}
  .op-title{font-size:17px!important}
}
@media(prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
