/* [Claude Code 2026-06-24] wolves_slot_rush client 樣式（霓虹深色主題；通用渲染器共用） */
/* [claude code] 2026-07-10 梨園變臉：新增觀眾喝采加倍的樣式（fo-cheer / fo-mult-big / #winMeter.fo-ramp） */
:root {
  --bg: #0d0f1a;
  --surface: #171a2b;
  --surface-2: #1f2336;
  --border: #2c3150;
  --text: #e8eaf6;
  --text-soft: #9aa0c0;
  --neon: #ff3df0;
  --neon-2: #36e0ff;
  --gold: #ffd24a;
  --win: #ffe169;
}
/* ---- theme 驅動配色：改 config 的 theme 即換整套風格（新增主題在這加一組）----
   覆寫 --neon/--neon-2 這對主色 → hero/卡片/按鈕/外框整體換色，無需改 code。 */
body[data-theme="neon"]   { --neon: #ff3df0; --neon-2: #36e0ff; }
body[data-theme="lucky777"] { --neon: #ffb31a; --neon-2: #ff4d6d; --gold: #ffd24a; }
body[data-theme="egypt"]  { --neon: #e8b14a; --neon-2: #ffd24a; --gold: #ffe08a; }
body[data-theme="ocean"]  { --neon: #34d3ff; --neon-2: #5ad1ff; }
body[data-theme="fruit"]  { --neon: #ff5f6d; --neon-2: #ffb84a; }
body[data-theme="oriental"] { --neon: #ff3838; --neon-2: #ffcf4a; }
body[data-theme="candy"] { --neon: #ff5fa2; --neon-2: #a06bff; --gold: #ffd24a; }
body[data-theme="pirate"] { --neon: #d4a017; --neon-2: #1f8a70; --gold: #ffd24a; }
body[data-theme="prism"] { --neon: #36e0ff; --neon-2: #b06bff; --gold: #ffe08a; }
body[data-theme="galaxy"] { --neon: #7b6bff; --neon-2: #36e0ff; --gold: #ffe08a; }
body[data-theme="frost"] { --neon: #5ad1ff; --neon-2: #aef0ff; --gold: #d6f3ff; }
body[data-theme="arcane"] { --neon: #a06bff; --neon-2: #d7b3ff; --gold: #ffe08a; }
body[data-theme="honey"] { --neon: #e8920c; --neon-2: #ffc94d; --gold: #ffd766; }
body[data-theme="meadow"] { --neon: #8bc34a; --neon-2: #ffd54a; --gold: #ffe08a; }
/* [Claude Code 2026-07-06] 賓果主題（藍紫 + 金球）*/
body[data-theme="bingo"] { --neon: #5b8bff; --neon-2: #b06bff; --gold: #ffd24a; }
/* [claude code] 2026-07-11 夜市麻將主題（麻將綠 + 金牌）*/
body[data-theme="mahjong"] { --neon: #2fa46a; --neon-2: #46c98a; --gold: #ffcf3a; }
/* [claude code] 2026-07-11 招財彈珠：金 + 桃紅賭場感 */
body[data-theme="plinko"] { --neon: #ffb31a; --neon-2: #ff5d8f; --gold: #ffd24a; }
/* [claude code] 2026-07-11 狼群狩獵（wolf_hunt / 移動百搭）：狩獵夜色（冷藍月光 + 血月金） */
body[data-theme="wolf"] { --neon: #6ea0d8; --neon-2: #9fc2e8; --gold: #ffcf6a; }
/* [claude code] 2026-07-14 尋寶掃雷（treasure_mines / mines）：寶石翠綠 + 金 */
body[data-theme="mines"] { --neon: #2bd4a8; --neon-2: #36e0ff; --gold: #ffd24a; }
/* [claude code] 2026-07-29 闖關奪寶（gem_quest / gemquest）：地城打怪（血橙 + 魔晶紫） */
body[data-theme="gemquest"] { --neon: #ff6a4d; --neon-2: #b06bff; --gold: #ffd24a; }
/* [claude code] 2026-07-14 神秘面具（mystery_mask / mystery）：神秘紫 + 面具金 */
body[data-theme="mask"] { --neon: #a06bff; --neon-2: #ff6bd0; --gold: #ffd24a; }
/* [claude code] 2026-07-18 招財貓（lucky_cat / holdwin）：日式招財朱紅 + 小判金 */
body[data-theme="cat"] { --neon: #e23b3b; --neon-2: #ffcf4a; --gold: #ffd24a; }
/* [claude code] 2026-07-19 能量核心（energy_core / charge）：科技電光藍青 + 能量金 */
body[data-theme="energy"] { --neon: #36e0ff; --neon-2: #7b6bff; --gold: #ffe08a; }
/* 蓄能槽進度條：蓄能中電光藍，放電中（.dis）轉電光黃橙 */
.pm-fill.charge { background: linear-gradient(90deg, #2bd4ff, #7b6bff); }
.pm-fill.charge.dis { background: linear-gradient(90deg, #ffd24a, #ff8a3b); }
#chargeTray.discharging .pm-num { color: #ffcf4a; }
/* 放電：JQK 被電掉的閃電效果 + 掉落補位 */
@keyframes cgZap { 0%{filter:brightness(3) drop-shadow(0 0 8px #7be0ff);transform:scale(1.15)} 50%{filter:brightness(2) drop-shadow(0 0 12px #ffd24a)} 100%{filter:brightness(1);transform:scale(.4);opacity:.15} }
.cell.cg-zap .glyph { animation: cgZap .34s ease-in forwards; }
@keyframes cgDrop { 0%{transform:translateY(-46px);opacity:.2} 100%{transform:translateY(0);opacity:1} }
/* [claude code] 2026-08-15 v2.94 掉落逐排錯開：延遲由 JS 寫進 `--cg-d`（上面先落、下面後落）。
   `both` 是必要的 —— 沒有它，延遲那段時間格子會先用最終樣子顯示出來，等於還是「直接冒出來」。 */
.cell.cg-drop .glyph { animation: cgDrop .46s cubic-bezier(.3,.7,.4,1) var(--cg-d, 0ms) both; }
/* [claude code] 2026-07-19 蓄能收集特效：⚡ 從盤面飛進蓄能槽 + ⚡ 格收集脈動 */
.cg-fly { position: fixed; z-index: 60; font-size: 26px; transform: translate(-50%,-50%); pointer-events: none;
  filter: drop-shadow(0 0 8px #7be0ff) drop-shadow(0 0 4px #ffd24a); }
@keyframes cgChargePop { 0%{filter:brightness(1)} 40%{filter:brightness(2.6) drop-shadow(0 0 12px #7be0ff);transform:scale(1.22)} 100%{filter:brightness(1);transform:scale(1)} }
.cell.cg-charge-pop .glyph { animation: cgChargePop .5s ease; }
/* [claude code] 2026-07-19 放電閃電：從蓄能槽方向拉虛線電擊 JQK */
.cg-dash { position: fixed; height: 0; border-top: 2px dashed #ffd24a; transform-origin: 0 0;
  box-shadow: 0 0 7px #ffd24a, 0 0 3px #7be0ff; z-index: 58; pointer-events: none; animation: cgDash .38s ease-out; }
@keyframes cgDash { 0%{opacity:0;filter:brightness(2.4)} 25%{opacity:1} 100%{opacity:0} }
/* 細單：能量核心盤面著色（廢料 JQK 變暗、⚡ 電光） */
.dt-scell.k-low { opacity: .45; }
.dt-scell.k-charge { background: rgba(54,224,255,.20); border-color: rgba(120,224,255,.6); box-shadow: inset 0 0 0 1px rgba(120,224,255,.5); }
/* [claude code] 2026-08-15 星宮聚合細單：⛎ 蛇夫座（base 的觸發來源 / 免費期的萬能宮）在細單上要一眼認得出 */
.dt-scell.k-zscat { background: rgba(185,140,255,.22); border-color: rgba(185,140,255,.65); box-shadow: inset 0 0 0 1px rgba(185,140,255,.55); }
/* [claude code] 2026-08-17 細單盤面：**被算進去的格**（每組一個顏色 + 左上角掛該組圖示）。
   使用者：「細單並沒有標注是中了什麼」—— 看得到「集滿 1 組」卻對不出是盤上哪幾格。 */
/* [claude code] 2026-08-17 免費里程條（只有 `zodiac.miles.need > 0` 的款會畫；星宮聚合沒有） */
.zod-miles { display: flex; align-items: center; gap: 8px; padding: 3px 10px; font-size: 12px; }
.zod-miles .zm-bar { flex: 1; height: 6px; border-radius: 999px; background: rgba(255,255,255,.12); overflow: hidden; }
.zod-miles .zm-bar i { display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, #7ad2ff, #34e0ff); transition: width .35s ease; }
.zod-miles.full .zm-bar i { background: linear-gradient(90deg, #ffe9a6, var(--gold)); }
.zod-miles.full .zs-total { color: var(--gold); font-weight: 900; }
.dt-scell.zd-hit { position: relative; }
.dt-scell.zd-g0 { background: rgba(255,90,95,.20); box-shadow: inset 0 0 0 2px rgba(255,120,120,.85); }
.dt-scell.zd-g1 { background: rgba(60,190,255,.20); box-shadow: inset 0 0 0 2px rgba(90,205,255,.85); }
.dt-scell.zd-g2 { background: rgba(90,225,140,.20); box-shadow: inset 0 0 0 2px rgba(120,235,165,.85); }
.dt-scell.zd-g3 { background: rgba(255,205,80,.20); box-shadow: inset 0 0 0 2px rgba(255,215,110,.85); }
.dt-scell .zd-tag { position: absolute; top: 1px; left: 2px; font-size: 9px; line-height: 1; pointer-events: none; }
.dt-slot.dt-charge .dt-scell { font-size: 16px; }
.dt-fs-head { font-size: 12px; color: var(--text-mute); text-align: center; margin: 6px 0 2px; }
* { box-sizing: border-box; }
body {
  margin: 0; background: radial-gradient(circle at 50% -10%, #1a1d36 0%, var(--bg) 60%);
  color: var(--text); font-family: -apple-system, "Segoe UI", "Microsoft JhengHei", sans-serif;
  min-height: 100vh;
}
.loading { position: fixed; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px; background: var(--bg); z-index: 50; color: var(--text-soft); font-size: 18px;
  transition: opacity .25s ease; }
/* 777 拉霸機 loading：金框機台 + 三軸符號往上滾（不旋轉） */
.ld-machine { display: flex; gap: 6px; padding: 8px 10px; border-radius: 14px;
  background: linear-gradient(#171a29, #0c0e18); border: 2px solid var(--gold, #ffd24a);
  box-shadow: 0 0 22px rgba(255,210,74,.35), inset 0 0 12px rgba(0,0,0,.5); }
.ld-reel { position: relative; width: var(--reel-w, 38px); height: var(--reel-h, 48px); overflow: hidden; border-radius: 7px;
  background: linear-gradient(#0a0c16, #1b1f30); box-shadow: inset 0 0 8px rgba(0,0,0,.6); }
/* 上下淡出遮罩，凸顯中間那格 */
.ld-reel::before, .ld-reel::after { content: ""; position: absolute; left: 0; right: 0; height: var(--reel-fade, 14px); z-index: 2; pointer-events: none; }
.ld-reel::before { top: 0; background: linear-gradient(#0c0e18, transparent); }
.ld-reel::after { bottom: 0; background: linear-gradient(transparent, #0c0e18); }
.ld-strip { display: flex; flex-direction: column; align-items: center; will-change: transform; }
/* span 高度 = reel 視窗高度（剛好一格）→ translateY(-50%) 無縫迴圈不受尺寸影響 */
.ld-strip span { height: var(--reel-h, 48px); display: flex; align-items: center; justify-content: center;
  font-size: var(--reel-fs, 26px); font-weight: 900; line-height: 1; }
.ld-strip span.s7 { color: var(--gold, #ffd24a); text-shadow: 0 0 8px rgba(255,210,74,.7); font-family: "Arial Black", system-ui, sans-serif; }
/* 三軸不同速度，像真拉霸各自轉；strip 內容重複兩次 → translateY(-50%) 無縫接回 */
.ld-reel:nth-child(1) .ld-strip { animation: ldRoll .55s linear infinite; }
.ld-reel:nth-child(2) .ld-strip { animation: ldRoll .72s linear infinite; }
.ld-reel:nth-child(3) .ld-strip { animation: ldRoll .9s linear infinite; }
/* 由上往下滾：strip 內容重複兩次，從 -50% 滑到 0 → 符號往下跑、無縫接回 */
@keyframes ldRoll { from { transform: translateY(-50%); } to { transform: translateY(0); } }
.loading-text { font-size: 15px; letter-spacing: 3px; color: var(--text-mute, #8b91a3);
  animation: ldText 1.2s ease-in-out infinite; }
@keyframes ldText { 0%,100% { opacity: .45; } 50% { opacity: 1; } }

.topbar { display: flex; justify-content: space-between; align-items: center; padding: 12px 20px;
  background: rgba(23,26,43,.9); border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 10; }
.brand { font-size: 20px; font-weight: 800; letter-spacing: .5px;
  text-shadow: 0 0 12px var(--neon); }
.ver { font-size: 11px; color: var(--text-soft); text-shadow: none; }
.top-right { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 10px; }
.coins-box { background: var(--surface-2); padding: 6px 14px; border-radius: 999px; font-weight: 700; color: var(--gold); }
/* [Claude Code 2026-07-08] 遊戲中把頂列（右上試玩區）的餘額收起 —— 盤面正上方 .wm-balance 已置中顯示餘額，不再擠在右上角試玩標旁 */
body[data-view="game"] .coins-box { display: none; }
.game-tools { display: inline-flex; align-items: center; gap: 6px; }

.btn-ghost { background: transparent; color: var(--text); border: 1px solid var(--border);
  padding: 6px 14px; border-radius: 8px; cursor: pointer; font-size: 14px; }
.btn-ghost:hover { border-color: var(--neon-2); color: var(--neon-2); }

.view { max-width: 980px; margin: 0 auto; padding: 24px 20px 60px; }
.section-title { text-align: center; color: var(--text-soft); font-weight: 600; }

/* ---- 大廳 hero + section head ---- */
.lobby-hero { text-align: center; padding: 28px 16px 18px;
  background: radial-gradient(circle at 50% 0%, rgba(255,61,240,.18), transparent 70%); border-radius: 18px; margin-bottom: 18px; }
.hero-title { font-size: clamp(28px, 6vw, 44px); font-weight: 900; letter-spacing: 2px;
  display: inline-flex; align-items: center; gap: 12px; color: #fff;
  text-shadow: 0 0 20px rgba(255,61,240,.6), 0 0 8px rgba(54,224,255,.55), 0 2px 4px rgba(0,0,0,.5); }
.hero-ico { font-size: .95em; filter: drop-shadow(0 0 10px rgba(255,210,74,.5)); }
.hero-sub { color: var(--text-soft); margin-top: 6px; font-size: 14px; }
/* [Claude Code 2026-06-25] 平台啟動日期徽章 */
.hero-since { display: inline-block; margin-top: 10px; padding: 3px 12px; border-radius: 999px;
  font-size: 12px; font-weight: 700; letter-spacing: .5px; color: var(--gold);
  background: rgba(255,210,74,.1); border: 1px solid rgba(255,210,74,.3); }
/* [Claude Code 2026-07-08] 串接 API 文件入口（大廳 LOGO 和遊戲中間，置中）
   [Claude Code 2026-07-08] 置中 + 連結改亮色（原本 var(--text) 在深底偏暗、看不出是連結） */
.lobby-apilink { display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  text-align: center; gap: 6px 14px; margin: 0 0 14px; }
.lobby-apilink a { display: inline-flex; align-items: center; gap: 6px; font-weight: 800; font-size: 14px;
  color: #a9ccff; text-shadow: 0 0 10px rgba(91,139,255,.55); text-decoration: none;
  padding: 8px 18px; border-radius: 999px;
  background: linear-gradient(135deg, rgba(91,139,255,.32), rgba(176,107,255,.26));
  border: 1px solid var(--neon); transition: transform .1s, box-shadow .15s, border-color .15s, color .15s; }
.lobby-apilink a:hover { transform: translateY(-1px); color: #dce8ff; border-color: var(--neon-2);
  box-shadow: 0 4px 18px rgba(91,139,255,.45); }

/* [Claude Code 2026-07-08] 大廳登入列（固定帳號登入 / 已登入狀態）
   [claude code] 2026-07-09 移到右上 topbar：改精簡 inline chip（不再置中大盒）；空 / 遊戲中不顯示 */
.lobby-auth { display: flex; align-items: center; }
.lobby-auth:empty { display: none; }
body[data-view="game"] #lobbyAuth { display: none; }
.la-form { display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  background: linear-gradient(160deg, var(--surface-2), var(--surface));
  border: 1px solid var(--border); border-radius: 999px; padding: 4px 6px 4px 12px; }
.la-title { font-weight: 800; color: var(--text-soft); letter-spacing: .5px; }
.la-inp { background: #10132a; border: 1px solid var(--border); border-radius: 999px;
  color: var(--text); padding: 6px 12px; font-size: 13px; min-width: 100px; flex: 0 1 150px; }
.la-inp:focus { outline: none; border-color: var(--neon-2); box-shadow: 0 0 0 2px rgba(176,107,255,.25); }
.la-btn { background: linear-gradient(135deg, var(--neon-2), var(--neon)); color: #fff; font-weight: 800;
  border: none; border-radius: 999px; padding: 6px 14px; font-size: 13px; cursor: pointer; transition: transform .1s, filter .15s; }
.la-btn:hover { filter: brightness(1.08); }
.la-btn:active { transform: scale(.97); }
.la-btn.ghost { background: var(--surface-2); color: var(--text-soft); border: 1px solid var(--border); }
.la-msg { font-size: 12px; color: var(--text-soft); }
.la-msg.err { color: #ff6b8a; font-weight: 700; }
.la-hint { color: var(--text-soft); font-size: 12px; margin: 8px 4px 0; }
.la-in { display: flex; align-items: center; gap: 10px;
  background: linear-gradient(135deg, rgba(176,107,255,.16), rgba(91,139,255,.12));
  border: 1px solid var(--border); border-radius: 999px; padding: 5px 6px 5px 14px; }
.la-who { font-weight: 700; color: var(--text); font-size: 14px; }
.la-who b { color: var(--neon-2); }
.la-bal { font-weight: 800; color: var(--gold, #ffd24a); }

/* [claude code] 2026-07-09 大廳文件 / 報告：可展開（<details>），預設關閉；文件變多也不佔版面 */
.lobby-docs { max-width: 520px; margin: 0 auto 16px; border: 1px solid var(--border); border-radius: 14px;
  background: linear-gradient(160deg, var(--surface-2), var(--surface)); overflow: hidden; }
.lobby-docs > summary { list-style: none; cursor: pointer; user-select: none;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 11px 16px; font-weight: 800; color: var(--text); letter-spacing: .5px; }
.lobby-docs > summary::-webkit-details-marker { display: none; }
.lobby-docs > summary:hover { color: var(--neon-2); }
.lobby-docs .ld-ico { filter: drop-shadow(0 0 6px rgba(255,210,74,.4)); }
.lobby-docs .ld-chev { color: var(--text-soft); font-size: 12px; transition: transform .15s; }
.lobby-docs[open] > summary .ld-chev { transform: rotate(180deg); }
.lobby-docs-body { padding: 4px 14px 14px; }
/* [claude code] 2026-07-14 文件 / 報告：改縱向排版統一 → 標題一行、描述固定在下一行（原本 flex-wrap 橫排會因標題長短不一，有的描述並排、有的折到下行，看起來不整齊） */
.lobby-docs-body .lobby-apilink { margin: 0 0 10px; flex-direction: column; gap: 5px; }
.lobby-docs-body .lobby-apilink:last-child { margin-bottom: 0; }

/* [claude code] 2026-07-09 頂列 meta 條（等級 + 每日流水任務；大廳 + 遊戲中都顯示，一次一階） */
/* [claude code] 2026-07-18 v2.4 預留「領取」鈕的高度：領取鈕（.mb-claim ~26px）比旁邊文字/進度條高，
   一顯示就把整條 bar 撐高 → 把下面的介面往下壓。用 min-height 預留鈕出現時的高度（box-sizing:border-box 含 padding）
   → 有沒有領取鈕，bar 高度都固定、不再位移。單行放得下鈕（桌面）就完全不跳；窄螢幕若換行是另一回事。 */
.meta-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px 22px;
  padding: 8px 16px; min-height: 44px; background: rgba(23,26,43,.72); border-bottom: 1px solid var(--border); }
.mb-level, .mb-mission { display: flex; align-items: center; gap: 9px; min-width: 0; }
.mb-lv { font-weight: 800; font-size: 13px; color: var(--text); white-space: nowrap; }
.mb-lv b { color: var(--neon-2); }
.mb-xpwrap { display: flex; align-items: center; gap: 7px; }
.mb-xpbar { width: 120px; max-width: 32vw; height: 7px; background: #10132a; border: 1px solid var(--border);
  border-radius: 999px; overflow: hidden; }
.mb-xpfill { height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--neon-2), var(--neon)); transition: width .4s ease; }
.mb-xptext { font-size: 11px; color: var(--text-soft); font-variant-numeric: tabular-nums; white-space: nowrap; }
.mb-mtitle { font-weight: 800; font-size: 12.5px; color: var(--text); white-space: nowrap; }
.mb-minfo { font-size: 12px; color: var(--text-soft); font-variant-numeric: tabular-nums; white-space: nowrap; }
.mb-minfo b { color: var(--gold); }
.mb-mbar { width: 130px; max-width: 32vw; height: 7px; background: #10132a; border: 1px solid var(--border);
  border-radius: 999px; overflow: hidden; }
.mb-mfill { height: 100%; border-radius: 999px; background: linear-gradient(90deg, #ffcf4a, #ff9f2e); transition: width .4s ease; }
.mb-claim { border: none; border-radius: 999px; font-weight: 800; cursor: pointer; padding: 5px 13px; font-size: 12.5px;
  white-space: nowrap; animation: mbClaimPulse 1.4s ease-in-out infinite; }
.mb-claim-lv { background: linear-gradient(135deg, #ffcf4a, #ff9f2e); color: #3a2600; box-shadow: 0 0 12px rgba(255,200,60,.5); }
.mb-claim-m { background: linear-gradient(135deg, #ff5b6e, #ff2e5b); color: #fff; box-shadow: 0 0 12px rgba(255,60,90,.45); }
.mb-claim:hover { filter: brightness(1.08); }
@keyframes mbClaimPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.06); } }
/* 桌面：等級 / 任務之間加分隔線 */
@media (min-width: 640px) { .mb-level { border-right: 1px solid var(--border); padding-right: 22px; } }

/* [claude code] 2026-07-09 紅包 pick-em overlay */
.redpack-overlay { position: fixed; inset: 0; z-index: 60; display: none; align-items: center; justify-content: center;
  background: rgba(6,8,18,.82); backdrop-filter: blur(3px); }
.redpack-overlay.show { display: flex; }
.rp-box { text-align: center; padding: 24px 20px; max-width: 92vw; }
.rp-title { font-size: 24px; font-weight: 900; color: #ffd24a; text-shadow: 0 0 16px rgba(255,90,90,.6); }
.rp-sub { color: var(--text-soft); margin: 6px 0 10px; font-size: 14px; }
/* [claude code] 2026-07-10 開獎前先列出「這次可抽到的金額」(只講金額,不講機率);開獎後把抽中那顆點亮 */
.rp-amts { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin: 0 0 18px; }
.rp-amt { font-size: 13px; font-weight: 800; color: #ffd88a; padding: 3px 11px; border-radius: 999px;
  background: rgba(255,207,74,.10); border: 1px solid rgba(255,207,74,.35); transition: all .3s; }
.rp-amt.hit { color: #3a2600; background: linear-gradient(160deg, #ffe08a, #ffcf4a); border-color: #fff;
  box-shadow: 0 0 14px rgba(255,200,60,.7); }
.rp-amt.miss { opacity: .4; }
.rp-cards { display: flex; gap: 16px; justify-content: center; perspective: 900px; }
.rp-card { width: 92px; height: 130px; cursor: default; }
.rp-card.pickable { cursor: pointer; }
.rp-card.pickable:hover { transform: translateY(-8px); transition: transform .15s; }
.rp-inner { position: relative; width: 100%; height: 100%; transform-style: preserve-3d; transition: transform .5s; }
.rp-card.flip .rp-inner { transform: rotateY(180deg); }
.rp-face { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  border-radius: 14px; backface-visibility: hidden; font-weight: 900; }
.rp-back { font-size: 40px; background: linear-gradient(160deg, #d4283c, #8a1020); border: 2px solid #ffcf4a;
  box-shadow: 0 6px 20px rgba(0,0,0,.4), inset 0 0 18px rgba(255,207,74,.25); }
.rp-front { font-size: 17px; color: #3a2600; background: linear-gradient(160deg, #ffe08a, #ffcf4a);
  transform: rotateY(180deg); border: 2px solid #ff9f2e; line-height: 1.2; }
.rp-card.shuffling { animation: rpShuffle .5s ease-in-out infinite; }
@keyframes rpShuffle { 0%,100% { transform: translateY(0) rotate(-2deg); } 50% { transform: translateY(-6px) rotate(2deg); } }
.rp-card.win .rp-front { box-shadow: 0 0 20px rgba(255,200,60,.85); border-color: #fff; }
.rp-card.win { animation: rpWin .5s ease; }
@keyframes rpWin { 0% { transform: scale(1); } 40% { transform: scale(1.12); } 100% { transform: scale(1); } }
.rp-card.dim { opacity: .55; }
.rp-result { margin-top: 20px; font-size: 18px; color: var(--text); opacity: 0; transform: translateY(6px);
  transition: opacity .3s, transform .3s; }
.rp-result.show { opacity: 1; transform: none; }
.rp-result b { color: var(--gold); font-size: 22px; }
.rp-close { margin-top: 18px; background: linear-gradient(135deg, var(--neon-2), var(--neon)); color: #fff;
  font-weight: 800; border: none; border-radius: 999px; padding: 8px 24px; font-size: 14px; cursor: pointer; }

/* [claude code] 2026-07-09 大廳 toast */
.lobby-toast { position: fixed; left: 50%; bottom: 40px; transform: translateX(-50%) translateY(20px); z-index: 70;
  background: rgba(23,26,43,.96); border: 1px solid var(--neon-2); color: var(--text); font-weight: 700;
  padding: 10px 20px; border-radius: 999px; box-shadow: 0 6px 24px rgba(0,0,0,.5); opacity: 0; pointer-events: none;
  transition: opacity .25s, transform .25s; }
.lobby-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

.lobby-section-head { display: flex; align-items: center; gap: 8px; font-weight: 700; margin: 6px 4px 12px; color: var(--text); }
.lobby-section-head .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--neon-2); box-shadow: 0 0 8px var(--neon-2); }
.lobby-section-head .count { background: var(--surface-2); color: var(--text-soft); font-size: 12px; padding: 1px 9px; border-radius: 999px; }

.lobby-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 16px; }

/* [claude code] 2026-08-02 大廳「🚧 未完成（開發中）」區：config 標 wip:true 的款排到最下面自成一區。
   刻意做成低調（橘色區隔 + 卡片整體降透明度），一眼看得出「這排跟上面那批不是同一個成熟度」，
   但仍可點進去玩（hover 會回到全彩）。沒有未完成款時整區由 JS 隱藏。 */
/* [claude code] 2026-08-13 v2.79 已上 DEMO 站：大廳**最上面**自成一區（與最下面的「🚧 未完成」對稱）。
   顏色用青色系（--neon-2）跟未完成的橘色分開 —— 一個是「已經給人看了」、一個是「還沒做完」。 */
.lobby-demo { margin-bottom: 26px; padding-bottom: 18px; border-bottom: 1px dashed var(--border); }
.lobby-section-head.demo { color: var(--neon-2); }
.lobby-section-head.demo .dot { background: var(--neon-2); box-shadow: 0 0 8px rgba(54,224,255,.75); }
.lobby-section-head.demo .count { background: rgba(54,224,255,.16); color: var(--neon-2); }
.lobby-demo-hint { margin: -6px 4px 14px; font-size: 12px; line-height: 1.6; color: var(--text-soft); }
.game-card.demo { border-color: rgba(54,224,255,.34); }
.game-card.demo:hover { border-color: var(--neon-2); box-shadow: 0 10px 34px rgba(54,224,255,.24); }
/* 徽章位置與 .card-dev 同一格（demo 款不會同時是 wip，不會疊在一起）*/
.card-demo { position: absolute; top: 12px; left: 12px; z-index: 3; font-size: 11px; font-weight: 800;
  background: rgba(54,224,255,.16); color: var(--neon-2); border: 1px solid rgba(54,224,255,.5);
  padding: 3px 10px; border-radius: 999px; letter-spacing: .03em; }
/* 同 wip：右上的「進入 / 試玩」鈕往下讓一排，免得在窄卡上跟左上的徽章撞在一起 */
.game-card.demo .card-emoji-row { margin-top: 18px; }

.lobby-wip { margin-top: 30px; padding-top: 20px; border-top: 1px dashed var(--border); }
.lobby-section-head.wip { color: #ffb454; }
.lobby-section-head.wip .dot { background: #ff9900; box-shadow: 0 0 8px rgba(255,153,0,.7); }
.lobby-section-head.wip .count { background: rgba(255,153,0,.16); color: #ffb454; }
.lobby-wip-hint { margin: -6px 4px 14px; font-size: 12px; line-height: 1.6; color: var(--text-soft); }
.game-card.wip { opacity: .78; border-color: rgba(255,153,0,.35); }
.game-card.wip::before { background: repeating-linear-gradient(135deg, #ff9900 0 10px, #6b4a12 10px 20px); opacity: .9; }
.game-card.wip:hover { opacity: 1; border-color: #ffb454; box-shadow: 0 10px 34px rgba(255,153,0,.26); }
/* 未完成卡的右上「進入 / 試玩」鈕往下讓一排，避免跟左上的 🚧 開發中 徽章在窄卡上撞在一起 */
.game-card.wip .card-emoji-row { margin-top: 18px; }
/* [claude code] 2026-07-30 v2.31 卡片改 flex column —— 才有辦法用 margin-top:auto
   把 .card-meta(RTP / 波動 / 最大倍數)釘在卡底,讓一整排卡片的那一列對齊。 */
.game-card { position: relative; background: linear-gradient(160deg, var(--surface-2), var(--surface));
  border: 1px solid var(--border); border-radius: 16px; padding: 18px 16px 16px; cursor: pointer;
  color: var(--text); text-align: left; overflow: hidden;
  display: flex; flex-direction: column;
  transition: transform .15s, box-shadow .15s, border-color .15s; }
.game-card::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 4px;
  background: linear-gradient(90deg, var(--neon), var(--neon-2)); opacity: .85; }
.game-card:hover { transform: translateY(-4px); border-color: var(--neon); box-shadow: 0 10px 34px rgba(255,61,240,.28); }
.card-badge { position: absolute; top: 12px; right: 12px; font-size: 11px; font-weight: 700;
  background: rgba(54,224,255,.15); color: var(--neon-2); border: 1px solid rgba(54,224,255,.4); padding: 3px 10px; border-radius: 999px; }
/* [Claude Code 2026-06-28] 大廳「開發中」徽章（沒填 completedAt 的款；放左上、橘色，與右上「▶ 開玩」不重疊）*/
.card-dev { position: absolute; top: 12px; left: 12px; z-index: 3; font-size: 11px; font-weight: 800;
  background: rgba(255,153,0,.18); color: #ffb454; border: 1px solid rgba(255,153,0,.5);
  padding: 3px 10px; border-radius: 999px; letter-spacing: .03em; }
/* [claude code] 2026-07-11 圖示 + 星等同一列（星等放圖示右邊）*/
.card-emoji-row { display: flex; align-items: center; gap: 10px; margin: 6px 0 8px; }
.card-emoji { font-size: 46px; line-height: 1; display: inline-block; transform-origin: 50% 50%; }
/* 大廳權重星等（放圖示旁）：滿星金色 + 發光、半星左半金、灰星暗 */
.card-stars { display: inline-flex; gap: 1px; font-size: 15px; line-height: 1; letter-spacing: 0; }
.card-stars .st { color: #3b405c; }
.card-stars .st.f { color: #ffcf4a; text-shadow: 0 0 6px rgba(255,200,60,.55); }
.card-stars .st.h { position: relative; color: #3b405c; }
.card-stars .st.h::before { content: "★"; position: absolute; left: 0; top: 0; width: 50%; overflow: hidden;
  color: #ffcf4a; text-shadow: 0 0 6px rgba(255,200,60,.55); }
/* [claude code] 2026-08-14 v2.88 換版進度指示（使用者要的）：**還沒換到遊戲畫面版型 v2 的款 → 星星變紅**。
   class 由 app.js 的 buildGameCard 依 `NEWUI_MECHS` 掛上（唯一資料來源）→ 換完一款就自動變回黃星。
   ⚠️ 只換顏色，星數（＝ lobbyWeight）與版面完全不動 —— 這是暫時的施工告示，全部換完就整段拿掉。 */
.card-stars.ui-todo .st.f { color: #ff5a5f; text-shadow: 0 0 6px rgba(255,80,90,.55); }
.card-stars.ui-todo .st.h::before { color: #ff5a5f; text-shadow: 0 0 6px rgba(255,80,90,.55); }
/* [Claude Code 2026-06-28] 大廳圖示動畫「一次只動一張」：JS 輪流給某張卡的圖示掛 fx-pulse。
   [Claude Code 2026-07-10] 效果改成「呼吸光暈」，只作用在圖示（.card-emoji）本身、不碰整張卡的框：
   - 平時 idle：JS 每隔 LOBBY_PULSE_MS 隨機挑一款，那款圖示呼吸一輪（fx-pulse，一次性）
   - 滑鼠移到卡上：該款圖示持續呼吸（infinite）+ 常駐金光，滑開即停
   [claude code] 2026-07-11 hover 加「常駐光暈」保底：就算 reduced-motion 關掉動畫，移上去也看得到亮一下。 */
.card-emoji.fx-pulse { animation: cardBreathe 1.7s ease-in-out; }
.game-card:hover .card-emoji {
  animation: cardBreathe 1.5s ease-in-out infinite;
  filter: brightness(1.25) drop-shadow(0 0 12px var(--neon, #5b6cf6));
}
@keyframes cardBreathe {
  0%, 100% { transform: scale(1);    filter: brightness(1.1) drop-shadow(0 0 4px var(--neon, #5b6cf6)); }
  50%      { transform: scale(1.18); filter: brightness(1.65) drop-shadow(0 0 16px var(--neon, #5b6cf6)); }
}
/* reduced-motion：不做縮放動畫，但 hover 仍給常駐金光（上面的 filter 不是 animation，保留）*/
@media (prefers-reduced-motion: reduce) {
  .card-emoji.fx-pulse, .game-card:hover .card-emoji { animation: none !important; }
}

/* 擴展百搭（黃金法老）：整軸展開成 WILD 時，每格金光放大一下 */
.cell.expand-fill { box-shadow: inset 0 0 0 2px var(--gold, #ffd24a), 0 0 16px rgba(255,210,74,.6); z-index: 4; }
.cell.expand-fill .glyph { animation: expandFill .42s ease; }
@keyframes expandFill { 0% { transform: scale(.4); opacity: .2; filter: brightness(2); } 60% { transform: scale(1.18); } 100% { transform: scale(1); opacity: 1; } }
/* [claude code] 2026-07-11 移動百搭（walking / 狼群狩獵）：頭狼 🐺 奔襲——狼格藍白發光、從右滑入；其餘格重抽時淡入 */
.cell.walk-wolf { box-shadow: inset 0 0 0 2px #bcd8f6, 0 0 16px rgba(140,180,230,.75); z-index: 4; }
.cell.walk-wolf .glyph { animation: walkWolfPulse 1s ease-in-out infinite; }
@keyframes walkWolfPulse { 0%,100% { transform: scale(1); filter: drop-shadow(0 0 4px #8fb6e6); } 50% { transform: scale(1.12); filter: brightness(1.4) drop-shadow(0 0 10px #bcd8f6); } }
.cell.walk-arrive .glyph { animation: walkArrive .28s cubic-bezier(.2,.9,.25,1); }
@keyframes walkArrive { 0% { transform: translateX(60%) scale(.7); opacity: .2; filter: brightness(2); } 60% { transform: translateX(-6%) scale(1.15); } 100% { transform: translateX(0) scale(1); opacity: 1; } }
.cell.walk-respin .glyph { animation: walkRespin .24s ease; }
@keyframes walkRespin { 0% { transform: translateY(-22%) scale(.9); opacity: .25; } 100% { transform: translateY(0) scale(1); opacity: 1; } }
/* [Claude Code 2026-06-28] 神秘符（mystery）：🔮 揭曉前脈動蓄勢、揭曉時翻牌 */
.cell.myst-orb { box-shadow: inset 0 0 0 2px #c08bff, 0 0 18px rgba(160,107,255,.7); z-index: 4; }
.cell.myst-orb .glyph { animation: mystPulse .54s ease infinite; }
@keyframes mystPulse { 0%,100% { transform: scale(1); filter: brightness(1); } 50% { transform: scale(1.15); filter: brightness(1.6) drop-shadow(0 0 8px #c08bff); } }
.cell.myst-flip { box-shadow: inset 0 0 0 2px var(--neon-2, #d7b3ff), 0 0 16px rgba(160,107,255,.6); z-index: 4; }
.cell.myst-flip .glyph { animation: mystFlip .56s ease; }
@keyframes mystFlip { 0% { transform: rotateY(90deg) scale(.6); opacity: .2; filter: brightness(2); } 55% { transform: rotateY(0deg) scale(1.2); } 100% { transform: rotateY(0deg) scale(1); opacity: 1; } }
/* [Claude Code 2026-06-28] 黏性百搭（sticky）：免費期黏住的 🐝 百搭金色光暈 + 輕微脈動（表示「黏住、持續生效」）*/
.cell.sticky-wild { box-shadow: inset 0 0 0 2px #ffcf4a, 0 0 14px rgba(255,180,40,.7); z-index: 4; }
.cell.sticky-wild .glyph { animation: stickyPulse 1.1s ease-in-out infinite; }
@keyframes stickyPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.09); filter: drop-shadow(0 0 6px #ffb400); } }
/* [Claude Code 2026-07-08] 黏性百搭免費期：已黏住的 WILD 用「靜態覆蓋層」釘在原位（旋轉時不跟著轉）。
   放在 reel 內、strip 之外 → 不透明蓋住底層滾動格；比 win(z4) 更上層；左下角 📌 提示「釘住」。 */
.cell.sticky-hold { z-index: 7; background: var(--surface-2);
  box-shadow: inset 0 0 0 2px #ffcf4a, 0 0 16px rgba(255,180,40,.85); }
.cell.sticky-hold .hold-pin { position: absolute; bottom: 2px; right: 3px; z-index: 8;
  font-size: clamp(.5rem, 2.4vw, .72rem); pointer-events: none; filter: drop-shadow(0 1px 2px rgba(0,0,0,.6)); }
/* [Claude Code 2026-06-29] 蜜蜂採蜜（cashcollect）：空格變暗、花蜜面額徽章、採集動畫 */
.cell.sym-EMPTY .glyph { opacity: .28; font-size: .7em; }   /* 空格：⬡ 淡化、縮小，看起來「空」 */
/* [claude code] 2026-08-14 v2.83 🌱 花苞 → 🌸 開花（依使用者：「出現是還沒開花的那種，然後再一格一格開花顯示金額」）。
   落盤時盤面上全是花苞（symbols 的 glyph 就是 🌱）→ 小一點、淡一點、微微搖，一看就是「還沒開」；
   開花那一下才放大成該面額的花，金額同時從底下彈出來。 */
.cell.sym-NECTAR .glyph { font-size: .74em; opacity: .8; filter: saturate(.8); transition: none; }
.cell.sym-NECTAR .glyph.nectar-open { font-size: 1em; opacity: 1; filter: none;
  animation: nectarBloom .42s cubic-bezier(.2, 1.5, .4, 1); }
@keyframes nectarBloom {
  0%   { transform: scale(.5) rotate(-14deg); opacity: .45; }
  55%  { transform: scale(1.24) rotate(5deg); opacity: 1; filter: drop-shadow(0 0 9px rgba(255,210,90,.8)); }
  100% { transform: scale(1) rotate(0); }
}
.cell .nectar-val { position: absolute; bottom: 4px; left: 50%; transform: translateX(-50%); z-index: 6; pointer-events: none;
  font-family: "Arial Black", system-ui, sans-serif; font-weight: 900; font-size: 11px; line-height: 1;
  padding: 2px 6px; border-radius: 8px; white-space: nowrap; animation: nectarValIn .3s ease;
  background: linear-gradient(135deg, #fff1c2, #ffcf4a); color: #5a3a00; box-shadow: 0 0 7px rgba(255,180,40,.7), 0 1px 2px rgba(0,0,0,.5); }
@keyframes nectarValIn {
  0%   { transform: translateX(-50%) translateY(7px) scale(.5); opacity: 0; }
  100% { transform: translateX(-50%) translateY(0) scale(1); opacity: 1; }
}
.cell.cash-bee { box-shadow: inset 0 0 0 2px #ffd54a, 0 0 16px rgba(255,200,60,.85); z-index: 4; }
.cell.cash-bee .glyph { animation: stickyPulse .7s ease-in-out infinite; }
.cell.cash-grab .glyph { animation: cashGrab .6s ease; }
@keyframes cashGrab { 0% { transform: scale(1); } 45% { transform: scale(1.25); filter: brightness(1.6) drop-shadow(0 0 8px #ffd54a); } 100% { transform: scale(1); } }
/* 採蜜賠付表：花蜜面額列 */
.nectar-list { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0; }
.nectar-chip { background: rgba(255,200,60,.14); border: 1px solid rgba(255,200,60,.4); color: var(--neon-2, #ffd54a);
  padding: 3px 9px; border-radius: 999px; font-size: 12.5px; font-weight: 700; }
/* [claude code] 2026-07-30 v2.31 大廳卡片統一版型（規範見 CLAUDE.md「大廳遊戲卡片規範」）。
   🔴 問題:grid 的一列會被「最高的那張卡」撐開 —— 環遊世界的 desc 寫了 356 字,
   整排卡片跟著變成三倍高、RTP 那列各自散在不同高度,大廳看起來就亂了。
   🔴 修法分兩層,缺一不可:
     ① 內容面:文案長度寫進規範 + `tools/lintcards` 可執行檢查(見該工具)
     ② 版型面:【就算文案超標,版型也不能爛】—— desc 固定夾 3 行、tags 固定一行、
        meta 用 margin-top:auto 推到卡底 → 不管文案多長,每張卡等高、RTP 那列對齊。
   只做①不做②,下次有人多打幾個字就又跑版;只做②不做①,卡片會出現沒頭沒尾的截斷句。 */
.card-name { font-size: 19px; font-weight: 800; }
.card-sub { font-size: 12px; color: var(--text-soft); letter-spacing: .5px; margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card-desc { font-size: 12.5px; color: #c8cce8; line-height: 1.5; margin: 10px 0 0; min-height: 3.6em;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3;
  overflow: hidden; }
/* tags 固定一行(超出就截掉)—— 讓每張卡的 tags 佔一樣高度,不會有人用 4 個長標籤把卡撐高 */
.card-tags { display: flex; flex-wrap: nowrap; gap: 5px; margin-top: 10px; overflow: hidden; }
.card-tags .tag { font-size: 11px; background: rgba(255,255,255,.05); border: 1px solid var(--border);
  color: var(--text-soft); padding: 2px 9px; border-radius: 999px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 0 1 auto; }
/* margin-top:auto → 不管上面內容多高,RTP / 波動 / 最大倍數這一列一律貼在卡底對齊 */
.card-meta { display: flex; flex-wrap: wrap; gap: 6px; margin-top: auto; padding-top: 10px; }
.card-meta span { font-size: 10.5px; color: var(--text-soft); background: var(--bg); border: 1px solid var(--border);
  padding: 2px 8px; border-radius: 8px; }
/* [Claude Code 2026-07-09] 大廳權重（lobbyWeight）金色小徽章 */
.card-meta span.cm-weight { color: #ffcf4a; border-color: rgba(255,200,60,.5);
  background: rgba(255,200,60,.08); font-weight: 700; text-shadow: 0 0 5px rgba(255,200,60,.35); }

/* ---- 直版 / 手機優先：整個遊戲區置中、限寬 ---- */
.game-stage { max-width: 480px; margin: 0 auto; padding: 8px 4px 24px; }
.game-head { display: grid; grid-template-columns: 48px 1fr auto; align-items: center; gap: 8px; margin-bottom: 12px; }
/* [claude code] 2026-07-29 v2.27 抬頭右側工具（ⓘ 展開 / 📋 賠付）*/
.head-tools { display: flex; gap: 6px; }
/* 可展開的抬頭區（標語 / 注單號 / 資訊 chips）：**預設關閉**，把高度讓給盤面；點 ⓘ 才展開。
   依使用者 2026-07-29：「只要留遊戲名那排就好了，有需要再呈現，不用一直占位置」。*/
.game-meta { display: none; }
.game-meta.open { display: block; animation: gmIn .18s ease; }
@keyframes gmIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.meta-toggle.on { color: var(--neon-2); border-color: var(--neon-2); }
/* [claude code] 2026-08-13 v2.72 版型兜底：遊戲名一律**單行**（最長 6 字，正常寬度綽綽有餘）。
   min-width:0 讓它在 grid 內收得起來，真的塞不下就 ellipsis —— 就算哪天版面又塌，
   也只會截字，不會像 v2.71 那樣被擠成直排、把整排抬頭撐高三倍。*/
.game-head h2 { margin: 0; text-align: center; font-size: 19px;
  min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.game-head .btn-ghost { padding: 6px 10px; }
.head-spacer { display: block; }
.icon-btn { font-size: 17px; padding: 6px 11px; line-height: 1; }

.machine { position: relative; background: var(--surface); border: 1px solid var(--border);
  border-radius: 18px; padding: 14px; box-shadow: 0 8px 30px rgba(0,0,0,.4); }

/* ---- 盤面（treadmill 掉落式）---- */
.board { display: grid; gap: 6px; background: #070a14; border-radius: 12px; padding: 6px; }
.reel { position: relative; overflow: hidden; border-radius: 10px; background: #0a0c16; }
.strip { position: absolute; inset: 0; }
.cell { position: absolute; left: 0; right: 0; top: 0; display: flex; align-items: center; justify-content: center;
  font-size: clamp(26px, 9vw, 46px); background: var(--surface-2);
  border: 2px solid #070a14; box-sizing: border-box; user-select: none; will-change: transform; }
.cell .glyph { position: relative; z-index: 2; line-height: 1; display: flex; align-items: center; justify-content: center; transition: transform .2s; }
/* 字牌類（A/K/Q/J/7/BAR）純文字 → 與 emoji 基線一致、置中不歪；各符號給色易辨 */
.cell .glyph.txt { font-family: "Arial Black", "Segoe UI", system-ui, sans-serif; font-weight: 900;
  letter-spacing: .5px; color: #e8eaf6; text-shadow: 0 2px 5px rgba(0,0,0,.55); }
.cell .glyph.txt-multi { font-size: .5em; letter-spacing: 1.5px; }
.cell.sym-SEVEN .glyph { color: #ff4d6d; text-shadow: 0 0 10px rgba(255,77,109,.45); }
.cell.sym-BAR  .glyph { color: #c77dff; text-shadow: 0 0 10px rgba(199,125,255,.45); }
.cell.sym-A .glyph { color: #ff7aa8; }
.cell.sym-K .glyph { color: #5ad1ff; }
.cell.sym-Q .glyph { color: #ffd24a; }
.cell.sym-J .glyph { color: #7ee787; }
.strip.spinning .glyph { filter: blur(2.5px); }
.cell.win { background: rgba(255,225,105,.12); box-shadow: inset 0 0 0 2px var(--win), 0 0 16px var(--win); z-index: 4; }
.cell.win .glyph { animation: pop .45s ease; }
@keyframes pop { 0%{transform:scale(1)} 45%{transform:scale(1.18)} 100%{transform:scale(1)} }

/* ---- WILD / SCATTER 辨識（比照 slot_town：金/青外框 + 角標）----
   [claude code] 2026-08-14 v2.83 `.is-scatter` = **依 scatterId 掛的**（app.js 的 setCell），
   與靠符號 key 命中的 `.sym-SCATTER` 共用同一組外觀 → 符號 key 叫什麼都有框
   （花蜜採集的 👑 蜂王 key 是 QUEEN，之前就是這樣漏掉框的）。 */
.cell.sym-WILD::before, .cell.sym-SCATTER::before, .cell.is-scatter::before {
  content: ""; position: absolute; inset: 3px; border-radius: 8px; pointer-events: none; z-index: 1; }
.cell.sym-WILD::before { border: 2px solid rgba(255,210,74,.65);
  box-shadow: 0 0 10px rgba(255,210,74,.45), inset 0 0 8px rgba(255,210,74,.3); }
.cell.sym-SCATTER::before, .cell.is-scatter::before { border: 2px solid rgba(52,224,255,.6);
  box-shadow: 0 0 10px rgba(52,224,255,.4), inset 0 0 8px rgba(52,224,255,.25); }
.cell.sym-WILD::after, .cell.sym-SCATTER::after, .cell.is-scatter::after {
  position: absolute; top: 3px; left: 3px; z-index: 3; padding: 1px 5px; border-radius: 6px;
  font-size: clamp(.4rem, 2.6vw, .58rem); font-weight: 900; letter-spacing: .04em; line-height: 1.25;
  pointer-events: none; box-shadow: 0 1px 3px rgba(0,0,0,.5); }
.cell.sym-WILD::after { content: "WILD"; background: linear-gradient(#ffe9a6, var(--gold)); color: #2a1d00; }
.cell.sym-SCATTER::after, .cell.is-scatter::after { content: "SCATTER"; background: linear-gradient(#bff4ff, #34e0ff); color: #042530; }
.cell.sym-WILD .glyph { filter: drop-shadow(0 0 6px rgba(255,210,74,.6)); }
.cell.sym-SCATTER .glyph, .cell.is-scatter .glyph { filter: drop-shadow(0 0 6px rgba(52,224,255,.6)); }

/* [Claude Code 2026-06-28] 倍率百搭（frost_wilds）：❄️ 百搭格右上角的 ×N 倍率徽章。
   放右上、避開既有「WILD」字樣（在左上 ::after）；藍冰漸層 + 發光。 */
.cell .wild-mult {
  position: absolute; top: 3px; right: 3px; z-index: 6; pointer-events: none;
  font-family: "Arial Black", system-ui, sans-serif; font-weight: 900;
  font-size: clamp(.5rem, 2.8vw, .72rem); line-height: 1; letter-spacing: .02em;
  padding: 2px 5px; border-radius: 7px;
  background: linear-gradient(135deg, #e8f9ff, #5ad1ff); color: #042a3a;
  box-shadow: 0 0 9px rgba(90,209,255,.85), 0 1px 3px rgba(0,0,0,.5);
  animation: wmPop .4s ease; }
@keyframes wmPop { 0%{transform:scale(.4);opacity:0} 60%{transform:scale(1.2)} 100%{transform:scale(1);opacity:1} }
/* frost 主題：百搭已用 ×N 徽章標示，隱藏左上「WILD」字樣避免兩標籤擠在一起（保留外框光暈）。 */
body[data-theme="frost"] .cell.sym-WILD::after { display: none; }
body[data-theme="frost"] .cell.sym-WILD::before { border-color: rgba(90,209,255,.7);
  box-shadow: 0 0 10px rgba(90,209,255,.5), inset 0 0 8px rgba(90,209,255,.3); }
/* [Claude Code 2026-06-25] candy 款：取消「框+角標」這種疊在格子上的辨識（消除掉落時會跟 glyph 分離），
   改成把光暈做在 glyph 上 → drop-shadow 隨 glyph 一起掉落/消除，棒棒糖🍭/轉盤🎡 與光暈永遠同進退。 */
/* candy 款：標示框做在 .glyph 上（不是 .cell）→ inset 環 + 光暈會隨 glyph 一起掉落/消除，永不分離。 */
body[data-theme="candy"] .cell.sym-WILD::before,
body[data-theme="candy"] .cell.sym-WILD::after,
body[data-theme="candy"] .cell.sym-SCATTER::before,
body[data-theme="candy"] .cell.sym-SCATTER::after { display: none; }
/* 框做小一點、留邊（emoji 縮 .82em + 內距），外光暈也收斂 → 不會被 reel 的 overflow:hidden 裁掉。 */
body[data-theme="candy"] .cell.sym-SCATTER .glyph,
body[data-theme="candy"] .cell.sym-BONUS .glyph { box-sizing: border-box; font-size: .82em; padding: 5px; border-radius: 12px; }
body[data-theme="candy"] .cell.sym-SCATTER .glyph { box-shadow: inset 0 0 0 2.5px #34e0ff, 0 0 7px rgba(52,224,255,.55); }
body[data-theme="candy"] .cell.sym-BONUS .glyph { box-shadow: inset 0 0 0 2.5px var(--gold), 0 0 7px rgba(255,95,162,.5); }
/* 小角標（跟著 glyph 走）標明是哪種特殊符 */
body[data-theme="candy"] .cell.sym-SCATTER .glyph::after,
body[data-theme="candy"] .cell.sym-BONUS .glyph::after {
  position: absolute; top: -6px; left: 50%; transform: translateX(-50%); z-index: 3; pointer-events: none;
  font-size: 8px; font-weight: 900; letter-spacing: .03em; line-height: 1.3; padding: 1px 5px; border-radius: 6px;
  white-space: nowrap; box-shadow: 0 1px 3px rgba(0,0,0,.55); }
body[data-theme="candy"] .cell.sym-SCATTER .glyph::after { content: "SCATTER"; background: linear-gradient(#bff4ff, #34e0ff); color: #042530; }
body[data-theme="candy"] .cell.sym-BONUS .glyph::after { content: "BONUS"; background: linear-gradient(#ffe9a6, var(--gold)); color: #5a1d00; }
/* [claude code] 2026-07-17 v1.95 icecream 款（烈日冰舖 serve）：同 candy 的修法 —— 消除掉落款的 SCATTER
   「框+角標」不能疊在 .cell 上（掉落動畫只動 .glyph → 外框先在原地出現、跟符號分離），
   改做在 .glyph 上（暖橘陽光色配 ☀️），框/角標隨符號一起掉落、永不分離。 */
body[data-theme="icecream"] .cell.sym-SCATTER::before,
body[data-theme="icecream"] .cell.sym-SCATTER::after { display: none; }
body[data-theme="icecream"] .cell.sym-SCATTER .glyph { box-sizing: border-box; font-size: .82em; padding: 5px; border-radius: 12px;
  box-shadow: inset 0 0 0 2.5px #ffb340, 0 0 7px rgba(255,179,64,.55); }
body[data-theme="icecream"] .cell.sym-SCATTER .glyph::after {
  content: "SCATTER"; position: absolute; top: -6px; left: 50%; transform: translateX(-50%); z-index: 3; pointer-events: none;
  font-size: 8px; font-weight: 900; letter-spacing: .03em; line-height: 1.3; padding: 1px 5px; border-radius: 6px;
  white-space: nowrap; box-shadow: 0 1px 3px rgba(0,0,0,.55);
  background: linear-gradient(#ffe9a6, #ffb340); color: #5a2d00; }
/* [claude code] 2026-07-18 v2.2 顧客符加框（依使用者：顧客變多了，要像 scatter 一眼看出是「會觸發成交」的特別符）。
   ⚠️ 框+「顧客」角標做在 .glyph 上（沿用 icecream SCATTER 寫法）→ 掉落補位時跟符號一起動、不分離。
   ⚠️ v2.2 修：**.glyph 不能掛 animation** —— 掉落動畫 csDrop 也在 .glyph 上，而本選擇器優先級較高，
       一掛 animation 就把 csDrop 蓋掉 → 顧客符不落下、框跟圖看起來分離。故框做「靜態」（同 scatter，無 pulse）。
       想要「動」的注意力就放在 ::after 角標（另一個元素、不影響 .glyph 的 csDrop transform）。 */
body[data-theme="icecream"] .cell.serve-cust .glyph {
  box-sizing: border-box; font-size: .82em; padding: 5px; border-radius: 12px;
  box-shadow: inset 0 0 0 2.5px #ffd24a, 0 0 8px rgba(255,205,70,.6); }
body[data-theme="icecream"] .cell.serve-cust .glyph::after {
  content: "顧客"; position: absolute; top: -6px; left: 50%; transform: translateX(-50%); z-index: 3; pointer-events: none;
  font-size: 8px; font-weight: 900; letter-spacing: .08em; line-height: 1.3; padding: 1px 5px; border-radius: 6px;
  white-space: nowrap; box-shadow: 0 1px 3px rgba(0,0,0,.55);
  background: linear-gradient(#ffe9a6, #ffd24a); color: #5a3d00;
  animation: serveCustTag 1.4s ease-in-out infinite; }
@keyframes serveCustTag { 0%,100%{ filter: brightness(1); box-shadow: 0 1px 3px rgba(0,0,0,.55); }
  50%{ filter: brightness(1.18); box-shadow: 0 0 8px rgba(255,220,95,.9); } }

/* 固定高度動作區：撐住「翻倍鈕 / 免費旋轉文字」其一的空間（兩者不同時出現）→ 高度固定、SPIN 不跳動。
   拿掉「贏得 N！」後只需一排高度，縮小與盤面的間距。 */
.action-zone { min-height: 44px; margin-top: 8px; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 6px; }
.win-banner { text-align: center; margin: 0; font-size: 17px; font-weight: 700;
  color: var(--win); text-shadow: 0 0 10px rgba(255,225,105,.5); }

/* [claude code] 2026-07-10 免費期遞增倍率:banner 上的「×N」要醒目(原本 ×2 固定又沒顯示,玩家無感) */
.win-banner .fs-mult { color: #ffd24a; font-weight: 900; text-shadow: 0 0 10px rgba(255,210,74,.55);
  display: inline-block; animation: fsMultPop .35s ease; }
@keyframes fsMultPop { 0% { transform: scale(.7); opacity: .3; } 60% { transform: scale(1.25); } 100% { transform: scale(1); } }
.win-banner .fs-win { color: var(--gold, #ffd24a); font-weight: 800; }
.win-banner:empty { display: none; }   /* 空時不佔行，避免把翻倍鈕往下推 */

/* ---- 大獎全螢幕特效 overlay（BIG / MEGA / EPIC WIN）---- */
.win-overlay { position: fixed; inset: 0; z-index: 40; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 10px; pointer-events: none;
  opacity: 0; visibility: hidden; transition: opacity .25s; background: radial-gradient(circle at 50% 45%, rgba(0,0,0,.55), rgba(0,0,0,.82)); }
.win-overlay.show { opacity: 1; visibility: visible; }
.wo-tier { font-size: clamp(40px, 13vw, 90px); font-weight: 900; letter-spacing: 2px;
  background: linear-gradient(90deg, var(--gold), #fff, var(--gold)); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; filter: drop-shadow(0 0 24px var(--gold)); animation: woPop .5s ease; }
.wo-amt { font-size: clamp(26px, 8vw, 52px); font-weight: 900; color: #fff; text-shadow: 0 0 18px var(--win); animation: woRise .6s ease;
  font-variant-numeric: tabular-nums; }   /* 等寬數字：跳的時候寬度不會忽大忽小 */
/* [claude code] 2026-08-13 跳錢中：微微抖 + 更亮；停住時「咚」一下放大再收 */
.wo-amt.rolling { animation: woRise .6s ease, woRoll .12s ease-in-out infinite alternate;
  text-shadow: 0 0 26px var(--win), 0 0 46px rgba(255,232,150,.75); }
@keyframes woRoll { from { transform: translateY(-1px) scale(1); } to { transform: translateY(1px) scale(1.012); } }
.wo-amt.landed { animation: woLand .42s cubic-bezier(.2,1.5,.4,1); }
/* [claude code] 2026-08-14 v2.93 「領取」鈕 —— 中大獎特效改成按了才收（不再自動關）。
   跳錢跑完（`.ready`）才長出來，免得數字還在跳就被按掉。 */
.wo-collect { margin-top: 18px; padding: 12px 40px; border: 0; border-radius: 999px; cursor: pointer;
  font-size: clamp(15px, 4.4vw, 19px); font-weight: 900; letter-spacing: .06em; color: #2a1d00;
  background: linear-gradient(#fff3c8, var(--gold));
  box-shadow: 0 6px 18px rgba(0,0,0,.45), 0 0 22px rgba(255,207,58,.6), inset 0 1px 0 rgba(255,255,255,.7);
  opacity: 0; transform: translateY(10px) scale(.94); pointer-events: none; transition: .28s ease; }
.win-overlay.ready .wo-collect { opacity: 1; transform: none; pointer-events: auto;
  animation: woCollectPulse 1.6s ease-in-out .4s infinite; }
.wo-collect:active { transform: scale(.96); }
@keyframes woCollectPulse { 0%, 100% { box-shadow: 0 6px 18px rgba(0,0,0,.45), 0 0 22px rgba(255,207,58,.6), inset 0 1px 0 rgba(255,255,255,.7); }
  50% { box-shadow: 0 6px 22px rgba(0,0,0,.5), 0 0 34px rgba(255,207,58,.95), inset 0 1px 0 rgba(255,255,255,.8); } }
@keyframes woLand { 0% { transform: scale(1.24); } 100% { transform: scale(1); } }
.win-overlay.tier-mega .wo-tier { background: linear-gradient(90deg, #ff3df0, #36e0ff, #ffd24a); -webkit-background-clip: text; background-clip: text; filter: drop-shadow(0 0 26px #ff3df0); }
.win-overlay.tier-epic .wo-tier { background: linear-gradient(90deg, #ff3df0, #7a5cff, #36e0ff, #ffd24a); -webkit-background-clip: text; background-clip: text; filter: drop-shadow(0 0 30px #7a5cff); animation: woPop .5s ease, woShake .6s ease .5s; }
@keyframes woPop { 0%{transform:scale(.3);opacity:0} 60%{transform:scale(1.15)} 100%{transform:scale(1);opacity:1} }
@keyframes woRise { 0%{transform:translateY(20px);opacity:0} 100%{transform:translateY(0);opacity:1} }
@keyframes woShake { 0%,100%{transform:translateX(0)} 25%{transform:translateX(-8px)} 75%{transform:translateX(8px)} }

/* ---- 控制列（直版置底一排）---- */
.control-bar { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 16px; flex-wrap: wrap; }
/* ---- 單注 +/- stepper ---- */
.bet-stepper { display: flex; align-items: center; gap: 10px; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 999px; padding: 5px 8px; }
.bet-label { color: var(--text-soft); font-size: 13px; padding-left: 6px; }
.bet-btn { width: 34px; height: 34px; border-radius: 50%; border: none; cursor: pointer;
  background: var(--surface); color: var(--text); font-size: 20px; font-weight: 700; line-height: 1;
  display: flex; align-items: center; justify-content: center; transition: background .15s, color .15s; }
.bet-btn:hover:not(:disabled) { background: var(--neon-2); color: #08101a; }
.bet-btn:disabled { opacity: .35; cursor: not-allowed; }
.bet-value { min-width: 64px; text-align: center; font-size: 17px; font-weight: 800; color: var(--gold); }
.btn-spin { background: linear-gradient(135deg, var(--neon), var(--neon-2)); color: #0a0c16;
  border: none; padding: 14px 40px; border-radius: 999px; font-size: 18px; font-weight: 800;
  cursor: pointer; letter-spacing: 1px; box-shadow: 0 6px 20px rgba(54,224,255,.35);
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  transition: transform .14s ease, box-shadow .18s ease, filter .14s ease; }
.btn-spin:disabled { opacity: .5; cursor: not-allowed; }
/* [claude code] 2026-08-13 ④ 圖示持續慢轉。純 CSS 畫的環形箭頭：一圈粗邊缺一角 + 一個小三角。
   2026-08-13 二版（依使用者：「那個 SPIN 左邊在轉的，能是**繞著 SPIN 字轉**的」）：
   從「按鈕左邊自轉」改成**沿著按鈕的橢圓軌道公轉**（CSS Motion Path）。 */
/* 2026-08-13 二版（使用者：「那個在轉的怪怪的，**就算是小亮點轉都好**」）：
   從「缺一角的環形箭頭」改成**一顆發光小亮點**。環形箭頭同時自轉又公轉，兩個旋轉疊在一起看起來雜；
   亮點沒有方向性，繞著跑就只是純粹的光，乾淨得多。 */
.spin-ico { width: 8px; height: 8px; flex: 0 0 auto; border-radius: 50%; border: none;
  background: radial-gradient(circle, #fff 0%, #fff3c8 40%, rgba(255,207,58,.85) 66%, rgba(255,207,58,0) 100%);
  box-shadow: 0 0 10px 3px rgba(255,232,150,.9), 0 0 20px 6px rgba(255,200,80,.45);
  animation: spinIcoPulse 1.6s ease-in-out infinite; }
@keyframes spinIcoPulse { 0%, 100% { opacity: .8; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.28); } }

/* 🔴 公轉：`offset-path: ellipse(...)` 用**百分比**貼著按鈕自己的大小 → 按鈕多寬多高都跟得上，
   不必寫死像素（寫死的話手機或字型不同就會跑到框外）。
   `offset-rotate: 0deg` = 沿路徑走但**自己不跟著轉向**，這樣它才能同時用 transform 做自轉。
   ⚠️ 包 @supports：不支援 Motion Path 的瀏覽器自動退回「左邊自轉」那版（上面那段），不會壞掉。 */
@supports (offset-path: ellipse(40% 30% at 50% 50%)) {
  .btn-spin { position: relative; }
  .spin-ico { position: absolute; left: 0; top: 0; margin: 0;
    offset-path: ellipse(44% 31% at 50% 50%);
    offset-rotate: 0deg;
    animation: spinOrbit 3.6s linear infinite, spinIcoPulse 1.6s ease-in-out infinite; }
  .btn-spin:disabled .spin-ico { animation-duration: 1.2s, 0.7s; }   /* 表演中：繞得快、閃得也快 */
  /* 圖示改成絕對定位後就不佔寬度了 → 左右各留一點，免得它壓到 SPIN 字 */
  .btn-spin .spin-txt { padding: 0 4px; }
}
@keyframes spinOrbit { to { offset-distance: 100%; } }

/* [claude code] 2026-08-13 ⑤ hover 的黃光。
   二版（依使用者：「能變成放大，再縮小放大的黃框嗎」）：從**靜態**黃框改成**脈動** ——
   一路 放大 → 收 → 再放大，光暈跟著一起呼吸。1.15s 一次，比心跳稍慢，看久不煩。 */
/* 三版（使用者：「黃框到最大時，**SPIN 字會往下動一下**」）：
   🔴 病根是脈動動畫在改 `transform: scale()` —— 按鈕一放大，裡面的字當然跟著長大位移。
   改成 **transform 固定在 :hover 上放大一次就不動**，動畫**只改 box-shadow**（光暈自己呼吸）。
   → 黃框照樣放大縮小，但按鈕與 SPIN 字**完全不動**。 */
.btn-spin:hover:not(:disabled) { filter: brightness(1.06); transform: scale(1.045);
  animation: spinGlow 1.15s ease-in-out infinite; }
@keyframes spinGlow {
  0%, 100% { box-shadow: 0 8px 24px rgba(54,224,255,.38), 0 0 12px 1px rgba(255,232,150,.4); }
  50%      { box-shadow: 0 10px 30px rgba(54,224,255,.46), 0 0 36px 10px rgba(255,232,150,.85); }
}
/* 🔴 按下去要壓得住 hover 的 animation（animation 的優先級高於一般宣告）→ 明確關掉它 */
.btn-spin:active:not(:disabled) { animation: none; transform: scale(.97);
  box-shadow: 0 4px 14px rgba(54,224,255,.35), 0 0 16px 3px rgba(255,232,150,.5); }

/* [claude code] 2026-07-29 v2.22 賠付表過寬修正（使用者回報「太寬下面會出現醜醜的 scroll bar」）：
   ① card 加寬 360→min(420, 100vw−24) ② 表格內距壓縮 + **數字欄不換行**（原本「相連數」被逐字拆成直排）
   ③ 欄多的表自動縮字級（.pt-compact）④ 真的塞不下才捲，且捲軸改細版主題色（.pt-wrap，由 openPaytable 統一包）。*/
.paytable-card { width: min(420px, calc(100vw - 24px)); max-height: 80vh; overflow-y: auto; overflow-x: hidden; }
.paytable h4 { margin: 0 0 10px; color: var(--text-soft); }
table.pt { width: 100%; border-collapse: collapse; font-size: 13px; }
table.pt th, table.pt td { padding: 4px 6px; text-align: left; border-bottom: 1px solid var(--border); white-space: nowrap; }
table.pt th { color: var(--text-soft); font-weight: 600; }
/* 首欄（符號 / 名稱）才允許換行，其餘（數字）一律不換行 */
table.pt th:first-child, table.pt td:first-child { white-space: normal; }
/* 欄多的表（闖關奪寶 6 欄等）自動縮字級 → 免捲軸 */
table.pt.pt-compact { font-size: 11.5px; }
table.pt.pt-compact th, table.pt.pt-compact td { padding: 3px 4px; }
/* 仍塞不下才捲：細捲軸 + 主題色，不再是系統預設那條粗白條 */
.pt-wrap { overflow-x: auto; scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
.pt-wrap::-webkit-scrollbar { height: 6px; }
.pt-wrap::-webkit-scrollbar-track { background: transparent; }
.pt-wrap::-webkit-scrollbar-thumb { background: var(--border); border-radius: 999px; }
.pt-wrap::-webkit-scrollbar-thumb:hover { background: var(--text-soft); }
/* modal 自己的垂直捲軸也改細版（原本系統預設粗條跟畫面不搭）*/
.paytable-card { scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
.paytable-card::-webkit-scrollbar { width: 7px; }
.paytable-card::-webkit-scrollbar-track { background: transparent; }
.paytable-card::-webkit-scrollbar-thumb { background: var(--border); border-radius: 999px; }
.fs-note { font-size: 12px; color: var(--neon-2); margin-top: 10px; }

.modal { position: fixed; inset: 0; background: rgba(0,0,0,.6); display: flex; align-items: center;
  justify-content: center; z-index: 30; }
.modal-card { background: var(--surface); border: 1px solid var(--border); border-radius: 16px;
  padding: 24px; width: 320px; position: relative; }
.modal-card h3 { margin: 0 0 8px; }
.modal-card .hint { font-size: 12px; color: var(--text-soft); }
.modal-card input { width: 100%; margin: 8px 0; padding: 10px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text); }
.modal-actions { display: flex; gap: 10px; margin-top: 6px; }
.modal-close { position: absolute; top: 10px; right: 12px; background: none; border: none;
  color: var(--text-soft); font-size: 22px; cursor: pointer; }
.acc-msg { font-size: 13px; color: var(--neon-2); min-height: 18px; margin: 10px 0 0; }
.newguest-btn { width: 100%; margin-top: 10px; border-color: var(--neon-2); color: var(--neon-2); }
.newguest-btn:hover { background: var(--neon-2); color: #08101a; }

/* ---- 遊戲內小圖示（標題前）---- */
.title-emoji { font-size: 22px; vertical-align: -2px; }

/* ---- 該款完成日期（SPIN 下方）---- */
.game-completed { text-align: center; color: var(--text-mute, #8b91a3); font-size: 12px; letter-spacing: .3px; margin: 14px 0 4px; }
/* [claude code] 2026-07-19 該款身世（🗓️ 開始做的日期 + 平台版本）：放遊戲畫面最下面、置中 */
.game-born { display: flex; justify-content: center; margin: 6px 0 4px; }
/* 遊戲內資訊列：波動 / 最大賠付 / 核心玩法 */
.game-info { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin: 0 0 10px; }
.game-info:empty { display: none; }
.gi-chip { font-size: 11.5px; font-weight: 600; color: var(--text-soft, #c7ccda);
  background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.1);
  padding: 3px 9px; border-radius: 999px; white-space: nowrap; }
.gi-vol { color: #ffcf7a; border-color: rgba(255,207,122,.3); }
.gi-max { color: var(--gold, #ffd24a); border-color: rgba(255,210,74,.3); }
.gi-core { color: #8fd3ff; border-color: rgba(143,211,255,.28); }
/* [claude code] 2026-07-16 每款「開始做的日期 + 當時平台版本」身世 chip */
.gi-born { color: #b6a7e8; border-color: rgba(182,167,232,.3); }

/* ---- 注單號（名字和盤面中間）---- */
/* 固定寬度 + monospace tabular，單號變動或在「—」之間切換時不會左右跳動 */
/* [claude code] 2026-07-18 各款主題味小標語（遊戲名 ↔ 注單號 之間）：小字、柔和、置中，一行放不下就自動折。 */
.game-tagline { text-align: center; font-size: 12.5px; color: var(--text-soft); line-height: 1.45;
  margin: -4px auto 9px; max-width: 90%; letter-spacing: .3px; }
/* [claude code] 2026-07-19 標語輪換動畫：每次 SPIN 兩段式「由上往下捲動」——
   第一段 tag-out：舊句往下滑出 + 淡出；第二段 tag-in：新句從上方滑入落定（整體往下捲，像翻過一句）。 */
/* [claude code] 2026-07-19 依使用者放慢、位移加大 → 「由上往下捲動」看得清楚（原 .17s/.32s 太快、被 SPIN 盤面動畫蓋過）。 */
.game-tagline.tag-out { animation: tagOut .42s ease-in both; }
.game-tagline.tag-in  { animation: tagIn .72s cubic-bezier(.22,.68,.36,1) both; }
@keyframes tagOut {
  0%   { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(20px); filter: blur(1.5px); }
}
@keyframes tagIn {
  0%   { opacity: 0; transform: translateY(-22px); filter: blur(2px); }
  55%  { opacity: 1; filter: blur(0); }
  100% { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .game-tagline.tag-out, .game-tagline.tag-in { animation: none; }
}
.spin-ticket { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 4px 0 10px; }
.st-label { font-size: 12px; color: var(--text-soft); letter-spacing: 1px; white-space: nowrap; }
.st-no { font-family: "JetBrains Mono", "SF Mono", Consolas, monospace; font-size: 13px; font-weight: 700;
  color: var(--gold); letter-spacing: .5px; font-variant-numeric: tabular-nums;
  min-width: 210px; text-align: center; padding: 4px 10px; border-radius: 8px;
  background: var(--surface-2); border: 1px solid var(--border);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-copy { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 8px; cursor: pointer; line-height: 1;
  font-size: 15px; background: var(--surface); color: var(--text-soft); border: 1px solid var(--border);
  transition: background .15s, color .15s, transform .12s; }
.st-copy:hover:not(:disabled) { background: var(--neon-2); color: #08101a; border-color: var(--neon-2); }
.st-copy:disabled { opacity: .4; cursor: not-allowed; }
.st-copy.copied { background: var(--get, #16a34a); color: #fff; border-color: var(--get, #16a34a); transform: scale(1.08); }

/* ---- 本局贏分計量區 ---- */
.win-meter { display: flex; align-items: center; justify-content: space-around; gap: 10px; margin-bottom: 10px;
  background: linear-gradient(180deg, rgba(255,210,74,.08), transparent); border: 1px solid var(--border);
  border-radius: 10px; padding: 7px 14px; }
/* [Claude Code 2026-06-29] 盤面正上方一排：本局贏分 + 餘額（玩遊戲時餘額好找）*/
.wm-group { display: flex; align-items: center; gap: 8px; }
.wm-balance { border-left: 1px solid var(--border); padding-left: 16px; }
.wm-balance .wm-value { color: var(--gold, #ffd24a); }
.wm-label { font-size: 12px; color: var(--text-soft); letter-spacing: 1px; }
.wm-value { font-size: 24px; font-weight: 900; color: var(--win); text-shadow: 0 0 10px rgba(255,225,105,.4);
  font-variant-numeric: tabular-nums; }
.wm-value.bump { animation: wmBump .3s ease; }
@keyframes wmBump { 0%{transform:scale(1)} 40%{transform:scale(1.25)} 100%{transform:scale(1)} }
/* [Claude Code 2026-06-29] 領獎慶祝彈窗（任務/升級領取）—— 中央金幣 + 標籤 + 金額，彈起放大再淡出 */
.reward-burst { position: fixed; left: 50%; top: 42%; transform: translate(-50%, -50%); z-index: 120;
  text-align: center; pointer-events: none; animation: rbPop 1.6s ease forwards; }
.reward-burst .rb-coins { font-size: 40px; letter-spacing: 6px; animation: rbCoins 1.6s ease forwards; }
.reward-burst .rb-label { font-size: 15px; font-weight: 800; color: #fff; letter-spacing: 1px; margin-top: 4px;
  text-shadow: 0 2px 8px rgba(0,0,0,.6); }
.reward-burst .rb-amt { font-size: 40px; font-weight: 900; color: var(--gold, #ffd24a);
  text-shadow: 0 0 16px rgba(255,210,74,.8), 0 2px 6px rgba(0,0,0,.6); font-variant-numeric: tabular-nums; }
@keyframes rbPop { 0% { opacity: 0; transform: translate(-50%, -40%) scale(.5); } 18% { opacity: 1; transform: translate(-50%, -50%) scale(1.15); }
  30% { transform: translate(-50%, -50%) scale(1); } 78% { opacity: 1; transform: translate(-50%, -54%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -70%) scale(.95); } }
@keyframes rbCoins { 0%,100% { transform: translateY(0); } 30% { transform: translateY(-8px); } 60% { transform: translateY(2px); } }

/* ---- AUTO 按鈕 ---- */
.auto-btn.auto-on { border-color: var(--neon); color: var(--neon); box-shadow: 0 0 12px rgba(255,61,240,.4); }

/* ---- modal 表單欄位（AUTO 設定）---- */
.field { display: block; color: var(--text-soft); font-size: 14px; margin: 10px 0 4px; }
.field select { margin-left: 8px; background: var(--surface-2); color: var(--text); border: 1px solid var(--border);
  padding: 6px 10px; border-radius: 8px; font-size: 14px; }
.field-title { color: var(--text-soft); font-size: 13px; margin: 14px 0 6px; }
.check { display: flex; align-items: center; gap: 8px; color: var(--text); font-size: 14px; margin: 8px 0; }
.check input[type="number"] { background: var(--surface-2); color: var(--text); border: 1px solid var(--border);
  border-radius: 6px; padding: 4px 6px; margin: 0 4px; }

/* ---- 翻倍按鈕（中獎後亮起，opt-in）---- */
/* [claude code] 2026-07-29 v2.22 翻倍鈕併進控制列第二排（原 .gamble-dock 已移除）：常駐 + 未中獎 disabled */
.gamble-btn { display: block; margin: 0 auto; padding: 9px 22px; border-radius: 999px; cursor: pointer;
  font-size: 15px; font-weight: 800; color: #2a1d00; border: none;
  background: linear-gradient(135deg, #ffe9a6, var(--gold)); box-shadow: 0 0 0 0 rgba(255,210,74,.6); }
.gamble-btn:disabled { opacity: .38; cursor: default; filter: grayscale(.5); }
.gamble-btn.armed { animation: gPulse 1.3s ease-in-out infinite; }
@keyframes gPulse { 0%,100%{ box-shadow: 0 0 10px 0 rgba(255,210,74,.5); } 50%{ box-shadow: 0 0 20px 6px rgba(255,210,74,.35); transform: scale(1.03); } }

/* ---- 翻倍玩法視窗 ---- */
.gamble-card { width: 330px; text-align: center; }
.gamble-stake { font-size: 16px; color: var(--text); margin: 4px 0; }
.gamble-stake span { color: var(--win); font-weight: 900; font-size: 22px; }
.gamble-board { position: relative; margin: 16px 0 4px; }
.gamble-choices { display: flex; gap: 14px; }
.gamble-color { flex: 1; padding: 20px 0; border-radius: 14px; border: 2px solid var(--border); cursor: pointer;
  font-size: 26px; color: #fff; transition: transform .12s, box-shadow .15s; }
.gamble-color span { display: block; font-size: 14px; font-weight: 800; margin-top: 2px; }
.gamble-color.red { background: linear-gradient(160deg, #ff5b6d, #c81e3a); }
.gamble-color.black { background: linear-gradient(160deg, #3a3f52, #14171f); }
.gamble-color:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(0,0,0,.5); }
.gamble-color:disabled { opacity: .5; cursor: not-allowed; }
/* 揭曉反饋：大 ✓×2 / ✗ + 綠/紅徑向閃光，蓋在選色上 */
.gamble-reveal { position: absolute; inset: -6px; display: flex; align-items: center; justify-content: center;
  border-radius: 16px; font-size: 46px; font-weight: 900; opacity: 0; visibility: hidden; pointer-events: none; }
.gamble-reveal.show { opacity: 1; visibility: visible; animation: gReveal .4s ease; }
.gamble-reveal.win { color: #aef5c0; background: radial-gradient(circle, rgba(46,230,166,.45), rgba(46,230,166,.05) 70%);
  text-shadow: 0 0 18px #2ee6a6; }
.gamble-reveal.lose { color: #ffb3b3; background: radial-gradient(circle, rgba(255,77,109,.45), rgba(255,77,109,.05) 70%);
  text-shadow: 0 0 18px #ff4d6d; }
@keyframes gReveal { 0%{ transform: scale(.4); opacity: 0; } 60%{ transform: scale(1.15); } 100%{ transform: scale(1); opacity: 1; } }
/* 開牌路單 */
.gamble-trail { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 12px 0; flex-wrap: wrap; }
.gt-label { font-size: 12px; color: var(--text-mute, #8b91a3); }
.gt-dots { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.g-dot { width: 11px; height: 11px; border-radius: 50%; display: inline-block; }
.g-dot.red { background: #ff4d6d; } .g-dot.black { background: #6b7280; }
.gt-empty { font-size: 12px; color: var(--text-soft); }
.g-tally { font-size: 12px; color: var(--text-soft); margin-left: 4px; }

/* ---- Hold & Win 鎖幣重轉 ---- */
/* 金幣符號（COIN）：金色光暈，holdwin 款的核心符號 */
.cell.sym-COIN .glyph { filter: drop-shadow(0 0 8px rgba(255,210,74,.85)); }
.cell.sym-COIN { background: radial-gradient(circle at 50% 45%, rgba(255,210,74,.22), transparent 70%); }
/* 鎖定金幣：金框 + 面額徽章 */
.cell.hw-lock { box-shadow: inset 0 0 0 2px var(--gold), 0 0 14px rgba(255,210,74,.5); border-radius: 8px; }
.cell.hw-lock.hw-pop { animation: hwPop .35s ease; }
@keyframes hwPop { 0%{ transform: scale(.4); opacity:.2; } 60%{ transform: scale(1.18); } 100%{ transform: scale(1); opacity:1; } }
.hw-val { position: absolute; left: 50%; bottom: 6px; transform: translateX(-50%);
  background: linear-gradient(135deg, #ffe9a6, var(--gold)); color: #2a1d00;
  font-size: 11px; font-weight: 900; padding: 1px 7px; border-radius: 999px;
  font-variant-numeric: tabular-nums; box-shadow: 0 1px 3px rgba(0,0,0,.4); white-space: nowrap; z-index: 6; }
/* 重轉中：未鎖定（空）格「靜態」變暗 → 讓鎖定金幣明顯突出（不再無意義一直閃）。 */
.cell.hw-dim { opacity: .28; filter: grayscale(.5); transition: opacity .2s; }
/* 落新幣前：該空格一次性快閃一下（不是無限），暗示「這格在轉」。 */
.cell.hw-spin { animation: hwSpin .45s ease; }
@keyframes hwSpin { 0%{ filter: brightness(.5); } 50%{ filter: brightness(1.5); } 100%{ filter: brightness(1); } }
/* HUD（重轉次數 + 收集總額）覆在盤面上方 */
.hw-hud { position: absolute; top: 6px; left: 50%; transform: translateX(-50%); z-index: 7;
  display: flex; align-items: center; gap: 14px; padding: 7px 18px; border-radius: 999px;
  background: rgba(8,16,26,.9); border: 1px solid var(--gold); box-shadow: 0 4px 16px rgba(0,0,0,.6);
  backdrop-filter: blur(3px); white-space: nowrap; }
.hw-title { font-size: 12px; font-weight: 900; color: var(--gold); letter-spacing: 1px; }
.hw-respins { font-size: 13px; color: var(--text); }
.hw-respins span { font-weight: 900; color: var(--neon-2); font-size: 18px; display: inline-block; min-width: 14px; text-align: center; }
/* 落新幣 → 重轉次數重置，數字跳一下（讓玩家看出「重置了」）。 */
.hw-respins span.reset { animation: hwReset .5s ease; color: var(--gold); }
@keyframes hwReset { 0%{ transform: scale(2); text-shadow: 0 0 14px var(--gold); } 100%{ transform: scale(1); } }
.hw-collect { font-size: 15px; font-weight: 900; color: var(--win); font-variant-numeric: tabular-nums; }
.hw-collect.bump { animation: wmBump .3s ease; }

/* ---- Candy 消除掉落（scatter-pays），三段表演：高亮 → 消除露空格 → 掉落補位 ---- */
/* 1) 中獎符「閃爍」（持續一閃一閃，停一下讓玩家看清中了什麼） */
.cell.cs-win { z-index: 4; }
.cell.cs-win .glyph { animation: csWin .34s ease-in-out infinite alternate; }
@keyframes csWin { from{ transform: scale(1); filter: none; } to{ transform: scale(1.2); filter: brightness(1.75) drop-shadow(0 0 11px var(--win)); } }
/* 2) 消除（放大一下再縮成 0 + 淡出，露出空格） */
.cell.cs-clear .glyph { animation: csClear .3s ease forwards; }
@keyframes csClear { 0%{ transform: scale(1.2); opacity: 1; filter: brightness(1.75); } 35%{ transform: scale(1.4); opacity: 1; } 100%{ transform: scale(0); opacity: 0; } }
/* 3) 掉落補位：survivor 從原位往下掉、新符從盤面上方掉入。距離用 --drop-from（px，負=從上方）。 */
.cell.cs-drop .glyph { animation: csDrop var(--drop-ms, 520ms) cubic-bezier(.33,1.06,.5,1) both; }
/* 🔴 WILD / SCATTER 的外框(::before)與角標(::after)**要跟著符號一起掉**（使用者：「scatter 框會在原地,
   等飛機掉下來,理論上應該要在一起」）。成因：掉落 / 中獎 / 消除這三支通用動畫都掛在子元素 `.glyph` 上，
   而框與角標是掛在 `.cell` 上的偽元素 → 符號在動、框卻黏在終點。
   ⚠️ 這兩個偽元素本來就沒有自己的 transform（純 inset / top-left 定位），套上去不會打架。
   **這是全平台通用修正**，不是哪一款專屬的。 */
.cell.cs-drop::before, .cell.cs-drop::after { animation: csDrop var(--drop-ms, 520ms) cubic-bezier(.33,1.06,.5,1) both; }
.cell.cs-win::before, .cell.cs-win::after { animation: csWin .34s ease-in-out infinite alternate; }
.cell.cs-clear::before, .cell.cs-clear::after { animation: csClear .3s ease forwards; }
@keyframes csDrop { from{ transform: translateY(var(--drop-from, -100%)); opacity: .35; } to{ transform: translateY(0); opacity: 1; } }
/* 倍率糖面值徽章（免費期） */
.cs-bombv { position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
  background: linear-gradient(135deg, #fff0a6, var(--gold)); color: #7a1d6b;
  font-size: 13px; font-weight: 900; padding: 2px 8px; border-radius: 999px;
  border: 2px solid #fff; box-shadow: 0 0 10px rgba(255,210,74,.8); z-index: 6; white-space: nowrap; }
.cell.cs-bombfire { animation: csBombFire .6s ease infinite; }
@keyframes csBombFire { 0%,100%{ filter: brightness(1); } 50%{ filter: brightness(1.8) drop-shadow(0 0 10px var(--gold)); } }

/* [claude code] 2026-08-15 v2.99 原本這裡是 `.serve-heat-badge`（烈日冰舖自製的 🔥×N 徽章）——
   已改用全平台通用的倍率條（`#gameMult` + `.ui-multbar`），整組移除。
   🔥 仍然會從盤面飛過去，只是目標換成倍率條上那顆亮著的 chip（見 app.js 的 serveMultTarget）。 */
/* 盤面 🔥 飄向倍數徽章（fixed，飛行途中放大發光→縮進徽章） */
.serve-heat-fly { position: fixed; z-index: 24; pointer-events: none; font-size: 30px;
  filter: drop-shadow(0 0 10px #ff6a3c); will-change: transform, opacity; }
/* 初始盤 🔥 待飄前的脈動提示 */
.cell.serve-heat-wait .glyph { animation: shWait .7s ease-in-out infinite; }
@keyframes shWait { 0%,100%{ filter: drop-shadow(0 0 3px #ff7a3c); transform: scale(1);} 50%{ filter: drop-shadow(0 0 12px #ff3d6e); transform: scale(1.18);} }

/* [claude code] 2026-07-18 v2.0 盤面熱度層：有火 → 盤上透出紅光，火愈多（倍數愈高）愈紅愈燙（hot1→hot4）。
   蓋在盤面上、不吃點擊；用漸層 + 混色，高熱度加「熱浪抖動」動畫。*/
.serve-heat-layer { position: absolute; inset: -4px; border-radius: 14px; pointer-events: none; z-index: 8;
  opacity: 0; transition: opacity .5s ease; mix-blend-mode: screen;
  background: radial-gradient(120% 90% at 50% 108%, rgba(255,90,40,.0), rgba(255,60,40,.0)); }
.serve-heat-layer.on { opacity: 1; }
.serve-heat-layer.hot1 { background: radial-gradient(130% 95% at 50% 110%, rgba(255,150,60,.30), rgba(255,110,50,.10) 55%, transparent 78%); }
.serve-heat-layer.hot2 { background: radial-gradient(130% 100% at 50% 110%, rgba(255,130,50,.46), rgba(255,80,40,.20) 58%, transparent 82%); }
.serve-heat-layer.hot3 { background: radial-gradient(135% 105% at 50% 112%, rgba(255,95,40,.60), rgba(255,55,45,.30) 60%, rgba(220,30,60,.10) 85%);
  box-shadow: inset 0 -30px 60px rgba(255,70,40,.35); }
.serve-heat-layer.hot4 { background: radial-gradient(140% 115% at 50% 114%, rgba(255,70,35,.74), rgba(255,40,45,.42) 55%, rgba(200,20,70,.18) 88%);
  box-shadow: inset 0 -40px 80px rgba(255,50,35,.5); animation: shHeatWave 1.1s ease-in-out infinite; }
.serve-heat-layer.hot3 { animation: shHeatWave 1.6s ease-in-out infinite; }
@keyframes shHeatWave { 0%,100%{ filter: brightness(1) saturate(1); transform: translateY(0) scaleY(1); }
  50%{ filter: brightness(1.22) saturate(1.25); transform: translateY(-2px) scaleY(1.03); } }

/* ---- Ways / Megaways 變動高度盤面 ---- */
.board.ways-board { display: flex !important; gap: 5px; align-items: center; justify-content: center; }
.ways-reel { display: flex; flex-direction: column; justify-content: center; gap: 5px; }
.ways-cell { position: relative; flex: 0 0 auto; display: flex; align-items: center; justify-content: center;
  background: var(--surface-2); border-radius: 8px; left: auto; right: auto; top: auto; }
/* 消除掉落款（ways / cluster）：WILD/SCATTER 的框做在 .glyph 上（不是 .cell）→ 掉落時框跟符號一起動、不分離、不被裁。 */
.ways-cell.sym-WILD::before, .ways-cell.sym-WILD::after,
.ways-cell.sym-SCATTER::before, .ways-cell.sym-SCATTER::after,
.clus-cell.sym-WILD::before, .clus-cell.sym-WILD::after,
.clus-cell.sym-SCATTER::before, .clus-cell.sym-SCATTER::after { display: none; }
.ways-cell.sym-WILD .glyph, .ways-cell.sym-SCATTER .glyph,
.clus-cell.sym-WILD .glyph, .clus-cell.sym-SCATTER .glyph { box-sizing: border-box; font-size: .78em; padding: 6px; border-radius: 11px; }
.ways-cell.sym-WILD .glyph, .clus-cell.sym-WILD .glyph { box-shadow: inset 0 0 0 2.5px var(--gold), 0 0 7px rgba(255,210,74,.55); }
.ways-cell.sym-SCATTER .glyph, .clus-cell.sym-SCATTER .glyph { box-shadow: inset 0 0 0 2.5px #34e0ff, 0 0 7px rgba(52,224,255,.55); }
.ways-cell.sym-WILD .glyph::after, .ways-cell.sym-SCATTER .glyph::after,
.clus-cell.sym-WILD .glyph::after, .clus-cell.sym-SCATTER .glyph::after {
  position: absolute; top: -6px; left: 50%; transform: translateX(-50%); z-index: 3; pointer-events: none;
  font-size: 8px; font-weight: 900; letter-spacing: .03em; line-height: 1.3; padding: 1px 5px; border-radius: 6px;
  white-space: nowrap; box-shadow: 0 1px 3px rgba(0,0,0,.55); }
.ways-cell.sym-WILD .glyph::after, .clus-cell.sym-WILD .glyph::after { content: "WILD"; background: linear-gradient(#ffe9a6, var(--gold)); color: #2a1d00; }
.ways-cell.sym-SCATTER .glyph::after, .clus-cell.sym-SCATTER .glyph::after { content: "SCATTER"; background: linear-gradient(#bff4ff, #34e0ff); color: #042530; }

/* ---- Cluster 群落消除（N×N CSS grid）---- */
.board.clus-board { display: grid !important; gap: 4px; justify-content: center; }
.clus-cell { position: relative; display: flex; align-items: center; justify-content: center;
  background: var(--surface-2); border-radius: 8px; left: auto; right: auto; top: auto; }

/* ---- 遠古巨獸（colossal 巨型符號 6×4 CSS grid + k×k 方塊 overlay）---- */
.board.colossal-board { display: grid !important; gap: 5px; justify-content: center; align-content: center; }
.col-cell { position: relative; display: flex; align-items: center; justify-content: center;
  left: auto; right: auto; top: auto; border-radius: 10px;
  background: linear-gradient(160deg, #141d33, #0d1424); box-shadow: inset 0 0 0 1px rgba(255,255,255,.05); }
.col-cell .glyph { line-height: 1; }
/* [claude code] 2026-07-12 不賠付的叢林雜物 → 去彩度 + 壓暗，讓「會賠的巨獸」在盤面一眼跳出來 */
.col-low { background: linear-gradient(160deg, #10131c, #0a0d15); opacity: .62; }
.col-low .glyph { filter: grayscale(.85) brightness(.75); }
/* 會賠的 4 隻巨獸 → 醒目：彩色 tier 邊框（下方 col-t0..3）+ 微微放大字，跟雜物拉開對比 */
.col-beast .glyph { transform: scale(1.06); filter: drop-shadow(0 0 4px rgba(255,255,255,.15)); }
.col-beast.col-t0 { background: linear-gradient(160deg, #3a1620, #1a0d12); box-shadow: inset 0 0 0 2px rgba(255,110,90,.55), 0 0 10px rgba(255,90,70,.22); }
.col-beast.col-t1 { background: linear-gradient(160deg, #2a1838, #150c1e); box-shadow: inset 0 0 0 2px rgba(190,120,255,.5), 0 0 9px rgba(170,107,255,.2); }
.col-beast.col-t2 { background: linear-gradient(160deg, #10283a, #0a1622); box-shadow: inset 0 0 0 2px rgba(90,200,255,.5), 0 0 9px rgba(70,180,255,.2); }
.col-beast.col-t3 { background: linear-gradient(160deg, #12321f, #0a1c12); box-shadow: inset 0 0 0 2px rgba(110,230,140,.5), 0 0 9px rgba(90,220,120,.2); }
.col-wild { background: linear-gradient(160deg, #3a2a0a, #241803); box-shadow: inset 0 0 0 2px var(--gold, #ffd24a), 0 0 12px rgba(255,180,40,.4); }
.col-wild .glyph { filter: drop-shadow(0 0 6px rgba(255,210,74,.7)); }
.col-scatter { background: linear-gradient(160deg, #06303c, #04202a); box-shadow: inset 0 0 0 2px #34e0ff, 0 0 12px rgba(52,224,255,.5); }
.col-scatter .glyph { filter: drop-shadow(0 0 7px rgba(52,224,255,.7)); animation: colScatPulse 1s ease-in-out infinite; }
@keyframes colScatPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.12); } }
/* k×k 巨型方塊 overlay（靠左踏入；預設暴龍金框 = t0，其餘 tier 換框色）*/
.col-colossal { position: relative; display: flex; align-items: center; justify-content: center; border-radius: 12px; z-index: 5;
  background: radial-gradient(circle at 40% 30%, rgba(255,220,120,.26), rgba(0,0,0,.15));
  box-shadow: inset 0 0 0 3px var(--gold, #ffd24a), 0 0 24px rgba(255,190,60,.5); }
.col-colossal.col-t1 { box-shadow: inset 0 0 0 3px #c58bff, 0 0 24px rgba(170,107,255,.5); }
.col-colossal.col-t2 { box-shadow: inset 0 0 0 3px #5ac8ff, 0 0 24px rgba(70,180,255,.5); }
.col-colossal.col-t3 { box-shadow: inset 0 0 0 3px #6ee68c, 0 0 24px rgba(90,220,120,.5); }
.col-colossal .glyph { filter: drop-shadow(0 0 10px rgba(255,255,255,.35)); }
.col-cell.cs-win, .col-colossal.cs-win { box-shadow: inset 0 0 0 3px var(--win, #ffe169), 0 0 20px var(--win, #ffe169); z-index: 6; }
.col-cell.cs-win .glyph { animation: csWin .34s ease-in-out infinite alternate; }
.col-cell.mb-drop { animation: colDrop .42s cubic-bezier(.33,1.06,.5,1) both; animation-delay: var(--mb-delay, 0ms); }
@keyframes colDrop { from { transform: translateY(-38px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
.col-colossal.mb-stomp { animation: colStomp .5s cubic-bezier(.2,.9,.25,1.2) both; }
@keyframes colStomp { 0% { transform: scale(.25); opacity: 0; } 60% { transform: scale(1.08); opacity: 1; } 100% { transform: scale(1); } }
/* 遠古巨獸賠付表：會賠 / 不賠 分區 + 符號 chip + 算分說明 */
.col-pay-head { margin: 12px 0 6px; font-size: 13px; font-weight: 800; }
.col-pay-head.yes { color: #6ee68c; }
.col-pay-head.no { color: #ff7a90; }
.col-pay-head.sp { color: var(--gold, #ffd24a); }
.col-symrow { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 2px; }
.col-symchip { display: inline-flex; align-items: center; gap: 3px; padding: 4px 9px; border-radius: 999px;
  font-size: 13px; font-weight: 700; border: 1.5px solid transparent; }
.col-symchip.pay { background: rgba(110,230,140,.14); border-color: rgba(110,230,140,.55); color: #d7ffe4; }
.col-symchip.nopay { background: rgba(255,122,144,.1); border-color: rgba(255,122,144,.4); color: #ffd6dd;
  filter: grayscale(.5); text-decoration: line-through; text-decoration-color: rgba(255,122,144,.7); }
.col-symchip.wild { background: rgba(255,210,74,.13); border-color: rgba(255,210,74,.5); color: #ffe9a6; }
.col-symchip.scat { background: rgba(52,224,255,.12); border-color: rgba(52,224,255,.5); color: #bff4ff; }
.col-howto { font-size: 12.5px; line-height: 1.85; color: var(--mut, #b9c2d6); background: rgba(255,255,255,.03);
  border-left: 3px solid var(--gold, #ffd24a); border-radius: 6px; padding: 9px 11px; margin: 4px 0 2px; }
.col-howto b { color: var(--text, #eef); }

/* ---- 轉盤 Bonus overlay ---- */
.wheel-overlay { position: absolute; inset: 0; z-index: 20; display: none;
  flex-direction: column; align-items: center; justify-content: center; gap: 14px;
  background: radial-gradient(circle at 50% 40%, rgba(40,10,50,.92), rgba(8,8,20,.96));
  border-radius: 14px; padding: 16px; }
.wheel-overlay.show { display: flex; animation: lineIn .3s ease; }
.wheel-title { font-size: 20px; font-weight: 900; color: var(--gold); letter-spacing: 1px;
  text-shadow: 0 0 16px rgba(255,210,74,.7); }
/* 圓形轉盤：旋轉圓盤（conic 分段）+ 固定指針 + 中心軸 */
.wheel-circle { position: relative; width: 248px; height: 248px; max-width: 80vw; max-height: 80vw; }
.wheel-disc { position: absolute; inset: 0; border-radius: 50%;
  border: 5px solid var(--gold); box-shadow: 0 0 26px rgba(255,210,74,.5), inset 0 0 22px rgba(0,0,0,.45);
  transform: rotate(0deg); will-change: transform; }
.wheel-label { position: absolute; top: 50%; left: 50%; font-size: 12px; font-weight: 900;
  color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.85); white-space: nowrap; pointer-events: none;
  transition: filter .2s ease; }
.wheel-label.win { filter: drop-shadow(0 0 7px var(--win)) brightness(1.25); font-size: 13px; }
.wheel-hub { position: absolute; top: 50%; left: 50%; width: 36px; height: 36px;
  transform: translate(-50%, -50%); border-radius: 50%; z-index: 3;
  background: radial-gradient(circle at 40% 35%, #ffe9a6, var(--gold) 55%, #8a5a00);
  border: 3px solid #fff; box-shadow: 0 2px 6px rgba(0,0,0,.5); }
.wheel-pointer { position: absolute; top: -8px; left: 50%; transform: translateX(-50%);
  width: 0; height: 0; border-left: 14px solid transparent; border-right: 14px solid transparent;
  border-top: 24px solid var(--win); z-index: 4; filter: drop-shadow(0 2px 3px rgba(0,0,0,.55)); }
.wheel-result { font-size: 22px; font-weight: 900; color: var(--win); min-height: 28px;
  text-shadow: 0 0 14px rgba(255,225,105,.6); }

/* ---- 開寶箱 Pick-em overlay（bothways 款）---- */
.pickme-overlay { position: absolute; inset: 0; z-index: 20; display: none;
  flex-direction: column; align-items: center; justify-content: center; gap: 12px;
  background: radial-gradient(circle at 50% 35%, rgba(16,46,40,.94), rgba(6,10,18,.97));
  border-radius: 14px; padding: 16px; }
.pickme-overlay.show { display: flex; animation: lineIn .3s ease; }
.pickme-title { font-size: 20px; font-weight: 900; color: var(--gold); letter-spacing: 1px;
  text-shadow: 0 0 16px rgba(255,210,74,.7); }
.pickme-sub { font-size: 13px; color: var(--text-soft); }
.pickme-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; width: 100%; max-width: 320px; }
.pickme-chest { aspect-ratio: 1; border-radius: 10px; display: flex; align-items: center; justify-content: center;
  font-size: 26px; background: var(--surface-2); border: 2px solid var(--border); cursor: default;
  transition: transform .12s ease; }
.pickme-chest.opening { transform: scale(1.14); box-shadow: 0 0 16px var(--gold); border-color: var(--gold); }
.pickme-chest.prize { background: linear-gradient(135deg, rgba(212,160,23,.28), rgba(31,138,112,.2));
  border-color: var(--gold); }
.pickme-chest .pc-val { font-size: 12px; font-weight: 900; color: var(--gold); }
.pickme-chest.end { background: linear-gradient(135deg, rgba(220,40,60,.4), rgba(40,8,14,.6));
  border-color: #ff5d6d; box-shadow: 0 0 18px rgba(255,93,109,.7); }
.pickme-collect { font-size: 22px; font-weight: 900; color: var(--win); min-height: 28px;
  text-shadow: 0 0 14px rgba(255,225,105,.6); }
.pickme-collect.bump { animation: wmBump .3s ease; }

/* ---- 淨化光稜：光稜發光 / 雜符被射閃光（mechanic=laser，重用 cs-* 掉落視覺）---- */
.cell.lp-laser { box-shadow: inset 0 0 16px rgba(54,224,255,.85), 0 0 14px rgba(54,224,255,.6); border-radius: 8px; z-index: 4; }
.cell.lp-laser .glyph { animation: lpLaser .42s ease infinite alternate; filter: drop-shadow(0 0 12px #36e0ff); }
.cell.lp-hit { animation: lpHit .32s ease; box-shadow: inset 0 0 14px rgba(255,95,120,.9); border-radius: 8px; }
@keyframes lpLaser { from { transform: scale(1); } to { transform: scale(1.22); } }
@keyframes lpHit { 0% { filter: brightness(1); } 45% { filter: brightness(2.3) drop-shadow(0 0 9px #fff); } 100% { filter: brightness(1); } }
/* 光稜連線（SVG polyline，畫在 #lineLayer）：虛線 —— 青色光暈 + 白色芯，柔和淡入 */
/* [Claude Code 2026-06-28] 閃電由實線改虛線（stroke-dasharray）*/
.bolt { fill: none; stroke: #36e0ff; stroke-width: 3; stroke-linecap: round;
  stroke-dasharray: 7 6; filter: drop-shadow(0 0 5px #36e0ff); opacity: .85; animation: boltFade .3s ease both; }
.bolt-core { fill: none; stroke: #ffffff; stroke-width: 1.3; stroke-linecap: round;
  stroke-dasharray: 7 6; opacity: .9; animation: boltFade .3s ease both; }
@keyframes boltFade { from { opacity: 0; } to { opacity: .88; } }

/* ---- [claude code] 2026-07-11 爆裂礦坑 Boom mine：炸彈落盤幾何爆炸 ---- */
/* 炸彈格點亮（依型別上色：0 直炸=橙 / 1 橫炸=金 / 2 圈炸=紅）*/
.cell.bm-bomb { border-radius: 8px; z-index: 4; box-shadow: inset 0 0 16px rgba(255,150,60,.85), 0 0 14px rgba(255,120,40,.6); }
.cell.bm-bomb .glyph { animation: bmArm .38s ease infinite alternate; filter: drop-shadow(0 0 12px #ff8a3c); }
@keyframes bmArm { from { transform: scale(1); } to { transform: scale(1.2); } }
/* 爆炸範圍逐格閃（--bm-bd 由 JS 設每格延遲 → 由炸彈往外 sweep）*/
.cell.bm-blast { border-radius: 8px; z-index: 3; animation: bmBlast .34s ease both; animation-delay: var(--bm-bd, 0ms); }
@keyframes bmBlast {
  0% { filter: brightness(1); box-shadow: none; }
  40% { filter: brightness(2.4) drop-shadow(0 0 10px #fff); box-shadow: inset 0 0 18px rgba(255,190,90,.95), 0 0 16px rgba(255,120,40,.8); }
  100% { filter: brightness(1); box-shadow: none; }
}
/* 炸彈型別配色（點亮 + 爆炸共用）*/
.cell.bm-bt0 { box-shadow: inset 0 0 16px rgba(255,150,60,.85), 0 0 14px rgba(255,120,40,.6); }   /* 直炸：橙 */
.cell.bm-bt1 { box-shadow: inset 0 0 16px rgba(255,214,90,.85), 0 0 14px rgba(255,190,60,.6); }   /* 橫炸：金 */
.cell.bm-bt2 { box-shadow: inset 0 0 16px rgba(255,90,90,.9), 0 0 15px rgba(255,60,60,.7); }       /* 圈炸：紅 */

/* [claude code] 2026-07-11 🛒 礦車 crash bonus 表演 overlay（蓋在 .board-wrap 上，動態建）——
   礦車沿軌道經過檢查點 ×1/2/3/5/10/30，停在 server 預定倍數處、🪨 石頭擋住。移植 slot_town lp-crash 系統 */
.bm-cart-ov { position: absolute; inset: 0; z-index: 30; display: grid; place-items: center; border-radius: 12px;
  background: rgba(20,10,4,.82); opacity: 0; transition: opacity .26s ease; pointer-events: none; }
.bm-cart-ov.show { opacity: 1; }
.bm-cart-box { text-align: center; width: 100%; }
.bm-cart-title { font-size: 1.05rem; font-weight: 900; color: #ffd24a; margin-bottom: 6px; text-shadow: 0 0 10px rgba(255,150,50,.6); }
.bm-cart-track { position: relative; width: min(86%, 360px); height: 60px; margin: 12px auto 8px; }
.bm-rail { position: absolute; left: 4%; right: 4%; top: 40px; height: 4px; border-radius: 3px;
  background: linear-gradient(90deg, rgba(255,157,60,.25), rgba(255,200,90,.6)); }
.bm-cp { position: absolute; top: 30px; transform: translateX(-50%); text-align: center; }
.bm-cp-dot { display: block; width: 9px; height: 9px; margin: 0 auto; border-radius: 50%;
  background: #4a2f14; border: 1px solid rgba(255,157,60,.5); transition: all .2s; }
.bm-cp-lab { display: block; font-size: .6rem; color: #b88a5a; margin-top: 4px; transition: color .2s; white-space: nowrap; }
.bm-cp.passed .bm-cp-dot { background: #ffce6a; border-color: #fff; box-shadow: 0 0 8px 2px rgba(255,206,106,.85); }
.bm-cp.passed .bm-cp-lab { color: #ffce6a; font-weight: 800; }
.bm-cart { position: absolute; top: 4px; font-size: 1.7rem; transform: translateX(-50%); z-index: 3;
  transition: left .42s cubic-bezier(.4,.1,.5,1); filter: drop-shadow(0 3px 4px rgba(0,0,0,.6)); }
.bm-cart.bm-cart-bump { animation: bmCartBump .4s ease; }
@keyframes bmCartBump { 0% { transform: translateX(-50%); } 28% { transform: translateX(-22%) rotate(6deg); } 100% { transform: translateX(-50%); } }
.bm-rock { position: absolute; top: 10px; font-size: 1.5rem; transform: translateX(-50%) scale(0); opacity: 0; z-index: 2;
  transition: transform .22s cubic-bezier(.34,1.5,.64,1), opacity .22s ease; }
.bm-rock.show { transform: translateX(-50%) scale(1); opacity: 1; }
.bm-cart-val { font-size: clamp(1.5rem, 8vw, 2.6rem); font-weight: 900; color: #ff9d3c; text-shadow: 0 0 18px rgba(255,150,50,.8); }
.bm-cart-val.bm-val-pop { animation: bmValPop .45s cubic-bezier(.2,1.4,.4,1), bmValPulse 1s ease-in-out .45s 2; }
@keyframes bmValPop { 0% { transform: scale(.4); opacity: 0; } 60% { transform: scale(1.25); opacity: 1; } 100% { transform: scale(1); } }
@keyframes bmValPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.08); } }

/* [claude code] 2026-08-14 v2.93 原本這裡是 `.bm-multbar`（爆裂礦坑專屬的倍率條定位）——
   已合併進通用的 `.game-multbar.pos-row`（見上面）。keyframes `bmChipPop` / `bmChipPopOn` 移到那裡。 */

/* ---- 無盡星河 Infinity：橫向可變軸數盤面 ---- */
/* [claude code] 2026-07-14 修「頁面冒上下捲軸 / 視窗先拉長才表演」：
   ① 高度由 JS 固定（infBoardHeight，以最大格 64 算）→ 不再隨軸數 / 格子縮放而變動，下面的控制列不會被推動。
   ② padding 10px + overflow:hidden → 接上定格的放大(inf-lock scale 1.12)與期待光暈都收在盤面內，
      不會撐出 body 的 scrollHeight（原本 overflow 只擋 x，垂直方向溢出就冒出捲軸）。
   ③ align-items:center → 格子變小時垂直置中留白，不會黏在頂端。 */
.board.inf-board { display: flex; flex-direction: row; align-items: center; justify-content: center;
  gap: 5px; overflow: hidden; padding: 10px 6px; }
.inf-reel { display: flex; flex-direction: column; gap: 4px; flex: 0 0 auto; }
/* ⚠️ 必須覆寫基礎 .cell 的 position:absolute（否則格子全疊在 top:0、reel 高度塌掉只剩一格）—— 比照 .ways-cell/.clus-cell */
.cell.inf-cell { position: relative; display: flex; align-items: center; justify-content: center; border-radius: 8px; }
.inf-reel.inf-grow { animation: infGrow .34s cubic-bezier(.2,.8,.25,1) both; }
@keyframes infGrow { 0% { opacity: 0; transform: translateX(22px) scale(.7); } 100% { opacity: 1; transform: none; } }
/* [claude code] 2026-07-12 星河生長期待表演：慢停翻滾（inf-antic，越長越亮）→ 接上定格 pop（inf-lock）；斷點軸灰掉（inf-breaker） */
.inf-reel.inf-antic { z-index: 3; animation: infAntic .42s ease-in-out infinite;
  box-shadow: 0 0 calc(5px + var(--inf-lvl, 0) * 2.5px) rgba(124,192,255,.6); border-radius: 8px; }
.inf-reel.inf-antic .glyph { animation: infRoll .13s linear infinite; }
@keyframes infAntic { 0%,100% { filter: brightness(1); } 50% { filter: brightness(1.55) drop-shadow(0 0 9px #8fd0ff); } }
@keyframes infRoll { 0% { opacity: .45; transform: translateY(-3px); } 100% { opacity: 1; transform: translateY(0); } }
.inf-reel.inf-lock { animation: infLock .32s cubic-bezier(.2,.9,.25,1.35) both; }
@keyframes infLock { 0% { transform: scale(.7); } 60% { transform: scale(1.12); } 100% { transform: scale(1); } }
.inf-reel.inf-breaker { opacity: .5; filter: grayscale(.65); }

/* ---- 中獎連線高亮（SVG 蓋層）---- */
.board-wrap { position: relative; }
.line-layer { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 5; overflow: visible; }
.win-line { fill: none; stroke: var(--win); stroke-width: 4; stroke-linejoin: round; stroke-linecap: round;
  filter: drop-shadow(0 0 6px var(--win)); opacity: .92; animation: lineIn .4s ease; }
@keyframes lineIn { from { opacity: 0; } to { opacity: .92; } }

/* ---- near-miss 期待停軸（差一個 scatter 就觸發）---- */
.reel.anticipate { animation: anticPulse .5s ease-in-out infinite; z-index: 3; }
@keyframes anticPulse { 0%,100%{ box-shadow: 0 0 0 0 rgba(52,224,255,.5); } 50%{ box-shadow: 0 0 22px 4px rgba(52,224,255,.55); } }
.board-wrap.anticipating .reel:not(.anticipate) { filter: brightness(.5); transition: filter .25s; }

/* ---- TURBO 加速鈕 ---- */
.turbo-btn.on { border-color: var(--gold); color: var(--gold); box-shadow: 0 0 12px rgba(255,210,74,.5); }

/* ---- 按下 SPIN 立即回饋 ---- */
.btn-spin.pressed { transform: scale(.95); filter: brightness(1.12); }

/* ---- [claude code] 2026-07-29 v2.22 控制列第二排（依使用者：改 slot_town 的做法）----
   SPIN 下面固定一排：[停止條件下拉][🔁 自動][🎲 翻倍]。取代原本的 AUTO 下接浮窗 + 翻倍獨立底座 —— 
   三個都常駐（翻倍未中獎時 disabled）→ 高度固定、不會忽有忽無把版面推來推去。*/
.control-row2 { display: flex; align-items: stretch; justify-content: center; gap: 8px;
  max-width: 420px; margin: 10px auto 0; }
.control-row2 .auto-stop-sel { flex: 1.15 1 0; min-width: 0; background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border); border-radius: 999px; padding: 0 10px; font-size: 13px; height: 42px; cursor: pointer; }
.control-row2 .auto-btn { flex: 1 1 0; height: 42px; padding: 0 10px; white-space: nowrap; }
.control-row2 .gamble-btn { flex: 1.2 1 0; height: 42px; padding: 0 10px; white-space: nowrap; }

/* ---- 任務 / 等級 ---- */
.meta-btn { position: relative; }
.meta-dot { position: absolute; top: 2px; right: 2px; width: 9px; height: 9px; border-radius: 50%;
  background: #ff4d6d; box-shadow: 0 0 6px #ff4d6d; }
.meta-card { width: 360px; max-width: calc(100vw - 32px); }
.meta-sec { margin-bottom: 18px; }
.meta-sec-head { font-weight: 800; color: var(--text); margin-bottom: 10px; display: flex; align-items: center; gap: 8px; }
.meta-sub { font-size: 12px; color: var(--text-soft); font-weight: 400; margin-left: auto; }
.lvl-badge { background: linear-gradient(135deg, var(--neon), var(--neon-2)); color: #0a0c16; font-weight: 900;
  padding: 2px 10px; border-radius: 999px; font-size: 13px; }
.lvl-bar { height: 12px; background: var(--surface-2); border-radius: 999px; overflow: hidden; border: 1px solid var(--border); }
.lvl-fill { height: 100%; background: linear-gradient(90deg, var(--neon), var(--neon-2)); transition: width .4s ease; }
.lvl-exp { font-size: 12px; color: var(--text-soft); text-align: right; margin: 4px 0 8px; }
.meta-claim { width: 100%; padding: 9px 0; border: none; border-radius: 10px; cursor: pointer; font-weight: 800;
  color: #2a1d00; background: linear-gradient(135deg, #ffe9a6, var(--gold)); }
.meta-claim:disabled { background: var(--surface-2); color: var(--text-mute, #8b91a3); cursor: not-allowed; }
.miss-list { display: flex; flex-direction: column; gap: 8px; }
.miss-row { display: flex; align-items: center; gap: 10px; }
.miss-info { flex: 1; }
.miss-need { font-size: 12px; color: var(--text-soft); margin-bottom: 3px; }
.miss-bar { height: 8px; background: var(--surface-2); border-radius: 999px; overflow: hidden; border: 1px solid var(--border); }
.miss-fill { height: 100%; background: linear-gradient(90deg, var(--neon-2), var(--neon)); }
.miss-claim { min-width: 62px; padding: 7px 10px; border: none; border-radius: 8px; cursor: pointer; font-weight: 800; font-size: 13px;
  color: #2a1d00; background: linear-gradient(135deg, #ffe9a6, var(--gold)); }
.miss-claim:disabled { background: var(--surface-2); color: var(--text-soft); cursor: not-allowed; }
.miss-claim.done { background: transparent; border: 1px solid var(--border); color: var(--get, #16a34a); }
.miss-step { color: var(--text-mute, #8b91a3); font-size: 11px; }
.miss-done-all { text-align: center; color: var(--get, #16a34a); font-weight: 700; padding: 10px 0; }

/* ---- 升級獎勵逐筆列（每筆標明等級、可個別領）---- */
.lvl-claims { display: flex; flex-direction: column; gap: 8px; }
.lvl-claim-none { color: var(--text-mute, #8b91a3); font-size: 13px; padding: 6px 2px; }
.lvl-claim-row { display: flex; align-items: center; gap: 10px; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: 10px; padding: 8px 12px; }
.lcr-label { flex: 1; font-weight: 700; color: var(--text); font-size: 13.5px; }
.lcr-btn { min-width: 92px; padding: 8px 12px; border: none; border-radius: 8px; cursor: pointer; font-weight: 800; font-size: 13px;
  color: #2a1d00; background: linear-gradient(135deg, #ffe9a6, var(--gold)); }
.lcr-btn:hover { filter: brightness(1.05); }

/* ---- 賠付 / 玩法 分頁 ---- */
.pt-tabs { display: flex; gap: 8px; margin-bottom: 12px; }
.pt-tab { flex: 1; padding: 8px 0; border: 1px solid var(--border); background: var(--surface-2);
  color: var(--text-soft); border-radius: 8px; cursor: pointer; font-size: 14px; font-weight: 600; }
.pt-tab.active { background: var(--neon-2); color: #08101a; border-color: var(--neon-2); }
.rule-row { display: grid; grid-template-columns: 92px 1fr; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.rule-t { font-weight: 700; color: var(--text); font-size: 13.5px; }
.rule-d { color: var(--text-soft); font-size: 13px; line-height: 1.55; }

/* ==== 賓果（lucky_bingo）：波動檔選擇 + 5×5 卡 + 開球托盤 ==== */
/* [Claude Code 2026-07-06] 底座是輪盤機器，賓果自成一路渲染，這整段是賓果專屬。 */

/* 波動檔選擇（保守 / 標準 / 衝刺）*/
.bingo-tiers { display: flex; gap: 8px; margin: 4px 0 10px; }
.bingo-tier { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 8px 4px; border: 1.5px solid var(--border); border-radius: 12px; cursor: pointer;
  background: var(--surface-2); color: var(--text-soft); transition: transform .1s, box-shadow .15s, border-color .15s; }
.bingo-tier:hover:not(:disabled) { transform: translateY(-1px); border-color: var(--neon-2); }
.bingo-tier:disabled { opacity: .55; cursor: default; }
.bingo-tier.sel { border-color: var(--neon-2); color: var(--text);
  background: linear-gradient(135deg, rgba(91,139,255,.28), rgba(176,107,255,.22));
  box-shadow: 0 0 0 1px var(--neon-2), 0 4px 16px rgba(91,139,255,.35); }
.bingo-tier .bt-name { font-weight: 800; font-size: 14px; }
.bingo-tier .bt-draw { font-size: 11px; opacity: .85; }

/* 5×5 賓果卡 */
.board.bingo-board { position: relative; display: grid; gap: 6px; padding: 8px; aspect-ratio: 1 / 1;
  background: linear-gradient(160deg, #1a1f3a, #141830); border-radius: 14px;
  box-shadow: inset 0 0 0 1px var(--border); }
.bingo-cell { position: relative; display: flex; align-items: center; justify-content: center;
  border-radius: 10px; background: #10132a; box-shadow: inset 0 0 0 1px #262c4c;
  font-weight: 800; font-size: clamp(14px, 5vw, 26px); color: var(--text);
  transition: transform .12s, background .18s, box-shadow .18s; user-select: none; }
.bingo-cell .bc-num { transition: color .18s; }
.bingo-cell.free { color: var(--gold); background: linear-gradient(160deg, #2a2340, #1c1832);
  box-shadow: inset 0 0 0 1.5px var(--gold), 0 0 10px rgba(255,210,74,.3); }
.bingo-cell.free .bc-free { font-size: 1.1em; text-shadow: 0 0 8px rgba(255,210,74,.7); }
/* 標記態：開球命中（[Claude Code 2026-07-08] 拿掉常駐 animation → 只有剛命中那格 .just-marked 才彈跳，
   否則每開一顆球整張卡的 marked 格都會重播一次彈跳，整個盤面跟著晃） */
.bingo-cell.marked { background: linear-gradient(160deg, #24407a, #1c3060);
  box-shadow: inset 0 0 0 1.5px var(--neon), 0 0 10px rgba(91,139,255,.4); color: #eaf1ff; }
.bingo-cell.just-marked { animation: bingoMark .3s ease; }
@keyframes bingoMark { 0% { transform: scale(.7); } 60% { transform: scale(1.12); } 100% { transform: scale(1); } }
/* 命中金球 */
.bingo-cell.gold { background: linear-gradient(160deg, #4a3a12, #6a4e14);
  box-shadow: inset 0 0 0 2px var(--gold), 0 0 14px rgba(255,210,74,.6); color: #fff3c8; }
.bingo-cell.gold::after { content: "🟡"; position: absolute; top: 2px; right: 3px; font-size: .5em; }
/* 完成線內的格：外光暈脈動（[Claude Code 2026-07-08] 放慢 1s→2s、收斂光暈範圍，減少「一直閃」的晃感） */
.bingo-cell.in-line { box-shadow: inset 0 0 0 2px var(--win), 0 0 12px rgba(255,225,105,.45);
  animation: bingoLine 2s ease-in-out infinite alternate; z-index: 2; }
@keyframes bingoLine { from { box-shadow: inset 0 0 0 2px var(--win), 0 0 8px rgba(255,225,105,.32); }
  to { box-shadow: inset 0 0 0 2px var(--win), 0 0 15px rgba(255,225,105,.6); } }

/* [Claude Code 2026-07-10] 做法 B — 差一格：這格再被開到就完成一條線。慢速脈動描邊，把期待感留在缺口上。
   [claude code] 2026-07-16 🔴 修「誤亮」（同 mjbingo v1.73 鐵則：提示樣式不可把未中格弄得像已亮）：
   原本 to 段帶外光暈 0 0 14px —— 未標記格是全亮底，掛上金框+外光暈看起來就跟 .in-line（已完成線）幾乎一樣
   → 玩家誤判它已中，結算拿掉時又「暗一下」。改成**只有內描邊脈動、無外光暈**，一眼就是「提示」不是「已中」。
   （.near 現在只在開球途中由 renderBingoCard(revealing=true) 套；結算 render 不套，收尾無跳動。） */
.bingo-cell.near { animation: bingoNear 1.1s ease-in-out infinite alternate; z-index: 3; }
@keyframes bingoNear {
  from { box-shadow: inset 0 0 0 2px rgba(255,225,105,.3); }
  to   { box-shadow: inset 0 0 0 2.5px rgba(255,225,105,.75); }
}

/* [Claude Code 2026-07-10] 做法 A — 連線掃光：完成線疊一條光束，看得出「這 5 格是一條線」。
   .bline 的 top/left/width/transform 由 JS（bingoLineStyle）算好塞進 style；
   .sweep = 這一球剛完成的線 → clip-path 由左掃到右現形一次，之後常駐。 */
.bingo-lines { position: absolute; inset: 8px; pointer-events: none; z-index: 4; }
.bline { position: absolute; height: 5px; border-radius: 999px; transform-origin: 50% 50%;
  background: linear-gradient(90deg, rgba(255,225,105,0), var(--win) 18%, #fff 50%, var(--win) 82%, rgba(255,225,105,0));
  box-shadow: 0 0 10px rgba(255,225,105,.75), 0 0 22px rgba(255,225,105,.35); opacity: .75; }
.bline.sweep { animation: bingoSweep .5s ease-out; }
@keyframes bingoSweep {
  0%   { clip-path: inset(0 100% 0 0); opacity: 1; filter: brightness(1.7); }
  70%  { clip-path: inset(0 0 0 0);    opacity: 1; filter: brightness(1.7); }
  100% { clip-path: inset(0 0 0 0);    opacity: .75; filter: none; }
}
@media (prefers-reduced-motion: reduce) {
  .bingo-cell.near, .bline.sweep { animation: none !important; }
}

/* 開球托盤 */
.bingo-tray { margin-top: 10px; padding: 10px; border-radius: 12px;
  background: var(--surface); box-shadow: inset 0 0 0 1px var(--border); }
.bt-current-wrap { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.bt-current-label { font-size: 12px; color: var(--text-soft); font-weight: 700; }
.bt-current { min-width: 46px; height: 46px; padding: 0 6px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; font-weight: 900; font-size: 22px;
  color: #08101a; background: radial-gradient(circle at 35% 30%, #cfe0ff, #7ea3ff);
  box-shadow: 0 3px 10px rgba(91,139,255,.5); }
.bt-current .bball.gold { color: #4a2f00; }
.bt-current .bball { position: relative; display: inline-flex; align-items: center; }
.bt-current .bb-gold { font-size: 11px; margin-left: 2px; color: #7a4f00; font-weight: 800; }
.bt-stat { flex: 1; text-align: right; font-size: 13px; color: var(--text-soft); }
.bt-stat b { color: var(--win); font-size: 15px; }
/* 已開球列 */
.bt-drawn { display: flex; flex-wrap: wrap; gap: 4px; max-height: 74px; overflow-y: auto; }
.bd-chip { min-width: 22px; height: 22px; padding: 0 4px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700;
  background: #10132a; color: var(--text-soft); box-shadow: inset 0 0 0 1px #2a3050; }
.bd-chip.hit { background: #24407a; color: #eaf1ff; box-shadow: inset 0 0 0 1px var(--neon); }
.bd-chip.gold { background: #6a4e14; color: #fff3c8; box-shadow: inset 0 0 0 1px var(--gold); }

/* 賓果賠付表小標 */
.bingo-pt-head { margin-top: 12px !important; color: var(--neon-2); }

/* ===== [claude code] 2026-07-11 夜市麻將賓果（mjbingo）：5×5/6×6 洗牌翻牌 + 金牌 ===== */
/* 控制列：盤面 + 賠付檔 */
.mj-controls { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 10px; }
.mj-row { display: flex; align-items: stretch; gap: 8px; }
.mj-row-label { align-self: center; min-width: 34px; font-size: 12px; font-weight: 800; color: var(--text-soft); }
.mj-opt { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  padding: 8px 4px; border: 1.5px solid var(--border); border-radius: 12px; cursor: pointer;
  background: var(--surface-2); color: var(--text-soft); font-weight: 800; font-size: 14px;
  transition: transform .1s, box-shadow .15s, border-color .15s; }
.mj-opt:hover:not(:disabled) { transform: translateY(-1px); border-color: var(--neon-2); }
.mj-opt:disabled { opacity: .55; cursor: default; }
.mj-opt.sel { border-color: var(--neon-2); color: var(--text);
  background: linear-gradient(135deg, rgba(47,164,106,.30), rgba(70,201,138,.22));
  box-shadow: 0 0 0 1px var(--neon-2), 0 4px 16px rgba(47,164,106,.35); }
.mj-opt .mo-name { font-weight: 800; font-size: 14px; }
.mj-opt .mo-sub { font-size: 11px; opacity: .85; font-weight: 700; }

/* 盤面（麻將桌氈綠底）*/
.board.mj-board { position: relative; display: grid; gap: 6px; padding: 8px; aspect-ratio: 1 / 1;
  background: radial-gradient(circle at 50% 20%, #16603f, #0d3b28 70%), #0d3b28;
  border-radius: 14px; box-shadow: inset 0 0 0 1px rgba(255,255,255,.06), inset 0 0 30px rgba(0,0,0,.35); }
.board.mj-board.mj-shuffling { animation: mjShuffle .34s ease-in-out; }
@keyframes mjShuffle { 0%,100% { transform: none; } 25% { transform: translateX(-3px) rotate(-.4deg); }
  50% { transform: translateX(3px) rotate(.4deg); } 75% { transform: translateX(-2px); } }

/* [claude code] 2026-07-11 麻將牌永遠亮牌面（象牙白 + 立體邊）；抽到才「亮起來」(.lit)，未抽到開牌中變暗 (.dim)。 */
.mj-cell { position: relative; display: flex; align-items: center; justify-content: center;
  border-radius: 9px; user-select: none; transition: transform .12s, box-shadow .18s, opacity .18s, filter .18s;
  color: #1b2330; font-weight: 800; overflow: hidden;
  background: linear-gradient(158deg, #fbf6e9 0%, #efe6d0 62%, #e2d4b6 100%);
  box-shadow: inset 0 2px 0 rgba(255,255,255,.8), inset 0 -5px 7px rgba(140,120,80,.35), 0 2px 5px rgba(0,0,0,.35); }
.mj-cell.sm { border-radius: 7px; }
/* [claude code] 2026-07-14 v1.71 未抽到 = 暗（基準狀態：桌面翻正後一開始就是暗的，抽中才 .lit 亮起來）。
   調得比原本更暗一點讓「亮起來」有感，但牌面仍看得清（是翻正的牌、不是蓋牌）。 */
.mj-cell.dim { opacity: .55; filter: saturate(.62) brightness(.8); }
.mj-cell.lit { opacity: 1; filter: none; z-index: 2;
  box-shadow: inset 0 2px 0 rgba(255,255,255,.9), inset 0 0 0 2px var(--gold), 0 0 12px rgba(255,207,58,.55), 0 2px 5px rgba(0,0,0,.35); }
.mj-cell.just-lit { animation: mjLit .32s ease; z-index: 3; }
@keyframes mjLit { 0% { transform: scale(.82); } 55% { transform: scale(1.12); } 100% { transform: scale(1); } }

/* 牌面內容：字牌 / 萬 / 花牌 = 字；筒 / 條 / 白板 = SVG（.mj-pip） */
.mj-honor { font-size: clamp(17px, 6.2vw, 32px); line-height: 1; font-weight: 900; text-shadow: 0 1px 0 rgba(255,255,255,.5); }
.mj-cell.sm .mj-honor { font-size: clamp(12px, 4vw, 22px); }
.mj-man { display: flex; flex-direction: column; align-items: center; line-height: .96; }
.mj-man .mm-n { font-size: clamp(13px, 4.6vw, 23px); font-weight: 900; color: #1b2330; }
.mj-man .mm-s { font-size: clamp(9px, 3.2vw, 15px); font-weight: 900; color: #c0392b; letter-spacing: -.04em; }
.mj-cell.sm .mj-man .mm-n { font-size: clamp(10px, 3.2vw, 17px); }
.mj-cell.sm .mj-man .mm-s { font-size: clamp(7px, 2.2vw, 11px); }
.mj-pip { width: 74%; height: 74%; display: block; }
.mj-cell.mj-red .mj-honor { color: #c62828; }
.mj-cell.mj-green .mj-honor { color: #1f8f4e; }
.mj-cell.mj-flower .mj-honor { color: #d9720c; }

/* 差一格：這格再被開到就完成一條線 → 金色脈動描邊（只在開牌中）。
   [claude code] 2026-07-14 v1.72 🔴 修「錯誤亮起」：原本 .near 是 opacity:1; filter:none;（＝把「未抽到」的格弄成全亮），
   看起來就像被抽中了（畫面上亮的格數 > 已開張數）；結算後 remove("near") 又讓它們掉回 .dim → 「最後暗一下把錯的暗回去」。
   [claude code] 2026-07-14 v1.73 再修殘留亮度差：v1.72 讓 .near「亮一點點」（.68）仍比一般暗格（.55）亮 → 結算不套 near 時
   會掉回 .55，就是使用者看到的「暗格再回到一致暗度」的亮度差。**改成完全不動亮度**（不覆寫 opacity/filter，
   一律沿用 .dim 的暗度），差一格只用「金色脈動描邊」表示 → 結算前後暗格亮度完全一致，不再有那一下。
   ⚠️ 鐵則：任何「提示 / 期待」樣式都**不可以改未抽到格的亮度**，只能加描邊 / 光暈，否則玩家會誤判已開張數、且結算會跳。 */
.mj-cell.near { animation: mjNear 1.1s ease-in-out infinite alternate; z-index: 3; }
@keyframes mjNear { from { box-shadow: inset 0 0 0 2px rgba(255,207,58,.55), 0 2px 5px rgba(0,0,0,.35); }
  to { box-shadow: inset 0 0 0 3px var(--gold), 0 0 16px rgba(255,207,58,.9), 0 2px 5px rgba(0,0,0,.35); } }

/* 金牌：金色牌面 + ×N 角標 */
.mj-cell.mj-gold { background: linear-gradient(158deg, #fff3c8 0%, #ffd868 55%, #e9b62e 100%);
  box-shadow: inset 0 2px 0 rgba(255,255,255,.9), inset 0 0 0 2px #e9a72e, 0 0 16px rgba(255,207,58,.85), 0 2px 5px rgba(0,0,0,.35); }
.mj-cell .mj-goldbadge { position: absolute; top: 1px; right: 3px; font-size: clamp(8px,2.4vw,12px); font-weight: 900; color: #7a4f00; z-index: 2; }
/* 完成線內的格：金色外光暈脈動 */
.mj-cell.in-line { z-index: 2; animation: bingoLine 2s ease-in-out infinite alternate; }

/* 開牌托盤走賓果托盤樣式（.bingo-tray）；補目前牌/記錄 chip 的麻將牌縮圖 */
.mj-current.bt-current { border-radius: 8px; background: linear-gradient(158deg, #fbf6e9, #e2d4b6); color: #1b2330;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 2px 6px rgba(0,0,0,.4); }
.mj-current .mj-cur-face { display: inline-flex; align-items: center; justify-content: center; width: 100%; height: 100%; position: relative; }
.mj-current .mj-cur-face.gold { filter: drop-shadow(0 0 3px rgba(255,207,58,.9)); }
.mj-current .mj-pip { width: 76%; height: 76%; }
.mj-current .mj-honor { font-size: 22px; }
.mj-current .mj-man .mm-n { font-size: 16px; } .mj-current .mj-man .mm-s { font-size: 10px; }
.mj-current .mj-goldbadge { font-size: 9px; top: 0; right: 1px; }
.mj-record .mj-chip { position: relative; width: 26px; height: 30px; min-width: 26px; padding: 0; border-radius: 5px;
  display: inline-flex; align-items: center; justify-content: center; overflow: hidden;
  background: linear-gradient(158deg, #fbf6e9, #e6d8bd); color: #1b2330;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 1px 2px rgba(0,0,0,.35); }
/* [claude code] 2026-07-14 v1.69 手牌金牌 +N 角標改「絕對定位小角標」塞進 chip 角落（原本 inline 會把 中+1 撐出格外）。 */
.mj-record .mj-chip .mj-goldbadge { position: absolute; top: 0; right: 0; font-size: 8px; line-height: 1;
  padding: 0 1px; font-weight: 900; color: #7a4f00; z-index: 2; }
.mj-record .mj-chip.gold { background: linear-gradient(158deg, #fff3c8, #ffd868); box-shadow: inset 0 0 0 1px #e9a72e, 0 0 6px rgba(255,207,58,.6); }
.mj-record .mj-chip .mj-pip { width: 82%; height: 82%; }
.mj-record .mj-chip .mj-honor { font-size: 15px; }
.mj-record .mj-chip .mj-man .mm-n { font-size: 11px; } .mj-record .mj-chip .mj-man .mm-s { font-size: 7px; }

/* [claude code] 2026-07-14 蓋牌（背面）：竹紋玉綠牌背，跟牌桌氈綠區隔（比桌面亮、帶織紋 + 內框）。 */
.mj-cell.mj-back {
  background: linear-gradient(158deg, #1f7d58 0%, #135c3f 60%, #0f4c35 100%);
  box-shadow: inset 0 2px 0 rgba(255,255,255,.18), inset 0 -4px 6px rgba(0,0,0,.3),
    inset 0 0 0 1.5px rgba(255,255,255,.13), 0 2px 5px rgba(0,0,0,.4);
}
.mj-back-art { width: 58%; height: 58%; border-radius: 4px;
  background: repeating-linear-gradient(45deg, rgba(255,255,255,.11) 0 3px, transparent 3px 6px),
    repeating-linear-gradient(-45deg, rgba(0,0,0,.10) 0 3px, transparent 3px 6px);
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.24); }
/* [claude code] 2026-07-14 翻牌動畫：蓋牌 → 翻面亮起（rotateY 翻過來）。 */
.mj-cell.just-flip { animation: mjFlip .36s ease; z-index: 3; }
@keyframes mjFlip {
  0%   { transform: perspective(320px) rotateY(-86deg); filter: brightness(1.5); }
  55%  { transform: perspective(320px) rotateY(9deg); }
  100% { transform: perspective(320px) rotateY(0); filter: none; }
}
/* [claude code] 2026-07-14 換桌：整盤淡出再淡入（重發一桌）。 */
.board.mj-board.mj-dealout { animation: mjDealOut .24s ease forwards; }
.board.mj-board.mj-dealin { animation: mjDealIn .3s ease; }
@keyframes mjDealOut { to { opacity: .15; transform: scale(.96); } }
@keyframes mjDealIn { from { opacity: .15; transform: scale(.96); } to { opacity: 1; transform: none; } }

/* [claude code] 2026-07-14 開局儀式列（洗牌 / 換桌）：對蓋牌盤面播表演 */
.mj-ritual { justify-content: center; gap: 10px; }
.mj-ritual-btn { flex: 1; max-width: 160px; padding: 8px 6px; border-radius: 10px; cursor: pointer;
  font-weight: 800; font-size: 13px; background: var(--surface-2); color: var(--text-soft); border: 1.5px solid var(--border);
  transition: transform .1s, border-color .15s, color .15s; }
.mj-ritual-btn:hover:not(:disabled) { transform: translateY(-1px); border-color: var(--neon-2); color: var(--text); }
.mj-ritual-btn:disabled { opacity: .5; cursor: default; }

/* [claude code] 2026-07-14 麻將盤完成線：紅線（比黃線在象牙牌面上清楚），v1.68 依回饋「再淡一點」→ 降透明度/細一點/柔光。 */
.mj-board .bline { height: 5px; opacity: .72;
  background: linear-gradient(90deg, rgba(255,90,110,0), #ff5c74 16%, #ff8a9c 50%, #ff5c74 84%, rgba(255,90,110,0));
  box-shadow: 0 0 0 1px rgba(70,0,12,.4), 0 0 7px rgba(255,80,100,.55); }

/* [claude code] 2026-07-14 v1.68 下面的「手牌」：先發蓋著的牌（玉綠背），開牌時逐張翻面。 */
.mj-record .mj-chip.mj-chip-back { background: linear-gradient(158deg, #1f7d58, #0f4c35);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 2px rgba(0,0,0,.4); }
.mj-record .mj-chip.mj-chip-back .mj-back-art { width: 62%; height: 62%; }
.mj-record .mj-chip.mj-chip-flip { animation: mjChipFlip .34s ease; }
@keyframes mjChipFlip {
  0%   { transform: perspective(220px) rotateY(-82deg); filter: brightness(1.5); }
  55%  { transform: perspective(220px) rotateY(8deg); }
  100% { transform: perspective(220px) rotateY(0); filter: none; }
}
/* [claude code] 2026-07-14 v1.69 發牌：蓋牌一張一張「放上去」（由上滑入 + 放大到定位）。 */
.mj-record .mj-chip.mj-chip-deal { animation: mjChipDeal .2s ease; }
@keyframes mjChipDeal {
  0%   { transform: translateY(-14px) scale(.7); opacity: 0; }
  100% { transform: translateY(0) scale(1); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .mj-cell.near, .mj-cell.just-lit, .mj-cell.just-flip, .board.mj-board.mj-shuffling,
  .board.mj-board.mj-dealout, .board.mj-board.mj-dealin, .mj-cell.in-line,
  .mj-record .mj-chip.mj-chip-flip, .mj-record .mj-chip.mj-chip-deal { animation: none !important; }
}

/* [claude code] 2026-07-11 「現在幾倍」倍率徽章（賓果 + 麻將賓果共用）：累計金球 / 金牌 → 目前總倍率。 */
.bt-multi-wrap { display: inline-flex; align-items: baseline; gap: 3px;
  padding: 3px 9px; border-radius: 999px; background: rgba(255,207,58,.10); box-shadow: inset 0 0 0 1px rgba(255,207,58,.28); }
.bt-multi-label { font-size: 11px; font-weight: 700; color: var(--text-soft); }
.bt-multi { font-size: 17px; font-weight: 900; color: var(--text-soft); transition: color .18s; }
.bt-multi.hot { color: var(--gold); text-shadow: 0 0 8px rgba(255,207,58,.6); }
.bt-multi-suffix { font-size: 11px; font-weight: 700; color: var(--text-soft); }
.bt-multi.bump { animation: mbBump .28s ease; }
@keyframes mbBump { 0% { transform: scale(1); } 45% { transform: scale(1.35); } 100% { transform: scale(1); } }
/* 賓果 stat 靠右時保留一點空間給倍率徽章 */
.bingo-tray .bt-current-wrap { flex-wrap: wrap; }

/* [claude code] 2026-07-10 梨園變臉（faceoff）
   👏 觀眾：金光脈動（他是觸發者，要最醒目）
   🎭 變臉：被翻的格子沿 Y 軸翻牌，翻到背面時 JS 換掉 glyph → 看起來就是「一瞬間換了張臉」 */
.cell.fo-aud { z-index: 5; }
.cell.fo-aud .glyph { animation: foAud .45s ease-in-out infinite alternate; }
@keyframes foAud { from { transform: scale(1); filter: drop-shadow(0 0 2px rgba(255,210,74,.5)); }
                   to   { transform: scale(1.22); filter: drop-shadow(0 0 12px rgba(255,210,74,.95)); } }
/* 變臉滾動：格內疊一條水平 strip（…👹👺🎭…target），translateX 滑到最後一格。
   左邊的格子滾得短、右邊滾得久 → 左到右依序停（duration 由 JS 給）。 */
.cell.fo-rolling { overflow: hidden; z-index: 4; }
.cell.fo-rolling .glyph { opacity: 0; }               /* 滾動中蓋掉底層符號 */
.fo-strip { position: absolute; inset: 0; display: flex; z-index: 3; will-change: transform; }
.fo-strip span { flex: 0 0 100%; display: flex; align-items: center; justify-content: center;
  font-size: inherit; line-height: 1; }
/* 落定時彈一下 + 金光，強調「這張臉定住了」 */
.cell.fo-landed .glyph { animation: foLand .26s ease-out; }
@keyframes foLand {
  0%   { transform: scale(1.35); filter: drop-shadow(0 0 14px rgba(255,210,74,.9)); }
  100% { transform: scale(1);    filter: none; }
}
.win-banner .fo-mult { color: #ffd24a; font-weight: 900; text-shadow: 0 0 10px rgba(255,210,74,.55); }

/* [claude code] 2026-07-10 觀眾喝采加倍：第 2 位觀眾起逐一點亮，每點亮一位就把臉譜那份再疊一倍。
   fo-cheer 是「這一位剛喊出來」的一次性爆閃，結束後留在 fo-aud 的常態脈動上。 */
.cell.fo-cheer { z-index: 6; }
.cell.fo-cheer .glyph { animation: foCheer .34s ease-out; }
@keyframes foCheer {
  0%   { transform: scale(1);    filter: drop-shadow(0 0 4px rgba(255,210,74,.6)); }
  45%  { transform: scale(1.75); filter: drop-shadow(0 0 20px rgba(255,210,74,1)); }
  100% { transform: scale(1.22); filter: drop-shadow(0 0 12px rgba(255,210,74,.95)); }
}
/* 倍率數字：每跳一檔彈出來一次，比原本的 fo-mult 更大更亮 */
.win-banner .fo-mult-big { display: inline-block; font-size: 1.4em; animation: foMultPop .3s ease-out; }
@keyframes foMultPop {
  0%   { transform: scale(.55); opacity: .25; }
  60%  { transform: scale(1.28); opacity: 1; }
  100% { transform: scale(1); }
}
/* 加倍過程中的贏分數字：轉金 + 發光，跟平常的白字分開 */
#winMeter.fo-ramp { color: #ffd24a; text-shadow: 0 0 16px rgba(255,210,74,.75); }
/* 錢飛進來的那一下：贏分被「撞」一下（比一般 bump 更重），強調錢是從觀眾那邊進來的 */
#winMeter.hit { animation: wmHit .32s ease-out; }
@keyframes wmHit {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.42); filter: drop-shadow(0 0 16px rgba(255,210,74,1)); }
  100% { transform: scale(1); }
}
/* 從觀眾格飛向贏分的「+金額」（fixed；起點由 JS 給，transform 位移到 meter） */
.fo-fly {
  position: fixed; z-index: 60; pointer-events: none; white-space: nowrap;
  font-size: 21px; font-weight: 900; color: #ffd24a; font-variant-numeric: tabular-nums;
  text-shadow: 0 0 14px rgba(255,210,74,.95), 0 2px 5px rgba(0,0,0,.7);
  transform: translate(-50%,-50%);
  transition-property: transform, opacity;
  transition-timing-function: cubic-bezier(.34,.85,.3,1), ease-in;
  animation: foFlyFade .1s ease-out;   /* 冒出來時彈一下 */
}
@keyframes foFlyFade { from { opacity: 0; } to { opacity: 1; } }

/* =====================================================================
   [claude code] 2026-07-11 招財彈珠（plinko）：釘板落球獨立盤面 + 球數選鈕 + 碎片/收集罐托盤
   ===================================================================== */
/* 球數選鈕列（取代單注 stepper） */
.plink-controls { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 10px; }
.plink-row { display: flex; align-items: stretch; gap: 8px; }
.plink-row-label { align-self: center; min-width: 34px; font-size: 12px; font-weight: 800; color: var(--text-soft); }
.plink-opt { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  padding: 8px 4px; border: 1.5px solid var(--border); border-radius: 12px; cursor: pointer;
  background: var(--surface-2); color: var(--text-soft); transition: transform .1s, box-shadow .15s, border-color .15s; }
.plink-opt:hover:not(:disabled) { transform: translateY(-1px); border-color: var(--neon-2); }
.plink-opt:disabled { opacity: .55; cursor: default; }
.plink-opt.sel { border-color: var(--neon-2); color: var(--text);
  background: linear-gradient(135deg, rgba(255,93,143,.28), rgba(255,179,26,.18));
  box-shadow: 0 0 0 1px var(--neon-2), 0 4px 16px rgba(255,93,143,.32); }
.plink-opt .po-n { font-weight: 900; font-size: 18px; }
.plink-opt .po-sub { font-size: 10px; opacity: .8; font-weight: 700; }
.plink-cost { text-align: center; font-size: 12px; color: var(--text-soft); }
.plink-cost b { color: var(--text); } .plink-cost .pc-cost { color: var(--gold); font-size: 14px; }

/* 盤面：#board 覆寫成 block + 絕對定位子層 */
.board.plink-board { display: block; position: relative; width: 100%; aspect-ratio: 13 / 15;
  background: radial-gradient(circle at 50% 10%, #1b2440, #0a0e1c 78%); border-radius: 14px; padding: 0;
  overflow: hidden; box-shadow: inset 0 0 0 1px rgba(255,255,255,.05), 0 8px 26px rgba(0,0,0,.4); }
/* 釘板（裝飾） */
.plink-pegs { position: absolute; left: 4%; right: 4%; top: 9%; height: 58%;
  display: flex; flex-direction: column; justify-content: space-between; pointer-events: none; }
.plink-peg-row { display: flex; justify-content: space-between; }
.plink-peg-row.odd { padding: 0 3.8%; }
.plink-peg { width: 6px; height: 6px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff, #8a93b5); box-shadow: 0 0 4px rgba(255,255,255,.3); }
/* 中間碎片收集器（移到左側，球會被導過來撞它） */
.plink-collector { position: absolute; left: 22%; top: 41%; transform: translateX(-50%); z-index: 5;
  display: flex; align-items: center; gap: 5px; padding: 4px 13px; border-radius: 999px; pointer-events: none;
  background: rgba(255,93,143,.18); box-shadow: inset 0 0 0 1.5px rgba(255,93,143,.6), 0 0 12px rgba(255,93,143,.3);
  font-size: 12px; font-weight: 800; color: #ffdbe6; transition: box-shadow .15s; }
.plink-collector .pc-ico { font-size: 16px; }
.plink-collector.hit { animation: pcHit .5s cubic-bezier(.3,1.6,.5,1); }
@keyframes pcHit {
  0%   { transform: translateX(-50%) scale(1); }
  30%  { box-shadow: inset 0 0 0 2.5px #fff, 0 0 30px rgba(255,93,143,1); transform: translateX(-50%) scale(1.42) rotate(-7deg); }
  55%  { transform: translateX(-50%) scale(.9) rotate(4deg); }
  100% { transform: translateX(-50%) scale(1); } }
.plink-collector.hit-big { box-shadow: inset 0 0 0 2.5px var(--gold), 0 0 30px rgba(255,210,74,.95); color: #fff3c8;
  animation: pcHitBig .55s ease infinite alternate; }
@keyframes pcHitBig { from { transform: translateX(-50%) scale(1); } to { transform: translateX(-50%) scale(1.16); } }
/* 撞擊迸出的碎片粒子 */
.plink-particle { position: absolute; width: 9px; height: 9px; border-radius: 50%; z-index: 6; pointer-events: none;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle at 35% 30%, #fff, #ff5d8f 70%); box-shadow: 0 0 7px rgba(255,93,143,.9); }
/* 球落格 → 飛一顆「🍬+N」到收集罐（fixed，起點終點由 JS 算） */
.plink-fly { position: fixed; z-index: 60; pointer-events: none; white-space: nowrap;
  transform: translate(-50%, -50%); font-size: 15px; font-weight: 900; color: #4a2f00;
  padding: 2px 9px; border-radius: 999px; background: linear-gradient(135deg, #ffe08a, var(--gold));
  box-shadow: 0 0 10px rgba(255,210,74,.85), 0 2px 6px rgba(0,0,0,.5); animation: plinkFlyIn .12s ease-out; }
@keyframes plinkFlyIn { from { opacity: 0; } to { opacity: 1; } }
/* 球層 */
.plink-balls { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
.plink-ball { position: absolute; width: 6.6%; aspect-ratio: 1; border-radius: 50%; transform: translate(-50%, -50%);
  background: radial-gradient(circle at 32% 26%, #ffffff 7%, #ffd9ea 26%, #ff5ea0 60%, #e21e72 100%);
  box-shadow: 0 0 4px #fff, 0 0 13px rgba(255,90,160,.9), inset 0 -2px 5px rgba(150,0,60,.4);
  display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: 900; color: #4a0d22;
  will-change: left, top; }
.plink-ball.gold { background: radial-gradient(circle at 32% 26%, #ffffff 7%, #fff0b8 26%, #ffcf3a 58%, #e09a10 100%);
  box-shadow: 0 0 5px #fff, 0 0 19px rgba(255,207,58,1), inset 0 -2px 5px rgba(130,85,0,.45); color: #5e4200; }
.plink-ball.free { background: radial-gradient(circle at 32% 26%, #ffffff 7%, #d6f7ff 26%, #5cd6ff 58%, #158fd0 100%);
  box-shadow: 0 0 5px #fff, 0 0 17px rgba(90,215,255,1); color: #05303f; }
.plink-ball .pb-mult { font-size: 8px; }
.plink-ball.gone { opacity: 0; transform: translate(-50%, -50%) scale(.4); transition: opacity .3s, transform .3s; }
/* 底部 13 金額格 */
.plink-slots { position: absolute; left: 0; right: 0; bottom: 0; height: 17%; z-index: 2;
  display: flex; gap: 2px; padding: 0 3px 3px; align-items: stretch; }
.plink-slot { flex: 1; min-width: 0; position: relative; display: flex; align-items: center; justify-content: center;
  border-radius: 0 0 7px 7px; font-size: clamp(7px, 2vw, 12px); font-weight: 800; color: #fff; padding: 2px 0;
  box-shadow: inset 0 2px 0 rgba(255,255,255,.14); }
.plink-t0 { background: linear-gradient(#3b4668, #2b3350); }
.plink-t1 { background: linear-gradient(#3f5a72, #2c4051); }
.plink-t2 { background: linear-gradient(#3f6f5f, #2c4f43); }
.plink-t3 { background: linear-gradient(#6f6a3a, #4f4b28); }
.plink-t4 { background: linear-gradient(#8a5a2c, #5f3d1c); }
.plink-t5 { background: linear-gradient(#a8432c, #6f2c1c); }
.plink-t6 { background: linear-gradient(#c62a5a, #8a1d3f); box-shadow: inset 0 0 0 1px rgba(255,210,74,.5); }
.plink-slot.plink-landed { animation: psLand .5s ease; z-index: 3; }
@keyframes psLand { 0% { transform: translateY(0); } 30% { transform: translateY(5px); filter: brightness(1.8); } 100% { transform: translateY(0); } }
.plink-slot .ps-hits { position: absolute; top: -13px; left: 50%; transform: translateX(-50%);
  font-size: 10px; font-weight: 900; color: var(--gold); background: rgba(0,0,0,.6);
  padding: 0 5px; border-radius: 999px; white-space: nowrap; }
/* 托盤：碎片 / 收集罐進度條 */
.plink-tray .plink-meters { display: flex; gap: 12px; margin-bottom: 8px; }
.plink-meter { flex: 1; }
.pm-head { display: flex; align-items: baseline; gap: 5px; font-size: 12px; font-weight: 700; color: var(--text-soft); }
.pm-head .pm-ico { font-size: 14px; }
.pm-head .pm-name { font-weight: 800; color: var(--text); }
.pm-head .pm-num { margin-left: auto; font-weight: 900; color: var(--gold); font-variant-numeric: tabular-nums; }
.pm-bar { height: 9px; border-radius: 999px; background: rgba(255,255,255,.08); overflow: hidden; margin: 4px 0 3px; }
.pm-fill { height: 100%; border-radius: 999px; width: 0; transition: width .4s ease; }
.pm-fill.frag { background: linear-gradient(90deg, #ff8fb6, #ff5d8f); }
.pm-fill.jar { background: linear-gradient(90deg, #ffe08a, var(--gold)); }
.pm-fill.pulse { animation: pmPulse .42s ease; }
@keyframes pmPulse { 0% { filter: brightness(1); } 40% { filter: brightness(2.1); } 100% { filter: brightness(1); } }
.pm-num.bump { animation: mbBump .28s ease; }
.pm-hint { font-size: 10px; color: var(--text-soft); opacity: .85; line-height: 1.35; }
.plink-stat { text-align: center; font-size: 13px; color: var(--text-soft); }
.plink-stat b { color: var(--win); }
/* 賠付表金額格條 */
.plink-pt-row { display: flex; flex-wrap: wrap; gap: 4px; margin: 6px 0 4px; }
.plink-pt-cell { padding: 4px 8px; border-radius: 7px; font-size: 12px; font-weight: 800; color: #fff; }
/* pickme overlay 收集罐格 */
.pickme-chest.jar.prize { }
@media (prefers-reduced-motion: reduce) {
  .plink-collector.hit, .plink-collector.hit-big, .plink-slot.plink-landed { animation: none !important; }
}

/* ============================================================================
   [claude code] 2026-07-14 尋寶掃雷（treasure_mines / mines）—— 獨立 view 樣式
   5×5 挖寶格 + 風險檔（地雷數）選擇 + 目前/下一格倍率；沿用 .machine / .win-meter /
   .control-bar / .bet-stepper / .btn-spin 既有元件。
   ============================================================================ */
.mn-machine { gap: 12px; }

.mn-riskbar { display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap; margin: 2px 0 4px; }
.mn-risk-label { font-size: .82rem; color: var(--text-soft); letter-spacing: .5px; }
.mn-risk { display: flex; gap: 6px; }
.mn-risk button {
  min-width: 44px; padding: 7px 10px; border-radius: 10px; cursor: pointer;
  background: var(--surface-2); color: var(--text); border: 1.5px solid var(--border);
  font-weight: 700; font-size: .95rem; transition: transform .1s, border-color .15s, background .15s, box-shadow .15s;
}
.mn-risk button:hover:not(:disabled) { border-color: var(--neon); transform: translateY(-1px); }
.mn-risk button.on {
  background: linear-gradient(135deg, var(--neon), var(--neon-2)); color: #08121a;
  border-color: transparent; box-shadow: 0 0 12px rgba(43, 212, 168, .5);
}
.mn-risk button:disabled { opacity: .55; cursor: default; }

.mn-head { text-align: center; font-size: .9rem; color: var(--text); min-height: 1.3em; padding: 2px 6px; }
.mn-multrow { display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap; font-size: .86rem; color: var(--text-soft); min-height: 1.4em; }
.mn-cur-label { opacity: .8; }
.mn-cur { font-weight: 900; font-size: 1.35rem; color: var(--gold); text-shadow: 0 0 10px rgba(255, 210, 74, .5); transition: color .2s, text-shadow .2s; }
.mn-cur.mn-boom-text { color: #ff5468 !important; text-shadow: 0 0 12px rgba(255, 84, 104, .6); }
.mn-next b { color: var(--neon-2); }
.mn-next .mn-cash { color: #7CFC9E; }
.mn-next .mn-boom { color: #ff8a9a; }
.mn-next .mn-full { color: #2bd4a8; }

.mn-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; max-width: min(92vw, 420px); width: 100%; margin: 6px auto 2px; }
.mn-cell {
  aspect-ratio: 1 / 1; border-radius: 12px; display: flex; align-items: center; justify-content: center;
  font-size: clamp(20px, 6.5vw, 34px); user-select: none;
  background: linear-gradient(160deg, #232842, #1a1e30);
  border: 1.5px solid var(--border); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .05);
  transition: transform .08s, box-shadow .15s, background .2s, border-color .15s; cursor: pointer;
}
.mn-cell:not(.revealed):not(.locked):hover { border-color: var(--neon); transform: translateY(-2px); box-shadow: 0 4px 14px rgba(43, 212, 168, .28); }
.mn-cell.locked { cursor: default; }
.mn-cell.dim { opacity: .3; }
.mn-cell.revealed { cursor: default; animation: mnPop .28s ease; }
.mn-cell.safe { background: radial-gradient(circle at 50% 40%, rgba(43, 212, 168, .3), #17233a); border-color: #2bd4a8; box-shadow: 0 0 12px rgba(43, 212, 168, .35); }
.mn-cell.mine { background: radial-gradient(circle at 50% 40%, rgba(255, 84, 104, .32), #2a1622); border-color: #ff5468; }
.mn-cell.mine.hit { box-shadow: 0 0 18px rgba(255, 84, 104, .7); animation: mnBoom .4s ease; }
@keyframes mnPop { 0% { transform: scale(.6); } 60% { transform: scale(1.12); } 100% { transform: scale(1); } }
@keyframes mnBoom { 0% { transform: scale(1); } 30% { transform: scale(1.25); } 100% { transform: scale(1); } }

.mn-mainbtn.mn-cashmode { background: linear-gradient(135deg, #ffcf4a, #ff9d2e); color: #3a2400; box-shadow: 0 0 16px rgba(255, 180, 60, .5); }
.mn-rules { padding-left: 1.2em; line-height: 1.7; font-size: .88rem; }
.mn-rules li { margin-bottom: 6px; }

@media (prefers-reduced-motion: reduce) {
  .mn-cell.revealed, .mn-cell.mine.hit { animation: none !important; }
}

/* ============================================================================
   [claude code] 2026-07-14 登入 / 建帳號 —— topbar 帳號區鈕 + 帳號來源徽章 + authModal
   ============================================================================ */
.la-open { white-space: nowrap; }
.la-origin {
  display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 999px;
  font-size: .64rem; font-weight: 700; vertical-align: middle; letter-spacing: .5px;
}
.la-origin.plt { background: rgba(160, 107, 255, .22); color: #d7b3ff; border: 1px solid rgba(160, 107, 255, .5); }
.la-origin.api { background: rgba(54, 224, 255, .18); color: #8fe6ff; border: 1px solid rgba(54, 224, 255, .45); }

.auth-card { max-width: 340px; width: 92%; text-align: center; }
.auth-tabs { display: flex; gap: 6px; margin: 4px 0 16px; }
.auth-tab {
  flex: 1; padding: 9px 0; border-radius: 10px; cursor: pointer; font-weight: 700; font-size: .95rem;
  background: var(--surface-2); color: var(--text-soft); border: 1.5px solid var(--border);
  transition: background .15s, color .15s, border-color .15s;
}
.auth-tab.active { background: linear-gradient(135deg, var(--neon), var(--neon-2)); color: #08121a; border-color: transparent; }
.auth-form { display: flex; flex-direction: column; gap: 10px; }
.auth-inp {
  width: 100%; padding: 11px 13px; border-radius: 10px; font-size: 1rem;
  background: var(--surface-2); color: var(--text); border: 1.5px solid var(--border);
}
.auth-inp:focus { outline: none; border-color: var(--neon); box-shadow: 0 0 0 3px rgba(160, 107, 255, .18); }
.auth-submit { width: 100%; margin-top: 2px; }
.auth-msg { min-height: 1.2em; font-size: .82rem; color: var(--neon-2); }
.auth-msg.err { color: #ff6b81; }
.auth-hint { margin-top: 12px; font-size: .76rem; line-height: 1.5; color: var(--text-soft); }

/* ---- [claude code] 2026-07-14 本注明細（玩家版細單）：注單號旁「🔍 明細」+ 明細 modal ---- */
.st-view { flex: 0 0 auto; height: 30px; padding: 0 10px; border-radius: 8px; cursor: pointer; line-height: 1;
  font-size: 12px; font-weight: 700; white-space: nowrap;
  background: var(--surface); color: var(--text-soft); border: 1px solid var(--border);
  transition: background .15s, color .15s, transform .12s; }
.st-view:hover:not(:disabled) { background: var(--gold); color: #1b2330; border-color: var(--gold); }
.st-view:disabled { opacity: .4; cursor: not-allowed; }

.detail-card { width: min(560px, 94vw); max-height: 88vh; overflow-y: auto; padding: 20px; }
.dt-title { font-size: 16px; font-weight: 800; margin-bottom: 6px; }
.dt-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 12px;
  font-size: 12px; color: var(--text-soft); }
.dt-meta .dt-game { color: var(--text); font-weight: 700; }
.dt-meta .dt-no { font-size: 11px; letter-spacing: .3px; word-break: break-all; }
.dt-loading, .dt-empty { padding: 22px 4px; text-align: center; font-size: 13px; color: var(--text-soft); line-height: 1.6; }
.dt-board { max-width: 360px; margin: 0 auto 12px; }
.dt-board .mj-cell { animation: none !important; }   /* 明細是靜態存證：不跑完成線脈動 */
.dt-sum { font-size: 13px; line-height: 1.7; color: var(--text-soft); text-align: center; }
.dt-sum b { color: var(--text); }
.dt-sum .dt-gold { color: var(--gold); }
.dt-sum .dt-win { color: var(--gold); font-size: 15px; }
.dt-formula { margin-top: 8px; padding: 8px 10px; border-radius: 8px; font-size: 12.5px; line-height: 1.6;
  background: var(--surface-2); border: 1px solid var(--border); color: var(--text); text-align: center; }
.dt-legend { margin-top: 8px; font-size: 11px; color: var(--text-soft); text-align: center; }
.dt-subtitle { margin: 14px 0 6px; font-size: 12px; font-weight: 700; color: var(--text-soft); }
.dt-chips { display: flex; flex-wrap: wrap; gap: 4px; max-height: 132px; overflow-y: auto; }

/* ---- [claude code] 2026-07-15 拉霸類明細盤面（狼王夜襲 walking / 花蜜採集 cashcollect）----
   靜態存證盤面：每格 glyph（花蜜格再帶面額籌碼）；中獎線上的格高亮。 */
.dt-slot { display: grid; gap: 4px; max-width: 360px; margin: 0 auto 8px; position: relative; }
/* [claude code] 2026-07-18 中獎線畫在盤面上：SVG 覆蓋整個盤、折線連過中獎格中心（不擋點擊） */
.dt-lineoverlay { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 3; overflow: visible; }
.dt-lineoverlay polyline { filter: drop-shadow(0 0 2px rgba(0,0,0,.55)); }
.dt-scell { position: relative; aspect-ratio: 1 / 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px; border-radius: 8px; font-size: 20px;
  background: var(--surface-2); border: 1px solid var(--border); }
.dt-scell .dt-glyph { line-height: 1; }
.dt-scell .dt-cell-amt { font-size: 10px; font-weight: 700; color: var(--gold); line-height: 1; }
.dt-scell.hit { border-color: var(--gold); box-shadow: inset 0 0 0 1px var(--gold); }
.dt-scell.k-wolf { background: rgba(120, 90, 200, .22); border-color: rgba(150, 120, 235, .55); }
.dt-scell.k-bee { background: rgba(240, 190, 60, .20); border-color: rgba(240, 190, 60, .55); }
.dt-scell.k-nectar { background: rgba(240, 140, 40, .14); border-color: rgba(240, 160, 60, .40); }
.dt-scell.k-empty { opacity: .55; }
/* [claude code] 2026-07-15 甜蜜蜂巢（sticky）：黏住的百搭 / 本轉新落地的百搭 / expanding 展開出來的百搭 */
.dt-scell.k-stuck { background: rgba(150, 110, 235, .24); border-color: rgba(170, 130, 245, .60); }
.dt-scell.k-newwild { background: rgba(90, 200, 140, .20); border-color: rgba(110, 220, 160, .55); }
.dt-scell.k-expanded { background: rgba(90, 160, 235, .20); border-color: rgba(110, 180, 245, .55); }
/* [claude code] 2026-07-15 無盡星河（infinity）：軸數可變（最多可長很多軸）→ 格縮小、超寬時橫向捲動 */
.dt-slot.dt-inf { max-width: 100%; }
.dt-slot.dt-inf .dt-scell { font-size: 15px; border-radius: 6px; }
/* [claude code] 2026-07-15 剩餘 9 款細單盤面著色 */
.dt-scell.k-bomb { background: rgba(240, 120, 200, .20); border-color: rgba(240, 120, 200, .55); }
.dt-scell.k-scatter { background: rgba(120, 200, 240, .20); border-color: rgba(120, 200, 240, .55); }
.dt-scell.k-bonus { background: rgba(240, 200, 60, .22); border-color: rgba(240, 200, 60, .60); }
.dt-scell.k-laser, .dt-scell.k-win { border-color: var(--gold); box-shadow: inset 0 0 0 1px var(--gold); }
.dt-scell.k-target, .dt-scell.k-cleared, .dt-scell.k-bomb2 { opacity: .5; }
.dt-scell.k-colossal { background: rgba(200, 120, 90, .22); border-color: rgba(220, 140, 100, .60); }
/* [claude code] 2026-07-18 招財貓（holdwin）：最終鎖定盤的金幣格（金框 + 面額籌碼） */
.dt-scell.k-coin { background: rgba(255, 200, 60, .22); border-color: rgba(255, 210, 74, .6); box-shadow: inset 0 0 0 1px rgba(255, 210, 74, .5); }
/* [claude code] 2026-07-17 烈日冰舖（serve）細單：顧客 / 🔥 熱浪格 */
.dt-scell.k-cust { background: rgba(240, 200, 60, .22); border-color: rgba(240, 200, 60, .60); }
.dt-scell.k-heat { background: rgba(240, 90, 60, .20); border-color: rgba(240, 110, 70, .55); }
.dt-scell.k-audience { background: rgba(120, 200, 240, .18); }
.dt-slot.dt-plinko-slots { max-width: 100%; }
.dt-slot.dt-plinko-slots .dt-scell { aspect-ratio: auto; padding: 6px 2px; font-size: 11px; }
.dt-slot.dt-mines { max-width: 240px; }
.dt-scell.m-mine { background: rgba(230, 70, 70, .22); border-color: rgba(230, 70, 70, .55); }
.dt-scell.m-safe { background: rgba(90, 200, 140, .20); border-color: rgba(110, 220, 160, .55); }
.dt-scell.m-hidden { opacity: .45; }
.dt-lines { display: flex; flex-direction: column; gap: 3px; margin: 0 auto 4px; max-width: 360px; }
.dt-line { display: flex; align-items: center; gap: 6px; padding: 4px 8px; border-radius: 7px;
  background: var(--surface-2); border: 1px solid var(--border); font-size: 12px; color: var(--text-soft); }
.dt-line .dt-lsym { font-size: 15px; }
.dt-line .dt-llabel { color: var(--text); font-weight: 600; }
.dt-line .dt-lmatch { margin-left: auto; }
.dt-line .dt-lpay { color: var(--gold); font-weight: 700; }
.dt-line .dt-lnum { font-size: 10px; font-weight: 800; color: var(--text-mute);
  background: rgba(255,255,255,.06); border-radius: 5px; padding: 1px 5px; }
/* [claude code] 2026-07-18 線號色點（與盤面上該條線同色 → 清單 ↔ 盤面對得起來） */
.dt-line .dt-lswatch { width: 11px; height: 11px; border-radius: 50%; flex: none;
  box-shadow: 0 0 0 1px rgba(0,0,0,.35), 0 0 4px rgba(255,255,255,.25); }
/* [claude code] 2026-07-18 中獎線的「整線路徑」符號帶（前 match 軸中獎、第 match 軸斷點、之後暗） */
.dt-linewrap { display: flex; flex-direction: column; gap: 2px; }
.dt-lines { gap: 6px; }
.dt-path { display: flex; gap: 3px; padding: 0 6px 2px; }
.dt-pcell { flex: 1; text-align: center; font-size: 14px; line-height: 1.7; border-radius: 5px;
  background: var(--surface-2); border: 1px solid var(--border); }
.dt-pcell.hit { border-color: var(--gold); background: rgba(255,210,74,.18); box-shadow: inset 0 0 0 1px var(--gold); }
.dt-pcell.stop { border-color: rgba(255,90,90,.65); background: rgba(255,90,90,.14); }
.dt-pcell.off { opacity: .4; }
.dt-pathnote { font-size: 11px; color: var(--text-mute); text-align: center; margin: 4px auto 0; max-width: 360px; line-height: 1.5; }
/* [claude code] 2026-07-18 賠付表「所有賠付線」迷你盤面圖 */
.pl-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 8px; margin: 4px 0 8px; }
.pl-item { display: flex; flex-direction: column; align-items: center; gap: 3px; }
.pl-num { font-size: 10px; font-weight: 800; color: var(--text-mute); }
.pl-mini { display: grid; gap: 2px; width: 100%; }
.pl-cell { aspect-ratio: 1 / 1; border-radius: 3px; background: var(--surface-2); border: 1px solid var(--border); }
.pl-cell.on { background: rgba(255,210,74,.85); border-color: var(--gold); box-shadow: 0 0 4px rgba(255,210,74,.45); }

/* ---- [claude code] 2026-07-14 我的紀錄（頂列 📜）：注單記錄（可翻頁 → 本注明細）+ 轉帳記錄 ---- */
.records-card { width: min(560px, 94vw); max-height: 88vh; display: flex; flex-direction: column; padding: 20px; }
.rc-days { font-size: 11px; font-weight: 400; color: var(--text-soft); margin-left: 6px; }
.rc-tabs { display: flex; gap: 6px; margin: 10px 0 8px; }
.rc-tab { flex: 1; padding: 7px 0; border-radius: 8px; cursor: pointer; font-size: 13px; font-weight: 700;
  background: var(--surface-2); color: var(--text-soft); border: 1px solid var(--border); }
.rc-tab.active { background: var(--gold); color: #1b2330; border-color: var(--gold); }
/* [claude code] 2026-07-16 注單記錄「依遊戲」下拉篩選列 */
.rc-filter { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; }
.rc-filter label { font-size: 12px; color: var(--text-soft); font-weight: 700; }
.rc-filter select { flex: 1; padding: 7px 10px; border-radius: 8px; font-size: 13px; font-weight: 700;
  background: var(--surface-2); color: var(--text); border: 1px solid var(--border); cursor: pointer; }
.rc-body { flex: 1; overflow-y: auto; min-height: 180px; }
.rc-list { display: flex; flex-direction: column; gap: 6px; }
.rc-row { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 9px;
  background: var(--surface-2); border: 1px solid var(--border); }
.rc-row.clickable { cursor: pointer; transition: border-color .15s, transform .08s; }
.rc-row.clickable:hover { border-color: var(--gold); transform: translateY(-1px); }
.rc-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.rc-game { font-size: 13px; font-weight: 700; color: var(--text); }
.rc-time { font-size: 11px; color: var(--text-soft); }
.rc-txn { font-size: 10px; color: var(--text-soft); word-break: break-all; }
.rc-nums { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 2px; font-size: 12px; }
.rc-bet, .rc-bal { color: var(--text-soft); }
.rc-win { color: var(--text-soft); font-weight: 700; }
.rc-win.pos { color: var(--gain, #e5484d); }        /* 台灣慣例：紅 = 贏 / 進帳 */
.rc-amt { font-weight: 800; }
.rc-amt.in { color: var(--gain, #e5484d); }
.rc-amt.out { color: var(--loss, #16a34a); }        /* 綠 = 出帳 */
.rc-tail { flex: 0 0 auto; font-size: 11px; }
.rc-more { color: var(--gold); font-weight: 700; }
.rc-nomore { color: var(--text-soft); opacity: .7; }

/* ---- [claude code] 2026-08-14 v2.83 場次記錄（一次坐下來玩的那一段，展開才看逐筆）---- */
.rc-views { flex: 0 0 auto; display: flex; gap: 4px; }
.rc-view { padding: 6px 12px; border-radius: 8px; cursor: pointer; font-size: 12px; font-weight: 700;
  background: var(--surface-2); color: var(--text-soft); border: 1px solid var(--border); }
.rc-view.active { background: var(--gold); color: #1b2330; border-color: var(--gold); }
.rc-sess { display: flex; flex-direction: column; }
.rc-sessrow.open { border-color: var(--gold); border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.rc-rounds { margin-left: 6px; font-size: 11px; font-weight: 700; color: var(--text-soft); }
.rc-net { font-weight: 900; font-size: 13px; font-variant-numeric: tabular-nums; color: var(--text-soft); }
.rc-net.pos { color: var(--gain, #e5484d); }        /* 台灣慣例：紅 = 賺 */
.rc-net.neg { color: var(--loss, #16a34a); }        /* 綠 = 賠 */
.rc-caret { display: inline-block; color: var(--gold); font-size: 13px; transition: transform .15s ease; }
.rc-sessrow.open .rc-caret { transform: rotate(180deg); }
/* 展開區：縮排 + 左側金線，一眼看出「這幾筆屬於上面那一場」 */
.rc-sub { display: flex; flex-direction: column; gap: 5px; margin: 0 0 2px 10px; padding: 6px 0 6px 10px;
  border-left: 2px solid rgba(255,210,74,.35); }
.rc-sub .rc-row { padding: 7px 9px; background: rgba(255,255,255,.03); }
.rc-sub .rc-game { font-size: 12px; }
.rc-more-btn { align-self: center; margin-top: 2px; padding: 6px 14px; border-radius: 8px; cursor: pointer;
  font-size: 12px; font-weight: 700; background: var(--surface-2); color: var(--gold); border: 1px solid var(--border); }
.rc-more-btn:disabled { opacity: .5; cursor: default; }
.rc-note { margin-top: 10px; padding: 8px 10px; border-radius: 8px; font-size: 11.5px; line-height: 1.55;
  color: var(--text-soft); background: rgba(255,180,60,.08); border: 1px solid rgba(255,180,60,.25); }
.rc-pager { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 10px; }
.rc-pgbtn { padding: 6px 12px; border-radius: 8px; cursor: pointer; font-size: 12px;
  background: var(--surface-2); color: var(--text); border: 1px solid var(--border); }
.rc-pgbtn:hover:not(:disabled) { border-color: var(--gold); }
.rc-pgbtn:disabled { opacity: .35; cursor: not-allowed; }
.rc-pginfo { font-size: 12px; color: var(--text-soft); }
/* [claude code] 2026-07-14 明細 modal 的開球記錄托盤（沿用 .bd-chip，只放寬高度限制）*/
.dt-balls { max-height: 120px; }

/* [claude code] 2026-07-14 大廳卡片「細單未開放」標記（server games.spinDetail=false 才掛；
   已支援的款不掛徽章 —— 依使用者：只標還沒做的）。灰底虛線、低調不搶版面。 */
.card-detail { margin-top: 6px; align-self: flex-start; padding: 2px 8px; border-radius: 999px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .3px; }
.card-detail.off { color: var(--text-soft); background: transparent; border: 1px dashed var(--border); opacity: .75; }

/* [claude code] 2026-07-14 花蜜採集：每隻蜜蜂的「×1」角標（多隻時才掛）→ 「幾隻＝幾倍」一眼看懂。
   配色沿用蜜蜂金；角標絕對定位在格子右上，不撐開格子。 */
.cell .bee-mult { position: absolute; top: 2px; right: 3px; z-index: 3;
  font-size: 11px; font-weight: 900; line-height: 1; padding: 1px 3px; border-radius: 5px;
  color: #4a3400; background: var(--gold); box-shadow: 0 0 6px rgba(255,207,58,.7); }

/* ===== [claude code] 2026-07-16 招財海盜寶藏（treasure）：鑰匙發光 / 開箱內容徽章 / 藏寶圖 HUD / 寶藏開箱 ===== */
/* 鑰匙發光 + ×N 角標 */
.cell.key-glow { box-shadow: inset 0 0 0 2px #ffd54a, 0 0 16px rgba(255,205,74,.9); z-index: 4; }
.cell.key-glow .glyph { animation: stickyPulse .7s ease-in-out infinite; }
.cell .key-mult { position: absolute; top: 2px; right: 3px; z-index: 3; font-size: 11px; font-weight: 900; line-height: 1;
  padding: 1px 3px; border-radius: 5px; color: #4a3400; background: var(--gold, #ffcf3a); box-shadow: 0 0 6px rgba(255,207,58,.7); }
/* 寶箱開啟 + 內容徽章（💰 金幣面額 / 🗺️ 碎片編號） */
.cell.chest-sealed .glyph { filter: brightness(.82); animation: chestSeal 1.1s ease-in-out infinite; }
@keyframes chestSeal { 0%,100% { transform: translateY(0) scale(1); } 50% { transform: translateY(-2px) scale(1.04); } }
.cell.chest-open .glyph { animation: chestPop .45s ease; }
@keyframes chestPop { 0% { transform: scale(1); } 40% { transform: scale(1.22) rotate(-6deg); filter: brightness(1.4); } 100% { transform: scale(1); } }
.cell.chest-grab .glyph { animation: cashGrab .6s ease; }
.cell .chest-cash { position: absolute; bottom: 4px; left: 50%; transform: translateX(-50%); z-index: 6; pointer-events: none;
  font-family: "Arial Black", system-ui, sans-serif; font-weight: 900; font-size: 11px; line-height: 1; padding: 2px 6px; border-radius: 8px; white-space: nowrap;
  background: linear-gradient(135deg, #fff1c2, #ffcf4a); color: #5a3a00; box-shadow: 0 0 7px rgba(255,180,40,.7), 0 1px 2px rgba(0,0,0,.5); }
.cell .chest-piece { position: absolute; bottom: 4px; left: 50%; transform: translateX(-50%); z-index: 6; pointer-events: none;
  font-weight: 900; font-size: 11px; line-height: 1; padding: 2px 6px; border-radius: 8px; white-space: nowrap;
  background: linear-gradient(135deg, #cdeafd, #6db8e6); color: #123a55; box-shadow: 0 0 8px rgba(90,170,235,.75), 0 1px 2px rgba(0,0,0,.5); animation: chestPop .5s ease; }
/* 藏寶圖進度 HUD（8 格） */
.treasure-map { display: none; flex-direction: column; align-items: center; gap: 4px; margin: 6px auto 2px; }
.treasure-map .tm-cap { font-size: 12px; font-weight: 800; color: #ffe08a; letter-spacing: 1px; text-shadow: 0 1px 3px rgba(0,0,0,.6); }
.treasure-map .tm-row { display: flex; gap: 5px; }
.treasure-map .tm-slot { position: relative; width: 26px; height: 26px; border-radius: 6px; display: flex; align-items: center; justify-content: center;
  background: rgba(20,30,45,.7); border: 1px solid rgba(120,150,190,.35); box-shadow: inset 0 0 6px rgba(0,0,0,.5); transition: all .25s ease; }
.treasure-map .tm-slot .tm-num { font-size: 13px; font-weight: 900; color: #5a6a80; }
.treasure-map .tm-slot.got { background: linear-gradient(135deg, #ffe9a8, #f5b13a); border-color: #ffd45a; box-shadow: 0 0 10px rgba(255,190,60,.8); }
.treasure-map .tm-slot.got .tm-num { color: #5a3a00; }
.treasure-map .tm-slot.just { animation: tmJust .55s ease; }
@keyframes tmJust { 0% { transform: scale(1); } 45% { transform: scale(1.35); box-shadow: 0 0 16px rgba(255,220,90,1); } 100% { transform: scale(1); } }
/* 寶藏開箱 overlay */
.treasure-bonus-ov { position: fixed; inset: 0; z-index: 120; display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 50% 40%, rgba(30,20,60,.82), rgba(8,6,18,.94)); backdrop-filter: blur(2px); }
.treasure-bonus-ov .tb-card { width: min(92vw, 560px); padding: 20px 18px; border-radius: 16px; text-align: center;
  background: linear-gradient(160deg, #2a1f4a, #17122e); border: 1px solid rgba(255,210,120,.4); box-shadow: 0 12px 48px rgba(0,0,0,.6); }
.treasure-bonus-ov .tb-title { font-size: 22px; font-weight: 900; color: #ffe08a; text-shadow: 0 0 12px rgba(255,190,60,.7); }
.treasure-bonus-ov .tb-total { font-size: 30px; font-weight: 900; color: #fff; margin: 6px 0 12px; transition: transform .2s ease; }
.treasure-bonus-ov .tb-total.done { transform: scale(1.12); color: #ffd45a; text-shadow: 0 0 16px rgba(255,200,60,.9); }
.treasure-bonus-ov .tb-boxes { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; max-height: 40vh; overflow-y: auto; padding: 4px; }
.treasure-bonus-ov .tb-box { position: relative; width: 52px; height: 52px; border-radius: 10px; display: flex; align-items: center; justify-content: center;
  font-size: 24px; background: rgba(10,10,24,.6); border: 1px solid rgba(150,150,190,.3); opacity: 0; transform: scale(.6); }
.treasure-bonus-ov .tb-box.open { opacity: 1; transform: scale(1); transition: all .25s cubic-bezier(.2,1.4,.5,1); }
.treasure-bonus-ov .tb-box.prize { background: linear-gradient(135deg, #4a3a10, #806014); border-color: #ffd45a; box-shadow: 0 0 12px rgba(255,190,60,.6); }
.treasure-bonus-ov .tb-box.skull { background: linear-gradient(135deg, #3a1015, #601020); border-color: #ff6a7a; box-shadow: 0 0 16px rgba(255,80,110,.7); }
.treasure-bonus-ov .tb-box .tb-amt { position: absolute; bottom: 2px; left: 50%; transform: translateX(-50%); font-size: 10px; font-weight: 900; color: #ffe08a; white-space: nowrap; }
.treasure-bonus-ov .tb-hint { margin-top: 12px; font-size: 12px; color: #b8b0d0; }
/* [claude code] 2026-07-16 招財海盜寶藏細單：藏寶圖碎片編號徽章（沿用 .dt-cell-amt 位置，藍色系區分金幣） */
.dt-slot .dt-scell .dt-piece-amt { position: absolute; bottom: 2px; left: 50%; transform: translateX(-50%);
  font-size: 10px; font-weight: 900; line-height: 1; padding: 1px 4px; border-radius: 6px; white-space: nowrap;
  background: linear-gradient(135deg, #cdeafd, #6db8e6); color: #123a55; box-shadow: 0 0 5px rgba(90,170,235,.6); }

/* [claude code] 2026-07-29 v2.20 闖關奪寶（gemquest）：三關 BOSS 群落消除闖關 --------------------- */
/* BOSS 面板（盤面上方）：關卡指示燈 + 頭像 + 頭上血條（MMORPG 樣式） */
.gq-boss { position: relative; margin: 0 auto 8px; width: min(100%, 470px); padding: 8px 12px 10px;
  border-radius: 14px; background: linear-gradient(160deg, rgba(45,25,60,.92), rgba(16,12,28,.94));
  border: 1px solid rgba(255,140,90,.30); box-shadow: 0 6px 20px rgba(0,0,0,.45); overflow: hidden; }
.gq-boss.cleared { animation: gqCleared .9s ease; }
@keyframes gqCleared { 0%{ box-shadow: 0 0 0 rgba(255,210,74,0); } 40%{ box-shadow: 0 0 28px rgba(255,210,74,.85); } 100%{ box-shadow: 0 6px 20px rgba(0,0,0,.45); } }
.gq-levels { display: flex; gap: 6px; justify-content: center; margin-bottom: 8px; }
.gq-lv { display: flex; flex-direction: column; align-items: center; gap: 1px; min-width: 62px; padding: 3px 6px;
  border-radius: 8px; font-size: 11px; font-weight: 800; color: var(--text-soft);
  background: rgba(255,255,255,.05); border: 1px solid transparent; }
.gq-lv small { font-size: 9px; font-weight: 700; opacity: .75; }
.gq-lv.on { color: #fff; background: linear-gradient(135deg, rgba(255,120,80,.35), rgba(255,60,110,.28)); border-color: rgba(255,150,110,.65); }
.gq-lv.done { color: var(--gold); background: rgba(255,210,74,.12); border-color: rgba(255,210,74,.35); }
.gq-boss-body { display: flex; align-items: center; gap: 12px; }
.gq-boss-info { flex: 1 1 auto; min-width: 0; }
.gq-boss-name { font-size: 12px; font-weight: 900; color: #ffd9c2; letter-spacing: .02em; margin-bottom: 4px; }
.gq-hpbar { position: relative; height: 13px; border-radius: 999px; overflow: hidden;
  background: rgba(0,0,0,.55); box-shadow: inset 0 0 0 1px rgba(255,255,255,.10); }
.gq-hpfill { height: 100%; width: 100%; border-radius: 999px;
  background: linear-gradient(90deg, #ff5d5d, #ff9a3c); box-shadow: 0 0 10px rgba(255,90,70,.55);
  transition: width .35s cubic-bezier(.3,1,.5,1); }
.gq-hpbar.hit { animation: gqBarHit .45s ease; }
@keyframes gqBarHit { 0%{ filter: brightness(2.2); } 100%{ filter: brightness(1); } }
/* near-miss：只差 1 滴血 → 血條青光脈動 */
.gq-hpbar.near { animation: gqBarNear 1s ease-in-out infinite; }
@keyframes gqBarNear { 0%,100%{ box-shadow: inset 0 0 0 1px rgba(255,255,255,.10); } 50%{ box-shadow: inset 0 0 0 1px #36e0ff, 0 0 12px rgba(54,224,255,.8); } }
.gq-hptxt { margin-top: 3px; font-size: 11px; font-weight: 800; color: #ffb9a0; font-variant-numeric: tabular-nums; }
.gq-boss-glyph { flex: 0 0 auto; font-size: 44px; line-height: 1; filter: drop-shadow(0 3px 8px rgba(0,0,0,.6)); }
.gq-boss-glyph.hit { animation: gqBossHit .5s cubic-bezier(.36,.07,.19,.97); }
@keyframes gqBossHit {
  0%   { transform: translateX(0) scale(1); filter: none; }
  18%  { transform: translateX(14px) scale(1.12) rotate(7deg); filter: brightness(3) sepia(1) hue-rotate(-35deg) saturate(6); }
  45%  { transform: translateX(-8px) scale(1.04) rotate(-4deg); filter: brightness(2) sepia(.7) hue-rotate(-35deg) saturate(4); }
  100% { transform: translateX(0) scale(1); filter: none; }
}
.gq-boss-hint { margin-top: 6px; font-size: 10.5px; color: var(--text-mute, #9aa0c0); text-align: center; }
/* 受擊特效（絕對定位在 BOSS 面板上，播完自己移除） */
.gq-slash, .gq-spark, .gq-dmg { position: absolute; pointer-events: none; z-index: 5; }
.gq-slash { right: 26px; top: 42%; font-size: 40px; animation: gqSlash .55s ease-out forwards; }
@keyframes gqSlash { 0%{ opacity: 0; transform: translate(-26px,-26px) rotate(-45deg) scale(.6);} 30%{ opacity: 1; }
  100%{ opacity: 0; transform: translate(22px,22px) rotate(35deg) scale(1.5); } }
.gq-spark { right: 30px; top: 34%; font-size: 34px; animation: gqSpark .55s ease-out forwards; }
@keyframes gqSpark { 0%{ opacity: 0; transform: scale(.3);} 35%{ opacity: 1; transform: scale(1.5);} 100%{ opacity: 0; transform: scale(2); } }
.gq-dmg { right: 18px; top: 8px; font-size: 26px; font-weight: 900; color: #ff5a5a;
  text-shadow: 0 0 10px rgba(255,60,60,.9), 0 2px 3px rgba(0,0,0,.8); animation: gqDmg .95s ease-out forwards; }
@keyframes gqDmg { 0%{ opacity: 0; transform: translateY(10px) scale(.6);} 25%{ opacity: 1; transform: translateY(-6px) scale(1.35);}
  100%{ opacity: 0; transform: translateY(-34px) scale(1); } }
/* 盤面：沿用 cluster 的 N×N grid（.clus-board / .clus-cell）；⚔️ 攻擊符石格加辨識度。
   [claude code] 2026-07-29 v2.22 修「紅框先在原地、等符號才掉進去」（使用者回報）——
   消除掉落款的掉落動畫**只動 .glyph**，框若做在 .cell 上就會先出現在目的地、跟符號分離。
   比照 candy(v1.95) / icecream 的修法：框改做在 .glyph 上 → 框跟著符號一起掉，永不分離。 */
.gq-cell .glyph { box-sizing: border-box; display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%; border-radius: 9px; }
.gq-cell.gq-drill .glyph { background: linear-gradient(160deg, #3a2140, #241426); box-shadow: inset 0 0 0 1.5px rgba(255,140,90,.55); }
.gq-cell.gq-hit { z-index: 5; }
/* 被砍的 ⚔️：純光暈脈動、**零幾何位移**（避免像 slot_town 早期那樣「框壓來壓去」）*/
.gq-cell.gq-hit .glyph { animation: gqHitPulse .32s ease-in-out infinite alternate; }
@keyframes gqHitPulse {
  from { box-shadow: inset 0 0 0 2px #ff6a5a; filter: none; }
  to   { box-shadow: inset 0 0 0 3px #ff8a6a, 0 0 18px rgba(255,90,70,.9); filter: brightness(1.7); }
}
/* 細單：⚔️ 攻擊符石格 / 一起清掉的 ⚔️（紅框） */
.dt-scell.k-drill { background: rgba(255,120,80,.16); border-color: rgba(255,150,110,.5); }
.dt-scell.drillhit { border-color: #ff6a5a; box-shadow: inset 0 0 0 1px #ff6a5a; }
.dt-slot.dt-gq .dt-scell { font-size: 15px; }

/* [claude code] 2026-07-29 v2.23 闖關奪寶 BONUS 表演（依使用者：怪要飛到中間死、紅包改成真寶箱且要有開啟動作、
   破第三關要變成「一直開箱到 💀」的 BONUS GAME）。以下是共用 overlay + 寶箱元件 + BOSS 陣亡飛行。*/
.gq-ov { position: fixed; inset: 0; z-index: 70; display: none; align-items: center; justify-content: center;
  background: radial-gradient(circle at 50% 42%, rgba(60,26,18,.86), rgba(8,6,14,.95)); backdrop-filter: blur(2px); }
.gq-ov.show { display: flex; animation: gqOvIn .28s ease; }
@keyframes gqOvIn { from { opacity: 0; } to { opacity: 1; } }
.gq-ov-box { width: min(94vw, 520px); max-height: 92vh; overflow-y: auto; padding: 18px 16px 20px; text-align: center;
  border-radius: 18px; background: linear-gradient(165deg, #35201a, #17111d);
  border: 1px solid rgba(255,190,110,.4); box-shadow: 0 16px 50px rgba(0,0,0,.62); }
.gq-ov-title { font-size: 23px; font-weight: 900; color: #ffd88a; text-shadow: 0 0 18px rgba(255,140,60,.7); }
.gq-ov-sub { margin-top: 6px; font-size: 12.5px; color: var(--text-soft); }
.gq-amts { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin: 12px 0 4px; }
.gq-amt { font-size: 13px; font-weight: 800; color: #ffd88a; padding: 3px 11px; border-radius: 999px;
  border: 1px solid rgba(255,190,110,.45); background: rgba(255,180,90,.08); transition: .25s; }
.gq-amt.hit { color: #3a2600; background: linear-gradient(160deg, #ffe08a, #ffcf4a); border-color: #fff;
  box-shadow: 0 0 14px rgba(255,200,60,.75); transform: scale(1.08); }
.gq-amt.miss { opacity: .35; }
.gq-ov-result { margin-top: 12px; font-size: 17px; font-weight: 900; color: #fff; opacity: 0; transform: translateY(6px); transition: .3s; }
.gq-ov-result.show { opacity: 1; transform: none; }
.gq-ov-result b { color: var(--win); text-shadow: 0 0 14px rgba(255,225,105,.8); }
.gq-ov-close { margin-top: 14px; padding: 10px 26px; border: none; border-radius: 999px; cursor: pointer;
  font-weight: 800; color: #2a1d00; background: linear-gradient(135deg, #ffe9a6, var(--gold)); }

/* ---- 寶箱元件（過關三選一 / 龍窟寶庫共用）：箱體 + 箱蓋，開箱時蓋子掀起、金光噴出、金額彈出 ---- */
.gq-chests { display: flex; gap: 14px; justify-content: center; margin-top: 10px; }
.gq-chest { position: relative; width: 96px; height: 92px; cursor: default; }
.gq-chest.ready { animation: gqChestIn .45s cubic-bezier(.2,1.4,.5,1) both; }
@keyframes gqChestIn { from { transform: translateY(-26px) scale(.7); opacity: 0; } to { transform: none; opacity: 1; } }
.gq-chest.pickable { cursor: pointer; }
.gq-chest.pickable:hover { transform: translateY(-6px); transition: transform .15s; }
.gq-chest.pickable .gc-lid { animation: gqLidTease 1.5s ease-in-out infinite; }
@keyframes gqLidTease { 0%,100% { transform: rotateX(0); } 50% { transform: rotateX(-10deg); } }
/* 箱蓋（上半）：以底邊為軸掀開 */
.gc-lid { position: absolute; left: 0; right: 0; top: 0; height: 38px; z-index: 3;
  border-radius: 12px 12px 4px 4px; transform-origin: 50% 100%; transition: transform .45s cubic-bezier(.3,1.2,.5,1);
  background: linear-gradient(180deg, #a4671f, #6d3f11); border: 2px solid #ffcf4a; border-bottom: none;
  box-shadow: inset 0 4px 10px rgba(255,220,150,.35); display: flex; align-items: center; justify-content: center; }
.gc-lock { font-size: 15px; filter: drop-shadow(0 1px 2px rgba(0,0,0,.6)); }
/* 箱體（下半）：金額顯示在這 */
.gc-body { position: absolute; left: 0; right: 0; top: 34px; bottom: 0; z-index: 2;
  border-radius: 4px 4px 12px 12px; background: linear-gradient(180deg, #7d4a15, #45280b); border: 2px solid #ffcf4a;
  display: flex; align-items: center; justify-content: center; }
.gc-amt { font-size: 15px; font-weight: 900; color: #ffe9a6; opacity: 0; transform: scale(.5); transition: .3s .18s; white-space: nowrap; }
/* 開箱：蓋子掀開 + 金光 + 金額彈出 */
.gq-chest.open .gc-lid { transform: rotateX(-118deg); }
.gq-chest.open .gc-lid .gc-lock { opacity: 0; }
.gq-chest.open .gc-amt { opacity: 1; transform: scale(1); }
.gc-glow { position: absolute; left: 50%; top: 30px; width: 10px; height: 10px; transform: translate(-50%,0); z-index: 1;
  border-radius: 50%; opacity: 0; background: radial-gradient(circle, rgba(255,230,150,.95), rgba(255,180,60,0) 70%); }
.gq-chest.open .gc-glow { animation: gqChestGlow .8s ease-out both; }
@keyframes gqChestGlow { 0% { opacity: 0; transform: translate(-50%,0) scale(.4); }
  35% { opacity: 1; transform: translate(-50%,-14px) scale(11); } 100% { opacity: 0; transform: translate(-50%,-22px) scale(15); } }
.gq-chest.win .gc-body { box-shadow: 0 0 26px rgba(255,210,90,.9); border-color: #fff; }
.gq-chest.win { animation: gqChestWin .5s ease; }
@keyframes gqChestWin { 0% { transform: scale(1); } 45% { transform: scale(1.12); } 100% { transform: scale(1); } }
.gq-chest.dim { opacity: .5; }
.gq-chest.skull .gc-body { background: linear-gradient(180deg, #5a1220, #2a0810); border-color: #ff6a7a;
  box-shadow: 0 0 22px rgba(255,80,110,.75); }
.gq-chest.skull .gc-amt { font-size: 24px; }

/* ---- 🐉 龍窟寶庫（破最終 BOSS 的 BONUS GAME）：九宮格寶箱，一直開到 💀 收手 ---- */
.gq-vault-total { margin: 10px 0 2px; font-size: 15px; font-weight: 800; color: var(--text-soft); }
.gq-vault-total span { font-size: 26px; font-weight: 900; color: var(--win); text-shadow: 0 0 16px rgba(255,225,105,.85); }
.gq-vault-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin: 10px auto 0; max-width: 340px; }
.gq-vault-grid .gq-chest { width: 100%; height: 82px; }
.gq-vault-grid .gc-lid { height: 34px; }
.gq-vault-grid .gc-body { top: 30px; }
.gq-vault-grid .gc-amt { font-size: 14px; }

/* ---- BOSS 陣亡：從血條那隻怪飛到畫面中央 → 放大 → 中彈紅閃 → 旋轉墜落淡出 ---- */
.gq-boss-glyph.gone { opacity: 0; }
.gq-death { position: fixed; z-index: 75; pointer-events: none; font-size: 46px; line-height: 1;
  transform: translate(-50%,-50%); filter: drop-shadow(0 6px 14px rgba(0,0,0,.7));
  animation: gqDeathFly 1.25s cubic-bezier(.25,.9,.3,1) forwards; }
@keyframes gqDeathFly {
  0%   { transform: translate(-50%,-50%) scale(1) rotate(0); filter: none; }
  38%  { transform: translate(calc(-50% + var(--fly-x)), calc(-50% + var(--fly-y))) scale(3.1) rotate(-12deg); }
  52%  { transform: translate(calc(-50% + var(--fly-x)), calc(-50% + var(--fly-y))) scale(3.4) rotate(8deg);
         filter: brightness(3) sepia(1) hue-rotate(-40deg) saturate(7); }
  100% { transform: translate(calc(-50% + var(--fly-x)), calc(-50% + var(--fly-y) + 90px)) scale(2.2) rotate(96deg);
         filter: grayscale(1) brightness(.5); opacity: 0; }
}
.gq-death-boom { position: fixed; z-index: 76; pointer-events: none; font-size: 60px; transform: translate(-50%,-50%);
  animation: gqDeathBoom .7s ease-out forwards; }
@keyframes gqDeathBoom { 0% { opacity: 0; transform: translate(-50%,-50%) scale(.3); }
  30% { opacity: 1; transform: translate(-50%,-50%) scale(1.9); } 100% { opacity: 0; transform: translate(-50%,-50%) scale(2.8); } }

/* ---- [claude code] 2026-07-29 v2.22 手機一屏可見（依使用者規則）----
   規則：**手機不捲動就要看得到 SPIN / 🔁 自動 / 🎲 翻倍**；「完成日 / 🗓️ 身世（日期＋平台版本）」可以被切掉。
   螢幕越矮，版面越緊：先縮邊距與字級，再把日期 / 身世 / 資訊列 / 標語收起來。
   [claude code] 2026-07-29 v2.26 門檻放寬（840→900 / 700→780）：筆電視窗高度常在 740~800，
   原本吃不到收合、盤面上方的裝飾把可用高度壓到放不下 6×6 → 盤面被迫夾到很小或溢出。
   盤面本身另由 JS 的 boardHeightBudget() 依「剩餘高度」夾格子大小（見 app.js）。*/
@media (max-height: 900px) {
  .game-stage { padding: 4px 4px 10px; }
  .game-head { margin-bottom: 6px; }
  .game-head h2 { font-size: 17px; }
  .game-info { margin-bottom: 6px; gap: 4px; }
  .machine { padding: 9px; border-radius: 14px; }
  .win-meter { margin-bottom: 6px; }
  .control-bar { margin-top: 9px; gap: 10px; }
  .control-row2 { margin-top: 6px; }
  .btn-spin { padding: 12px 32px; font-size: 17px; }
  .game-completed, .game-born { display: none !important; }   /* 使用者：日期 / 版本可以看不到 */
  /* [claude code] 2026-07-29 v2.26 闖關奪寶 BOSS 面板在矮螢幕壓扁（原本約 150px，是盤面上方最肥的一塊）*/
  .gq-boss { padding: 6px 10px 7px; margin-bottom: 6px; }
  .gq-boss-hint { display: none; }
  .gq-levels { margin-bottom: 5px; gap: 4px; }
  .gq-lv { min-width: 52px; font-size: 10px; padding: 2px 5px; }
  .gq-lv small { font-size: 8px; }
  .gq-boss-glyph { font-size: 34px; }
  .gq-boss-name { font-size: 11px; margin-bottom: 3px; }
  .gq-hpbar { height: 11px; }
  .gq-hptxt { font-size: 10px; margin-top: 2px; }
}
@media (max-height: 780px) {
  .spin-ticket { margin-bottom: 4px; font-size: 11px; }
  .machine { padding: 7px; }
  .btn-spin { padding: 10px 26px; font-size: 16px; }
  .control-row2 .auto-stop-sel, .control-row2 .auto-btn, .control-row2 .gamble-btn { height: 38px; font-size: 12.5px; }
}

/* ============================================================
   [claude code] 2026-07-29 v2.29 環遊世界（travel）：旅程列 / 行李箱 / 盤面符號分類 / 出國選單
   盤面沿用 cluster 的 N×N grid（.clus-board / .clus-cell）與 cs-win / cs-clear / cs-drop 三段表演；
   這裡只加「哪些符號會被收集」的視覺分類（本國綠框 / 🛂 金框 / ✈️ 藍框 / 外國淡出）與旅程 HUD。
   ============================================================ */
.tv-trip { width: min(100%, 470px); margin: 0 auto 8px; padding: 7px 12px 8px; border-radius: 14px;
  background: linear-gradient(160deg, rgba(38,58,92,.9), rgba(18,20,34,.92));
  border: 1px solid rgba(120,190,255,.28); box-shadow: 0 6px 20px rgba(0,0,0,.35); }
.tv-head { display: flex; align-items: center; gap: 8px; }
.tv-flag { font-size: 20px; }
.tv-name { font-size: 14.5px; font-weight: 900; color: #eaf4ff; }
.tv-rule { font-size: 11.5px; color: #9fd0ff; padding: 1px 8px; border-radius: 999px;
  border: 1px solid rgba(120,190,255,.4); background: rgba(80,160,255,.12); }
.tv-day { margin-left: auto; font-size: 12.5px; font-weight: 800; color: var(--gold); }
.tv-daybar { margin-top: 5px; height: 7px; border-radius: 999px; overflow: hidden; background: rgba(255,255,255,.09); }
.tv-dayfill { height: 100%; width: 0; border-radius: 999px; transition: width .45s cubic-bezier(.2,.9,.3,1);
  background: linear-gradient(90deg, #4ea8ff, #9be0ff); box-shadow: 0 0 12px rgba(90,180,255,.6); }
.tv-stats { display: flex; gap: 14px; margin-top: 5px; font-size: 12px; color: var(--text-soft); flex-wrap: wrap; }
.tv-stat b { color: #fff; font-size: 13px; margin: 0 2px; }
.tv-ico { margin-right: 3px; }
.tv-tier { margin-left: 6px; font-size: 11px; padding: 1px 7px; border-radius: 999px; font-weight: 800;
  color: #6a4a12; background: linear-gradient(135deg, #e7c07a, #c99a4e); }
.tv-tier.t1 { color: #3d4450; background: linear-gradient(135deg, #eef3f8, #b9c6d4); }
.tv-tier.t2 { color: #4a3400; background: linear-gradient(135deg, #ffe9a6, var(--gold)); box-shadow: 0 0 12px rgba(255,205,90,.6); }
.tv-pot-pop { animation: tvPotPop .4s ease; }
@keyframes tvPotPop { 0% { transform: scale(1); } 45% { transform: scale(1.28); color: var(--win); } 100% { transform: scale(1); } }

/* 盤面符號分類（框做在 .glyph 上 → 掉落時框跟著符號走，不分離；對齊 v2.22 鐵則） */
.tv-cell .glyph { box-sizing: border-box; display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%; border-radius: 9px; transition: opacity .2s; }
.tv-cell.tv-home .glyph { box-shadow: inset 0 0 0 1.5px rgba(90,225,160,.5); background: rgba(70,210,150,.1); }
.tv-cell.tv-stamp .glyph { box-shadow: inset 0 0 0 1.5px rgba(255,205,90,.7); background: rgba(255,200,80,.14); }
.tv-cell.tv-board .glyph { box-shadow: inset 0 0 0 1.5px rgba(120,190,255,.7); background: rgba(90,170,255,.14); }
.tv-cell.tv-foreign .glyph { opacity: .38; filter: grayscale(.55); }

/* 行李箱：本國 6 種紀念品各一格，裝滿即時給獎 */
.tv-bags { display: grid; grid-template-columns: repeat(6, 1fr); gap: 5px; width: min(100%, 470px); margin: 6px auto 0; }
.tv-bag { position: relative; padding: 4px 2px 5px; border-radius: 10px; text-align: center; overflow: hidden;
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.1); }
.tv-bag-glyph { font-size: 17px; line-height: 1.1; }
.tv-bag-num { font-size: 10px; color: var(--text-soft); }
.tv-bag-bar { margin-top: 3px; height: 4px; border-radius: 999px; background: rgba(255,255,255,.1); overflow: hidden; }
.tv-bag-fill { height: 100%; width: 0; border-radius: 999px; transition: width .35s ease;
  background: linear-gradient(90deg, #5ae1a0, #9bffcf); }
.tv-bag.full { animation: tvBagFull .6s ease; border-color: var(--win); }
@keyframes tvBagFull {
  0% { transform: none; box-shadow: none; }
  35% { transform: translateY(-5px) scale(1.09); box-shadow: 0 0 20px rgba(255,225,105,.85); }
  100% { transform: none; box-shadow: none; }
}
/* 收集到的符號飛向行李箱 / 旅費 */
.tv-fly { position: fixed; z-index: 65; font-size: 22px; pointer-events: none;
  animation: tvFly var(--fly-ms, 520ms) cubic-bezier(.3,.1,.4,1) forwards; }
@keyframes tvFly {
  from { transform: translate(-50%,-50%) scale(1); opacity: 1; }
  to { transform: translate(calc(-50% + var(--fly-x)), calc(-50% + var(--fly-y))) scale(.45); opacity: .1; }
}

/* 出國選單 overlay（沿用 .gq-ov 骨架，改成旅遊藍） */
.tv-ov { background: radial-gradient(circle at 50% 40%, rgba(22,48,86,.9), rgba(8,8,16,.95)); }
.tv-ov-box { background: linear-gradient(165deg, #1d3350, #131425); border-color: rgba(120,190,255,.45); }
.tv-ov .gq-ov-title { color: #cfe8ff; text-shadow: 0 0 18px rgba(80,170,255,.7); }
.tv-pick-countries { display: grid; grid-template-columns: repeat(2, 1fr); gap: 9px; margin: 13px 0 4px; }
.tv-pick-country { padding: 9px 8px; border-radius: 13px; cursor: pointer; text-align: left; transition: .18s;
  background: rgba(255,255,255,.05); border: 1.5px solid rgba(255,255,255,.12); }
.tv-pick-country:hover { background: rgba(120,190,255,.12); }
.tv-pick-country.on { border-color: #6fc0ff; background: rgba(90,170,255,.2); box-shadow: 0 0 16px rgba(90,170,255,.4); }
.tv-pc-head { font-size: 14px; font-weight: 900; color: #fff; }
.tv-pc-sub { margin-top: 2px; font-size: 11px; color: var(--text-soft); line-height: 1.45; }
.tv-pc-syms { margin-top: 4px; font-size: 15px; letter-spacing: 1px; }
.tv-pick-label { margin-top: 12px; font-size: 12px; color: var(--text-soft); }
.tv-pick-days { display: flex; gap: 8px; justify-content: center; margin-top: 6px; flex-wrap: wrap; }
.tv-pick-day { padding: 7px 16px; border-radius: 999px; cursor: pointer; font-weight: 800; font-size: 13px;
  color: #cfe8ff; background: rgba(255,255,255,.06); border: 1.5px solid rgba(255,255,255,.14); transition: .18s; }
.tv-pick-day.on { color: #10233a; background: linear-gradient(135deg, #bfe4ff, #6fc0ff); border-color: #fff; }
.tv-pick-info { margin-top: 11px; font-size: 12px; line-height: 1.7; color: var(--text-soft);
  background: rgba(255,255,255,.04); border-radius: 10px; padding: 8px 10px; text-align: left; }
.tv-pick-info b { color: #fff; }
.tv-pick-btns { display: flex; gap: 10px; justify-content: center; }
.tv-ov .gq-ov-close { background: linear-gradient(135deg, #bfe4ff, #6fc0ff); color: #10233a; }
.tv-ov .gq-ov-close.tv-cancel { background: rgba(255,255,255,.1); color: var(--text-soft); }
/* 細單：travel 盤面格分類 */
.dt-scell.k-home { background: rgba(70,210,150,.14); border-color: rgba(90,225,160,.5); }
.dt-scell.k-stamp { background: rgba(255,200,80,.16); border-color: rgba(255,205,90,.6); }
.dt-scell.k-board { background: rgba(90,170,255,.16); border-color: rgba(120,190,255,.6); }
.dt-scell.k-foreign { opacity: .42; }
.dt-scell.tvpick { box-shadow: inset 0 0 0 2px var(--win); }

@media (max-height: 780px) {
  .tv-trip { padding: 5px 10px 6px; margin-bottom: 5px; }
  .tv-bags { gap: 4px; }
  .tv-bag-glyph { font-size: 15px; }
}

/* [claude code] 2026-07-29 v2.30 環遊世界收集規則改「湊數量」後的三種格子狀態（依使用者回饋）:
   ① .cs-win  = 有湊夠、被收走計分（沿用平台通用高亮）
   ② .tv-stay = 沒湊夠、**留在盤上**累積 → 藍框呼吸 + 右上角「差 N」角標
   ③ .tv-sweep= 沒收集到的外國符號 / 用掉的 ✈️ → 淡出離場 */
.tv-cell { position: relative; }
.tv-cell.tv-stay { z-index: 4; }
.tv-cell.tv-stay .glyph { animation: tvStayPulse .9s ease-in-out infinite alternate; }
@keyframes tvStayPulse {
  from { box-shadow: inset 0 0 0 1.5px rgba(120,190,255,.5); }
  to   { box-shadow: inset 0 0 0 2.5px #6fc0ff, 0 0 14px rgba(90,170,255,.55); }
}
.tv-cell.tv-stay::after {
  content: attr(data-short); position: absolute; right: 2px; top: 1px; z-index: 5;
  font-size: 10px; font-weight: 800; line-height: 1.5; padding: 0 4px; border-radius: 999px;
  color: #10233a; background: linear-gradient(135deg, #bfe4ff, #6fc0ff); box-shadow: 0 1px 4px rgba(0,0,0,.4);
}
.tv-cell.tv-sweep .glyph { animation: tvSweep .32s ease forwards; }
@keyframes tvSweep { to { opacity: .12; transform: scale(.82); filter: grayscale(1); } }
/* 行李箱格上的「湊 N 顆」門檻角標 */
.tv-bag-glyph { position: relative; }
.tv-bag-min { position: absolute; right: -2px; top: -3px; font-size: 9px; font-weight: 800;
  padding: 0 3px; border-radius: 999px; color: #10233a; background: linear-gradient(135deg, #bfe4ff, #6fc0ff); }
.tv-need { color: var(--text-mute); font-size: 11px; margin-left: 1px; }

.dt-scell.tvstay { box-shadow: inset 0 0 0 2px #6fc0ff; }
.dt-line.dt-line-dim { opacity: .6; }

/* ===== [claude code] 2026-07-31 v2.33 深海潛行（dive）=====
   航道是「往深處捲動的視窗」：.dv-view 固定高度 + overflow hidden，.dv-lane 整片 translateY
   → 鏡頭跟著潛水員下沉。未揭露的排一律深黑（server 也沒給內容，見 engine/dive.go 的裁切）。 */
.dv-hud { width: min(100%, 470px); margin: 0 auto 8px; padding: 7px 12px 8px; border-radius: 14px;
  background: linear-gradient(135deg, rgba(20,60,95,.72), rgba(8,26,48,.72)); border: 1px solid rgba(110,190,255,.28); }
/* [claude code] 2026-08-14 v2.92 「換潛點」鈕（選完潛點就留在潛水畫面，要換點才點這裡）。
   [claude code] 2026-08-14 v2.93 🔴 可點的只有左邊那顆 `.dv-pick`，不是整排 ——
   v2.93 把 🪣 漁獲袋也收進這一排了，整排可點的話「看一下賺多少」會誤觸換潛點。 */
.dv-head { display: flex; align-items: center; gap: 7px; }
.dv-pick { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; border-radius: 8px;
  padding: 2px 6px; margin: -2px -2px; transition: background .15s; }
.dv-pick:hover { background: rgba(120,190,255,.12); }
.dv-pick:focus-visible { outline: 2px solid #6fc0ff; outline-offset: 1px; }
.dv-switch { font-size: 10.5px; font-weight: 800; color: #9fd0ff; padding: 1px 6px; border-radius: 999px;
  border: 1px solid rgba(120,190,255,.4); background: rgba(90,170,255,.12); white-space: nowrap; }
.dv-emoji { font-size: 19px; }
.dv-name { font-weight: 900; font-size: 14px; color: #cfe8ff; }
/* [claude code] 2026-08-05 v2.42 .dv-spot-btn（換潛點鈕）已移除 —— 潛點改成每趟在盤面四個區直接選 */
.dv-depth { margin-left: auto; font-size: 11.5px; color: var(--text-soft); }
/* [claude code] 2026-08-14 v2.93 原本這裡有 `.dv-oxy` / `.dv-oxybar` / `.dv-oxyfill`（HUD 的氧氣條）——
   氧氣改掛在潛水員身上（`.dv-d-oxy`，見下）後整組移除，HUD 也從兩排收成一排。 */
.dv-catch { font-size: 12px; color: var(--text-soft); }
.dv-catch b { color: var(--win); font-size: 14px; }
/* [claude code] 2026-08-14 v2.93 🫧 氧氣徽章：掛在潛水員右下角（取代 HUD 那條氧氣條）。
   剩幾排就寫幾 —— 貼在潛水員身上，往下潛時數字跟著他一起動，比抬頭去看一條進度條直覺得多。 */
.dv-d-oxy { position: absolute; right: -2px; bottom: -2px; z-index: 3; pointer-events: none;
  font-weight: 900; line-height: 1; padding: 2px 4px; border-radius: 999px;
  color: #06202e; background: linear-gradient(#bfeaff, #6fc0ff);
  box-shadow: 0 0 8px rgba(110,200,255,.75), inset 0 1px 0 rgba(255,255,255,.6); }
.dv-d-oxy.low { background: linear-gradient(#ffd8a8, #ff9a4a); color: #2e1605;
  box-shadow: 0 0 10px rgba(255,150,70,.85); animation: dvOxyLow .9s ease-in-out infinite; }
.dv-d-oxy.out { background: linear-gradient(#ffb3b3, #ff6a6a); color: #2e0a0a; animation: none; }
@keyframes dvOxyLow { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.14); } }
.dv-diver { display: flex; align-items: center; justify-content: center; }
.dv-d-g { line-height: 1; }

/* 盤面就是「選潛點」的畫面（[claude code] 2026-08-05 v2.42）：四個區由上而下＝越潛越深，
   點一區就直接出發。取代原本的彈窗選單 + 「換潛點」鈕。 */
/* [claude code] 2026-08-14 v2.91 換到版型 v2 + 簡化：高度由 JS 夾成「可用高度」（見 renderDVChooser），
   四個區用 flex 均分 → 不管螢幕多矮，SPIN 都還在畫面上（手機一屏可見鐵則）。 */
.board.dv-choose { display: flex; flex-direction: column; gap: 6px; width: min(100%, 470px); margin: 0 auto;
  padding: 8px; border-radius: 14px; background: linear-gradient(180deg, rgba(20,70,110,.5), rgba(2,10,24,.92)); }
.dv-ch-head { font-size: 12.5px; font-weight: 800; color: #cfe8ff; text-align: center; flex: 0 0 auto; }
.dv-zone { padding: 7px 10px; border-radius: 12px; cursor: pointer; text-align: left; transition: .18s;
  flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; justify-content: center;
  border: 1px solid rgba(120,190,255,.3); background: linear-gradient(180deg, rgba(90,170,255,.14), rgba(90,170,255,.05)); }
/* 越下面的區＝越深：底色越暗、藍越沉 */
.dv-zone.z1 { background: linear-gradient(180deg, rgba(70,150,240,.13), rgba(40,100,190,.06)); }
.dv-zone.z2 { background: linear-gradient(180deg, rgba(50,110,200,.13), rgba(20,60,140,.06)); border-color: rgba(120,190,255,.24); }
.dv-zone.z3 { background: linear-gradient(180deg, rgba(24,60,130,.16), rgba(2,10,30,.5)); border-color: rgba(120,190,255,.2); }
.dv-zone:hover { border-color: #6fc0ff; box-shadow: 0 0 14px rgba(90,170,255,.35); transform: translateY(-1px); }
.dv-zone.go { border-color: #6fc0ff; box-shadow: 0 0 20px rgba(90,170,255,.6); }
.dv-z-main { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px; }
.dv-z-emoji { font-size: 17px; }
.dv-z-name { font-size: 14px; font-weight: 900; color: #eaf4ff; }
/* [claude code] 2026-08-14 v2.91 波動檔徽章 —— SLOT 玩家的母語，四個潛點真正的差別就是這個。
   低→極高：綠 → 黃 → 橘 → 紅（跟平台其他地方的「越燙越紅」一致；⚠️ 這是風險刻度不是損益，
   所以不套「台灣紅賺綠賠」那條 —— 那條管的是賺賠配色）。 */
.dv-z-vol { font-size: 10.5px; font-weight: 900; padding: 1px 7px; border-radius: 999px; letter-spacing: .03em; }
.dv-z-vol.v0 { color: #0e2a18; background: linear-gradient(#b9f0cd, #6bd898); }
.dv-z-vol.v1 { color: #2a2206; background: linear-gradient(#ffe9a8, #ffcf4a); }
.dv-z-vol.v2 { color: #2e1605; background: linear-gradient(#ffcb9a, #ff9a4a); }
.dv-z-vol.v3 { color: #2e0a0a; background: linear-gradient(#ffb3b3, #ff6a6a); }
.dv-z-gate { font-size: 10.5px; font-weight: 800; color: #ffd76a; }
/* 「最貴的那隻」貼右：🔴 顯示的是 ×總注（賠率 ÷ divisor），不是設定檔裡的原始賠率 */
.dv-z-top { margin-left: auto; font-size: 11px; color: #9fd0ff; white-space: nowrap; }
.dv-z-top b { color: #ffd76a; font-size: 12.5px; }
.dv-z-sub { margin-top: 3px; font-size: 11px; color: var(--text-soft); line-height: 1.45;
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; }
/* 內部參數（氧氣 / 光圈）降成小 meta：留著（不給看等於逼玩家瞎選），但不再是主角 */
.dv-z-meta { font-size: 10px; color: #7fb4e0; opacity: .9; }
.dv-ch-info { font-size: 10.5px; color: var(--text-soft); line-height: 1.4; text-align: center; flex: 0 0 auto; }
/* 按了 SPIN 但還沒選 → 整片閃一下提醒「要先點一個區」 */
.board.dv-choose.hint { animation: dvHint .7s ease; }
@keyframes dvHint { 0%,100% { box-shadow: none; } 40% { box-shadow: 0 0 0 2px #6fc0ff, 0 0 22px rgba(90,170,255,.55); } }
@media (max-height: 780px) {
  .dv-zone { padding: 5px 9px; }
  /* [claude code] 2026-08-14 v2.91 矮螢幕先收「氧氣 / 光圈」那顆小 meta（次要資訊），
     再收底下那句回報率說明 —— 波動檔與最貴倍數是選擇依據，最後才會被犧牲。 */
  .dv-z-meta { display: none; }
  .dv-ch-info { display: none; }
}

/* 航道視窗 */
.board.dv-view { display: block; overflow: hidden; position: relative; margin: 0 auto;
  border-radius: 14px; background: linear-gradient(180deg, rgba(20,70,110,.5), rgba(2,10,24,.92)); }
.dv-lane { display: grid; gap: 4px; transition: transform .42s cubic-bezier(.4,.1,.2,1); will-change: transform; }
.dv-cell { position: relative; border-radius: 9px; display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.03); box-shadow: inset 0 0 0 1px rgba(255,255,255,.05); }
.dv-cell .glyph { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; }
.dv-cell.dv-hidden { background: rgba(0,0,0,.42); box-shadow: none; }
.dv-cell.dv-sea .glyph { opacity: .3; }
/* [claude code] 2026-08-14 v2.92 **前方還沒潛到的排**：看得到、但明顯「還在遠處」——
   壓暗 + 輕微模糊 + 縮一點。要一眼分得出「已經收到的」跟「只是先看到的」，
   不然玩家會以為那些已經進袋了。潛到那排時 dvRevealRow 重畫，這個 class 自動消失。 */
.dv-cell.dv-peek { opacity: .42; filter: blur(.7px) saturate(.75); transform: scale(.9); }
.dv-cell.dv-peek .glyph { text-shadow: none; }
/* [claude code] 2026-08-14 v2.93 格子上的金額徽章：撿到的（金）/ 錯過的（紅，帶刪除線＝沒進袋）。
   使用者：「撿到的東西, 可以顯示金額嗎, 這樣子才知道自己少撿了多少錢的」。 */
.dv-cell { position: relative; }
.dv-val { position: absolute; left: 50%; bottom: 1px; transform: translateX(-50%); z-index: 5;
  font-size: 10px; font-weight: 900; line-height: 1; padding: 1px 4px; border-radius: 6px;
  white-space: nowrap; pointer-events: none; }
.dv-val.take { color: #2a1d00; background: linear-gradient(#fff3c8, var(--gold));
  box-shadow: 0 0 7px rgba(255,207,58,.7); }
.dv-val.miss { color: #ffd8d8; background: rgba(120,20,20,.75); text-decoration: line-through;
  border: 1px solid rgba(255,120,120,.5); }
.dv-cell.dv-oxy2 .glyph { filter: drop-shadow(0 0 6px rgba(140,220,255,.9)); }
.dv-cell.dv-gate2 .glyph { animation: dvGateGlow 1.1s ease-in-out infinite alternate; }
@keyframes dvGateGlow { from { filter: drop-shadow(0 0 3px rgba(255,190,90,.6)); }
  to { filter: drop-shadow(0 0 14px rgba(255,170,60,1)); transform: scale(1.08); } }
/* 光圈照到（可收） */
.dv-cell.lit { box-shadow: inset 0 0 0 2px rgba(255,240,170,.75), 0 0 16px rgba(255,225,120,.4);
  background: rgba(255,230,140,.12); }
/* 收進漁獲袋 */
.dv-cell.took .glyph { animation: dvTook .34s ease forwards; }
@keyframes dvTook { to { opacity: 0; transform: scale(.5) translateY(-10px); } }
/* 錯過的：擦身而過（側邊）/ 差一點就到（前方） */
.dv-cell.miss-side { box-shadow: inset 0 0 0 2px rgba(150,175,205,.55); }
.dv-cell.miss-ahead { box-shadow: inset 0 0 0 2px rgba(255,140,140,.7); background: rgba(255,90,90,.1); }
.dv-cell.miss-big .glyph { animation: dvMissBig 1s ease-in-out infinite alternate; }
@keyframes dvMissBig { from { transform: scale(1); } to { transform: scale(1.14); filter: drop-shadow(0 0 12px rgba(255,120,120,.95)); } }
/* 潛水員 */
.dv-diver { position: absolute; z-index: 6; pointer-events: none; display: flex; align-items: center; justify-content: center;
  transition: transform .42s cubic-bezier(.4,.1,.2,1); filter: drop-shadow(0 0 10px rgba(140,220,255,.85)); }
.board.dv-view.shake { animation: dvShake .45s ease; }
@keyframes dvShake { 0%,100% { transform: translateX(0); } 20% { transform: translateX(-7px); }
  45% { transform: translateX(6px); } 70% { transform: translateX(-4px); } }
/* 飛進漁獲袋 */
.dv-fly { position: fixed; z-index: 65; font-size: 22px; pointer-events: none;
  transform: translate(-50%, -50%); animation: dvFly var(--fly-ms, 460ms) cubic-bezier(.3,.1,.2,1) forwards; }
@keyframes dvFly { to { transform: translate(calc(-50% + var(--fly-x)), calc(-50% + var(--fly-y))) scale(.42); opacity: .1; } }

/* 「這趟錯過了什麼」面板 */
.dv-missed { width: min(100%, 470px); margin: 6px auto 0; padding: 6px 10px 7px; border-radius: 12px;
  font-size: 11.5px; color: var(--text-soft); text-align: left;
  background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.08); }
.dv-missed .dv-m-title { font-weight: 800; color: #ffb0b0; }
.dv-missed .dv-m-list { margin-top: 3px; display: flex; flex-wrap: wrap; gap: 4px 8px; }
.dv-missed .dv-m-item.big { color: #ffd0d0; font-weight: 800; }

/* [claude code] 2026-08-05 v2.42 潛點選單彈窗（.dv-ov / .dv-pick-* / .dv-ps-*）已移除 ——
   潛點改成每趟在盤面上的四個區直接選（見上面 .board.dv-choose / .dv-zone）。
   🔱 深淵之門的 BONUS 彈窗仍在，用的是 .dv-gate-ov（下面那組，琥珀色，不受影響）。 */

/* 深淵之門 BONUS overlay（續潛階梯） */
.dv-gate-ov .gq-ov-box { background: linear-gradient(160deg, rgba(52,26,8,.97), rgba(10,6,20,.98)); border-color: rgba(255,180,80,.45); }
.dv-gate-ov .gq-ov-title { color: #ffd88a; text-shadow: 0 0 18px rgba(255,150,60,.8); }
.dv-rungs { display: grid; gap: 4px; margin-top: 12px; max-height: 46vh; overflow-y: auto; }
.dv-rung { display: flex; align-items: center; gap: 8px; padding: 5px 10px; border-radius: 10px;
  background: rgba(255,255,255,.05); opacity: 0; transform: translateY(6px); transition: .22s; }
.dv-rung.show { opacity: 1; transform: none; }
.dv-rung .dv-r-lv { font-size: 11.5px; color: var(--text-soft); min-width: 54px; text-align: left; }
.dv-rung .dv-r-mult { font-size: 12px; color: #ffd88a; }
.dv-rung .dv-r-pay { margin-left: auto; font-weight: 900; color: var(--win); }
.dv-rung.end { background: rgba(255,90,90,.16); }
.dv-rung.end .dv-r-lv { color: #ffc9c9; }
.dv-gate-total { margin-top: 10px; font-size: 17px; font-weight: 900; color: #fff; }
.dv-gate-total b { color: var(--win); text-shadow: 0 0 14px rgba(255,225,105,.8); }

/* 細單：航道盤面 */
.dt-dive { gap: 3px; }
.dt-scell.dvlit { box-shadow: inset 0 0 0 2px rgba(255,240,170,.8); background: rgba(255,230,140,.13); }
.dt-scell.dvtook { box-shadow: inset 0 0 0 2px var(--win); background: rgba(255,225,105,.16); }
.dt-scell.dvmiss { box-shadow: inset 0 0 0 2px rgba(255,140,140,.7); }
.dt-scell.dvhidden { background: rgba(0,0,0,.4); }
.dt-scell.dvdiver { box-shadow: inset 0 0 0 2px #6fc0ff, 0 0 12px rgba(90,170,255,.6); }

@media (max-height: 840px) {
  .dv-hud { padding: 5px 10px 6px; margin-bottom: 5px; }
  .dv-missed { display: none !important; }
}

/* ===== [claude code] 2026-08-05 v2.44 蟻巢遠征（ants：地面覓食）=====
   🔴 舊版是「往地下捲動的視窗 + 迷霧」，整組砍掉：這款盤面**一屏全可見、無捲動、無迷霧**
   （食物本來就該全部看得到 —— 那才是螞蟻覓食的畫面）。 */
.ant-hud { width: min(100%, 470px); margin: 0 auto 8px; padding: 7px 12px 8px; border-radius: 14px;
  background: linear-gradient(135deg, rgba(74,52,30,.75), rgba(32,22,12,.78)); border: 1px solid rgba(210,160,90,.3); }
.an-head { display: flex; align-items: center; gap: 10px; }
.an-squad { font-weight: 900; font-size: 13px; color: #d8b57e; }
/* [claude code] 2026-08-09 v2.51 出動池是這款唯一要盯的數字 → 字最大、顏色最亮 */
.an-squad b { font-size: 19px; color: #ffe6b0; margin-left: 2px; }
/* 這趟倍數：×1 時低調，>×1 就發亮（「愈後面愈值錢」要看得到） */
.an-mult { font-size: 13px; font-weight: 900; color: #9aa4b2; }
.an-mult.an-mult-hot { color: #ffd45e; text-shadow: 0 0 10px rgba(255,200,70,.6); }
.an-trip { font-size: 12.5px; color: #d8b57e; }
.an-catch { margin-left: auto; font-size: 12.5px; color: var(--text-soft); }
.an-catch b { color: var(--win); font-weight: 900; }
.an-legend { margin-top: 5px; font-size: 10.5px; line-height: 1.6; color: var(--text-soft); }
.an-lg { display: inline-block; padding: 0 4px; border-radius: 999px; font-size: 9.5px; font-weight: 800;
  color: #2a1a08; background: rgba(240,200,130,.92); }

/* 地面（一屏全可見） */
.board.ant-view { display: flex; align-items: center; justify-content: center; margin: 0 auto; overflow: visible;
  border-radius: 14px; background: linear-gradient(180deg, rgba(96,120,60,.35), rgba(30,26,14,.9)); }
.ant-ground { display: grid; }
.ant-cell { position: relative; border-radius: 8px; display: flex; align-items: center; justify-content: center;
  background: rgba(120,140,70,.18); box-shadow: inset 0 0 0 1px rgba(255,255,255,.05); }
.ant-cell .glyph { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; }
.ant-cell.an-empty { background: rgba(120,140,70,.14); }
/* [claude code] 2026-08-05 v2.49 空地畫 🌿 但壓淡 —— 有草地才像一片地面（細單本來就有，主畫面補回來），
   壓淡是為了讓「有食物的格」仍然一眼跳出來。 */
.ant-cell.an-empty .glyph { opacity: .3; }
.ant-cell.an-food { background: rgba(255,210,120,.12); box-shadow: inset 0 0 0 1.5px rgba(255,200,110,.4); }
.ant-cell.an-nest { background: rgba(150,110,60,.5); box-shadow: inset 0 0 0 2px rgba(230,180,110,.7); }
.ant-cell.an-hill { background: rgba(120,120,130,.3); }
.ant-cell.an-water { background: rgba(90,160,220,.22); }
.ant-cell.an-hole { background: rgba(20,16,10,.75); }
.ant-cell.an-blocked { opacity: .5; }
/* 🔴 [claude code] 2026-08-09 v2.53 **燃料框**（使用者：「希望能加入 scatter 或是不用標注字的框，
   用來讓別人明白很特別」）：回巢補的隻數 ≥ 派出去的 —— 這是「還能不能再出一趟」的關鍵，
   但它在賠付表上是最便宜的那幾樣，玩家不會注意。**用框講，不寫字**：
     · 淨不虧 → 綠色呼吸框
     · 大幅增兵（🍯）→ 金色脈動框 + 外光暈（這款的 FREE SPIN，要跟 SCATTER 一樣搶眼） */
.ant-cell.an-fuel { box-shadow: inset 0 0 0 2px rgba(120,235,150,.7); animation: anFuel 2.1s ease-in-out infinite; }
@keyframes anFuel { 50% { box-shadow: inset 0 0 0 2.5px rgba(150,255,180,1), 0 0 10px rgba(110,230,150,.45); } }
.ant-cell.an-fuel-big { background: rgba(255,205,90,.14);
  box-shadow: inset 0 0 0 2.5px rgba(255,205,90,.9), 0 0 12px rgba(255,190,70,.5);
  animation: anFuelBig 1.5s ease-in-out infinite; }
@keyframes anFuelBig { 50% { box-shadow: inset 0 0 0 3px rgba(255,235,150,1), 0 0 22px rgba(255,200,80,.95); } }
.ant-cell.an-fuel-big .glyph { animation: anFuelPop 1.5s ease-in-out infinite; }
@keyframes anFuelPop { 50% { transform: scale(1.12); } }
/* 已搬走 / 湊不到的格不要再閃（框只用來標「還在地上、而且是燃料」） */
.ant-cell.an-took.an-fuel, .ant-cell.an-took.an-fuel-big,
.ant-cell.an-cant.an-fuel, .ant-cell.an-cant.an-fuel-big { animation: none; }
.ant-cell.an-cant.an-fuel, .ant-cell.an-cant.an-fuel-big { box-shadow: inset 0 0 0 1.5px rgba(255,140,140,.35); }
/* 🔴 [claude code] 2026-08-09 v2.52 **搬走的格要看得出結果**（使用者：「只是拿掉數字，看不出來結果」）：
   圖示留著壓淡 + 左下 ✅ + 右上「+實拿多少」→ 整盤掃完就是一張「這局在哪幾格賺了多少」的收據。 */
.ant-cell.an-took { background: rgba(120,200,120,.10); box-shadow: inset 0 0 0 1.5px rgba(140,220,140,.42); }
.ant-cell.an-took .glyph { opacity: .34; filter: grayscale(.5); }
.an-need.an-need-took { color: #06301a; background: linear-gradient(135deg, #b6f5c9, #6fdd92); }
.ant-cell.an-took .an-pay { color: #8ef0a8; text-shadow: 0 1px 3px rgba(0,0,0,.85); }
/* 食物角落：要幾隻（左下）+ 搬回來值多少（右上） */
.an-need { position: absolute; left: 1px; bottom: 0; font-size: 9.5px; font-weight: 800; line-height: 1.4;
  padding: 0 3px; border-radius: 999px; color: #2a1a08; background: rgba(240,200,130,.92); }
/* 🔴 [claude code] 2026-08-09 v2.51 當下出動池湊不到的格：標籤翻紅寫「差 N」+ 整格壓暗。
   使用者要的「畫面上顯示還能出動幾隻」不只是 HUD 一個數字 ——
   盤面當場分成「搬得動 / 搬不動」兩種顏色，才看得出這趟會發生什麼。 */
.an-need.an-need-short { color: #3a0d0d; background: linear-gradient(135deg, #ffc9c9, #ff8a8a); }
.ant-cell.an-cant { opacity: .62; box-shadow: inset 0 0 0 1.5px rgba(255,140,140,.35); }
.ant-cell.an-cant .an-pay { opacity: .55; }
.an-pay { position: absolute; right: 2px; top: 0; font-size: 9px; font-weight: 900; color: var(--win);
  text-shadow: 0 1px 3px rgba(0,0,0,.8); }
/* 🔴 [claude code] 2026-08-09 v2.53 **換一片地** 取代原本的「由上往下掉」。
   使用者：「畫面上不用由上下往掉，能讓人換場景的動作，感覺好像換個地方」——
   逐格掉看起來像**洗牌 / 重發同一副牌**，跟「螞蟻走到另一塊地覓食」對不上。
   A. 整片滑出 / 滑入（鏡頭跟著螞蟻走到下一塊地）　B. 進場後由近而遠逐圈浮現（原地淡入，不位移） */
.ant-ground.an-scene-in { animation: anSceneIn .52s cubic-bezier(.22,.9,.28,1); }
@keyframes anSceneIn { from { transform: translateX(46%) scale(.94); opacity: 0; } to { transform: none; opacity: 1; } }
.ant-ground.an-scene-out { animation: anSceneOut .3s ease-in forwards; }
@keyframes anSceneOut { to { transform: translateX(-42%) scale(.94); opacity: 0; } }
.ant-cell.an-hide { opacity: 0; }
.ant-cell.an-rise { animation: anRise .34s cubic-bezier(.34,1.4,.64,1); }
@keyframes anRise { from { opacity: 0; transform: scale(.62); } to { opacity: 1; transform: none; } }
/* 每一局換一種草地色調 —— 「這次是走到另一片地」最直接的訊號（色調由盤面 hash 決定，可重播） */
.board.ant-view.an-scene-0 { background: linear-gradient(180deg, rgba(96,120,60,.35), rgba(30,26,14,.9)); }
.board.ant-view.an-scene-1 { background: linear-gradient(180deg, rgba(72,124,86,.35), rgba(18,30,20,.9)); }
.board.ant-view.an-scene-2 { background: linear-gradient(180deg, rgba(130,116,54,.35), rgba(34,28,12,.9)); }
.board.ant-view.an-scene-3 { background: linear-gradient(180deg, rgba(78,110,124,.32), rgba(16,24,30,.9)); }
.board.ant-view.an-scene-4 { background: linear-gradient(180deg, rgba(124,92,60,.34), rgba(32,22,12,.9)); }
.board.ant-view.an-scene-5 { background: linear-gradient(180deg, rgba(96,84,128,.30), rgba(22,18,32,.9)); }

/* 扛走 / 差一點 */
.ant-cell.an-carry .glyph { animation: anCarry .45s ease forwards; }
@keyframes anCarry { to { opacity: 0; transform: scale(.4) translateY(-16px); } }
.ant-cell.an-short { box-shadow: inset 0 0 0 2px rgba(255,130,130,.75); }
.ant-cell.an-short .glyph { animation: anShake .5s ease-in-out infinite alternate; }
@keyframes anShake { from { transform: translateX(-2px) rotate(-5deg); } to { transform: translateX(2px) rotate(5deg); } }
.ant-cell.an-short-big { background: rgba(255,90,90,.16); }
.an-shorttag { position: absolute; left: 50%; top: -8px; transform: translateX(-50%); white-space: nowrap; z-index: 9;
  font-size: 10px; font-weight: 900; padding: 1px 5px; border-radius: 999px;
  color: #3a0d0d; background: linear-gradient(135deg, #ffc9c9, #ff7a7a); }

/* 螞蟻（沿路走；同格散開 + ×N，不疊圖） */
/* 🔴 [claude code] 2026-08-09 v2.52 盤面上的兩顆徽章（出動池 / 倍數）。
   使用者：「能出動的數量和倍數很重要，放在上面看中間表演時完全不會注意，也很難去查看」——
   表演時視線都在盤面上，所以把這兩個數字**搬進盤面裡**：池子貼巢口（兵從那裡出去）、倍數貼右上角。 */
.an-pool-badge { position: absolute; z-index: 12; transform: translate(-50%, -100%);
  display: flex; align-items: center; gap: 3px; padding: 2px 9px 2px 7px; border-radius: 999px;
  background: linear-gradient(135deg, rgba(92,62,28,.97), rgba(48,32,14,.97));
  border: 1.5px solid rgba(255,205,120,.75); box-shadow: 0 3px 10px rgba(0,0,0,.55);
  white-space: nowrap; line-height: 1.15; }
.an-pool-badge .apb-ico { font-size: 13px; }
.an-pool-badge b { font-size: 19px; font-weight: 900; color: #ffe6b0; text-shadow: 0 1px 4px rgba(0,0,0,.7); }
.an-mult-badge { position: absolute; z-index: 12; right: 2px; top: 2px; padding: 2px 8px; border-radius: 999px;
  font-size: 12px; font-weight: 900; color: #9aa4b2; line-height: 1.3;
  background: rgba(18,16,28,.82); border: 1px solid rgba(255,255,255,.12); }
.an-mult-badge b { font-size: 17px; margin-left: 2px; }
.an-mult-badge.an-mult-hot { color: #ffd45e; border-color: rgba(255,200,70,.6);
  box-shadow: 0 0 14px rgba(255,190,60,.45); }
/* 數字有變就放大閃一下 —— 「本錢在動」要用餘光就看得到（漲綠、跌紅） */
.an-pool-badge.an-bump { animation: anBump .42s cubic-bezier(.34,1.56,.64,1); }
@keyframes anBump { 0% { transform: translate(-50%,-100%) scale(1); } 45% { transform: translate(-50%,-100%) scale(1.32); } 100% { transform: translate(-50%,-100%) scale(1); } }
.an-mult-badge.an-bump { animation: anBumpPlain .42s cubic-bezier(.34,1.56,.64,1); }
@keyframes anBumpPlain { 0% { transform: scale(1); } 45% { transform: scale(1.35); } 100% { transform: scale(1); } }
.an-pool-badge.an-bump-up { border-color: rgba(150,240,170,.95); box-shadow: 0 0 16px rgba(120,230,150,.6); }
.an-pool-badge.an-bump-down { border-color: rgba(255,160,140,.9); box-shadow: 0 0 14px rgba(255,130,110,.45); }

.ant-bug { z-index: 6; pointer-events: none; display: flex; align-items: center; justify-content: center;
  transition: transform .22s linear; filter: drop-shadow(0 0 5px rgba(255,220,150,.7)); }
.an-bug-n { position: absolute; left: 50%; bottom: -2px; transform: translateX(-50%); white-space: nowrap;
  font-size: 10px; font-weight: 900; color: #2a1a08; background: rgba(255,225,150,.95);
  border-radius: 999px; padding: 0 4px; line-height: 1.35; }
.an-bug-n:empty { display: none; }
.an-fly { position: fixed; z-index: 65; font-size: 20px; pointer-events: none;
  transform: translate(-50%, -50%); animation: anFly var(--fly-ms, 460ms) cubic-bezier(.3,.1,.2,1) forwards; }
@keyframes anFly { to { transform: translate(calc(-50% + var(--fly-x)), calc(-50% + var(--fly-y))) scale(.42); opacity: .1; } }

/* [claude code] 2026-08-09 v2.51 🔴 偵察兵樣式整段移除（an-scout / an-trail / an-found / an-foundtag）——
   「由近而遠」之後不需要演一個出門的理由，理由就寫在盤面上。 */
/* 扛著食物走 —— 食物掛在領頭那隻身上，整群一起往巢口移動 */
.an-carrying { position: absolute; left: 50%; top: -60%; transform: translateX(-50%);
  font-size: 0.95em; filter: drop-shadow(0 1px 3px rgba(0,0,0,.6)); }
.ant-bug.an-loaded { filter: drop-shadow(0 0 6px rgba(255,225,120,.9)); z-index: 9; }

/* 每一趟發生什麼（搬回什麼 + 最可惜的那一樣） */
.ant-log { width: min(100%, 470px); margin: 6px auto 0; padding: 6px 10px 7px; border-radius: 12px;
  font-size: 11.5px; color: var(--text-soft); text-align: left;
  background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.08); }
.an-lg-row { line-height: 1.75; }
.an-lg-row b { color: #f2d9a8; }
.an-lg-ok { margin-left: 6px; color: var(--win); font-weight: 700; }
.an-lg-non { margin-left: 6px; opacity: .7; }
.an-lg-miss { margin-left: 6px; color: #ffb0b0; }
/* 🍯 回巢增兵那一段（這款的免費遊戲）要在紀錄裡看得到 */
.an-lg-fed { margin-left: 6px; color: #ffd45e; font-weight: 700; }
.an-lg-fin { border-top: 1px dashed rgba(255,255,255,.14); margin-top: 3px; padding-top: 3px; }
/* 賠付表：開局扛不動 / 淨增兵 */
.an-pt-over { color: #ff9a9a; }
.an-pt-plus { color: #ffd45e; }
/* 賠付表上的「框」色塊 —— 跟盤面那圈光是同一套語言，玩家對得起來 */
.an-pt-frame { display: inline-block; width: 14px; height: 14px; border-radius: 4px; vertical-align: -2px;
  box-shadow: inset 0 0 0 2px rgba(120,235,150,.85); }
.an-pt-frame.big { box-shadow: inset 0 0 0 2.5px rgba(255,205,90,.95), 0 0 8px rgba(255,190,70,.55);
  background: rgba(255,205,90,.16); }

/* 細單：地面盤 */
.dt-ants { gap: 3px; }
.dt-ants .dt-scell { position: relative; }
.dt-need { position: absolute; right: 1px; bottom: 0; font-size: 9px; font-weight: 800;
  padding: 0 2px; border-radius: 999px; color: #2a1a08; background: rgba(240,200,130,.9); }
.dt-scell.anfood { box-shadow: inset 0 0 0 1.5px rgba(255,200,110,.4); }
.dt-scell.antook { box-shadow: inset 0 0 0 2px var(--win); background: rgba(255,225,105,.16); }
.dt-scell.anshort { box-shadow: inset 0 0 0 2px rgba(255,130,130,.75); }
.dt-scell.annest { box-shadow: inset 0 0 0 2px rgba(230,180,110,.8); }
.dt-scell.anterrain { opacity: .6; }

@media (max-height: 840px) {
  .ant-hud { padding: 5px 10px 6px; margin-bottom: 5px; }
  /* [claude code] 2026-08-05 圖例與「搬回什麼」是在回答「這數字什麼意思 / 我拿到什麼」→ 矮螢幕先縮不先砍 */
  .an-legend { margin-top: 3px; font-size: 10px; }
  .ant-log { padding: 5px 9px 6px; }
}
@media (max-height: 700px) {
  .an-legend { display: none !important; }
}

/* ================= 金運麻將（mechanic="mjway"）=================
   [claude code] 2026-08-13 建立。4-5-5-5-4 = 2000 路滾輪 + 消除掉落 + 連鎖升倍 + 金牌翻百搭。
   牌面直接沿用夜市麻將賓果那套 low art（.mj-cell / .mj-honor / .mj-man / .mj-pip），
   這裡只加「滾輪排版 + 金牌 + 百搭/奪寶牌面 + 三段表演 + 倍率條」。
   ⚠️ 通用的 .cell.cs-win/.cs-clear/.cs-drop 是把動畫套在子元素 .glyph 上；
      麻將牌沒有 .glyph（內容是牌面 span）→ 這裡另外寫一組套在格子本身。 */
/* [claude code] 2026-08-13 ① 暖色桌面底（依使用者：「牌的切割感不要那麼重」）。
   在此之前縫隙是深色底板的純黑 → 每張白牌都像被切開的磚。改成暗紅金的牌桌感 +
   中央往外的柔光，縫隙有了顏色，整盤就連成一片。 */
/* [claude code] 2026-08-13 v2.73 `margin-top` 把整塊盤面往下讓 12px，空間留給上緣的倍率條
   （配 `.mw-multbar` 的 top −13 → −25，兩者位移相同 → 條的絕對位置不變）。
   ⚠️ 這 12px 會被 `boardHeightBudget()` 的 offsetTop 鏈自動算進去 → 牌張跟著夾小約 2px，
   不會頂出控制列（手機一屏可見鐵則）。 */
.board.mw-board { display: flex !important; position: relative; gap: 4px; margin-top: 12px;
  align-items: center; justify-content: center; overflow: visible;
  background:
    radial-gradient(ellipse at 50% -10%, rgba(190,60,45,.30), transparent 62%),
    radial-gradient(ellipse at 50% 115%, rgba(140,40,35,.22), transparent 60%),
    linear-gradient(162deg, #2b161a 0%, #1d1014 58%, #170c10 100%);
  box-shadow: inset 0 0 0 1px rgba(255,200,90,.18), inset 0 0 42px rgba(0,0,0,.55); }
/* [claude code] 2026-08-13 角飾改「跨界疊上去」（使用者看參考圖後的補充：
   「他們感覺是使用一些東西，蓋在上面，有連續感，又不會很突兀」）。

   🔴 關鍵是**跨過盤面的邊界**：一半在盤外、一半蓋住牌的邊緣（z-index 疊在牌之上）
   → 那條「盤面到此為止」的直線被打斷，整塊才不像一個被框住的矩形。
   第一版把裝飾規規矩矩放在盤內、opacity .13 當浮水印 —— 邊界完全沒被碰到，等於白做。

   🔴 「不突兀」靠的是 **mask 讓外緣淡出**：實心貼上去會像貼紙，
   用 radial-gradient 遮罩把邊緣化掉，它才會像長在背景裡。
   ⚠️ 溢出量刻意壓在 ~20px 以內 —— 再多會頂到抬頭區與控制列。 */
.mw-deco { position: absolute; inset: 0; pointer-events: none; z-index: 3; overflow: visible; }
.mw-deco-c { position: absolute; line-height: 1; user-select: none;
  font-size: clamp(34px, 13vw, 74px); opacity: .42; filter: saturate(.85) drop-shadow(0 3px 6px rgba(0,0,0,.5));
  -webkit-mask-image: radial-gradient(closest-side, #000 52%, transparent 96%);
  mask-image: radial-gradient(closest-side, #000 52%, transparent 96%); }
/* 🔴 只放四角。**左右腰不要放**（2026-08-13 使用者回報「左8萬、右2筒上面，像有蓋到東西」）——
   腰身的位置正好壓在最外側那一軸的牌上，而牌是象牙白、雲也是白的 → 糊成一團，
   看起來不是裝飾、是髒污。四角可以，是因為外軸只有 4 格、上下本來就有空隙，壓到的是背景。 */
.mw-deco-0 { left: -20px;  top: -18px;    transform: rotate(-14deg); }
.mw-deco-1 { right: -20px; top: -18px;    transform: rotate(14deg) scaleX(-1); }
.mw-deco-2 { left: -18px;  bottom: -16px; transform: rotate(10deg); opacity: .36; }
.mw-deco-3 { right: -18px; bottom: -16px; transform: rotate(-10deg) scaleX(-1); opacity: .36; }
@media (max-width: 420px) {
  /* 手機上盤面貼近螢幕邊 → 溢出量收一半，免得被裁掉只剩半隻 */
  .mw-deco-0, .mw-deco-2 { left: -10px; }
  .mw-deco-1, .mw-deco-3 { right: -10px; }
}

/* [claude code] 2026-08-13 ②③ 點牌跳出的賠付小卡 */
.mw-paypop { position: absolute; z-index: 12; transform: translate(-50%, -100%);
  display: flex; align-items: center; gap: 13px; padding: 9px 15px 9px 11px;
  border-radius: 13px; pointer-events: none; white-space: nowrap;
  background: linear-gradient(160deg, #a3160f, #7a0c07);
  box-shadow: inset 0 0 0 2px var(--gold), 0 8px 22px rgba(0,0,0,.55), 0 0 18px rgba(255,180,60,.35);
  animation: mwPopIn .16s ease both; }
.mw-paypop.below { transform: translate(-50%, 0); }
@keyframes mwPopIn { from { opacity: 0; transform: translate(-50%, -92%) scale(.9); } }
.mw-paypop.below { animation-name: mwPopInB; }
@keyframes mwPopInB { from { opacity: 0; transform: translate(-50%, 8%) scale(.9); } }
/* 2026-08-13 二版（使用者：「圖 + 右邊6個數字就可以，但**再放大一點**」）：
   拿掉牌名與底下那行算式，整體尺寸拉大約 1.4 倍 —— 這張卡是「掃一眼」用的，
   完整算式在 📋 賠付表與 🔍 細單裡本來就有。 */
.mw-pp-face { width: 48px; height: 61px; flex: 0 0 auto; border-radius: 8px; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(158deg, #fbf6e9, #e2d4b6); color: #1b2330;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 2px 6px rgba(0,0,0,.45); }
.mw-pp-face .mj-honor { font-size: 29px; }
.mw-pp-face .mj-pip { width: 82%; height: 82%; }
.mw-pp-face .mj-man .mm-n { font-size: 20px; } .mw-pp-face .mj-man .mm-s { font-size: 13px; }
.mw-pp-face .mw-ingot { font-size: 22px; } .mw-pp-face .mw-wtxt { font-size: 11px; }
.mw-pp-face .mw-scat-art { font-size: 27px; animation: none; }
.mw-pp-body { display: flex; flex-direction: column; gap: 2px; }
.mw-pp-row { display: flex; align-items: baseline; gap: 12px; line-height: 1.12; }
.mw-pp-n { font-size: 17px; font-weight: 900; color: #cfe3ff; min-width: 12px; }
.mw-pp-v { font-size: 21px; font-weight: 900; color: var(--gold); text-shadow: 0 1px 2px rgba(0,0,0,.45); }
.mw-pp-note { font-size: 12px; font-weight: 700; color: rgba(255,235,200,.85); }
/* 被點的那張牌：金色描邊（不改亮度 —— 對齊「提示樣式不動亮度」那條） */
.mw-cell.mw-picked { z-index: 6; box-shadow: inset 0 2px 0 rgba(255,255,255,.85),
  inset 0 0 0 2.5px var(--gold), 0 0 15px rgba(255,207,58,.8), 0 2px 5px rgba(0,0,0,.35); }
.mw-reel { display: flex; flex-direction: column; justify-content: center; }
/* 🎰 滾輪落盤：轉的時候整軸裁切（.spinning），裡面那條 .mw-strip 由上往下捲進來。
   ⚠️ 只有轉的那幾百毫秒才裁切 —— 常態不裁，不然金牌 / 百搭的外發光會被切掉。 */
.mw-reel.spinning { overflow: hidden; justify-content: flex-start; }
/* [claude code] 2026-08-13 v2.76 使用者：「總覺得他轉動停下來後，會往左右再拉開一點」。
   🔴 病根就是上面那個 `overflow: hidden`：它是**四邊都裁**的 ——
      轉的時候牌的**外發光 / 陰影（金牌、百搭那圈光）左右兩側被切掉**，
      一停下來 `.spinning` 拿掉、overflow 恢復 visible，那圈光才整個跑出來
      → 牌沒有真的移動半格，但「亮的範圍」變寬了，看起來就是往左右撐開一點。
   解法：改用 `clip-path` **只裁上下、左右往外放 18px** —— 垂直方向照舊裁乾淨（滾輪不會溢出到別軸），
   水平方向留空間給發光 → **轉動中與停住後一樣寬**，那一下的「拉開」就沒有了。
   🔴 clip-path 不佔版面（不像 padding 會改寬度）→ 軸距完全不動。
   ⚠️ 包 @supports：不支援的瀏覽器自動退回上面那條 overflow: hidden，行為與 v2.75 相同、不會壞。 */
@supports (clip-path: inset(0 -18px)) {
  .mw-reel.spinning { overflow: visible; clip-path: inset(0 -18px); }
}
.mw-strip { display: flex; flex-direction: column; will-change: transform; }
/* [claude code] 2026-08-13 v2.74 按下 SPIN 到結果回來之間的**無限空轉**（見 app.js 的 mwSpinLaunch）。
   strip 裡放兩份內容相同的假牌，捲完一個週期（--mw-loop = 一份的高度）畫面與起點一致 → 無縫。 */
@keyframes mwLoop { from { transform: translateY(var(--mw-loop)); } to { transform: translateY(0); } }
/* 覆寫基礎 .cell 的 absolute 定位（比照 .ways-cell/.clus-cell），不然整軸會塌成一格 */
.mw-cell { position: relative !important; flex: 0 0 auto; overflow: hidden; }
/* 層級：牌(1) < 角飾(3) < 中獎高亮(4~6) < 倍率條(6) < 賠付小卡(12)
   —— 角飾要「蓋在牌上面」才有疊上去的感覺，但不能蓋掉中獎高亮與小卡。 */
.mw-reel { position: relative; z-index: 1; }

/* 🟡 金牌：中獎後不會爆掉，而是原地翻成百搭 → 用金色牌面 + 角標，讓玩家一眼認得 */
.mw-cell.mw-gold { background: linear-gradient(158deg, #fff6d0 0%, #ffd45e 55%, #e6ad24 100%);
  box-shadow: inset 0 2px 0 rgba(255,255,255,.92), inset 0 0 0 2px #e0a11f,
    0 0 14px rgba(255,203,58,.7), 0 2px 5px rgba(0,0,0,.35); }
.mw-cell.mw-gold::after { content: "金"; position: absolute; top: 0; right: 2px;
  font-size: clamp(7px, 2.1vw, 11px); font-weight: 900; color: #7a4f00; opacity: .85; }

/* 💰 百搭（元寶牌）：金紅漸層 + 元寶 + 直排「百搭」 */
.mw-cell.mw-wild { background: linear-gradient(160deg, #fff2c4 0%, #ffcf4a 46%, #d98b18 100%);
  box-shadow: inset 0 2px 0 rgba(255,255,255,.95), inset 0 0 0 2.5px #b9302a,
    0 0 16px rgba(255,196,60,.85), 0 2px 5px rgba(0,0,0,.4); }
.mw-wild-art { display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: 1; gap: 1px; }
.mw-ingot { font-size: clamp(13px, 4.6vw, 24px); filter: drop-shadow(0 1px 1px rgba(0,0,0,.3)); }
.mw-wtxt { font-size: clamp(8px, 2.5vw, 12px); font-weight: 900; color: #9c1d14; letter-spacing: .06em; }

/* 🧧 奪寶（胡）：紅底金字 + 呼吸光暈（只觸發免費，不參與連線） */
.mw-cell.mw-scat { background: linear-gradient(158deg, #a3160f 0%, #7d0c07 60%, #5c0704 100%);
  box-shadow: inset 0 2px 0 rgba(255,255,255,.25), inset 0 0 0 2px #ffcf4a,
    0 0 16px rgba(255,120,60,.75), 0 2px 5px rgba(0,0,0,.45); }
.mw-scat-art { font-size: clamp(17px, 6vw, 32px); font-weight: 900; line-height: 1;
  color: #ffe28a; text-shadow: 0 0 8px rgba(255,180,60,.95), 0 1px 0 rgba(0,0,0,.5);
  animation: mwScat 1.3s ease-in-out infinite alternate; }
@keyframes mwScat { from { transform: scale(1); filter: none; } to { transform: scale(1.08); filter: brightness(1.3); } }

/* 三段表演（套在格子本身，不是 .glyph） */
/* 🔴 中獎高亮走過兩次極端，這是第三版：
   一版 `brightness(1.45)` → 使用者：「很閃很亮」（象牙白再提亮就是過曝刷白）
   二版 只留金色描邊     → 使用者：「中獎目前不明顯」（白牌上的細金框看不出來）
   三版 **改變對比的方向**：不是把中獎的弄更亮，而是**把沒中的壓暗**（`.mw-board.mw-hl`）。
        中獎的維持原本亮度 + 金框 + 微放大，靠周圍變暗自己跳出來 —— 這是不會過曝的作法。 */
.mw-cell.cs-win { z-index: 4; animation: mwWin .46s ease-in-out infinite alternate; }
@keyframes mwWin {
  from { transform: scale(1.01);
    box-shadow: inset 0 2px 0 rgba(255,255,255,.85), inset 0 0 0 2.5px rgba(255,207,58,.75), 0 0 10px rgba(255,207,58,.45); }
  to { transform: scale(1.06);
    box-shadow: inset 0 2px 0 rgba(255,255,255,.9), inset 0 0 0 3.5px var(--gold), 0 0 20px rgba(255,190,40,.9), 0 3px 8px rgba(0,0,0,.4); } }
/* 沒中的牌壓暗（只在高亮那一小段時間）。⚠️ 這跟「提示樣式不可動亮度」那條不衝突 ——
   那條講的是**未揭曉**的格（會讓玩家誤判已開幾張）；這裡是結果已定、且**變暗的是沒中的**，
   中獎的反而維持原亮度，不會有誤判。 */
.mw-board.mw-hl .mw-cell:not(.cs-win):not(.mw-turn):not(.cs-clear) {
  opacity: .34; filter: saturate(.55) brightness(.8); transition: opacity .18s ease, filter .18s ease; }
.mw-cell.cs-clear { animation: mwClear .3s ease forwards; z-index: 3; }
@keyframes mwClear { 0% { transform: scale(1.045); opacity: 1; }
  35% { transform: scale(1.16); opacity: .95; } 100% { transform: scale(0); opacity: 0; } }
.mw-cell.cs-drop { animation: mwDrop var(--drop-ms, 430ms) cubic-bezier(.33,1.06,.5,1) both; }
@keyframes mwDrop { from { transform: translateY(var(--drop-from, -100%)); opacity: .4; } to { transform: translateY(0); opacity: 1; } }
/* 🟡 這張金牌等一下要翻成百搭：先脈動一下把注意力抓過來（翻牌動畫沿用 .mj-cell.just-flip） */
.mw-cell.mw-turn { z-index: 5; animation: mwTurn .3s ease-in-out infinite alternate; }
@keyframes mwTurn { from { box-shadow: inset 0 0 0 2px #e0a11f, 0 0 10px rgba(255,203,58,.7); }
  to { box-shadow: inset 0 0 0 3px #fff0b0, 0 0 22px rgba(255,225,120,1); } }

/* 倍率條（貼在盤面最上緣）：base 顯示 x1 x2 x3 x5、免費顯示雪球值。
   ⚠️ 它是 #board 的最後一個 child（mwReelEl 靠 children[r] 取軸 → 一定要 append 在所有軸之後）。 */
/* [claude code] 2026-08-13 倍率條改成「壓在盤面上緣的橫幅」（同一個道理：跨過邊界才有連續感）。
   底色用麻將牌背那個玉綠（.mj-cell.mj-back 同一組色）→ 跟這款的牌是同一套視覺語言。 */
/* [claude code] 2026-08-13 v2.73 依使用者「主 SLOT 區再下來一點，目前被倍數蓋的有點多」：
   🔴 條與盤面**一起移、位移量相同**（board `margin-top: 12px` ↔ 這裡 top −13 → −25）
   → 條的**絕對位置不動**（不會往上頂到餘額 / 本局贏分那排），純粹是牌往下讓開。
   結果：條的下緣落在盤面 padding 內 2px（27−25）、牌從 padding 6px 起排
   → **一張牌都沒被蓋到**，但條仍壓在盤面背景的上緣，跨界的連續感保留。 */
/* ================= [claude code] 2026-08-15 星宮聚合（zodiac）=================
   三種格子狀態，刻意做成**三種不同強度**，玩家一眼分得出「中了 / 有希望 / 特殊符」：
   - `.zd-elem` 聚合成立（金框 + 脈動）＝ 這局真的算到分的格
   - `.zd-near` 就差一宮（虛線淡框）＝ **純表演**，提示「這組差一個就成立了」
   - `.zd-scat` ⛎ 蛇夫座（紫光）＝ base 的觸發來源、免費期的萬能宮
   🔴 三者靠**框線樣式 + 亮度**分，不是只靠顏色（辨識要靠形狀，色盲也分得出）。 */
/* [claude code] 2026-08-15 v3.5 星宮聚合的**兩條倍率**（雪球在上、組數階梯在下）。
   🔴 高度**永遠佔著兩條** —— `boardHeightBudget` 是 buildBoard 當下量的，
      「進免費期才長出一條」會把盤面往下推、可能把 SPIN 頂出畫面（手機一屏可見鐵則）。
      所以 base 期上面那條是**安靜的待命樣子**（只寫名字），不是空白。 */
.game-multbar.zod-2row { display: flex; flex-direction: column; gap: 4px; }
.zod-snowbar { height: 27px; border-radius: 8px; display: flex; align-items: center; justify-content: center;
  gap: 8px; pointer-events: none; transition: background .25s ease, box-shadow .25s ease;
  background: rgba(255,255,255,.045); box-shadow: inset 0 0 0 1px rgba(255,255,255,.10); }
/* 第 13 宮：整條轉成冰藍（與組數階梯的綠 / 免費期的橘都分得開） */
.zod-snowbar.on { background: linear-gradient(180deg, #3a86e0 0%, #1d4f9e 55%, #10306b 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.30), inset 0 0 0 1.5px rgba(170,225,255,.65),
    0 4px 12px rgba(0,0,0,.5); }
.zs-lab { font-size: clamp(10px, 2.9vw, 13px); font-weight: 900; letter-spacing: .04em; color: rgba(255,255,255,.55); }
.zod-snowbar.on .zs-lab { color: #d9f0ff; }
.zs-idle { font-size: clamp(9px, 2.6vw, 11.5px); color: rgba(255,255,255,.33); }
.zs-val { font-size: clamp(13px, 3.8vw, 18px); font-weight: 900; color: #fff;
  text-shadow: 0 0 10px rgba(180,230,255,.9); }
/* 🔴 「本轉 ×N」＝ 組數倍率 × 雪球，**這才是真正乘進贏分的數** —— 用金色跟兩個因子分開 */
.zs-total { font-size: clamp(11px, 3.1vw, 14px); font-weight: 900; padding: 1px 9px; border-radius: 999px;
  color: #2a1d00; background: linear-gradient(#fff3c8, var(--gold));
  box-shadow: 0 0 10px rgba(255,207,58,.75); }

/* 🔴 [claude code] 2026-08-15 v3.3 **四象限配色**（使用者：「那個紫底是必須的嗎，如果不是，
   能否加入四種底色區分四個象限，更直覺」）。
   ⚠️ 先講清楚：**那塊紫底是 emoji 自己的設計** —— Noto / Android 把 ♈–♓ 畫成「白字 + 紫色圓角磚」，
   不是我們畫的，所以沒辦法「拿掉」。但可以做兩件事：
     ① `hue-rotate` 把那塊磚**整個轉色**（白色字沒有色相、不受影響 → 白字保持白字）
     ② 格子本身鋪一層同色系底 → 三宮一組看起來就是一家的
   🔴 **顏色是「分組」用的，不是「辨識」用的** —— 12 個星座本來就靠形狀分得出來（對齊平台
      「辨識靠形狀不靠顏色」那條）；這裡加色是為了讓「同元素三宮」一眼成群。
   🔴 選擇器直接吃 `setCell` 產生的 `sym-<KEY>` class → **不用改任何 JS**。 */
.cell.sym-ARIES, .cell.sym-LEO, .cell.sym-SAGITTARIUS,
.cell.sym-TAURUS, .cell.sym-VIRGO, .cell.sym-CAPRICORN,
.cell.sym-GEMINI, .cell.sym-LIBRA, .cell.sym-AQUARIUS,
.cell.sym-CANCER, .cell.sym-SCORPIO, .cell.sym-PISCES { border-radius: 10px; }
/* 🔥 火象：♈ 牡羊 · ♌ 獅子 · ♐ 射手 */
.cell.sym-ARIES, .cell.sym-LEO, .cell.sym-SAGITTARIUS {
  background: linear-gradient(180deg, rgba(255,110,60,.26), rgba(150,35,15,.16));
  box-shadow: inset 0 0 0 1px rgba(255,150,100,.32); }
.cell.sym-ARIES .glyph, .cell.sym-LEO .glyph, .cell.sym-SAGITTARIUS .glyph { filter: hue-rotate(96deg) saturate(1.2); }
/* ⛰️ 土象：♉ 金牛 · ♍ 處女 · ♑ 摩羯 */
.cell.sym-TAURUS, .cell.sym-VIRGO, .cell.sym-CAPRICORN {
  background: linear-gradient(180deg, rgba(210,160,70,.24), rgba(110,75,25,.16));
  box-shadow: inset 0 0 0 1px rgba(230,190,110,.30); }
.cell.sym-TAURUS .glyph, .cell.sym-VIRGO .glyph, .cell.sym-CAPRICORN .glyph { filter: hue-rotate(132deg) saturate(1.05); }
/* 💨 風象：♊ 雙子 · ♎ 天秤 · ♒ 水瓶 */
.cell.sym-GEMINI, .cell.sym-LIBRA, .cell.sym-AQUARIUS {
  background: linear-gradient(180deg, rgba(120,230,215,.22), rgba(30,110,110,.14));
  box-shadow: inset 0 0 0 1px rgba(150,240,225,.30); }
.cell.sym-GEMINI .glyph, .cell.sym-LIBRA .glyph, .cell.sym-AQUARIUS .glyph { filter: hue-rotate(268deg) saturate(1.1); }
/* 💧 水象：♋ 巨蟹 · ♏ 天蠍 · ♓ 雙魚 */
.cell.sym-CANCER, .cell.sym-SCORPIO, .cell.sym-PISCES {
  background: linear-gradient(180deg, rgba(70,140,255,.26), rgba(20,45,140,.16));
  box-shadow: inset 0 0 0 1px rgba(120,175,255,.32); }
.cell.sym-CANCER .glyph, .cell.sym-SCORPIO .glyph, .cell.sym-PISCES .glyph { filter: hue-rotate(310deg) saturate(1.15); }
/* [claude code] 2026-08-15 v3.8 原本這裡是 v3.7 的「✦ 標稀有宮」（金色角標 + 金框）——
   已改用**盤面下方的星盤面板**表達「這一組到齊了沒」，整組移除（見下面的 .zod-panel）。
   ⛎ 蛇夫座維持原本的紫 —— 它不屬於任何元素，保持原色才看得出「它是外來的第 13 宮」。 */

/* ================= [claude code] 2026-08-15 v3.8 星宮聚合的星盤面板 =================
   使用者定案：「下面有個分四區的 12 星座盤, 盤面掉完後, 有的就會依序亮起來, 沒有就灰著,
   有中獎的象限就會框起來, 上面也會表演亮起來」。
   🔴 它回答的是**「這一組到齊了沒」** —— 三個格子亮兩個灰一個，缺什麼一眼就看到，
      完全不用解釋規則，也不必再為稀有度做特別標記。
   🔴 三種狀態靠**亮度 + 框線**分（不是只靠顏色）：灰（沒有）/ 金（盤上有）/ 紫（⛎ 補的）。 */
.zod-panel { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px;
  width: min(100%, 470px); margin: 6px auto 0; padding: 6px;
  border-radius: 12px; background: rgba(10,14,30,.55); box-shadow: inset 0 0 0 1px rgba(255,255,255,.06); }
.zq { display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 4px 2px; border-radius: 9px; transition: box-shadow .2s ease, background .2s ease;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.07); }
/* 四區底色跟盤面上的四象限配色同一套 → 星盤與盤面一眼對得起來 */
.zq0 { background: linear-gradient(180deg, rgba(255,110,60,.16), rgba(150,35,15,.10)); }
.zq1 { background: linear-gradient(180deg, rgba(210,160,70,.15), rgba(110,75,25,.10)); }
.zq2 { background: linear-gradient(180deg, rgba(120,230,215,.14), rgba(30,110,110,.09)); }
.zq3 { background: linear-gradient(180deg, rgba(70,140,255,.16), rgba(20,45,140,.10)); }
/* 聚合成立 → 整區框起來（跟盤面上的金框同一個語彙）*/
.zq.on { box-shadow: inset 0 0 0 2px var(--gold), 0 0 14px rgba(255,207,58,.5);
  animation: zqOn .9s ease-in-out infinite; }
@keyframes zqOn { 0%, 100% { box-shadow: inset 0 0 0 2px var(--gold), 0 0 10px rgba(255,207,58,.4); }
  50% { box-shadow: inset 0 0 0 2px var(--gold), 0 0 20px rgba(255,207,58,.85); } }
.zq-ico { font-size: clamp(11px, 3vw, 14px); line-height: 1; opacity: .85; }
.zq-slots { display: flex; gap: 2px; }
/* 沒有 = 灰掉且縮小（一眼看得出「缺一個」）*/
/* 🔴 [claude code] 2026-08-15 v3.9 待命（灰）狀態要**看得清楚**（使用者：「星盤可以預設是灰的,
   永遠都在下面, 固定位置順序, 和藏寶圖一樣」）。
   原本 `opacity: .22` 太淡 —— 那不是「灰著」，那是「幾乎看不見」，
   星盤就淪為一條空白帶，讀不出「這是一張固定的 12 宮表」。
   藏寶圖那種常駐 HUD 的重點是：**沒收集到的格子也要看得出它是什麼**，玩家才知道自己在集什麼。
   → 拉到 .45 + grayscale（灰但認得出圖案），亮起來時才有明顯落差。 */
.zs { font-size: clamp(13px, 3.8vw, 18px); line-height: 1; opacity: .45;
  filter: grayscale(1) brightness(.85);
  transform: scale(.9); transition: opacity .18s ease, transform .18s ease, filter .18s ease; }
/* 盤上真的有 = 亮起來 */
.zs.lit { opacity: 1; filter: none; transform: scale(1);
  animation: zsPop .32s cubic-bezier(.2,1.5,.4,1); }
@keyframes zsPop { 0% { transform: scale(.7); } 60% { transform: scale(1.22); } 100% { transform: scale(1); } }
/* ⛎ 補起來的那一宮 = 紫（跟「盤上真的有」分開，不然玩家會以為它真的落下來了）*/
.zs.wild { opacity: 1; filter: none; transform: scale(1);
  text-shadow: 0 0 8px #b98cff, 0 0 3px #fff; }
@media (max-height: 780px) {
  .zod-panel { gap: 3px; padding: 4px; margin-top: 4px; }
  .zq { padding: 2px 1px; }
  .zq-ico { display: none; }
}

.cell.zd-elem { box-shadow: inset 0 0 0 2px var(--gold), 0 0 14px rgba(255,207,58,.55); border-radius: 8px; }
/* 🔴 [claude code] 2026-08-15 v3.4 修「中獎後四象限配色被打回紫底」（使用者截圖抓到）。
   原本 zdPulse 的 keyframes 寫了 `filter: none` / `filter: drop-shadow(...)` ——
   **animation 的優先權高於一般宣告**，所以只要格子中獎掛上 `.zd-elem`，
   象限配色那條 `filter: hue-rotate(...)` 就被整個蓋掉 → 中獎格全部退回 emoji 原本的紫。
   （非中獎格沒被蓋，所以畫面會變成「中的是紫的、沒中的是彩色的」，正好相反。）
   → **脈動只動 `transform`**；發光改掛在格子的 box-shadow 上（那條本來就是金框，不衝突）。
   ⚠️ 通則：**要在會疊加狀態 class 的元素上做動畫，keyframes 裡不要碰 `filter`**
      —— 底下那層的 filter 一定會被吃掉，而且是靜默的。 */
.cell.zd-elem .glyph { animation: zdPulse .9s ease-in-out infinite; }
@keyframes zdPulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.12); } }
.cell.zd-elem { animation: zdCellGlow .9s ease-in-out infinite; }
@keyframes zdCellGlow {
  0%, 100% { box-shadow: inset 0 0 0 2px var(--gold), 0 0 12px rgba(255,207,58,.45); }
  50% { box-shadow: inset 0 0 0 2px var(--gold), 0 0 24px rgba(255,207,58,.9); } }
.cell.zd-near { box-shadow: inset 0 0 0 2px rgba(255,255,255,.28); border-radius: 8px; }
.cell.zd-near .glyph { opacity: .85; }
.cell.zd-scat { box-shadow: inset 0 0 0 2px #b98cff, 0 0 16px rgba(185,140,255,.6); border-radius: 8px; }
.cell.zd-scat .glyph { filter: drop-shadow(0 0 10px #b98cff); }

/* ================= [claude code] 2026-08-14 v2.83 通用倍率條 `.ui-multbar` =================
   規則見 CLAUDE.md「🔴 倍數顯示一律用倍率條」。**全平台的倍數只有這一種長相**：
   綠底金框的一條 + chips，當前值亮起（金）、免費期整條轉橘（`.fs`）。
   長相與 chips 都在這裡；「貼在哪」由 host 的 `.pos-*` class 決定（見下面 .game-multbar / .mw-multbar）。 */
.ui-multbar { display: flex; align-items: center; justify-content: center; gap: 4px;
  height: 27px; border-radius: 8px; pointer-events: none;
  background: linear-gradient(180deg, #2b8f66 0%, #15694a 55%, #0d4633 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.28), inset 0 0 0 1.5px rgba(255,207,58,.5),
    0 4px 12px rgba(0,0,0,.5); }
.ui-mchip { font-size: clamp(11px, 3.2vw, 15px); font-weight: 900; letter-spacing: .04em;
  padding: 1px 10px; border-radius: 999px; color: rgba(255,255,255,.5); white-space: nowrap; }
/* [claude code] 2026-08-14 v2.93 階梯格數多的款（淨化光稜 7 格）縮一點，免得窄螢幕擠出框 */
.ui-multbar.many .ui-mchip { padding: 1px 6px; font-size: clamp(10px, 2.7vw, 13px); letter-spacing: 0; }
.ui-mchip.on { color: #2a1d00; background: linear-gradient(#fff3c8, var(--gold));
  box-shadow: 0 0 12px rgba(255,207,58,.85), inset 0 1px 0 rgba(255,255,255,.7);
  transform: scale(1.16); text-shadow: 0 1px 0 rgba(255,255,255,.5); }
.ui-multbar.fs .ui-mchip.on { background: linear-gradient(#ffd0a0, #ff7a3c); color: #3a1200;
  box-shadow: 0 0 16px rgba(255,122,60,.9); }
/* 🔴 條上不放說明文字（v2.84 使用者定：「不用那些文字」）—— 原本的 `.ui-mhint` 小字已移除。
   規則要講去 ⓘ 說明 / 📋 賠付表 / 跑馬燈；這條只回答「現在幾倍」。 */

/* 麻將胡牌了：條貼在盤面上緣（絕對定位，盤面自己 margin-top 讓出空間） */
.mw-multbar { position: absolute; top: -25px; left: 10px; right: 10px; z-index: 6; }

/* 賠付表的小牌縮圖 */
.mw-pt-tile { display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 33px; border-radius: 5px; vertical-align: middle; overflow: hidden;
  background: linear-gradient(158deg, #fbf6e9, #e2d4b6); color: #1b2330;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.7), 0 1px 2px rgba(0,0,0,.35); }
.mw-pt-tile .mj-honor { font-size: 15px; }
.mw-pt-tile .mj-pip { width: 82%; height: 82%; }
.mw-pt-tile .mj-man .mm-n { font-size: 11px; } .mw-pt-tile .mj-man .mm-s { font-size: 7px; }
.mw-pt-tile .mw-ingot { font-size: 13px; } .mw-pt-tile .mw-wtxt { font-size: 7px; }
.mw-pt-tile .mw-scat-art { font-size: 15px; animation: none; }

/* 細單：逐步盤面（靜態存證 → 不跑任何脈動動畫） */
.dt-board.dt-mw { display: flex; gap: 3px; align-items: center; justify-content: center; padding: 4px 0; }
.dt-mw-reel { display: flex; flex-direction: column; justify-content: center; gap: 3px; }
.dt-mw-cell { position: relative; width: 26px; height: 33px; border-radius: 5px; overflow: hidden; animation: none !important; }
.dt-mw-cell .mj-honor { font-size: 15px; }
.dt-mw-cell .mj-pip { width: 82%; height: 82%; }
.dt-mw-cell .mj-man .mm-n { font-size: 11px; } .dt-mw-cell .mj-man .mm-s { font-size: 7px; }
.dt-mw-cell .mw-ingot { font-size: 13px; } .dt-mw-cell .mw-wtxt { font-size: 7px; }
.dt-mw-cell .mw-scat-art { font-size: 15px; animation: none !important; }
.dt-mw-cell.dt-mw-hit { box-shadow: inset 0 0 0 2px var(--win, #ffe169), 0 0 7px rgba(255,225,105,.6); }
.dt-mw-cell.dt-mw-turn { box-shadow: inset 0 0 0 2px #ffb02e, 0 0 9px rgba(255,176,46,.85); }
.dt-step-head { margin: 8px 0 3px; font-size: 12px; font-weight: 800; color: rgba(255,255,255,.8); }



/* ================= [claude code] 2026-08-13 v2.74 新版型（依使用者參考圖：PG 那類直版 SLOT）=================
   盤面 → ① 訊息帶 → ② 金額列（左餘額 · 右單注）→ ③ 五顆一排 → ④ 自動面板（由下往上）。
   🔴 先只在「麻將胡牌了」啟用（app.js 的 NEWUI_MECHS 白名單）；舊版型 .control-bar / .control-row2
      整組留著沒動，其餘 23 款完全不受影響。驗收 OK 再把 mechanic 加進白名單整批換過去。
   🔴 這一整區的高度會被 boardHeightBudget() 實測（量 #uiBelt + #uiMoney + #uiPad）→ 盤面自動夾小，
      不會頂出畫面（手機一屏可見鐵則）。改這裡的高度不必回頭改那支函式。 */

/* ---- ① 訊息帶：待機跑馬燈 ↔ 中獎贏分，同一塊、同樣高度（不會忽有忽無把版面推來推去）---- */
.ui-belt { position: relative; max-width: 480px; margin: 8px auto 8px; height: 46px;
  border-radius: 12px; overflow: hidden;
  background: linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.015));
  border: 1px solid var(--border);
  transition: background .2s ease, border-color .2s ease, box-shadow .2s ease; }
/* 中獎態：金色微光。整塊換底色而不是只換文字顏色 → 餘光掃過去就知道「這局有錢」 */
.ui-belt.win { border-color: rgba(255,210,74,.55);
  background: linear-gradient(180deg, rgba(255,210,74,.16), rgba(255,160,40,.06));
  box-shadow: inset 0 0 0 1px rgba(255,210,74,.2), 0 0 18px rgba(255,190,60,.18); }

/* 跑馬燈：句子直接出現 → 停一下 → 往左移出框 → 換下一句（使用者指定的節奏） */
.belt-marquee { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  padding: 0 14px; }
.belt-msg { display: inline-block; white-space: nowrap; font-size: 13.5px; letter-spacing: .02em;
  color: rgba(255,255,255,.68); text-shadow: 0 1px 2px rgba(0,0,0,.5); }
.belt-msg.in { animation: beltIn .34s ease both; }
/* 🔴 出框距離用 `calc(-100% - 52vw)`：`-100%` 只移動自己的寬度，短句根本走不出框 —— 再補一個
   比容器還寬的 vw 才保證真的離場。linear = 等速滑出，像真的跑馬燈。 */
.belt-msg.out { animation: beltOut .9s linear both; }
@keyframes beltIn { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
@keyframes beltOut { from { opacity: 1; transform: translateX(0); }
  to { opacity: .25; transform: translateX(calc(-100% - 52vw)); } }

/* 中獎：本局贏分置中（表演跑完才由 armGamble 長出右邊那顆翻倍鈕）*/
.belt-win { position: absolute; inset: 0; display: none; align-items: center; justify-content: center; gap: 9px;
  padding: 0 12px; }
.ui-belt.win .belt-marquee { display: none; }
.ui-belt.win .belt-win { display: flex; }
.bw-cap { font-size: 12px; color: rgba(255,255,255,.62); }
.bw-amt { font-size: 21px; font-weight: 900; color: var(--win); font-variant-numeric: tabular-nums;
  text-shadow: 0 0 12px rgba(255,225,105,.55); }
/* [claude code] 2026-08-13 v2.76 使用者：「得 N 倍在跳動時，能跳動一下，讓人知道他換了，**但別太搶眼**」
   → 幅度從 1.16 收到 **1.06**、時間 .28s → **.2s**：看得出「數字換了」，但不會每連鎖一次就在那邊彈。
   🔴 只有數字自己 scale，`.belt-win` 是 flex 置中 → 旁邊的「共贏得」與倍數不會被推位移。 */
.bw-amt.bump { animation: bwBump .2s ease; }
@keyframes bwBump { 50% { transform: scale(1.06); } }
/* [claude code] 2026-08-14 v2.86 拿掉贏分旁邊的「×N 倍」（v2.76 加的 `.bw-x`）——
   使用者:「後面那個 ×0.30 不用顯示, 因為多餘了」。玩家要看的是**拿到多少錢**;
   倍數在賠付表與細單裡都查得到,擺在贏分旁邊只是把一行字變兩件事。 */
/* 🔴 絕對定位貼右，不佔 flex 的位置 —— 贏分要**固定置中**（使用者：「他會置中顯示，右邊會多一個按鈕」）。
   若讓它參與置中排版，翻倍鈕一出現整組就會往左挪一截，數字看起來像跳了一下。
   [claude code] 2026-08-13 v2.75 依使用者：「要可以翻倍時，會從右邊移出來；剛進遊戲時他是縮進去右邊的」
   → 🔴 **不用 display 切換**（那只會忽有忽無地閃出來），改成**一直在那裡、平時縮在框外**：
      預設 translateX 推出右邊界 + opacity 0 + 不可點；可以翻倍時加 `.on` 滑回來。
      `.ui-belt` 有 `overflow: hidden` → 縮出去那截自然被裁掉，看不到半顆鈕。 */
.bw-gamble { position: absolute; right: 10px; top: 50%; margin-top: -14px;
  padding: 5px 12px; border-radius: 999px; cursor: pointer;
  font-size: 12.5px; font-weight: 800; color: #2a1d00; border: none;
  background: linear-gradient(#fff3c8, var(--gold));
  box-shadow: 0 2px 10px rgba(255,207,58,.5);
  transform: translateX(calc(100% + 16px)); opacity: 0; pointer-events: none;
  transition: transform .34s cubic-bezier(.22,.75,.3,1.16), opacity .22s ease; }
.bw-gamble.on { transform: translateX(0); opacity: 1; pointer-events: auto; }
.bw-gamble:hover { filter: brightness(1.08); }
/* 🔴 v2.77：這裡刻意**不加** prefers-reduced-motion —— 翻倍鈕「從右邊滑出來」是使用者指定的行為，
   關掉它就變成憑空出現、失去「從哪裡來」的交代。同理 .ps-ring 那條也已移除（見下面的說明）。 */

/* 加速鈕搬到底部第一顆了 → 遊戲畫面的頂列不要再放一顆（回大廳仍在，那裡沒有底部那排）*/
body[data-newui="1"][data-view="game"] #turboBtn { display: none; }

/* [claude code] 2026-08-13 v2.76 依使用者：盤面下面那行中獎明細（「三條 連4軸 × 2路 倍率×2 +80」）
   **先收起來**、程式碼留著 —— 要再打開只要拿掉這一條規則，`#winBanner` 的內容照樣在寫。
   🔴 它原本是**固定 44px + margin 8px 的保留區**（刻意佔位讓 SPIN 不跳動）→ 收掉就省 52px，
      整組介面自然往上靠；`boardHeightBudget()` 的 reserve 本來就沒算它，收掉之後反而更準。
   ⚠️ 副作用：免費轉的進度提示（「🧧 免費 3/8 本轉從 🔥×4 起跳」）也走這個元素 → 一併看不到。 */
body[data-newui="1"] .action-zone { display: none; }

/* ---- ② 金額列：左餘額 · 右單注（依使用者確認：照參考圖）---- */
.ui-money { max-width: 480px; margin: 0 auto 9px; padding: 0 4px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.um-cell { display: inline-flex; align-items: center; gap: 7px; padding: 7px 14px; border-radius: 999px;
  background: rgba(255,255,255,.05); border: 1px solid var(--border); line-height: 1; }
.um-ico { font-size: 14px; }
.um-cap { font-size: 11px; color: var(--text-soft); }
.um-val { font-weight: 800; font-variant-numeric: tabular-nums; }
.um-bal .um-val { font-size: 16px; color: var(--gold); }
.um-bal .um-val.bump { animation: bwBump .28s ease; }
.um-bet .um-val { font-size: 15px; color: var(--text); }

/* ---- ③ 五顆一排：加速 · − · SPIN · ＋ · 自動 ---- */
.ui-pad { max-width: 480px; margin: 0 auto; padding: 2px 4px 4px;
  display: flex; align-items: center; justify-content: center; gap: 14px; }
.pad-btn { flex: 0 0 auto; border-radius: 50%; cursor: pointer; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--text); border: 1px solid var(--border); background: rgba(255,255,255,.06);
  transition: transform .12s ease, background .16s ease, color .16s ease, border-color .16s ease; }
.pad-btn:hover { background: rgba(255,255,255,.11); }
.pad-btn:active { transform: scale(.92); }
.pad-side { width: 42px; height: 42px; font-size: 17px; color: var(--text-soft); }
.pad-step { width: 48px; height: 48px; font-size: 25px; font-weight: 700; }
.pad-btn:disabled { opacity: .38; cursor: not-allowed; }
/* TURBO 開著 → 亮起來；關著就是一顆安靜的灰鈕（用 class 切，不用換字） */
#padTurbo.on { color: var(--gold); border-color: rgba(255,210,74,.6); background: rgba(255,210,74,.14);
  box-shadow: 0 0 12px rgba(255,200,70,.3); }
/* 自動進行中 → 同樣亮起來，讓「現在是自動」有存在感 */
#padAuto.on { color: var(--neon-2); border-color: rgba(54,224,255,.6); background: rgba(54,224,255,.14);
  box-shadow: 0 0 12px rgba(54,224,255,.28); }

.pad-spin { position: relative; flex: 0 0 auto; width: 86px; height: 86px; border-radius: 50%;
  border: none; cursor: pointer; color: #0a0c16; font-weight: 900; letter-spacing: 1px;
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  background: linear-gradient(135deg, var(--neon), var(--neon-2));
  box-shadow: 0 6px 22px rgba(54,224,255,.38);
  transition: transform .14s ease, box-shadow .18s ease, filter .14s ease; }
.pad-spin:hover { filter: brightness(1.06); }
.pad-spin:active { transform: scale(.95); }
/* 🔴 轉動中不要壓太暗 —— 這顆鈕「正在快轉」本身就是重要的回饋，壓成半透明等於把回饋關掉。 */
.pad-spin:disabled { opacity: .82; cursor: not-allowed; }

/* [claude code] 2026-08-13 v2.74 依使用者：「SLOT 的 SPIN 是轉 → 按鈕做成圓的，平時就慢慢轉，
   按下去（轉動中）變快轉」。缺口環 + 一顆箭頭尖，整圈一起轉。
   [claude code] 2026-08-13 v2.76 二版（使用者：「要**圍著字轉**，表演中要**轉更快**」）：
   · `inset` 8px → **15%**：環從貼著鈕的外緣往內收，變成**繞著 SPIN 那幾個字**跑
     （用 % 不用 px：矮螢幕鈕縮到 68px 時，環會跟著等比內縮，不會壓到字）
   · 平時 7s → **5s**：7s 慢到看不出來它在動（使用者看到的就是一個靜止的框）
   · 轉動中 0.5s → **0.26s**、自動中 1.4s → **1.1s**
   · 顏色加深到 .52 —— 疊在霓虹漸層上，.42 太淡，環的形狀讀不出來 */
.ps-ring { position: absolute; inset: 15%; border-radius: 50%; pointer-events: none;
  animation: padRingRot 3.6s linear infinite; }
/* 🔴 [claude code] 2026-08-15 v3.6 環改成「**接近整圈 + 一個順時鐘箭頭**」
   （使用者：「那個 SPIN 轉的那個, 可以變成順時鐘的箭頭嗎, 他目前斷了」）。
   舊寫法用 border 做環，但**兩個邊設成 transparent → 實際只剩半圈**（180°），
   看起來就是「斷掉的框」而不是「一個在轉的箭頭」。
   → 改用 `conic-gradient` 畫 **330° 的弧**（12 點鐘往順時鐘留 30° 缺口），
     箭頭放在弧的**順時鐘前端**（正上方）**指向右邊** —— 右 = 12 點鐘方向的順時鐘切線，
     所以一眼看得出它在往順時鐘跑。
   ⚠️ `mask` 是把「實心扇形」挖成「環」的必要手段（Chrome / Android WebView 都支援；本產品是 PWA+TWA）。 */
/* [claude code] 2026-08-16 v3.11 依使用者：「這個順時鐘的圓圈箭頭，我希望**只有半圓**就好了」。
   330° → **180°**：缺口從 30° 開到 180°，弧從 6 點鐘（180deg）順時鐘走到 12 點鐘（360deg）。
   🔴 **弧的順時鐘終點仍然壓在 12 點鐘** —— 箭頭（::after）是釘在正上方的，
      只改「弧從哪裡開始」就不會動到箭頭那三個對位（半徑 / 起點 / 顏色，見下面）。
      要是改成「從 0deg 開始畫 180deg」，弧會停在 6 點鐘、箭頭孤零零留在 12 點鐘。 */
.ps-ring::before { content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0deg 180deg, rgba(10,12,22,.60) 180deg 360deg);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px)); }
/* 箭頭：在弧的順時鐘前端（正上方），**指向右** → 方向感明確（沒有箭頭的話正轉反轉看起來一樣）。
   🔴 [claude code] 2026-08-15 v3.7 對位修正（使用者：「箭頭和線好像沒有對好」）。三個地方都要對：
     ① **半徑**：環的線佔「最外圈 3px」→ 線的中心在距上緣 **1.5px**。
        箭頭高 8px（上下各 4px）→ `top` 要寫 **-2.5px**（1.5 − 4），中心才落在線上。
        原本寫 -5px = 中心在 0，整支浮在線的外面。
     ② **起點**：弧的順時鐘終點正好在 12 點鐘（= left 50%）→ 箭頭底邊要**貼著 50%**，
        原本 `margin-left: -2px` 把它往左推了 2px，看起來就是「接不上」。
     ③ **顏色**：原本箭頭 .72、環 .60 —— 深淺不同會讀成「兩個零件」。改成同值。 */
.ps-ring::after { content: ""; position: absolute; top: -2.5px; left: 50%;
  width: 0; height: 0; border-top: 4px solid transparent; border-bottom: 4px solid transparent;
  border-left: 8px solid rgba(10,12,22,.60); }
@keyframes padRingRot { to { transform: rotate(360deg); } }
/* 🔴 [claude code] 2026-08-13 v2.77 使用者：「文字旁的黑半圓**沒有在轉**，SPIN 表演中時會轉更快」。
   病根是我 v2.74 自己加的那條 `@media (prefers-reduced-motion: reduce) { .ps-ring { animation: none } }`
   —— 系統只要開了「減少動態 / 關閉動畫效果」（Windows 11 協助工具裡預設就有人關），
   整條 animation 直接 **none** → 不但平時不轉，連 `.pad-spin:disabled` 那個「轉更快」也一起失效
   （沒有動畫可言，改 `animation-duration` 當然沒有任何作用）＝ 使用者看到的兩個現象一次到齊。
   → **那條規則已移除**：這個環不是裝飾，是「現在在跑 / 跑完了」的狀態回饋（等同 loading spinner），
     而且是等速平滑旋轉、沒有閃爍或視差，關掉它反而讓人不知道機台在做什麼。
   同時整體再加快一級（平時 5s → 3.6s、轉動中 .26s → **.18s**、自動中 1.1s → .9s）。
   🔴 `.busy` 是雙保險：`:disabled` 由 MutationObserver 鏡射，萬一哪次時序沒跟上，class 這條照樣會快轉。 */
.pad-spin:disabled .ps-ring, .pad-spin.busy .ps-ring { animation-duration: .18s; }
.pad-spin.auto .ps-ring { animation-duration: .9s; }

/* [claude code] 2026-08-13 v2.76 依使用者：「MOUSE 移上去後，要有黃圓光放大、再縮小放大，是動畫，
   **但不要讓 SPIN 字搖動**」。
   🔴 這是 `.btn-spin` 已經踩過的同一顆雷（見上面「三版」那段）：脈動只要改到**按鈕自己**的
      `transform: scale()`，裡面的字必然跟著長大位移。
   🔴 這裡的解法更徹底：脈動做在**偽元素**上 —— 一圈獨立的黃色光環自己放大縮小，
      按鈕與 SPIN 字**完全不參與這個動畫**，一格都不會動。 */
.pad-spin::after { content: ""; position: absolute; inset: -5px; border-radius: 50%;
  border: 2px solid rgba(255,214,90,.9); pointer-events: none; opacity: 0;
  box-shadow: 0 0 18px rgba(255,200,70,.55), inset 0 0 12px rgba(255,200,70,.28); }
.pad-spin:hover:not(:disabled)::after { animation: padHalo 1.15s ease-in-out infinite; }
@keyframes padHalo {
  0%, 100% { opacity: .45; transform: scale(.93); }
  50%      { opacity: 1;   transform: scale(1.15); }
}
/* 自動進行中：鈕變成金色 → 環與箭頭改成深褐（配 .ps-txt 的 #2a1d00），深藍那組在金底上會糊掉。
   🔴 [claude code] 2026-08-16 這兩條原本還是 **border 時代的寫法**（v3.6 把環改成 conic-gradient
      時漏改），造成兩個問題：
        ① `::before` 已經不用 border 了 → 那些 border-color 全是死規則，自動模式下環根本沒變色
        ② `::after` 是**用 border 疊出來的三角形**，`border-color: transparent` 把 `border-left-color`
           一起蓋掉 → **自動模式下箭頭直接消失**（只剩一塊方向相反的小楔形）
      改成各自用對的屬性：環換 background、箭頭只換 border-left-color。 */
.pad-spin.auto .ps-ring::before {
  background: conic-gradient(from 0deg, transparent 0deg 180deg, rgba(42,29,0,.45) 180deg 360deg); }
.pad-spin.auto .ps-ring::after { border-left-color: rgba(42,29,0,.45); }

.ps-txt { font-size: 18px; }
.ps-sub { font-size: 10px; font-weight: 700; opacity: .78; letter-spacing: 0; }
.ps-sub:empty { display: none; }
/* 自動進行中：SPIN 變成「剩餘次數（+ 條件）」，再按一下就中止 */
.pad-spin.auto { background: linear-gradient(135deg, #ffb03a, var(--gold)); color: #2a1d00;
  box-shadow: 0 6px 22px rgba(255,190,60,.42); }
.pad-spin.auto .ps-txt { font-size: 23px; }

/* ---- ④ 自動旋轉面板：由下往上拉出 ---- */
.auto-sheet { position: fixed; inset: 0; z-index: 60; display: none; }
.auto-sheet.show { display: block; }
.as-mask { position: absolute; inset: 0; background: rgba(4,6,14,.62); animation: asFade .2s ease both; }
@keyframes asFade { from { opacity: 0; } }
.as-card { position: absolute; left: 0; right: 0; bottom: 0; max-width: 520px; margin: 0 auto;
  background: var(--surface); border-top: 1px solid var(--border);
  border-radius: 18px 18px 0 0; padding: 14px 18px calc(22px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -12px 40px rgba(0,0,0,.55); animation: asUp .26s cubic-bezier(.22,.7,.3,1) both; }
@keyframes asUp { from { transform: translateY(100%); } }
.as-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.as-title { font-size: 17px; font-weight: 800; }
.as-close { width: 32px; height: 32px; border-radius: 50%; cursor: pointer; font-size: 15px;
  color: var(--text-soft); background: rgba(255,255,255,.06); border: 1px solid var(--border); }
.as-close:hover { color: var(--text); }
.as-sec { margin-bottom: 14px; }
.as-label { font-size: 12px; color: var(--text-soft); margin-bottom: 7px; }
.as-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.as-chip { padding: 9px 0; min-width: 62px; flex: 1 1 62px; text-align: center; cursor: pointer;
  border-radius: 11px; font-size: 14px; font-weight: 800; color: var(--text-soft);
  background: rgba(255,255,255,.05); border: 1px solid var(--border);
  transition: background .14s ease, color .14s ease, border-color .14s ease; }
.as-chips-stop .as-chip { flex: 1 1 96px; min-width: 96px; font-size: 13px; font-weight: 700; }
.as-chip:hover { background: rgba(255,255,255,.1); color: var(--text); }
.as-chip.on { color: #2a1d00; border-color: transparent; background: linear-gradient(#fff3c8, var(--gold));
  box-shadow: 0 2px 12px rgba(255,207,58,.4); }
.as-start { width: 100%; margin-top: 4px; padding: 14px 0; border: none; border-radius: 13px;
  cursor: pointer; font-size: 16px; font-weight: 900; letter-spacing: 1px; color: #0a0c16;
  background: linear-gradient(135deg, var(--neon), var(--neon-2));
  box-shadow: 0 6px 20px rgba(54,224,255,.35); }
.as-start:hover { filter: brightness(1.06); }

/* 矮螢幕：新版型也要能一屏放得下（對齊「手機一屏可見鐵則」的逐級收合）*/
@media (max-height: 780px) {
  .ui-belt { height: 42px; margin: 6px auto 6px; }
  .ui-money { margin-bottom: 7px; }
  .pad-spin { width: 76px; height: 76px; }
  .ps-txt { font-size: 16px; }
  .pad-step { width: 44px; height: 44px; font-size: 23px; }
  .pad-side { width: 38px; height: 38px; font-size: 15px; }
  .ui-pad { gap: 11px; }
}
@media (max-height: 690px) {
  .ui-belt { height: 38px; margin: 5px auto 5px; }
  .belt-msg { font-size: 12.5px; }
  .bw-amt { font-size: 18px; }
  .um-cell { padding: 5px 11px; }
  .pad-spin { width: 68px; height: 68px; }
  .ps-txt { font-size: 15px; }
}


/* ================= 花蜜採集的 🐝 倍率條 =================
   [claude code] 2026-08-14 v2.83 依使用者「倍數的那種，我想統一使用麻將胡牌了的方式」——
   原本這裡是一顆獨立的琥珀色 pill（`.cm-ico` / `.cm-val` / `.cm-hint`，v2.82），
   現在整條改用通用的 `.ui-multbar`（見上面），這裡只負責「貼在盤面上緣」。
   🔴 −7px 只壓進盤面自己的 padding（6px），**不會蓋到第一列格子**。 */
/* [claude code] 2026-08-14 v2.84 拿掉 max-width：條改成**貼齊盤面兩端**（內縮 10px），
   與麻將那條的 `left/right: 10px` 同寬 —— 使用者要的是「像麻將那樣」，寬度也算在內。 */
/* [claude code] 2026-08-14 v2.93 🔴 **通用倍率條 host**（合併原本的 .cash-multbar / .bm-multbar）。
   長相都在 `.ui-multbar`；這裡只管「貼在哪」：
   - `.pos-tight`：負 margin 壓進盤面 padding（花蜜採集 —— 盤面高、要省高度）
   - `.pos-row`  ：正 margin 空出**獨立一列**（爆裂礦坑 / 淨化光稜 —— 盤面矮、不缺高度）
   ⚠️ 麻將胡牌了的 `.mw-multbar` 不走這裡（絕對定位 append 在盤面內）。 */
.game-multbar { position: relative; z-index: 6; padding: 0 10px; }
.game-multbar.pos-tight { margin: 0 0 -7px; }
.game-multbar.pos-row { margin: 0 0 8px; }
/* 只彈 chips、不彈整條（v2.92 使用者：「不要整個綠框一起跳」）。
   ⚠️ `.ui-mchip.on` 平常就帶 scale(1.16) → 100% 要寫 1.16，寫 1 會在收尾瞬間縮一下。 */
.game-multbar.pop .ui-mchip { animation: bmChipPop .42s cubic-bezier(.2,1.5,.4,1); }
.game-multbar.pop .ui-mchip.on { animation: bmChipPopOn .42s cubic-bezier(.2,1.5,.4,1); }

/* [claude code] 2026-08-16 v3.13 語言切換選單（頂列 🌐）。
   🔴 用 absolute 掛在 .lang-wrap 底下：頂列本身是 flex，選單若參與排版會把整列撐開。 */
.lang-wrap { position: relative; display: inline-flex; }
.lang-menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 60;
  background: var(--panel, #171a2b); border: 1px solid rgba(255,255,255,.14);
  border-radius: 10px; padding: 4px; min-width: 128px;
  box-shadow: 0 8px 24px rgba(0,0,0,.5);
}
.lang-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 8px 10px; border: 0; border-radius: 7px; cursor: pointer;
  background: transparent; color: var(--text, #e8ecf8); font-size: 13.5px; text-align: left;
  white-space: nowrap;
}
.lang-item:hover { background: rgba(255,255,255,.08); }
.lang-item.on { background: rgba(255,255,255,.12); font-weight: 800; }
.lang-item .lg-short { font-size: 11px; opacity: .7; min-width: 20px; }

/* ===== [claude code] 2026-08-16 烈火燎原（blaze）=====
   🔴 火勢等級用**大小**做階梯，不用顏色 —— 人眼有內建次序的只有「數量 / 大小 / 明度 / 填滿程度」，
   色相（藍焰比紅焰熱）是要背的知識，不是常識。所以 bz-f1..bz-f5 只變大小與光暈強度，色相一路是火色。 */
.cell.bz-block { filter: grayscale(.75) brightness(.62); }         /* 燒不掉的東西：一眼看出它是死的 */
.cell.bz-block .glyph { opacity: .8; }
.cell.bz-entry { box-shadow: inset 0 0 0 2px var(--gold), 0 0 12px rgba(255,190,60,.55); border-radius: 8px;
  animation: bzEntry .5s ease-in-out infinite alternate; }
@keyframes bzEntry { from { box-shadow: inset 0 0 0 2px var(--gold), 0 0 6px rgba(255,190,60,.35); }
  to { box-shadow: inset 0 0 0 2px var(--gold), 0 0 18px rgba(255,190,60,.75); } }

/* 🔴 火種：**火先出現在最底那排的某一格**（使用者要「看得到火從哪來」），停一拍才開始往外燒。
   跟 bz-fire 共用同一顆 🔥，差別是**格子本身還沒被燒掉**（符號完好、只有火壓在上面 + 底下一圈餘燼光）。 */
.cell.bz-seed { position: relative; border-radius: 8px;
  background: radial-gradient(circle at 50% 80%, rgba(255,160,40,.34), transparent 70%); }
.cell.bz-seed::after { content: "🔥"; position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: center; pointer-events: none;
  animation: bzSeedIn .34s cubic-bezier(.2,1.6,.4,1) both, bzFlame .9s ease-in-out .34s infinite alternate; }
@keyframes bzSeedIn { from { opacity: 0; transform: translateY(10px) scale(.4); }
  to { opacity: 1; transform: translateY(0) scale(1); } }

.cell.bz-fire { position: relative; border-radius: 8px;
  background: radial-gradient(circle at 50% 72%, rgba(255,140,30,.42), rgba(190,40,10,.14) 62%, transparent 78%); }
.cell.bz-fire .glyph { animation: bzBurn .42s ease-out both; }
@keyframes bzBurn { 0% { transform: scale(1); filter: none; }
  55% { transform: scale(1.18); filter: brightness(1.5) saturate(1.4); }
  100% { transform: scale(.86); opacity: .34; filter: brightness(.8) saturate(.7); } }
/* 火本體：疊在格子上的 🔥，大小 = 火勢等級 */
.cell.bz-fire::after { content: "🔥"; position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: center; pointer-events: none; animation: bzFlame .9s ease-in-out infinite alternate; }
@keyframes bzFlame { from { transform: translateY(1px) scale(.94); } to { transform: translateY(-2px) scale(1.06); } }
.cell.bz-f1::after { font-size: .62em; filter: drop-shadow(0 0 3px rgba(255,150,40,.6)); }
.cell.bz-f2::after { font-size: .82em; filter: drop-shadow(0 0 5px rgba(255,150,40,.7)); }
.cell.bz-f3::after { font-size: 1.02em; filter: drop-shadow(0 0 8px rgba(255,140,30,.8)); }
.cell.bz-f4::after { font-size: 1.24em; filter: drop-shadow(0 0 12px rgba(255,120,20,.9)); }
.cell.bz-f5::after { font-size: 1.5em; filter: drop-shadow(0 0 18px rgba(255,90,10,1)); }
/* 那格值多少（第二拍才冒出來：先燒起來 → 才知道拿多少） */
.cell .bz-pay { position: absolute; left: 50%; bottom: 6%; transform: translateX(-50%);
  font-size: 11px; font-weight: 900; color: #fff; background: rgba(200,40,0,.85);
  border: 1px solid rgba(255,200,90,.9); border-radius: 999px; padding: 1px 6px; white-space: nowrap;
  z-index: 3; animation: bzPay .45s cubic-bezier(.2,1.5,.4,1) both; }
@keyframes bzPay { from { opacity: 0; transform: translate(-50%, 8px) scale(.7); }
  to { opacity: 1; transform: translate(-50%, 0) scale(1); } }
/* 🔥 火勢等級標在格子上（使用者：「只看到一堆火,但沒有看到火幾」）——
   大小看得出強弱、數字才算得出賠付（那格的價錢 × 火幾）。🔴 點著就不熄:標記留到整轉結束。 */
.cell .bz-lv { position: absolute; top: 2px; left: 3px; z-index: 3;
  font-size: 10px; font-weight: 900; line-height: 1; color: #ffe0a8;
  text-shadow: 0 1px 2px rgba(0,0,0,.9), 0 0 6px rgba(255,120,20,.9); pointer-events: none;
  animation: bzLv .3s ease-out both; }
@keyframes bzLv { from { opacity: 0; transform: scale(.5); } to { opacity: 1; transform: scale(1); } }

/* 🔴 直向長跑道：整個 run 是一根連續的直條，鏡頭跟著火往上搖（做法照潛水航道）。
   舊的「兩倍高、一層換一層」整段作廢 —— 那是換頁不是鏡頭，而且方向做反過（新的一層從下面頂上來）。 */
.bz-view { position: fixed; overflow: hidden; z-index: 30; border-radius: 12px; pointer-events: none;
  /* 🔴 一定要**不透明**(底色同 .board):它是疊在真盤面上的,沒底色的話下面那盤會透上來 → 雙重影像。
     🔴 z-index 要在 .win-overlay(40) **底下** —— 原本 55 會讓 BIG WIN 被火蓋住 / 疊在一起。 */
  background: #070a14; }
.bz-run { position: absolute; left: 0; top: 0; width: 100%; height: 100%; will-change: transform; }
.bzs-cell { position: absolute; display: flex; align-items: center; justify-content: center;
  border-radius: 8px; background: var(--surface-2); font-size: inherit;
  box-sizing: border-box; }   /* 底色與字級對齊真正的 .cell,疊上去看不出接手 */
.bzs-glyph { line-height: 1; }
.bzs-block { filter: grayscale(.75) brightness(.62); }
.bzs-seed { background: radial-gradient(circle at 50% 80%, rgba(255,160,40,.34), transparent 70%); }
.bzs-seed::after, .bzs-fire::after { content: "🔥"; position: absolute; inset: 0; display: flex;
  align-items: center; justify-content: center; animation: bzFlame .9s ease-in-out infinite alternate; }
.bzs-seed::after { animation: bzSeedIn .34s cubic-bezier(.2,1.6,.4,1) both, bzFlame .9s ease-in-out .34s infinite alternate; }
.bzs-fire { background: radial-gradient(circle at 50% 72%, rgba(255,140,30,.42), rgba(190,40,10,.14) 62%, transparent 78%); }
.bzs-fire .bzs-glyph { animation: bzBurn .42s ease-out both; }
.bzs-fire.bz-f1::after { font-size: .62em; filter: drop-shadow(0 0 3px rgba(255,150,40,.6)); }
.bzs-fire.bz-f2::after { font-size: .82em; filter: drop-shadow(0 0 5px rgba(255,150,40,.7)); }
.bzs-fire.bz-f3::after { font-size: 1.02em; filter: drop-shadow(0 0 8px rgba(255,140,30,.8)); }
.bzs-fire.bz-f4::after { font-size: 1.24em; filter: drop-shadow(0 0 12px rgba(255,120,20,.9)); }
.bzs-fire.bz-f5::after { font-size: 1.5em; filter: drop-shadow(0 0 18px rgba(255,90,10,1)); }
.bzs-cell .bz-lv { position: absolute; top: 2px; left: 3px; z-index: 3;
  font-size: 10px; font-weight: 900; line-height: 1; color: #ffe0a8;
  text-shadow: 0 1px 2px rgba(0,0,0,.9), 0 0 6px rgba(255,120,20,.9);
  animation: bzLv .3s ease-out both; }
/* 🔴 燒到錢的那一格要**看得出來不一樣**（使用者:「沒有燒到錢的快樂感」）—— 金框 + 金光一閃 */
.bzs-cash { box-shadow: inset 0 0 0 2px var(--gold, #ffcf4a), 0 0 16px rgba(255,200,80,.6); }
.bzs-cash::before { content: ""; position: absolute; inset: 0; border-radius: 8px;
  background: radial-gradient(circle, rgba(255,220,120,.85), transparent 65%);
  animation: bzCash .5s ease-out both; pointer-events: none; }
@keyframes bzCash { from { opacity: .95; transform: scale(.6); } to { opacity: 0; transform: scale(1.5); } }
.bzs-cell .bz-pay { position: absolute; left: 50%; bottom: 4%; transform: translateX(-50%);
  font-size: 11px; font-weight: 900; color: #fff; background: rgba(200,40,0,.88);
  border: 1px solid rgba(255,200,90,.9); border-radius: 999px; padding: 1px 6px; white-space: nowrap;
  z-index: 4; animation: bzPay .45s cubic-bezier(.2,1.5,.4,1) both; }

/* 錢飛向計分帶 */
.bz-fly { position: fixed; z-index: 35; pointer-events: none; font-weight: 900; font-size: 15px;
  color: var(--gold, #ffcf4a); text-shadow: 0 2px 6px rgba(0,0,0,.85);
  animation: bzFly var(--fly-ms, 620ms) cubic-bezier(.35,.7,.4,1) both; }
@keyframes bzFly {
  0% { transform: translate(-50%,-50%) scale(.7); opacity: 0; }
  18% { transform: translate(-50%,-50%) scale(1.15); opacity: 1; }
  100% { transform: translate(calc(-50% + var(--fly-x)), calc(-50% + var(--fly-y))) scale(.75); opacity: .15; }
}

/* 🔴 盤面下方的計分帶:左邊「這一格怎麼算的」、右邊「累計」。
   使用者:「我也看不到、也算不著,他到底燒到了多少錢」—— 版型 v2 把 #winBanner 藏起來,
   中獎當下訊息帶又切去顯示贏分,寫在那裡的算式從頭到尾沒露臉 → 這款要有自己的位置。
   ⚠️ 它在盤面**下面** → boardHeightBudget 要扣它(手機一屏可見鐵則)。 */
.bz-tally { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin: 6px auto 0; padding: 6px 12px; max-width: 560px; min-height: 30px;
  border-radius: 10px; background: rgba(255,170,60,.12);
  border: 1px solid rgba(255,170,60,.3); font-size: 13px; }
.bzt-eq { color: #ffd9a6; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bzt-sum { color: var(--text, #eee); white-space: nowrap; }
.bzt-sum b { color: var(--gold, #ffcf4a); font-size: 16px; font-weight: 900; }
.bzt-sum.pop { animation: bzSumPop .32s cubic-bezier(.2,1.6,.4,1) both; }
@keyframes bzSumPop { 0% { transform: scale(1); } 45% { transform: scale(1.18); } 100% { transform: scale(1); } }

/* 細單（🔍 明細）用的盤面 */
.dt-slot.dt-blaze .dt-scell { font-size: 16px; }
.dt-scell.dt-bzcell { position: relative; }
.dt-scell.bzblock { opacity: .42; }
.dt-scell.bzburn { background: rgba(220,70,20,.24); border-color: rgba(255,150,60,.6);
  box-shadow: inset 0 0 0 1px rgba(255,150,60,.5); }
.dt-scell.bzgoods { background: rgba(240,110,20,.34); }
.dt-scell.bzentry { box-shadow: inset 0 0 0 2px var(--gold); }
.dt-scell .dt-bzlv { position: absolute; top: 1px; right: 2px; font-size: 9px; font-weight: 800;
  color: #ffd08a; line-height: 1; }
.dt-scell .dt-bzpay { font-size: 10px; font-weight: 800; color: var(--gold); line-height: 1; }
