/* ============================================================
   設計代幣：色票取自球隊徽章（深藍／皮革米／老金／縫線紅）
   ============================================================ */
:root{
  --bg:#0a1420; --panel:#12253c; --panel2:#1a3352; --edge:#2f5170;
  --chalk:#f2f5ef; --dim:#93a8ba; --amber:#e0ac4c; --clay:#c1432f;
  --good:#6fcf9c; --bad:#ff7f6b; --blue:#6fb8ea;
  --cream:#f0e4c8; --gold-deep:#a97a2c; --stitch:#c1432f;
  /* IBM Plex Mono 沒有中文字形——字體 fallback 是逐字元運作的，中文如果沒有明確
     指定接手字體，會一路退到 Windows 系統的細明體（serif 感很重，跟站內視覺
     完全不搭）。把 Noto Sans TC 插在通用 mono 之前：英數字仍由 IBM Plex Mono
     處理（等寬、tabular 數字都不受影響），中文由 Noto Sans TC 接手，跟 --sans
     同一套中文字型，全站觀感一致。使用者實測回報過側欄/逐年成績表格的中文
     「沒套用到 Google Fonts」，就是這個坑。 */
  --mono:'IBM Plex Mono','Noto Sans TC',ui-monospace,Menlo,monospace;
  --sans:'Noto Sans TC',-apple-system,'PingFang TC','Microsoft JhengHei',sans-serif;
  --r-s:8px; --r-m:12px; --r-l:16px;
  --sh-s:0 2px 8px #00000030; --sh-m:0 8px 22px #0006; --sh-l:0 14px 36px #0007;
  --safe-b:env(safe-area-inset-bottom);
  --ease-pop:cubic-bezier(.22,1.1,.36,1);
}
*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
/* overflow:hidden 避免 #app 換成固定高度 app shell 之後,萬一有次像素捨入誤差
   讓 body 本身也冒出一條殘留捲軸——#app 內部真正的捲動全部交給 #scroll-region
   處理,body/html 自己不該再捲動。#start 開場畫面是 position:fixed;inset:0 疊在
   最上層、有自己的 overflow-y:auto,不受這裡影響。 */
html,body{height:100%;overflow:hidden}
/* iOS 連點會把網頁放大（2026-08-27 玩家回報）：iOS 10 之後 Safari **故意忽略** viewport 的
   `maximum-scale=1.0` 與 `user-scalable=no`（無障礙考量），所以 index.html 那行擋不住
   雙擊縮放——這個遊戲整場都在快速點按鈕，兩下點在同一個位置就會被判定成 double-tap zoom。
   正解是 CSS 的 touch-action：`manipulation` ＝「拿掉雙擊縮放，其餘照舊」，
   **雙指縮放（pinch-zoom）完全保留**，不會犧牲無障礙。
   設在 html 上即可涵蓋全站（#log 事件卡、#v2-nav、#board、開場精靈、所有彈窗）——
   touch-action 雖然不是繼承屬性，但瀏覽器判定手勢時會沿著祖先鏈取交集。
   #act 另外已有更嚴格的 `pan-y`（只允許垂直捲動），那條保留、不受影響；
   `.tbl-scroll` 的左右捲動也不受影響（manipulation 仍允許 pan-x）。
   規格上瀏覽器判定手勢時會沿祖先鏈取交集，所以設在 html 理論上就夠；但 touch-action
   **不是繼承屬性**（子元素的計算值仍是 auto），而 Safari 對祖先鏈的實作向來不完全可靠，
   所以下面對實際會被連點的容器與元件再各設一次，兩層保險。
   **之後新增的可點元件如果不在下面的清單裡，記得加進去**（或確認它在已列的容器內）。 */
html{touch-action:manipulation}
button,a,summary,label,[role="button"],
#log,#board,#v2-nav,#act-toggle,#dsk-hubtabs,#dsk-side,#start,
.card,.btn,.abrow,.die,.seg,.v2-hero,.opts-grid{touch-action:manipulation}
body{background-color:var(--bg);color:var(--chalk);font-family:var(--sans);font-size:15px;line-height:1.6;
  background-image:
    radial-gradient(1.2px 1.2px at 12px 18px,#ffffff08 100%,transparent),
    radial-gradient(1.2px 1.2px at 46px 52px,#ffffff06 100%,transparent),
    linear-gradient(135deg,#12335522 0%,transparent 35%),
    radial-gradient(ellipse 95% 48% at 50% -10%,#1f5a4560 0%,transparent 70%);
  background-size:64px 64px,64px 64px,auto,auto}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important;scroll-behavior:auto!important}}

/* ---------- 版面容器 ----------
   #app 固定滿版視窗高度(不是 min-height，是 height)，本身不捲動：
   #scroll-region 是唯一有 overflow-y:auto 的區塊(flex:1，自動吃掉扣掉 #act 之後
   剩下的所有高度)，#act 是固定大小、不捲動的另一個 flex 子項目。這樣兩者永遠是
   平行、不重疊的區塊，不用再猜誰佔多高、算剩多少空間給誰——#act 內容再長，最多
   也只會壓縮 #scroll-region 的可視範圍，不會蓋住它裡面的內容。padding-bottom
   幫 #v2-nav（底部分頁列，position:fixed）預留空間，數字要跟 #v2-nav 的實際
   高度、#act-toggle 的 bottom 偏移對齊。 */
/* color:var(--chalk) 明講在這裡（不是只靠繼承 body 的計算值）是淺色主題能不能生效的
   關鍵：CSS 自訂屬性重新定義（見下方 #app[data-theme="light"]）只在「重新定義的那個
   元素自己與其子孫」的作用域內生效，但 color 這個屬性本身走的是「繼承已經算好的值」，
   不是「繼承時重新解析 var()」——body 沒有進到 body:has(#app[data-theme="light"]) 的作用域，
   如果 #app 不自己重新宣告一次 color:var(--chalk)，#app 底下所有沒有自己設定 color
   的元素都會沿用 body 在深色 token 下算出來的近白色文字，淺色主題會變成白字配白底。 */
/* 底部留給固定導覽列（#v2-nav）的空間：預設 58px＋安全區，但導覽列的實際高度會跟著系統文字縮放長高
   （Android 1.5 倍文字約 85px），固定值會讓導覽列蓋住 #act 最底下那排按鈕（2026-10-09 Android 玩家
   「畫面被切掉」的第二個成因）。main.js 用 ResizeObserver 量 #v2-nav 的實際高度寫進 --nav-h（含它自己的
   安全區 padding）；桌機導覽列 display:none 時量到 0，就退回原本的預設值，桌機版面一個像素都不變。 */
#app{max-width:640px;margin:0 auto;padding:0 12px var(--nav-h,calc(58px + var(--safe-b)));
  height:100vh;height:100dvh;display:flex;flex-direction:column;overflow:hidden;color:var(--chalk)}
@media (max-width:359px){#app{padding-left:8px;padding-right:8px}}
@media (min-width:700px){#app{max-width:760px}}
#scroll-region{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch}
/* 捲軸美化：#scroll-region 跟 #act 現在都會實際捲動，瀏覽器預設捲軸太搶眼——
   細一點、配色貼近站內邊框色（--edge），滑鼠移過去才稍微亮一點，其餘時間融進
   版面。scrollbar-width/scrollbar-color 給 Firefox，::-webkit-scrollbar 系列給
   Chromium/Safari，兩套並存互不影響。 */
#scroll-region,#act{scrollbar-width:thin;scrollbar-color:var(--edge) transparent}
#scroll-region::-webkit-scrollbar,#act::-webkit-scrollbar{width:6px}
#scroll-region::-webkit-scrollbar-track,#act::-webkit-scrollbar-track{background:transparent}
#scroll-region::-webkit-scrollbar-thumb,#act::-webkit-scrollbar-thumb{background:var(--edge);border-radius:99px}
#scroll-region::-webkit-scrollbar-thumb:hover,#act::-webkit-scrollbar-thumb:hover{background:var(--amber)}

/* ============================================================
   桌機版面：側欄＋主欄（≥1100px 才生效，手機／窄桌機完全不受影響）
   ============================================================
   #dsk-side／#dsk-maincol 是全新元素，跟 #board 那套既有手機版元件完全獨立，
   低於斷點時分別是 display:none／display:contents（後者讓 #dsk-maincol 在
   layout 上直接「消失」，#scroll-region 跟 #act 維持原本是 #app 直接 flex
   子項目的行為，跟這輪改動前一模一樣）。只有 ≥1100px 時才會實際變成側欄＋
   主欄並排的兩個 flex 子項目。詳見 CLAUDE.md 對應章節。 */
#dsk-side{display:none}
#dsk-maincol{display:contents}
#dsk-topbar{display:none}
@media (min-width:1100px){
  #app{max-width:1160px;flex-direction:row;align-items:stretch;gap:20px;padding-bottom:24px}
  #dsk-maincol{display:flex;flex-direction:column;flex:1;min-width:0}
  /* #dsk-topbar 是跟 #scroll-region／#act 平行的 flex 子項目（flex:none，大小固定），
     結構上就不會被 #scroll-region 自己的捲動影響——原理跟 #act 完全一樣，不需要
     position:sticky。 */
  #dsk-topbar{display:block;flex:none}
  /* 側欄本身就是一張直向卡片、拉滿 #app 整個高度，內部自己捲動(內容通常裝得下，這只是保底) */
  #dsk-side{display:flex;flex:0 0 264px;flex-direction:column;
    background:linear-gradient(135deg,#132a3d,#0d1f2c);border:1px solid #2f5266;border-radius:var(--r-l);
    box-shadow:var(--sh-s);overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;scrollbar-color:var(--edge) transparent}
  #dsk-side::-webkit-scrollbar{width:6px}
  #dsk-side::-webkit-scrollbar-thumb{background:var(--edge);border-radius:99px}
  .dsk-sec{padding:14px 16px}
  .dsk-sec+.dsk-sec{border-top:1px solid #24445a}
  #dsk-profile-sec{flex:1}
  /* 頭貼獨立佔一整塊，背後疊一圈放射狀光暈——沿用 .v2-hero 既有的光暈背景手法，
     不是另外發明新的視覺語言。原本頭貼只有 64px、跟姓名並排在一行，側欄拉滿版
     之後中段常常留一大塊空白，放大頭貼是最自然能吃掉這塊空白的地方。 */
  .dsk-hero{margin:-16px -16px 12px;padding:16px 16px 12px;text-align:center;
    background:radial-gradient(circle at 50% 20%,#2a6b4e80,transparent 60%),linear-gradient(135deg,#13324a,#0d2131)}
  .dsk-avatar{width:106px;height:106px;border-radius:50%;object-fit:cover;
    border:3px solid #3f7189;box-shadow:0 6px 18px #0008}
  .dsk-id{text-align:center}
  .dsk-id b{display:block;font-size:19px}
  .dsk-id small{display:block;color:var(--dim);font-size:11.5px;margin-top:3px}
  .dsk-team{margin-top:10px;font-size:12.5px;font-weight:700;background:#e0ac4c1c;border:1px solid #e0ac4c45;
    border-radius:999px;padding:5px 11px;color:#f4d493;display:inline-block}
  /* 背號跟「目前效力於」共用同一個藥丸，這個列本來就有多的橫向空間（球隊名很少
     撐滿整條）；空字串時 <span> 不佔任何寬度，不用另外判斷顯示/隱藏。 */
  #dsk-jersey{margin-left:6px;padding-left:8px;border-left:1px solid #e0ac4c45;color:var(--cream);font-family:var(--mono)}
  #dsk-jersey:empty{display:none} /* 還沒選背號（業餘階段）時完全不畫分隔線/留白 */
  .dsk-list{display:flex;flex-direction:column;gap:6px;margin-top:12px}
  .dsk-row2{display:grid;grid-template-columns:1fr 1fr;gap:7px}
  .dsk-stat{display:flex;justify-content:space-between;align-items:baseline;
    background:linear-gradient(180deg,#0a1826,#0d1f2e);border:1px solid #2c4e64;border-radius:var(--r-s);padding:9px 12px}
  .dsk-stat span{font-size:12px;color:var(--dim);letter-spacing:.1em}
  .dsk-stat b{font-family:var(--mono);font-size:18px;font-weight:700;color:var(--amber);
    text-shadow:0 0 8px #e0ac4c4d;font-variant-numeric:tabular-nums}
  .dsk-pstatus.grow b{color:#9cc9ec;text-shadow:0 0 8px #3d76a64d}
  .dsk-pstatus.peak b{color:var(--amber)}
  .dsk-pstatus.decline b{color:#f0a99c;text-shadow:0 0 8px #a1493a4d}
  #dsk-settings-sec{flex:none}
  .dsk-btn{display:block;width:100%;text-align:left;background:linear-gradient(135deg,#1a3c56,#12293a);
    border:1px solid #355971;color:var(--chalk);font-family:var(--sans);font-size:13px;font-weight:700;
    border-radius:var(--r-s);padding:10px 12px;cursor:pointer;transition:border-color .15s,transform .1s}
  .dsk-btn:active{transform:scale(.98)}
  .dsk-btn:hover{border-color:var(--amber)}
  .dsk-btn b{color:var(--amber);font-weight:800;margin-left:2px}
  .dsk-btn.warn{border-color:#8a4b52}
  /* 保存進度／重新開始改橫排省一行高度，其餘按鈕（閱讀模式等）維持整行 */
  .dsk-btn-row{display:grid;grid-template-columns:1fr 1fr;gap:8px}
  .dsk-group+.dsk-group{margin-top:14px;padding-top:12px;border-top:1px solid #24445a}
  .dsk-group-h{display:block;margin-bottom:9px;font-size:13px;font-weight:800;letter-spacing:.06em;color:#a7e0c4}
  .dsk-theme-row{display:flex;align-items:center;justify-content:space-between;gap:8px;
    background:#0a1826;border:1px solid #2c4e64;border-radius:var(--r-s);padding:8px 10px;font-size:12px;color:#b9cfda}
  .dsk-theme-row button{flex:none;background:transparent;border:1px solid #3f7189;color:#8bacbd;border-radius:999px;
    font-size:10.5px;padding:4px 9px;cursor:pointer;font-family:var(--sans)}
  .fs-row{margin-top:8px}
  .dsk-meta{display:flex;flex-direction:column;gap:6px;margin-top:8px}
  .dsk-meta-row{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:11.5px;color:var(--dim);
    background:#0a1826;border:1px solid #2c4e64;border-radius:var(--r-s);padding:7px 10px}
  .dsk-meta-row b{color:#c2d6de;font-weight:700;font-family:var(--mono)}
  .dsk-meta-row button{flex:none;background:transparent;border:1px solid #3f7189;color:#8bacbd;border-radius:var(--r-s);
    font-size:12px;padding:3px 7px;cursor:pointer}

  /* 主欄：頭部資訊列在這個寬度改用側欄呈現，原本的 #board 整條隱藏；
     生涯中控台的分頁選單／賽季燈號搬到字卡區正上方，字級比手機版的小標籤明顯放大——
     這是整個右欄最上層的導覽，要讓它看起來像主選單，不是隨手一個小按鈕。 */
  #board{display:none}
  #lamps{display:none!important} /* #lamps 移出 #board 之後（見「記分板」一節），要各自維持「桌機隱藏」，不能只靠 #board 帶著一起藏；
    後面「記分板」一節又補了一條同 specificity 的 #lamps{display:flex}（手機常駐樣式），源碼順序比這裡晚、優先權打平時會贏，
    桌機版本沒被隱藏、出現兩個賽季燈號——這裡要 !important 蓋掉，比照 #board/#v2-nav 既有的同類規則寫法 */
  #dsk-hubtabs{display:flex;gap:8px;padding:2px 2px 12px}
  #dsk-hubtabs button{flex:1;background:#0b1f2e;border:1px solid #2f5266;color:#9cbdcf;border-radius:var(--r-m);
    padding:12px 8px;font:800 15px var(--sans);letter-spacing:.01em;cursor:pointer;transition:border-color .15s,color .15s}
  #dsk-hubtabs button.on{color:#ffda81;border-color:#c8963e;background:#1a2f22;box-shadow:0 0 0 1px #e0ac4c30}
  #dsk-phase{display:flex;gap:14px;justify-content:center;padding:0 4px 12px}
  /* #v2-panel 在桌機主欄裡永遠展開（用 #dsk-hubtabs 切換內容，不再需要點頭部收合/展開），
     蓋掉 .collapsed 那組 max-height:0 的規則，順手把「詳情▾/收合▴」的角標藏起來，
     免得看起來還能點但點了其實沒有視覺變化。這三條選擇器跟本檔案後段（.v2-hero／
     .v2-panel.collapsed 那組)原有規則的 specificity 相同、但源碼位置更早，正常
     cascade 順序會輸給後面的規則——比照 #clubhouse{display:none!important} 已有的
     先例，這裡同樣用 !important 確保優先權，不是隨手亂加。 */
  #v2-panel.collapsed .v2-grid,#v2-panel.collapsed .v2-list{max-height:640px!important;opacity:1!important}
  /* 新骨架（.v2-body）的摺疊是 grid-template-rows，桌機同樣強制展開 */
  #v2-panel.collapsed .v2-body{grid-template-rows:minmax(0,1fr)!important}
  .v2-hero::after{display:none!important}
  .v2-hero{cursor:default!important}
  #log{max-width:none}
  /* #v2-nav（底部固定分頁列）的功能被 #dsk-hubtabs 取代，桌機不需要兩組分頁控制項
     同時存在——它的 CSS 基礎規則本身已經是 display:flex!important（給手機版
     position:fixed 用），renderV2Panel() 也會把 inline style 設回 flex，兩個
     !important 規則同分時比源碼順序、基礎規則在後面會贏，所以這裡不能只加
     !important，要用 html 前綴墊高 specificity 才蓋得過去。#app 底部原本幫這條
     固定 nav 留的安全間距（見最上面 #app{padding-bottom:24px}）已經同步縮小，
     這裡不用重複設定。 */
  html #v2-nav{display:none!important}
}

/* ============================================================
   開場畫面
   ============================================================ */
/* 選角頁改走「開幕戰球場燈光」主題：比賽內畫面更暗、更有聚光燈感,跟賽季中的資訊面板拉開區隔。
   color:var(--chalk) 明講在這裡（不是只靠繼承 body 的計算值），理由跟 #app 的
   同一行修正一樣，見「淺色主題」章節開頭的說明。 */
#start{position:fixed;inset:0;z-index:50;overflow-y:auto;background-color:#060d16;color:var(--chalk);
  background-image:radial-gradient(circle at 20% 0%,#2a6b4d70,transparent 30%),radial-gradient(circle at 85% 18%,#8a4a2250,transparent 34%),radial-gradient(ellipse 70% 40% at 50% 100%,#0d2c4a55,transparent 60%),linear-gradient(135deg,#060d16,#0a1c2c);
  background-size:150% 150%,150% 150%,100% 100%,auto;animation:driftGlow 24s ease-in-out infinite alternate}
@keyframes driftGlow{from{background-position:0% 0%,100% 0%,50% 100%,0 0}to{background-position:14% 10%,86% 16%,50% 100%,0 0}}
#start .wrap{max-width:640px;margin:0 auto;padding:12px 20px 64px}
@media (min-width:700px){#start .wrap{max-width:700px;padding:16px 24px 72px}}
/* logo 置中：.hero 縮到跟圖片一樣寬(fit-content)再 margin:auto 置中,
   底下的 .title-credits 用 text-align:right 靠齊同一個寬度,視覺上落在 logo 右下方 */
.hero{width:fit-content;max-width:100%;margin:0 auto}
#start h1{margin-top:0}
.brand-logo{display:block;max-width:min(420px,86vw);width:100%;height:auto;filter:drop-shadow(0 10px 24px #00000060);
  animation:logoIn .7s var(--ease-pop) .12s backwards}
/* 純 CSS keyframe(不依賴 JS 補 class)：萬一動畫因為任何原因沒播到,元素本來就還是看得到的,
   不會出現「JS 沒趕上、內容整個消失」的風險。.12s 的 delay 是刻意留給頁面初次繪製喘口氣,
   讓「淡入」比較有機會真的被使用者看到,而不是跟 load 搶時間搶輸。 */
@keyframes logoIn{from{opacity:0;transform:translateY(18px) scale(.94)}to{opacity:1;transform:none}}
/* 特色標籤：放在「創造角色」標題列右側(說明按鈕旁)，不再獨占最上面一整行 */
.feature-tags{display:flex;flex-wrap:wrap;gap:6px;margin:0;font-weight:400}
.feature-tags span{font-size:11px;color:#e2d9fa;background:#a78bfa1c;border:1px solid #a78bfa40;
  border-radius:999px;padding:4px 10px;letter-spacing:.02em}
/* 版本更新條改成紫色系,跟金色的「稀有事件/CTA」語意分開 */
/* 更新條收成一行：標題+感謝文字+兩個按鈕用 flex 排在同一列，螢幕太窄才換行，
   不再像以前一樣把完整 changelog 攤開常駐佔位置（那些內容本來就在「更新日誌」彈窗裡看得到）。 */
.release-note{font-family:var(--mono);font-size:12px;letter-spacing:.04em;color:var(--cream);background:#8b5cf614;
  border-left:2px solid #a78bfa;border-radius:0 var(--r-s) var(--r-s) 0;padding:8px 12px;margin:0 0 14px;
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:6px 12px}
.release-line{font-family:var(--sans);font-size:11px;color:#cabdf0;letter-spacing:.02em}
.forum-link{display:inline-flex;align-items:center;justify-content:center;background:#e5ad2430;border:1px solid #e5ad2488;
  border-radius:999px;color:#ffe4a3;font:700 10.5px var(--sans);letter-spacing:.03em;line-height:1.25;
  padding:3px 9px;text-decoration:none;white-space:nowrap;transition:background .15s,border-color .15s,transform .15s}
.forum-link:hover{background:#e5ad2450;border-color:#f6c34d;transform:translateY(-1px)}
.release-forum-btn{margin-left:4px;vertical-align:middle}
/* 公告輪播（2026-09-16）：.rl-news 裡放多個 .rl-item，JS 每隔幾秒只顯示其中一個。
   用 display:contents 讓「顯示中」那一個的文字與按鈕直接變成 .rl-news 的 flex 子項目，
   手機版那條「nowrap 要下在容器上」「按鈕 margin-left:auto 推到右邊」的版面完全不用改。
   display:contents 會蓋掉 UA 的 [hidden]{display:none}，所以要自己補一條。 */
.rl-item{display:contents}
.rl-item[hidden]{display:none}
/* 「檢查更新」鈕（2026-10-09）：給裝成手機版、沒有瀏覽器重新整理鈕的玩家一個主動入口。
   掛在版本膠囊裡，不佔 .about-actions 的第七顆位置（桌機那排六顆 nowrap 剛好排滿）。
   file:// 直開時 main.js 會把它藏起來（沒有伺服器可問）。 */
.rl-check{display:inline-flex;align-items:center;margin-left:6px;padding:2px 8px;border-radius:999px;
  background:#e5ad2422;border:1px solid #e5ad2466;color:#ffe4a3;font:700 10.5px var(--sans);letter-spacing:.03em;
  line-height:1.25;cursor:pointer;white-space:nowrap;transition:background .15s,border-color .15s}
.rl-check:hover{background:#e5ad2440;border-color:#f6c34d}
.rl-check:disabled{cursor:default;opacity:.85}
.rl-check[hidden]{display:none}
.about-actions{display:flex;flex-wrap:wrap;gap:8px;margin:0}
.about-btn{display:block;background:#a78bfa1c;border:1px solid #a78bfa4a;color:#d9cffb;
  font-family:var(--sans);font-size:11.5px;font-weight:700;letter-spacing:.04em;border-radius:999px;
  padding:5px 12px;cursor:pointer;transition:background .15s,border-color .15s;
  text-decoration:none} /* .about-btn 現在也用在 <a href="feedback.html">（錯誤回報）上，重置底線 */
.about-btn:hover{background:#a78bfa30;border-color:#a78bfa}

/* ---------- 代言卡（2026-08-31）----------
   抽到代言事件時畫在題目下方：品牌、品類、廣告詞、代言費。
   玩家要在選擇之前就看得到「是哪個牌子、拿多少錢」，這張卡就是為此存在。
   走 var() token，深淺主題自動跟著換（CLAUDE.md 9.21）。 */
.endorse-card{
  margin:12px 0 4px;padding:12px 14px;
  background:linear-gradient(150deg,#1a2f47,#132234);
  border:1px solid var(--gold-deep);border-left:3px solid var(--amber);
  border-radius:8px;font-family:var(--sans);text-align:left;
}
.endorse-top{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.endorse-cat{
  flex:none;font:600 10.5px var(--sans);letter-spacing:.06em;
  color:var(--cream);background:#0000004d;border:1px solid var(--edge);
  border-radius:99px;padding:2px 8px;
}
.endorse-brand{font-size:16px;font-weight:900;color:var(--amber);letter-spacing:.02em}
.endorse-slogan{
  margin-top:7px;font-size:13px;line-height:1.6;color:var(--cream);
  font-style:italic;opacity:.92;
}
.endorse-fee{
  display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  margin-top:10px;padding-top:9px;border-top:1px dashed var(--edge);
}
.endorse-fee span{font-size:11.5px;color:var(--dim);letter-spacing:.05em}
.endorse-fee b{font-family:var(--mono);font-size:16px;font-weight:700;color:var(--good)}
body:has(#app[data-theme="light"]) .endorse-card{
  background:linear-gradient(150deg,#fffaf0,#f4f7f8);border-color:#c79a3a;border-left-color:var(--amber)}
body:has(#app[data-theme="light"]) .endorse-cat{color:#5b4410;background:#00000008}
body:has(#app[data-theme="light"]) .endorse-slogan{color:#41505c}

/* ---------- 手機選單（<1100px）：把 .about-actions 收進右上角圖示觸發的收合選單 ----------
   使用者反映手機版第一屏完全看不到任何可互動選項（守位按鈕要滑一次才看得到），量測後
   最大的空間消耗來源之一是這裡常駐攤開的 4 顆按鈕。桌機（≥1100px）完全不受影響，維持
   原本行內攤開的 4 顆按鈕（.about-actions 的預設 display:flex 規則不變）；這個 media
   query 只覆寫 <1100px 的行為。 */
.mobile-menu-btn{display:none}
@media (max-width:1099px){
  /* 原本這個角落放的是 #ver-badge（純文字版本號），使用者要求拿掉——中間角色卡
     已經看得到版本資訊，不需要重複；選單鈕因此可以往上移到原本 ver-badge 的位置
     （top:8px），不用再讓一格給已經不存在的版本號。
     right:20px（不是貼齊邊緣的 8px）：#start 本身沒有套用站內細版捲軸樣式
     （那組只給 #scroll-region/#act，見「版面容器」一節），瀏覽器原生捲軸在
     Windows Chrome 大約 15-17px 寬，貼太近會讓按鈕看起來卡進捲軸裡——使用者
     截圖回報過這個問題，拉開一點距離讓按鈕清楚跟捲軸分開。 */
  /* 位置（2026-09-15 使用者回報「右上角選單按鈕位置也不是很正確」）：頂部那條 Line
     公告（.rl-news）實高 41px、選單鈕 33px，所以 top 要 4px 才是**垂直置中**——
     原本的 8px 是「底部對齊」，看起來像掉下來壓在公告條上。
     ⚠ 改公告列的上下 padding（現為 9px）就要回來改這個 4px。
     顏色：原本用 #a78bfa／#e2d9fa 這組紫。紫色本身不是憑空冒出來的——開場畫面的
     「meta 區」（.release-note／.about-btn／.start-disclaimer／.feature-tags）一直都用
     它當點綴色。但**手機版的選單鈕是疊在頂部那條公告列上的**，而那條列上只有金框的
     版本膠囊與綠框的 Line 膠囊，紫色膠囊夾在中間就顯得像外掛元件
     （2026-09-15 使用者回報「選單的樣式也設計一下」）。改成老金描邊＋皮革米字，
     跟它實際相鄰的東西同一種語言；桌機那組行內 .about-btn 維持原本的紫，不受影響。 */
  .mobile-menu-btn{display:flex;position:fixed;top:4px;right:20px;z-index:56;align-items:center;gap:6px;
    background:#0e2436e0;backdrop-filter:blur(4px);border:1px solid var(--gold-deep,#a97a1c);color:var(--cream,#fff8ea);
    font-family:var(--sans);font-size:12px;font-weight:800;letter-spacing:.02em;border-radius:999px;
    padding:7px 13px 7px 12px;box-shadow:0 4px 12px #00000040;cursor:pointer}
  .mobile-menu-btn:active{background:#16334a}
  /* .about-actions 從「行內攤開的 4 顆按鈕」變成 position:fixed 的收合選單，預設
     display:none，點 .mobile-menu-btn 才加上 .open 展開（見 script.js）。 */
  /* 選單面板（2026-09-15 重新設計）：原本是紫色描邊的白／深色方塊，跟整個畫面的
     金藍色票搭不起來。改成跟事件卡同一種語言——深藍底、老金細描邊、上緣一條金線
     當「這是一個面板」的標記；圓角沿用 --r-m。 */
  .about-actions{position:fixed;top:44px;right:12px;z-index:56;display:none;flex-direction:column;gap:1px;
    background:#0c1e2ff7;backdrop-filter:blur(6px);
    border:1px solid #2a4560;border-top:2px solid var(--gold-deep,#a97a1c);
    border-radius:var(--r-m);padding:6px;box-shadow:0 12px 30px #0009;
    min-width:196px;max-width:calc(100vw - 24px)}
  .about-actions.open{display:flex}
  /* 收合選單在淺色主題要有自己的面板底（桌機那個行內版不需要，見全域那條的說明） */
  body:has(#app[data-theme="light"]) .about-actions{background:#fffffff7;border-color:#c3d5d9;border-top-color:var(--gold-deep,#8a5a10)}
  /* 展開後是直向清單，不是行內藥丸——.about-btn 的視覺在這個寬度下整組改寫成清單項目樣式 */
  /* 每一項是清單列：左對齊、夠大的點擊區（40px），按下去用老金淡底回饋。 */
  .about-btn{display:flex;align-items:center;gap:8px;text-align:left;padding:10px 11px;border-radius:var(--r-s);
    background:transparent;border:0;min-height:40px;font-size:13px;color:var(--chalk)}
  .about-btn:active{background:#a97a1c2e}
  .about-actions-divider{margin:5px 8px;border-top:1px solid #24405a}
  /* 主題切換那一列：左邊標題、右邊目前值。顏色跟其他項一致（原本是 #c9bff2 的紫，
     在淺色主題的白底上對比不足）。 */
  .about-btn-dev{justify-content:space-between;color:var(--dim)}
  .about-btn-dev b{color:var(--amber);font-weight:800}
  .dev-tag{flex:none;font-family:var(--sans);font-size:9px;font-weight:700;letter-spacing:.04em;color:#8fa9b8;
    background:#0000002e;border:1px solid #345368;border-radius:999px;padding:2px 7px}
  /* 手機版拿掉「創造角色」標題旁的裝飾性特色標籤（🎯多樣性選擇/🔁種子化人生/🏆完整生涯），
     純文案沒有功能，留著會把「下一步」按鈕推出第一屏；桌機這條規則不生效，繼續顯示。 */
  .feature-tags{display:none}
}
/* 貼在 logo 右下方:不用絕對定位疊上圖片(logo 圖片本身右下角已經有金色副標字,疊字會打架),
   改成緊接在 logo 下面、靠右對齊,視覺上仍是「logo 的右下方」 */
.title-credits{margin:6px 2px 2px;text-align:right;color:#8facba;font:10px var(--mono);letter-spacing:.04em;line-height:1.85}
.title-credits b{color:#d7e6ec}
.title-credits a{color:#ffda81;text-decoration:none;border-bottom:1px solid #ffce6355}

/* 續玩存檔提示條:用金色系(跟事件卡的 gold 語氣一致),跟紫色的版本更新條區分開來——
   這是「你有進行中的生涯」這種需要優先注意到的訊息,不是次要的版更公告 */
/* 新版提示條（2026-09-09）：跟 .continue-banner 同一種語彙，但用縫線紅提高存在感
   ——玩家停在舊版是會影響遊玩的事，不是純資訊。 */
.update-banner{display:flex;flex-wrap:wrap;align-items:center;gap:10px;justify-content:space-between;
  margin:0 0 12px;padding:11px 14px;border:1px solid var(--stitch);border-radius:var(--r-m);
  background:linear-gradient(100deg,#c1432f22,#12263a80)}
.update-banner-text{font-size:13px;color:var(--chalk);line-height:1.6}
.update-banner-text b{display:block;color:var(--stitch)}
.update-banner-text span{font-family:var(--mono);font-size:11px;color:var(--dim)}
/* .btn 預設是 width:100%（給表單用的），不覆寫的話按鈕會換行撐成整條。
   比照 .continue-actions .btn 收成一顆行內按鈕。 */
.update-banner .btn{flex:none;width:auto;padding:8px 14px;font-size:12.5px}
.continue-banner{display:flex;flex-wrap:wrap;align-items:center;gap:10px;justify-content:space-between;
  font-family:var(--sans);background:linear-gradient(100deg,#e0ac4c1c,#12263a80);
  border:1px solid #e0ac4c4a;border-radius:var(--r-m);padding:12px 14px;margin:0 0 14px}
.continue-text{display:flex;flex-direction:column;gap:2px;font-size:12.5px;color:var(--cream)}
.continue-text b{font-size:13.5px;color:var(--amber)}
.continue-text span{color:var(--dim);font-family:var(--mono);font-size:11.5px}
.continue-actions{display:flex;flex-wrap:wrap;gap:8px}
.continue-actions .btn{width:auto;padding:8px 14px;font-size:12.5px}

/* 雲端存檔（2026-09-12）：跟上面兩條提示條同一種語彙，但用天空藍——它既不是
   「你有進行中的生涯」（金），也不是「你停在舊版」（紅），而是一個可以不理會的
   附加功能。**整組預設 display:none，由 src/cloud.js 決定要不要出現**：沒有伺服器、
   離線、file:// 直開時整段不存在，開場畫面跟以前一模一樣。
   開局畫面的高度是零和的（見 CLAUDE.md 同名章節），所以這幾條刻意做得比續玩條更薄。 */
.cloud-bar{display:flex;flex-wrap:wrap;align-items:center;gap:10px;justify-content:space-between;
  font-family:var(--sans);background:linear-gradient(100deg,#3d8fd41c,#12263a80);
  border:1px solid #3d8fd44a;border-radius:var(--r-m);padding:9px 14px;margin:0 0 10px}
/* flex-basis **一定要是 0**（不是 auto）：flex-wrap 的換行是先用「基準寬度」算的，
   flex-shrink 要等分行之後才生效——basis:auto 等於拿文字的內容寬度去排，手機上
   名字那塊會直接吃掉整行、把按鈕擠到第二列（實測 390px 下 312px）。basis:0 讓它
   先縮到 0、按鈕排得進同一行，再把剩下的空間長回來。
   grow 也是必要的：不給的話三個子項目會被 space-between 推成「左、中、右」，
   名字跟狀態就飄到整條的正中間、離頭貼很遠。 */
.cloud-text{flex:1 1 0;display:flex;flex-direction:column;gap:1px;font-size:12px;color:var(--cream);min-width:0}
/* 名字維持單行省略；**狀態那行要能換行**——它可能帶著「可自行設定球員頭貼」的提示，
   截成半句話比多佔一行還糟（見 cloudRenderBar() 裡那段說明）。 */
.cloud-text b{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cloud-text span{line-height:1.5}
/* 「可自行設定球員頭貼」——提示本身就是入口（見 cloudRenderBar()）。做成文字連結而不是
   按鈕：它要待在句子裡，多一顆按鈕就等於多佔一格，那正是這一整條在省的東西。 */
.cloud-hint-link{background:none;border:0;padding:0;cursor:pointer;font:inherit;
  color:var(--amber);text-decoration:underline;text-underline-offset:2px}
.cloud-hint-link:hover{color:var(--cream)}
.cloud-text b{font-size:13px;color:#8ec5f0}
.cloud-text span{color:var(--dim);font-size:11.5px}
.cloud-actions{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.cloud-actions .btn{width:auto;padding:7px 13px;font-size:12px}
/* 頭貼縮圖：讓玩家一眼看到「現在球員長什麼樣」，換了立刻反映。 */
.cloud-face{flex:none;width:34px;height:34px;border-radius:50%;object-fit:cover;
  border:1px solid #3d8fd466;background:#0d1d2b}
.cloud-face-empty{display:flex;align-items:center;justify-content:center;font-size:16px;opacity:.55}
/* 「這個可以點開」要看得出來（2026-09-12 使用者回報「那麼小個文字可能有的人都不知道
   可以點開」）。**沿用全站既有的語彙，不要再發明第三種**：虛線膠囊 ＋ 會跟著開合
   旋轉的三角形，跟 .v2-fold summary／.v2-chip-toggle 完全一樣（見 CLAUDE.md 9.8b）。
   三角形由 ::before 依 aria-expanded 畫，所以 JS 那邊不用自己在文字裡塞箭頭——
   「螢幕閱讀器讀到的狀態」與「眼睛看到的狀態」天生同步，不可能各說各話。
   「帳號與資料」是低頻、而且底下有一顆不可逆的按鈕，維持收在展開列裡、不跟登出同層。 */
.cloud-fold{display:inline-flex;align-items:center;gap:6px;flex:none;cursor:pointer;
  font-family:var(--sans);font-size:12px;font-weight:700;letter-spacing:.02em;
  color:#9ebbc9;background:transparent;border:1px dashed #3f7189;border-radius:999px;
  padding:5px 12px;transition:border-color .15s,color .15s}
.cloud-fold::before{content:'▸';color:var(--amber);font-size:11px;line-height:1;
  transition:transform .2s var(--ease-pop)}
.cloud-fold[aria-expanded="true"]::before{transform:rotate(90deg)}
.cloud-fold:hover{border-color:var(--amber);color:var(--amber)}
.cloud-panel{flex-basis:100%;display:flex;flex-wrap:wrap;align-items:center;gap:8px;
  margin-top:2px;padding-top:9px;border-top:1px dashed #3d8fd440}
.cloud-panel .btn{width:auto;padding:7px 12px;font-size:11.5px}
/* 「接續雲端進度」是這條裡最重要的一顆：**維持實心按鈕、不降成虛線膠囊**，但用同一顆
   會旋轉的三角形，讓玩家一眼認出「這是展開，不是直接執行」。排在最前面並用琥珀色描邊
   跟其他鈕分層；真正不可逆的兩個決定（接續／放棄）收在展開之後，不擺在第一層。 */
.cloud-resume{border-color:#e0ac4c77;color:var(--amber);font-weight:700;
  display:inline-flex;align-items:center;gap:6px}
/* 三角形自己畫一份（不掛 .cloud-fold）：那個 class 帶著「透明底＋虛線框」，
   套上來會把實心按鈕的外觀整個蓋掉，這一條裡的主次就沒了。 */
.cloud-resume::before{content:'▸';color:var(--amber);font-size:11px;line-height:1;
  transition:transform .2s var(--ease-pop)}
.cloud-resume[aria-expanded="true"]::before{transform:rotate(90deg)}
.cloud-resume-panel{gap:10px;align-items:center}
.cloud-resume-info{flex:1 1 auto;display:flex;flex-direction:column;gap:4px;min-width:0}
.cloud-resume-info b{font-size:13.5px;color:var(--chalk)}

.cloud-resume-acts{flex:none;margin-top:0}
.cloud-resume-acts .btn{flex:none;width:auto}
.cloud-panel .btn.cloud-danger{border-color:#c0392b88;color:#ff8b7a;background:#2a0f0f66}
.cloud-priv{color:var(--dim);font-size:11.5px;text-decoration:underline;text-underline-offset:3px;margin-left:auto}
.cloud-priv:hover{color:#8ec5f0}
.cloud-msg{font-size:12px;color:var(--dim);line-height:1.6;margin:0 0 10px;padding:0 2px;
  word-break:break-word}
/* 近三段生涯：這不是存檔，是墓誌銘——重點是最右邊那顆「用這個種子開新生涯」。 */
.cloud-careers{margin:0 0 12px}
.cloud-careers-t{margin:0}
.cloud-careers-t[aria-expanded="true"]{margin-bottom:8px}
/* 手機：開場第一屏的垂直空間是零和的（見 CLAUDE.md「開場畫面的高度是零和的」）。
   實測未壓縮前這一條加生涯清單吃掉 193px，把「創造角色」推到 y=369。
   縮頭貼、縮內距、縮字級，配合上面「第一層只留兩顆鈕」，整條收成一列。 */
@media (max-width:699px){
  .cloud-bar{padding:7px 10px;gap:8px;margin-bottom:7px}
  .cloud-face{width:28px;height:28px}
  .cloud-text{font-size:11.5px}
  .cloud-text b{font-size:12.5px}
  .cloud-text span{font-size:11px}
  .cloud-actions{gap:6px}
  .cloud-actions .btn,.cloud-fold{padding:6px 10px;font-size:11.5px}
  .cloud-fold{gap:5px}
  .cloud-careers{margin-bottom:8px}
  .cloud-panel{gap:6px;padding-top:8px}
  .cloud-panel .btn{padding:6px 10px;font-size:11px}
  .cloud-resume-panel{gap:8px}
}
/* 三段生涯自動並排：**開場畫面的垂直空間是零和的**（見 CLAUDE.md 同名章節），
   三張卡各佔一整行會直接把 logo 壓掉一截。寬度夠就排成一列，窄機自己收成直排。 */
.cloud-career-list{display:grid;gap:6px;grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
.cloud-career{display:flex;flex-direction:column;align-items:stretch;gap:8px;
  border:1px solid var(--edge);border-radius:var(--r-m);background:linear-gradient(160deg,#14293f88,#0e1f2e88);
  padding:10px 12px}
/* 姓名與生涯評價同一行：那是這張卡最先要被讀到的兩件事（他是誰、他走到哪）。 */
.cc-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}
.cc-head b{font-size:14px;color:var(--chalk);letter-spacing:.02em}
.cc-tier{flex:none;font-size:10.5px;font-weight:700;letter-spacing:.04em;padding:2px 8px;
  border-radius:999px;border:1px solid var(--edge);background:#0b1b2a;color:var(--dim)}
/* 名人堂＝金、明星＝銀，其餘素色。門檻只有 tierOf() 那一份，這裡純粹是顏色分層。 */
.cc-tier.cc-t-hof{border-color:#e0ac4c88;background:#3a2c0566;color:var(--amber)}
.cc-tier.cc-t-star{border-color:#c8d0e088;background:#23273366;color:#e8eef7}
/* 四項事實用 icon＋標籤＋值的格子，不要再串成一長條 A｜B｜C——那種寫法在手機上會折成
   三行，而且讀的時候得自己切開。 */
.cc-facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:5px 10px;margin:0}
.cc-fact{display:flex;align-items:center;gap:6px;min-width:0}
.cc-fact .v2-ic{flex:none;width:14px;height:14px;color:var(--dim);opacity:.8}
.cc-fact dt{flex:none;font-size:10.5px;color:var(--dim)}
.cc-fact dd{margin:0;font-size:12px;color:var(--cream);font-weight:700;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 有些生涯紀錄是在支援重畫之前留下的（沒有存檔可用），那張卡會少兩顆鈕——
   把動作列推到底部，三張卡的「用這個種子開新生涯」才會對齊在同一條線上。 */
.cc-acts{display:flex;flex-wrap:wrap;gap:6px;margin-top:auto}
/* 接續雲端進度那條把事實格改成橫排（生涯卡是 2×2，那邊一張卡只有一欄寬）。
   **一定要寫在 .cc-facts 後面**：兩者同權重，靠源碼順序決勝——寫在前面的話 grid 會贏，
   畫面上會變成「進度／最後存檔 換行 世界種子」那種散開的兩欄。 */
.cc-facts.cc-facts-row{display:flex;flex-wrap:wrap;gap:4px 14px}
.cloud-career .btn{flex:1 1 auto;width:auto;display:inline-flex;align-items:center;justify-content:center;
  gap:5px;padding:7px 10px;font-size:11.5px}
.cloud-career .btn .v2-ic{width:14px;height:14px;flex:none}
/* 「用這個種子開新生涯」是主要動作，兩顆產圖鈕是附屬的——用寬度與色調分層，
   不要三顆長得一模一樣。 */
.cloud-career .btn.cc-seed{flex:1 1 100%;border-color:#e0ac4c55;color:var(--amber)}
.cloud-career .btn.cc-art{flex:1 1 0;color:#9ebbc9}

/* 重新產生的圖放彈窗：一張結算圖很高，塞進開場會把「創造角色」推到天邊。 */
.career-art-box{width:min(560px,94vw);max-height:88vh;overflow-y:auto}
.career-art-box h3{margin-right:34px}
.career-art-wait{padding:26px 0;text-align:center;color:var(--dim);font-size:13px}

/* 開場表單：姓名／守位／慣用手／型態／高中／志向 */
.field{margin-top:20px;animation:fieldIn .32s var(--ease-pop) backwards}
/* 精靈的欄位用 hidden 屬性切換（renderWizard() 依 [data-wg] 分組控制）。
   本專案踩過兩次「元素自己宣告了 display，hidden 就失效」的坑（#v2-nav、#bd-menu-panel），
   這裡先補上防線。 */
[data-wg][hidden]{display:none!important}
@keyframes fieldIn{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
/* 依序出現的錯落感:同一個容器裡的第 1、2 個 .field 錯開一點點開始播,純 CSS,不靠 JS 補 class。
   姓名/種子固定顯示在最上面,各步驟切換時也會重播一次這個小錯落(刻意的,當作切換回饋)——
   延遲刻意壓得短(.1s),不然每點一次上一步/下一步都要等快一秒才看到完整內容,反而顯得卡。 */
.field:nth-of-type(1){animation-delay:.05s} .field:nth-of-type(2){animation-delay:.1s}
.field label{display:block;font-size:11.5px;letter-spacing:.14em;color:#a9c7d7;font-weight:700;margin-bottom:8px}
.hand-preview{margin-top:8px;padding:8px 10px;border:1px solid #31536a;border-radius:var(--r-s);background:#0c1d2b;color:#b9d0db;font-size:11px;line-height:1.65}
.hand-preview b{color:var(--amber)}
/* 精靈區塊的區段標題:比一般 .field label 大一號,宣告「底下這一整塊都是同一件事」 */
/* 改成 flex 排版：文字+說明按鈕+特色標籤同一列，螢幕太窄才自動換行 */
.section-title{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;margin:24px 2px 10px;font-size:14px;letter-spacing:.1em;color:var(--cream);font-weight:800}
.field input{width:100%;background:#0e1f2f;border:1px solid #2f5268;border-radius:var(--r-m);color:var(--chalk);
  font-family:var(--sans);font-size:16px;padding:12px 14px;outline:none;transition:border-color .15s,box-shadow .15s}
.field input:focus{border-color:var(--amber);box-shadow:0 0 0 3px #e0ac4c22}
.seg{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.hp-note{display:block}
.seg.two{grid-template-columns:repeat(2,1fr)}
.seg.school{grid-template-columns:repeat(3,1fr)}
.seg.school button{font-size:12.5px;padding:10px 3px}
.seg button{position:relative;overflow:hidden;background:#101f30;border:1px solid #2f5268;border-radius:var(--r-m);color:var(--dim);
  font-family:var(--sans);font-size:14px;font-weight:700;padding:11px 4px;cursor:pointer;min-height:48px;transition:border-color .15s,background .2s,transform .1s}
.seg button:active{transform:scale(.97)}
.seg button.on{background:linear-gradient(135deg,#233f2f,#1a3428);color:var(--amber);border-color:var(--amber);box-shadow:0 0 0 1px #e0ac4c30,inset 0 0 0 1px #e0ac4c18}
.seg button small{display:block;font-size:10px;font-weight:400;color:var(--dim);line-height:1.35;margin-top:2px}

/* 姓名（含隨機取名骰子）／世界種子（含說明按鈕）：固定顯示，不隨步驟切換 */
.name-row{display:flex;gap:8px}
.name-row input{flex:1}
.dice-btn{flex:none;width:48px;height:48px;font-size:20px;background:#101f30;border:1px solid #2f5268;
  border-radius:var(--r-m);cursor:pointer;transition:border-color .15s,transform .1s}
.dice-btn:active{transform:scale(.94) rotate(-8deg)}
.dice-btn:hover{border-color:var(--amber)}
/* 不綁定在 .field label 底下,讓 .section-title 這類非 .field 的標題也能套用 */
.info-btn{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;
  margin-left:4px;border-radius:50%;background:#2f5268;color:#cfe0ea;border:0;font-size:10px;font-weight:700;
  cursor:pointer;vertical-align:middle;letter-spacing:0;transition:background .15s}
.info-btn:hover{background:var(--amber);color:#241a08}
.seed-row{display:flex;align-items:center;gap:10px;background:#0a1a2699;border:1px solid #294d64;
  border-radius:var(--r-m);padding:8px 12px}
.seed-row input{flex:1;background:transparent;border:0;color:var(--amber);font-family:var(--mono);
  font-size:13px;outline:none;padding:2px 0}
.seed-row a{flex:none;color:var(--blue);font-size:12px;text-decoration:none;border-bottom:1px dashed currentColor}

/* 分步驟精靈：守位設定／球員風格／出身與志向 三步，姓名跟種子在精靈外面，全程看得到 */
#wizard{margin-top:24px;background:linear-gradient(160deg,#0f2032cc,#0a1826cc);border:1px solid #2f5268;
  border-radius:var(--r-l);padding:18px 18px 16px;box-shadow:var(--sh-m)}
.wiz-progress{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}
.wiz-dots{display:flex;gap:7px}
.wiz-dot{width:22px;height:6px;border-radius:99px;background:#2f5268;border:0;padding:0;cursor:pointer;transition:background .2s,width .2s}
.wiz-dot.on{background:var(--amber);width:30px}
.wiz-dot.done{background:#5fb28f}
.wiz-label{font:10px var(--mono);letter-spacing:.08em;color:#8fb3c5}
.wiz-step .field:first-child{margin-top:14px}
.wiz-note{margin-top:14px;color:var(--dim);font-size:12px;line-height:1.6}
.wiz-nav{display:flex;gap:10px;margin-top:20px}
.wiz-nav .btn{margin-top:0}
/* 第一步沒有「上一步」時整排只剩「下一步」,靠 display:none(而不是 visibility:hidden)
   讓「下一步」不會被一塊看不見但還占著版面的空間往右擠,維持真正置中/滿版 */
#wiz-prev{flex:none;width:112px;text-align:center;display:none}
#wiz-next,#btn-start{flex:1;text-align:center}
.start-disclaimer{display:grid;gap:5px;margin:16px 0 6px;padding:13px 14px;border:1px solid #a78bfa45;
  border-left:3px solid #a78bfa;border-radius:var(--r-m);background:linear-gradient(100deg,#8b5cf617,#12263a80);
  color:#b5c7d1;font-size:12px;line-height:1.8}
.start-disclaimer b{font:11px var(--mono);letter-spacing:.14em;color:#e2d9fa}

/* 種子說明彈出視窗 */
.modal-overlay{position:fixed;inset:0;z-index:70;background:#04090fb3;backdrop-filter:blur(3px);
  display:flex;align-items:center;justify-content:center;padding:24px}
.modal-overlay[hidden]{display:none}
.modal-box{max-width:440px;width:100%;max-height:calc(100vh - 48px);max-height:calc(100dvh - 48px);overflow-y:auto;
  background:linear-gradient(160deg,#14293ff2,#0c1c2af2);border:1px solid #3a6178;
  border-radius:var(--r-l);padding:22px;box-shadow:var(--sh-l);animation:modalIn .22s var(--ease-pop) backwards}
@keyframes modalIn{from{opacity:0;transform:translateY(12px) scale(.97)}to{opacity:1;transform:none}}
.modal-box h3{font-size:17px;color:var(--cream);margin-bottom:12px}
.modal-box p{font-size:13.5px;line-height:1.75;color:#c8d8e0}
.modal-box p+p{margin-top:10px}
.modal-box .btn{margin-top:18px}
.modal-forum-btn{margin-left:3px}
.line-community-modal{position:relative;text-align:center;border-color:#dca829a8;background:linear-gradient(155deg,#18344ad9,#0c1c2af5)}
.modal-x{position:absolute;top:11px;right:12px;display:grid;place-items:center;width:28px;height:28px;padding:0;border:1px solid #55778a;border-radius:50%;background:#0b1a27b8;color:#b9cbd5;font:400 23px/1 var(--sans);cursor:pointer;transition:.15s}
.modal-x:hover{border-color:#f0c357;color:#ffe9ad;background:#e5ad2426}
.line-community-modal h3{margin-right:30px;color:#ffe7a7;line-height:1.5}.line-community-modal>p{color:#c5d6df}
.line-community-join{display:inline-flex;align-items:center;justify-content:center;margin-top:12px;padding:10px 24px;border:1px solid #e3b13f;border-radius:999px;background:linear-gradient(135deg,#cf942437,#7f54161c);color:#fff0bf;font-size:14px;font-weight:900;letter-spacing:.06em;text-decoration:none;box-shadow:0 5px 18px #0003;transition:.15s}
.line-community-join:hover{transform:translateY(-2px);background:#d99a1d52;box-shadow:0 8px 22px #0005}
.line-qr-label{margin-top:18px!important;font-size:12px!important;color:#95b0bf!important}.line-qr{display:block;width:min(190px,72vw);height:auto;margin:8px auto 12px;border:5px solid #f7edd5;border-radius:10px;background:#fff;box-shadow:0 6px 18px #0005}
.line-no-remind{display:flex;justify-content:center;align-items:center;gap:7px;margin:4px auto 0;color:#a9bfca;font-size:12px;cursor:pointer}.line-no-remind input{accent-color:#dca829;width:15px;height:15px}
/* 作者資訊區塊:原作者／優化版都用同一種列格式,原作者放最上面優先強調 */
.credit-block{background:#0a1a2680;border:1px solid #2f5268;border-radius:var(--r-m);padding:10px 12px;margin-bottom:14px}
.credit-row{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;font-size:13px}
.credit-row+.credit-row{margin-top:8px;padding-top:8px;border-top:1px dashed #2f5268}
.credit-label{flex:none;font:10px var(--mono);letter-spacing:.08em;color:#8fb3c5;background:#16324a;
  border-radius:4px;padding:2px 6px}
.credit-row b{color:var(--cream);font-size:14px}
.credit-row a{color:#ffda81;text-decoration:none;border-bottom:1px solid #ffce6355;font-size:12px}
.modal-divider{margin-top:16px;font:10px var(--mono);letter-spacing:.2em;color:#7fa1b3;
  text-transform:uppercase;border-top:1px solid #2f5268;padding-top:14px}
/* 更新日誌彈窗的摘要清單：一條一行，前面一個琥珀色小方塊當項目符號。
   這裡刻意只放摘要——完整內容在 update.html，彈窗塞不下也沒人會讀。 */
/* 更新日誌摘要（2026-09-09 改成「圖示＋分類標題 → 逐項」）：原本每一條前面都自己
   標一次分類（「新增功能｜…」），十條看下來很雜。分類抽成標題，底下才列項目。 */
.update-brief{margin-top:12px}
.update-brief h4{margin:14px 0 7px;font-size:13px;letter-spacing:.06em;color:var(--amber);
  font-weight:700}
.update-brief h4:first-child{margin-top:4px}
.update-brief ul{margin:0;padding:0;list-style:none;display:grid;gap:7px}
.update-brief li{position:relative;padding-left:15px;font-size:13px;line-height:1.7;color:#c8d8e0}
.update-brief li::before{content:'';position:absolute;left:0;top:.62em;width:6px;height:6px;
  border-radius:1px;background:var(--amber);transform:rotate(45deg)}
.update-brief b{color:var(--cream)}
/* 摘要寫細一點之後彈窗會內捲：把「我知道了」釘在可視範圍底部，玩家捲到哪裡
   都關得掉。按鈕本身是實心底色，捲動的內容不會透出來。 */
#update-modal .modal-box .btn{position:sticky;bottom:0;z-index:2}
@media (min-width:480px){.brand-logo{max-width:460px}}
@media (max-width:359px){
  .seg{grid-template-columns:repeat(2,1fr)}
  .seg.school{grid-template-columns:repeat(2,1fr)}
  #bd-top{flex-wrap:wrap;row-gap:4px}
  #bd-name{flex:1 1 auto;min-width:60%}
}

/* ---------- 開場畫面：桌機整合面板（≥1100px）---------- */
.start-side{display:none}
@media (min-width:1100px){
  #start .wrap{max-width:1180px;display:flex;flex-direction:column}
  .start-topband{order:1;max-width:760px;margin:0 auto 14px}
  .start-topband .continue-banner{margin-bottom:16px}
  .start-topband .release-note{margin-bottom:0}
  /* 手機選單限定的項目（分隔線＋主題切換）：桌機的 .about-actions 還是原本行內
     4 顆按鈕的樣子，這兩個新元素不該冒出來多一顆。 */
  .mobile-only{display:none}

  .start-panel{order:3;display:flex;align-items:stretch;border:1px solid #3a6178;border-radius:var(--r-l);
    background:linear-gradient(160deg,#0f2032cc,#0a1826cc);box-shadow:var(--sh-l);overflow:hidden;margin-bottom:28px}
  .start-side{display:block;flex:0 0 300px;padding:26px 24px;border-right:1px solid #2f5268;
    background:linear-gradient(165deg,#16324a80,#0c1c2a80)}
  .start-formcol{flex:1;min-width:0;padding:26px 30px}
  /* 「創造角色」標題現在是 .start-formcol 的第一個子元素（見 index.html 的順序調整），
     這裡的 :first-child 選取器要跟著改，否則會選不到東西變成死規則——桌機面板本身
     已經有 padding，最上面那個元素不需要再疊自己的 margin-top。手機版故意不套這條
     （沿用 .section-title 原本的 margin-top:24px），維持原本上下間距，避免看起來太擠。 */
  .start-formcol .section-title:first-child{margin-top:0}

  /* 桌機版作品聲明置於頂部資訊與角色面板之間，避免落到首屏外。撐滿 .wrap（跟
     .start-panel 同寬即可，不需要撐滿整個瀏覽器視窗）——曾經用過 width:100vw+負
     margin 的「滿版出血」寫法讓它跳出 .wrap 撐滿視窗，但 #start 沒有
     overflow-x:hidden，100vw 在有捲軸時會比實際可視寬度寬，直接在 #start 撐出
     左右（連帶上下）捲動、捲了卻沒東西可看，已改回不出血的寫法。 */
  .start-disclaimer{order:2;max-width:none;margin:0 0 16px;padding:12px 24px 0;border:0;border-top:1px solid #1f3a4d;
    border-radius:0;background:none;display:flex;flex-wrap:wrap;align-items:baseline;justify-content:center;
    gap:6px 0;color:var(--dim);font-size:11.5px;line-height:1.7;text-align:center}
  .start-disclaimer b{flex:none;font:800 10px var(--sans);letter-spacing:.1em;color:#7fa1b3;margin-right:12px}
  .start-disclaimer span:not(:first-of-type){margin-left:10px;padding-left:10px;border-left:1px solid #24445a}
}

@media (min-width:1280px){
  .start-disclaimer{flex-wrap:nowrap;white-space:nowrap;font-size:10.5px}
}

/* 角色檔案預覽（.start-side 內容）：跟遊戲內 #dsk-side 同一種視覺語言（圓形頭貼＋
   置中資訊），但這裡的標籤文字（型態/高中/志向）改用比較大、比較粗的無襯線字——
   使用者實測回報原本 10px 等寬字的中文標籤太小、難辨識，這批全部换成 --sans 並加粗。 */
.cp-kicker{display:flex;align-items:center;justify-content:center;gap:8px;font:800 12px var(--sans);letter-spacing:.04em;color:#a9c7d7}
.cp-badge{font-family:var(--sans);font-size:10.5px;font-weight:800;letter-spacing:.04em;color:#241a08;
  background:var(--amber);border-radius:999px;padding:2px 9px}
.cp-avatar{width:100px;height:100px;border-radius:50%;object-fit:cover;display:block;margin:14px auto 12px;
  border:3px solid var(--amber);box-shadow:0 6px 16px #00000050;background:#0a1826}
.cp-name{font-size:21px;font-weight:900;color:var(--cream);line-height:1.25;text-align:center;word-break:break-all}
.cp-sub{margin-top:3px;font-size:13px;color:#a9c7d7;letter-spacing:.02em;text-align:center}
.cp-rows{display:flex;flex-direction:column;gap:12px;margin-top:18px;padding-top:16px;border-top:1px dashed #2f5268}
.cp-row{display:flex;flex-wrap:wrap;align-items:baseline;gap:3px 10px}
.cp-row span{flex:none;width:52px;font:800 12.5px var(--sans);letter-spacing:.02em;color:#a9c7d7}
.cp-row b{color:var(--chalk);font-size:14px;font-weight:800}
.cp-row small{flex-basis:100%;color:var(--dim);font-size:11.5px;line-height:1.5}
.cp-seedrow{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:16px;padding-top:14px;
  border-top:1px dashed #2f5268;font-size:12px;color:#a9c7d7}
.cp-seedrow span{font:800 12px var(--sans);letter-spacing:.02em}
.cp-seedrow b{font-family:var(--mono);color:var(--amber);font-size:12.5px;letter-spacing:.02em;word-break:break-all;text-align:right}
.cp-note{margin:14px 0 0;color:var(--dim);font-size:11px;line-height:1.6}

/* ============================================================
   記分板（頂部固定資訊列）
   ============================================================ */
/* #bd-sticky-wrap 是 #scroll-region（見上面「版面容器」）裡的第一個子元素，不是
   整個 #app 的子元素——sticky 定位是相對「最近的可捲動祖先」，所以
   position:sticky;top:0 只會貼在 #scroll-region 自己的可視範圍頂端，不會跟 #act
   搶位置（#act 是 #scroll-region 的平行兄弟，各自有自己的空間，兩者結構上就不會
   重疊)。手機/桌機都是 sticky 貼頂——早期版本手機版拿掉過 sticky（讓頭部跟著內容
   捲走騰空間），使用者實測後反而要求改回來：「還是覺得固定顯示好一點，也有參與
   感」，改用 9.14 的選單橫向排列從另一個方向省空間，不用犧牲頭部的常駐可見性。

   後續（背號機制那輪）#lamps 移出 #board、跟 #board 一起包進 #bd-sticky-wrap：
   sticky 定位改掛在這個外層 wrapper，#board 本身不再自己 sticky（巢狀 sticky
   容易出現非預期的疊層行為，只在最外層宣告一次）；#board 收合/展開只改變自己的
   高度，wrap 整塊（含下面的 #lamps）永遠一起貼頂，#lamps 顯示位置不會受收合/
   展開影響。 */
#bd-sticky-wrap{position:sticky;top:0;z-index:20}
#board{margin:0 -12px;background:linear-gradient(135deg,#132d46,#0c1f30 68%,#173a2e);
  border-bottom:1px solid #47728a;padding:12px 16px 9px;box-shadow:var(--sh-m)}
#bd-top{display:flex;align-items:center;gap:9px}
/* 徽章換成 avatar 頭貼（放大到 42px、圓形、琥珀描邊），跟開場角色卡／桌機側欄
   用同一種頭貼處理手法。頭貼透過 data-src 延遲載入，只在非桌機版面（<1100px，
   #board 才可能實際顯示）才賦值 src——見 script.js 的 syncLazyAvatars()，避免
   桌機玩家（#board 整條被 CSS 隱藏）平白多下載一次這張圖。 */
.bd-avatar-wrap{position:relative;flex:none}
.board-badge{width:42px;height:42px;border-radius:50%;object-fit:cover;border:2px solid var(--amber);
  box-shadow:0 2px 6px #00000040;background:#0a1826}
/* 背號牌疊在頭貼右下角——手機版頭貼只有 42px，牌子跟著縮小，兩位數字級也要
   夠小才塞得下；[hidden] 交給瀏覽器原生行為處理（還沒選背號的業餘階段完全不畫）。
   使用者實測後反映「有點小」，要求放大字體/牌子本身，尺寸從 15px/8.5px 字級
   調到 22px/11px，維持疊在頭貼角落的位置不變。 */
#bd-jersey{position:absolute;right:-3px;bottom:-3px;min-width:22px;height:22px;padding:0 3px;border-radius:999px;
  background:#0d1f2c;border:2px solid var(--amber);color:var(--amber);display:flex;align-items:center;
  justify-content:center;font:800 11px var(--mono);line-height:1;box-shadow:0 1px 5px #0008}
#bd-id{flex:1;min-width:0}
#bd-name{font-weight:900;font-size:16px;letter-spacing:.02em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.3}
#bd-name small{color:var(--dim);font-weight:500;font-size:11px;margin-left:6px}
/* 「目前狀態」原本是姓名列下面獨立一整行的藥丸樣式，併到姓名正下方當副標題行，
   省掉一整行；不再是獨立的 pill（背景/邊框都拿掉），純文字更省高度。

   #bd-status-row 是後續加的：「詳細資料」展開鈕要跟這行共用同一條，不能塞進
   #bd-team 的 innerHTML 裡（board() 每次都整個重寫 #bd-team.innerHTML，塞在
   裡面會被清掉）。用 margin-left:auto 把展開鈕推到最右邊，不是 justify-content:
   space-between——後者會把 #bd-team 內部原本緊貼在一起的「標籤/圓點/球隊名」
   三個 <span> 也一起打散拉開，同一批 mockup 踩過這個坑。 */
#bd-status-row{display:flex;align-items:center;gap:8px;margin-top:1px}
#bd-team{flex:1;min-width:0;font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.status-label{color:#8fa9b8;font-weight:500}.status-team{font-weight:800}
#bd-detail-toggle{flex:none;margin-left:auto;background:transparent;border:none;color:#8bacbd;
  font-family:var(--sans);font-size:10.5px;font-weight:700;white-space:nowrap;cursor:pointer;padding:2px 0}
#bd-detail-toggle b{color:#8bacbd;font-weight:700;margin-left:1px}
#bd-detail-toggle:active{color:var(--amber)}
#bd-detail-toggle:active b{color:var(--amber)}
/* 「閱讀模式」「重新開始」「主題切換」「複製種子代碼」收進 #bd-menu-btn 觸發的
   #bd-menu-panel 下拉選單（跟開場 #mobile-menu-btn 是同一套開關邏輯，見
   script.js）。這四項曾經在 r11 那輪拿出選單改放姓名列右側，理由是「藏起來玩家
   不知道功能存在」；這次背號機制上線後使用者重新要求收回選單——連同新增的複製
   種子代碼，姓名列右側放不下四顆按鈕，選單比逐一攤開更適合。 */
#bd-quick{flex:none;position:relative}
#bd-menu-btn{background:#0a1826;border:1px solid #2c4e64;color:#b9cfda;border-radius:var(--r-s);
  font-size:17px;line-height:1;padding:6px 10px;cursor:pointer}
#bd-menu-btn:active{background:#0f2333;transform:scale(.96)}
#bd-menu-panel{position:absolute;right:0;top:calc(100% + 6px);z-index:25;width:208px;
  background:linear-gradient(135deg,#152c40,#0e2130);border:1px solid #2f5266;border-radius:var(--r-m);
  padding:8px;box-shadow:var(--sh-m);display:flex;flex-direction:column;gap:6px}
#bd-menu-panel[hidden]{display:none} /* 蓋掉上面 display:flex，[hidden] 才真的隱藏 */
#bd-menu-panel button{text-align:left;background:#0a1826;border:1px solid #2c4e64;color:var(--chalk);
  font-family:var(--sans);font-size:12.5px;font-weight:700;border-radius:var(--r-s);padding:8px 10px;cursor:pointer}
#bd-menu-panel button b{color:var(--amber);font-weight:800;float:right}
#bd-menu-panel button.warn{border-color:#8a4b52}
#bd-menu-panel button:active{background:#0f2333}
#bd-menu-panel .dev-tag{float:right}
/* 字體大小調整（.fs-row/.fs-head）：桌機側欄跟遊戲內手機選單（#bd-menu-panel）
   共用同一套 class，之前只有桌機側欄有這顆滑桿（使用者反映「電腦版有、手機版
   沒有」），樣式從桌機專屬的 media query 裡搬出來變成基礎樣式，兩邊都能用；
   #bd-menu-panel 寬度從 180px 加寬到 208px，滑桿才不會擠。 */
.fs-row{background:#0a1826;border:1px solid #2c4e64;border-radius:var(--r-s);padding:8px 10px}
.fs-row .fs-head{display:flex;justify-content:space-between;font-size:12px;color:#b9cfda;margin-bottom:6px}
.fs-row input[type=range]{width:100%;accent-color:var(--amber)}
/* 四張數值卡改成單行「標籤 數字」（原本是數字在上、標籤在下兩行堆疊），
   卡片本身矮了一截；nth-child(3)（綜合）維持原本的皮革米色重點強調，只是
   字級跟著整體縮小，不再用 23px 那麼誇張。

   #bd-grid-wrap 是後續加的收合容器，[hidden] 交給瀏覽器原生行為處理（沒有另外
   宣告 display，不會蓋掉 [hidden] 預設的 display:none），margin-top 從 #bd-grid
   自己搬到 wrap 上，收合時完全不佔版面（原本這裡曾經是一整行只有「詳細資料」
   自己、左邊全空的獨立列，使用者反映「看起來像故意留一條空行」，改成跟
   #bd-status-row 共用同一行才修正）。 */
#bd-grid-wrap{margin-top:9px}
#bd-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:7px}
.bd-cell{background:linear-gradient(180deg,#0a1826,#0d1f2e);border:1px solid #2c4e64;border-radius:var(--r-s);
  padding:6px 4px;text-align:center;white-space:nowrap;overflow:hidden;transition:border-color .3s}
.bd-cell span{font-size:9.5px;color:var(--dim);letter-spacing:.06em}
.bd-cell b{font-family:var(--mono);font-size:13px;font-weight:700;color:var(--amber);margin-left:3px;
  font-variant-numeric:tabular-nums}
/* 綜合力(第3格)當作球員卡的「背號」重點呈現,用皮革米色跟其他三格拉開層級;
   金色留給真正的成就時刻(金卡事件),這裡刻意不用滿飽和金,避免金色被用到爛掉 */
.bd-cell:nth-child(3){background:linear-gradient(160deg,var(--cream),#d8c79f);border-color:#c9b587;box-shadow:0 4px 14px #00000030}
.bd-cell:nth-child(3) span{color:#5c4d33;font-weight:700}
.bd-cell:nth-child(3) b{color:#241a08;font-size:14px}
.bd-cell.stat-up{border-color:var(--good)!important;box-shadow:0 0 0 1px var(--good) inset,0 0 10px #6fcf9c55;transition:border-color .2s,box-shadow .2s}
.bd-cell.stat-down{border-color:var(--bad)!important;box-shadow:0 0 0 1px var(--bad) inset,0 0 10px #ff7f6b55;transition:border-color .2s,box-shadow .2s}
/* #lamps 移出 #board 之後（見上面 #bd-sticky-wrap 說明），自己補一條分隔線跟
   底色，維持「這是資訊卡的一部分、不是漂浮在外面」的視覺關聯，不受 #board
   收合/展開影響、永遠顯示。 */
#lamps{display:flex;gap:12px;justify-content:center;padding:8px 4px;margin:0 -12px;
  background:#0d1f2c;border-bottom:1px solid #2c4e64}
.lamp{display:flex;align-items:center;gap:5px;font-size:10px;color:var(--dim);letter-spacing:.08em}
.lamp i{width:8px;height:8px;border-radius:50%;background:#20374a;border:1px solid #345368;display:inline-block;transition:background .3s,box-shadow .3s}
.lamp.on{color:var(--chalk)} .lamp.on i{background:var(--amber);box-shadow:0 0 8px var(--amber);border-color:var(--amber)}
@media (max-width:359px){#bd-top{flex-wrap:wrap;row-gap:4px}#bd-id{flex:1 1 auto;min-width:60%}}
/* 精簡模式：一般卡片內文用 line-clamp 收成 3 行預覽，靠原生 DOM 渲染裁切，
   不是字串截斷(不會切壞裡面的 <b>/<span> 標籤)；「展開全文」按鈕點了才拿掉裁切。
   重大時刻卡(.major)一律不裁切，保留完整敘事份量。 */
/* max-width 故意跟卡片實際寬度脫鉤：桌機版 #app 最寬到 760px，如果讓文字用滿整個
   卡片寬度再裁行數，寬螢幕一行能塞的字數暴增，裁了幾乎等於沒裁。固定一個手機尺寸的
   寬度讓斷行行為在各種螢幕寬度下一致。裁 2 行（不是 3 行）：這個專案的卡片文案本來
   就偏精簡（多半 1-2 句），3 行幾乎每張卡都完整顯示，精簡模式感覺不出差異；改 2 行
   後大多數稍有敘事份量的卡片才會真的被裁到，「展開全文」才有存在感。 */
.cbody-clip{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;max-width:400px}
.cbody-more{display:block;background:none;border:0;color:var(--dim);font-size:11.5px;text-decoration:underline dashed;
  text-underline-offset:3px;padding:4px 0 0;cursor:pointer;font-family:var(--sans)}
.cbody-more:hover{color:var(--amber)}

/* ---------- 球員檔案卡（守位／武器庫）---------- */
/* 內容跟記分板副標題／生涯中控台(主頁+養成分頁)重複,拿掉這塊常駐版面,把空間還給故事內容。
   JS 仍會照常寫入 ch-role/ch-plan/ch-tools,只是不顯示,不用動 script.js。
   (下面 #clubhouse>div 等描述性樣式保留但已無效,是刻意的——之後想重新啟用只要刪掉這行 display:none) */
#clubhouse{display:none!important;grid-template-columns:1fr 1.3fr;gap:1px;margin:0 0 2px;background:#2c4e64;border:1px solid #2c4e64;
  border-radius:0 0 var(--r-l) var(--r-l);overflow:hidden;box-shadow:var(--sh-s)}
#clubhouse>div{background:linear-gradient(135deg,#0e2130,#0a1a26);padding:9px 12px;min-height:54px}
.club-label{display:block;color:#7fa1b3;font:9px var(--mono);letter-spacing:.1em;margin-bottom:2px}
#ch-role{display:block;color:#f4d493;font-size:13px;letter-spacing:.02em}
#ch-plan{display:block;color:#b3c6cf;font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#ch-tools{display:flex;gap:4px;flex-wrap:wrap;margin:2px 0 0}
#ch-tools span{display:inline-block;background:#16324a;border:1px solid #35617a;border-radius:999px;padding:1px 7px;font-size:10px;color:#d8ebf3}
.twtool{border-color:#e2a44e!important;color:#ffe0a3!important}

/* ============================================================
   生涯紀錄（事件卡／年度區塊）
   ============================================================ */
/* flex:1 不再需要——#log 現在是 #scroll-region 裡跟著內容自然排版的最後一個區塊，
   不用再搶「跟誰分還剩下的高度」，捲動範圍完全交給 #scroll-region 自己處理。 */
#log{padding:16px 2px 4px;display:flex;flex-direction:column;gap:12px}
@media (min-width:700px){#log{padding-left:6px;padding-right:6px}}
.card{position:relative;background:linear-gradient(135deg,#132a3d,#0d1f2c);border:1px solid #2f5266;
  border-radius:var(--r-l);padding:0 15px 15px;animation:pop .4s var(--ease-pop) backwards;overflow-wrap:anywhere;overflow:hidden;box-shadow:var(--sh-s)}
/* overflow:hidden 本身就會建立新的區塊格式化上下文、自動包住內部浮動元素,不再需要額外的 clearfix ::after */
@keyframes pop{from{opacity:0;transform:translateY(16px) scale(.96)}to{opacity:1;transform:none}}
/* 進場掃光:預設每張卡都有一點(白色、低調),金卡另外疊加更亮更暖的版本 */
.card::before{content:'';position:absolute;inset:0;pointer-events:none;z-index:1;
  background:linear-gradient(115deg,transparent 30%,#ffffff22 45%,#ffffff38 50%,#ffffff22 55%,transparent 70%);
  background-size:250% 100%;background-position:150% 0;animation:shine 1.3s ease-out .15s 1}
.card.gold::before{background:linear-gradient(115deg,transparent 30%,#ffe6a34a 45%,#fff6d966 50%,#ffe6a34a 55%,transparent 70%)}
@keyframes shine{to{background-position:-60% 0}}
/* 桌機（≥1100px）：進場掃光帶是百分比漸層，跟著卡片等比放大——850px 寬的卡上
   40% 寬的光帶會變成蓋住半張卡、持續一秒多的大片模糊色塊（gold 卡最明顯，
   版面審視實測回報「像污漬」）。桌機把色帶收窄＋透明度降低，維持「一道光掃過」
   的精緻感；shine 動畫本身操作 background-position，覆寫 background 捷徑會重設
   size/position，要一併重新宣告。 */
@media (min-width:1100px){
  .card::before{background:linear-gradient(115deg,transparent 42%,#ffffff14 48%,#ffffff24 50%,#ffffff14 52%,transparent 58%);background-size:250% 100%;background-position:150% 0}
  .card.gold::before{background:linear-gradient(115deg,transparent 42%,#ffe6a32e 48%,#fff6d945 50%,#ffe6a32e 52%,transparent 58%);background-size:250% 100%;background-position:150% 0}
  body:has(#app[data-theme="light"]) .card.gold::before{background:linear-gradient(115deg,transparent 42%,#c47f121f 48%,#c47f122e 50%,#c47f121f 52%,transparent 58%);background-size:250% 100%;background-position:150% 0}
}
/* 重大時刻卡(引退／總冠軍／結婚／MVP等)：更大、票根斜切造型、右上角星徽,跟一般小事件拉開層級 */
.card.major{padding:0 18px 20px;box-shadow:var(--sh-m),0 0 0 1px #e0ac4c30;
  clip-path:polygon(0 0,calc(100% - 22px) 0,100% 22px,100% 100%,22px 100%,0 calc(100% - 22px))}
.card.major::after{content:'★';position:absolute;top:10px;right:16px;font-size:15px;color:var(--amber);
  text-shadow:0 0 10px #e0ac4c80;z-index:1}
.card.major h4{padding-right:44px;font-size:12px}
.card.major p{font-size:15px}
/* 標題改成整條實色標籤帶(票根/球探報告分類籤的感覺),不再只是細線+小圖示 */
.card h4{margin:0 -15px 12px;padding:10px 34px 10px 15px;font-size:11px;letter-spacing:.14em;font-weight:800;
  background:linear-gradient(120deg,#274a63,#1a3348);color:#bcd6e4;text-transform:uppercase;position:relative}
.card h4::after{content:'';position:absolute;right:14px;top:50%;transform:translateY(-50%);
  width:8px;height:8px;border-radius:50%;background:currentColor;opacity:.55}
.card.gold h4{background:linear-gradient(120deg,var(--amber),var(--gold-deep));color:#2a1a06}
.card.bad h4{background:linear-gradient(120deg,#a1493a,#6e2c22);color:#ffe9e5}
.card.good h4{background:linear-gradient(120deg,#3d8462,#245239);color:#e6fbee}
.card.info h4{background:linear-gradient(120deg,#3d76a6,#204a6c);color:#e8f4ff}
.card p{font-size:14px;line-height:1.75} .card p+p{margin-top:5px}
/* 人物台詞列（機遇系統 3.0，2026-10-24）：npcLine() 產生，放在既有卡片內文或選項標題裡。
   左邊圓形頭像（經紀人是插畫、良師／摯友／伴侶是名字首字徽章），右邊名字＋一句話。
   左側色條跟著人物種類走，讓玩家掃過去就知道「這句是誰說的」。 */
.npc-line{display:flex;align-items:flex-start;gap:10px;margin:9px 0 3px;padding:8px 11px 8px 9px;
  border-radius:10px;border-left:2px solid var(--npc-c,var(--amber));
  background:linear-gradient(90deg,#ffffff0d,#ffffff04 70%,transparent);text-align:left}
.npc-line:first-child{margin-top:2px}
.npc-k-mentor{--npc-c:#6fb8ea} .npc-k-friend{--npc-c:#6fcf9c} .npc-k-partner{--npc-c:#ef8fb0} .npc-k-agent{--npc-c:var(--amber)}
.npc-ava{flex:none;width:34px;height:34px;border-radius:50%;overflow:hidden;display:inline-flex;align-items:center;justify-content:center;
  box-shadow:0 0 0 1.5px var(--npc-c,#e0ac4c),0 2px 6px #0005;margin-top:1px}
.npc-ava svg{width:100%;height:100%;display:block}
.npc-badge{font-weight:800;font-size:15px;line-height:1;color:#fff;letter-spacing:0}
.npc-badge.npc-mentor{background:linear-gradient(135deg,#4a8cc4,#24557f)}
.npc-badge.npc-friend{background:linear-gradient(135deg,#4ea97b,#26674a)}
.npc-badge.npc-partner{background:linear-gradient(135deg,#d77799,#94405f)}
.npc-txt{min-width:0;flex:1}
.npc-who{display:block;font-size:11.5px;letter-spacing:.04em;color:var(--dim);line-height:1.5}
.npc-who b{color:var(--chalk);font-weight:700}
.npc-say{display:block;font-size:13.5px;line-height:1.65;color:var(--chalk)}
.npc-cands{display:grid;grid-template-columns:1fr;gap:2px}
@media (min-width:700px){.npc-cands{grid-template-columns:1fr 1fr;gap:10px}}
#act .title .npc-line{margin:8px 0 2px;font-weight:400;letter-spacing:0}
.npc-fx{display:block;margin-top:2px;font-size:12px;color:var(--good);letter-spacing:.02em}
.npc-fx::before{content:'＋ ';opacity:.7}
.npc-rollcall{margin-top:14px;padding-top:10px;border-top:1px dashed #ffffff26}
.npc-rollcall-h{display:block;font-size:11px;letter-spacing:.24em;color:var(--amber);font-weight:800;margin-bottom:2px}
.impact-tags{display:flex;flex-wrap:wrap;gap:5px;padding:9px 15px 0;position:relative;z-index:2}
.impact-tags span{border:1px solid #52758a;background:#0a1b29;color:#b8d1de;border-radius:999px;padding:2px 7px;font-size:10px;font-weight:700;letter-spacing:.03em}
.impact-tags span:nth-child(2){border-color:#7d669a;color:#dfd0fa}.impact-tags span:nth-child(3){border-color:#8b6b3b;color:#f0d093}
/* 決策回執（2026-09-09）：card() 帶了第 4 個參數時出現，把「你剛剛選了什麼」
   跟底下的效果條列接起來。刻意畫在 .cbody 外面——精簡閱讀模式會裁 .cbody。
   語氣色不跟卡片走（good/bad 的卡都可能是同一個選擇的結果），一律中性。 */
/* 2026-09-09 改樣式：第一版是深藍實心方框（比卡片底色還深），讀起來像卡片被挖了
   一個洞、也像唯讀輸入框。改成左側一條琥珀實色條＋往右淡出的光暈，不畫外框——
   有存在感但不會被當成另一個元件，左邊那條也跟卡片語氣色的標題帶呼應。 */
.card.result .receipt{display:flex;align-items:center;gap:10px;margin:10px 15px 0;
  padding:7px 12px;border:0;border-left:3px solid var(--amber);border-radius:0 6px 6px 0;
  background:linear-gradient(90deg,rgba(224,172,76,.16),rgba(224,172,76,.04) 60%,transparent)}
.card.result .receipt span{color:var(--amber);opacity:.9;font-size:10.5px;letter-spacing:.12em;
  font-weight:700;flex:none}
.card.result .receipt b{color:var(--chalk);font-size:14.5px;line-height:1.4;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 年度回顧把這一年最值得記住的四件事壓成一張可掃讀的卡。 */
.card.recap{border-color:#496f84;background:linear-gradient(135deg,#17364d,#0b1d2c)}
.share-card{overflow:hidden;border-color:#4c7592;background:linear-gradient(145deg,#17364d,#0a1826)}
.share-preview{margin-top:12px;padding:8px;background:linear-gradient(145deg,#091522,#17364d);border:1px solid #b88a3c66;border-radius:var(--r-m);box-shadow:inset 0 0 0 1px #ffffff08}
.share-preview img{display:block;width:100%;border-radius:var(--r-s);border:1px solid #315a78;background:var(--bg)}
.share-actions{display:flex;gap:8px;margin-top:10px}
.share-actions .btn{flex:1}
.recap-grid{display:grid;grid-template-columns:1fr 1fr;gap:7px;padding-top:2px}
.recap-grid>div{background:#091a27;border:1px solid #2d5064;border-radius:9px;padding:8px}
.recap-grid span{display:block;color:#83a8ba;font-size:10px;letter-spacing:.08em;margin-bottom:4px}
.recap-grid b{display:block;color:#e1edf1;font-size:12px;line-height:1.55}.recap-sub{color:#f0cc78}
.recap-honors{margin-top:8px;padding:7px 9px;border-left:2px solid var(--amber);background:#d99d2420;color:#f3d98f;font-size:12px;line-height:1.6}
.tag{display:inline-block;font-family:var(--mono);font-size:12px;padding:0 6px;border-radius:4px;
  background:#0a1826;border:1px solid var(--edge);color:var(--amber);margin:0 2px}
.up{color:var(--good);font-weight:700}.dn{color:var(--bad);font-weight:700}.hl{color:var(--amber);font-weight:700}
.muted,.sub{color:var(--dim)}
.statline{font-family:var(--mono);font-size:12px;color:var(--chalk);background:#0a1826;border:1px dashed #3a6178;
  border-radius:var(--r-s);padding:8px 9px;margin-top:6px;line-height:1.7}
/* 資訊分層：球季數據卡先給幾個核心數字，完整數據收進原生 <details>，
   第一眼乾淨、想看的人還是點得到 */
.stat-headline{font-family:var(--mono);font-size:13px;color:var(--chalk);margin-top:6px;letter-spacing:.01em}
.stat-headline b{color:var(--amber);font-weight:700}
.stat-full{margin-top:4px}
.stat-full summary{cursor:pointer;font-size:11.5px;color:var(--dim);list-style:none;display:inline-block;
  padding:2px 0;border-bottom:1px dashed #3a617880}
.stat-full summary::-webkit-details-marker{display:none}
.stat-full summary::before{content:'▸ ';display:inline-block;transition:transform .15s}
.stat-full[open] summary::before{transform:rotate(90deg)}
.stat-full .statline{margin-top:6px}
/* 逐年紀錄等寬表格的局部捲動容器（scrollTableWrap()，script.js）：儲存格 nowrap
   只透過這個容器的後代選擇器套用——沒被捲動容器包住的表格外層常是
   .card{overflow:hidden}，直接對 table.fin 全域 nowrap 會讓超寬內容被裁掉、
   連捲動的機會都沒有。.tbl-scroll-hint 是手機限定的「可左右滑動」提示，
   桌機表格放得下、不需要。 */
.tbl-scroll{overflow-x:auto}
.tbl-scroll table th,.tbl-scroll table td{white-space:nowrap}
.tbl-scroll-hint{display:none}
/* 生涯累積數據這種「一列資料、十幾二十欄」的摘要表（table.sum，見 endgame.js 的
   sumTable()）：手機上不用表格排，改成「欄名＋數值」兩欄堆疊。
   實測投手 14 欄、野手 20 欄，390px 就算字縮到 10.5px、內距壓到 2px 仍需要 535px——
   橫向捲動治不好，玩家讀起來累、截圖分享一定被切掉（2026-09-12 玩家回報）。
   **逐年年表不要套這個**：那是幾十列的表，堆疊後會變成很長一條，它走 .tbl-scroll。 */
@media (max-width:699px){
  table.fin.sum,table.st.sum{display:block;margin-top:4px}
  table.fin.sum tr:first-child,table.st.sum tr:first-child{display:none}  /* 表頭改由每格自己帶 */
  table.fin.sum tr,table.st.sum tr{display:grid;grid-template-columns:1fr 1fr;gap:0 12px}
  table.fin.sum td,table.st.sum td{display:flex;align-items:baseline;justify-content:space-between;
    gap:8px;padding:5px 2px;text-align:right;white-space:nowrap}
  table.fin.sum td::before,table.st.sum td::before{content:attr(data-l);color:var(--dim);
    font-size:10.5px;letter-spacing:.02em;flex:none}
  /* 欄名較長的（AVG/Max km/h、OAVG/OSLG、CS/PB/CERA）獨佔整列，才不會擠成兩行。
     哪些算長由 sumTable() 決定（>7 字元加 .wide），CSS 不重複判斷一次。 */
  table.fin.sum td.wide,table.st.sum td.wide{grid-column:1 / -1}
}
@media (max-width:389px){
  table.fin.sum tr,table.st.sum tr{grid-template-columns:1fr}
}
@media (max-width:699px){.tbl-scroll-hint{display:block;text-align:center;font-size:10.5px;color:var(--dim);padding:3px 0 1px}}
table.fin,table.st{width:100%;border-collapse:collapse;font-family:var(--mono);font-size:13px;margin-top:6px}
table.fin th,table.fin td,table.st th,table.st td{border-bottom:1px solid var(--edge);padding:5px 5px;text-align:right}
table.fin th,table.st th{color:var(--dim);font-weight:500;letter-spacing:.04em}
table.fin td:first-child,table.fin th:first-child,table.st td:first-child,table.st th:first-child{text-align:left}
.yr-head{display:flex;align-items:center;gap:10px;text-align:center;color:var(--dim);font-size:11px;
  letter-spacing:.22em;padding:14px 2px 4px;cursor:pointer;user-select:none;transition:color .15s}
.yr-head::before,.yr-head::after{content:'';flex:1;height:0;border-top:2px dashed #c1432f4a;transition:border-color .15s}
.yr-head:hover{color:var(--amber)} .yr-head:hover::before,.yr-head:hover::after{border-color:#e0ac4c70}
.yr-block.collapsed .yr-body{display:none}
.yr-block.collapsed .yr-head::after{content:' ▸';flex:none;border:none}
.yr-block:not(.collapsed) .yr-head.has-body::after{content:' ▾';flex:none;border:none}
.bar{position:relative}
.bar em{position:absolute;top:-2px;bottom:-2px;width:2px;background:#e0ac4c80;border-radius:1px}
.credits{margin:6px 2px 88px;padding:14px 10px 4px;border-top:1px solid #24445a;text-align:center;color:#7e97a5;
  font:10px var(--mono);letter-spacing:.04em;line-height:1.9}
.credits b{color:#b7cfda;font-weight:700}
.credits a{color:#ffda81;text-decoration:none;border-bottom:1px solid #ffce6355}
.credits a:hover{color:#fff0bd}
.credits .disclaimer{display:block;max-width:560px;margin:14px auto 0;padding-top:12px;border-top:1px dashed #24445a;
  color:#6f8998;font-size:10px;line-height:1.75}

/* ============================================================
   操作區（底部行動表單：選項按鈕／擲骰分配）
   ============================================================ */
/* #act 現在是 #app 底下跟 #scroll-region 平行的 flex 子項目（flex:none，大小
   完全交給內容決定），結構上就不會跟 #scroll-region 裡的任何東西重疊——不用再
   靠 JS 量 #board 高度來算「還剩多少空間」（先前的 syncActMaxHeight() 已經整個
   刪掉），手機版跟桌機版共用同一條規則。max-height 封頂在 45vh：面板內容不長時
   完全沒感覺，選項一多（例如武器開發室常見的 7-8 個選項）就會被這條線卡住、自己
   往內捲動（overflow-y:auto），保證上面的 #scroll-region 至少有視窗 55% 的空間。 */
#act{flex:none;margin:0 -12px;background:linear-gradient(180deg,#0d2032f5,#081420ff);
  border-top:1px solid #3c6580;padding:14px 16px calc(12px + var(--safe-b));box-shadow:0 -10px 26px #0006;
  transition:transform .22s var(--ease-pop),opacity .2s ease;
  max-height:45vh;max-height:45dvh;overflow-y:auto;overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;touch-action:pan-y}
/* .hiding 先播放視覺轉場(仍保留版面空間);轉場結束後才切到 .collapsed 真正 display:none 讓出空間 */
#act.hiding{transform:translateY(30px);opacity:0;pointer-events:none}
#act.collapsed{display:none!important}
/* 行動區的題目（2026-09-09 使用者回報「每一個標題都放大一個字級」）。
   底下用 <small> 帶的說明句（例如選背號那段「選定後將跟著你到引退」）原本會再縮一級，
   變成 9.5px 的長句，實際上根本讀不下去——那是玩家做不可逆決定前唯一的說明，
   單獨給它一個可讀的字級，並拿掉標題用的寬字距。 */
#act .title{font-size:13px;letter-spacing:.08em;color:var(--dim);margin-bottom:8px;font-weight:700}
#act .title small{display:block;margin-top:4px;font-size:12.5px;letter-spacing:.01em;line-height:1.6;color:var(--dim)}
/* 決策分類小標籤(感情/良師/家庭/生涯路線)，貼在選項標題最前面，讓玩家先知道
   「這是什麼類型的決定」再讀細節 */
.choice-kind{display:inline-block;background:#a78bfa22;border:1px solid #a78bfa55;color:#d9cffb;
  border-radius:999px;padding:1px 8px;font-size:10px;letter-spacing:.04em;margin-right:6px;
  font-weight:700;vertical-align:middle}
#act .row2{display:flex;gap:8px}#act .row2 .btn{flex:1;text-align:center}
/* 加點面板的確認／復原鈕（#al-btm）：使用者實測回報手機版分配能力點時，內容一多
   （野手 6-9 項能力）就會被 #act 自己的 45vh 上限卡住往內捲動，確認/復原鈕滑出
   視窗外，沒有明顯的「還可以往下滑」提示，容易被誤以為卡死（投手只有 4 項能力，
   剛好不會踩到，回報的都是野手/捕手）。比照 #act 本身「結構上排除問題」的既有
   原則（見上方 9.13 說明），不是再猜一次高度或加捲動提示，而是讓這排按鈕
   position:sticky 貼在 #act 這個捲動容器的底部——不管上面幾項能力，按鈕永遠留在
   可視範圍內，capped/沒有點數要分配的正常情況（內容本來就矮於 45vh）視覺上完全
   沒有差異。 */
/* 加點面板的批次投入切換列（2026-08-21 QA E1）：pool 模式專用，跟 .pool 那行數字放在
   一起。全部用色票變數，淺色主題自動跟著走，不另外寫一份。 */
#act .al-quick{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin:-4px 0 10px;font-size:12.5px;color:var(--dim)}
#act .al-quick>span{margin-right:2px}
#act .al-quick .al-quick-sep{flex:1;min-width:6px}
/* 「每次投入的量」與「一次做完」之間的細分隔線（2026-09-09）：兩者性質不同，
   但也不該像原本那樣被 flex 撐開到畫面兩端。 */
#act .al-quick .al-quick-div{width:1px;align-self:stretch;margin:2px 4px;background:var(--edge)}
#act .al-quick .al-q{display:inline-block;font-family:var(--sans);font-size:12.5px;font-weight:700;line-height:1;padding:7px 11px;border-radius:999px;
  background:var(--panel);border:1px solid var(--edge);color:var(--chalk);cursor:pointer;user-select:none;transition:border-color .15s,background .15s}
#act .al-quick .al-q.on{background:var(--amber);border-color:var(--amber);color:#1a1205}
#act .al-quick .al-q.off{opacity:.4;cursor:default}
#act .al-quick .al-q:not(.off):active{transform:translateY(1px)}
#act .al-quick .al-q:focus-visible{outline:2px solid var(--amber);outline-offset:2px}
/* 最後一列不被 sticky 的復原／確認鈕蓋住（QA E12） */
#act #al-rows{padding-bottom:6px}
/* 加點面板的標題列（2026-09-13）：標題靠左、復原鈕靠右。復原從底部那排搬上來，
   底部因此只剩一顆「確認」，高度 64px→38px，手機上不再蓋住最後幾列能力條。
   .al-undo 刻意做得比主按鈕小（它是修正用的次要動作，不該跟確認搶視覺重量）。 */
#act .al-head{display:flex;align-items:center;gap:10px;margin-bottom:6px}
#act .al-head .title{flex:1;min-width:0;margin-bottom:0}
/* 2026-09-15 使用者回報「電腦版上顯得太小了，反而不好點」。實測四個視窗都是固定的
   65×30px（桌機、手機都一樣），而同一個面板裡的能力列是 400×46（桌機）／176×64（手機）
   ——復原是整面板最小的點擊目標之一。30px 高在桌機低於舒適的指標目標，在手機更遠低於
   觸控建議的 44px。
   ⚠ **不能單純放大**：上面那條註解寫明它刻意比主按鈕小（次要動作，不該跟「確認」搶
   視覺重量），放大就把那個層級關係破壞掉了。
   ⚠ **不要用 `::after` 負 inset 去外擴命中區**——`.btn` 本身是 `overflow:hidden`
   （漣漪效果要靠它把水波裁在按鈕裡），負 inset 會被直接裁掉，實測外擴 0px。
   改成單純把盒子放大：30×65 → 40×81（面積 +64%）。層級關係還在——主按鈕是滿版
   15px 字、這顆是標題列裡 13px 的小寬度按鈕，一眼就分得出主次。 */
#act .btn.al-undo{flex:none;width:auto;padding:10px 18px;font-size:13px;letter-spacing:.5px;
  text-align:center;min-height:0;line-height:1.5}
/* 分配能力點的期間把 #act 放寬：45vh 是為「選項清單」訂的（要留 55% 給事件卡閱讀，
   見 9.13），但加點畫面此刻沒有事件卡要讀，而捕手有 9 列能力條。
   62vh → 66vh（2026-09-15）：復原鈕放大之後標題列長高 11.5px，把捕手第 9 列擠出可視
   範圍（實測 390×844 只剩 8/9）。**空間從這裡讓回來，不要把按鈕縮回去**——按鈕太小
   本來就是使用者回報的問題；而分配期間沒有事件卡要讀，這 4vh 讓得起。
   驗收線在 regression 4.6.4（9 列全可見 ＋ SE 375×667 的貼底確認鈕仍看得到）。 */
#act.act-alloc{max-height:66vh;max-height:66dvh}
/* 「前往下個階段」閘門（stageGate()）：只有一顆按鈕、沒有標題，內距壓到最小，
   把字卡區的可視高度讓出來——這個功能的重點就是「讓玩家讀得到剛剛發生什麼」。 */
/* 閘門的高度上限（2026-10-09 Android 玩家回報「重來之後起始武器那邊畫面被切掉、不能確認」）：
   原本 max-height:none 是讓閘門不被 #act 的 45dvh 卡住，但 #app 是 overflow:hidden——系統文字放大
   （Android 1.3~1.5 倍很常見）或螢幕較矮時，標題＋說明＋武器格線＋按鈕長得比畫面高，整塊從 #app 底部
   被裁掉，「開始旅程」在畫面外也捲不到（實測 360×640、1.5 倍文字：字卡區已被壓到 0，按鈕只剩 50px）。
   現制：上限 72dvh、#act 本身可捲（繼承 overflow-y:auto），確認鈕 sticky 在 #act 底部——不管清單多長、
   字多大，按鈕永遠看得到、按得到。選擇器加 #app 是為了壓過 ui.css 的 body.dn-stage #act 34dvh。 */
#app #act.act-gate{padding:8px 16px calc(8px + var(--safe-b));max-height:72vh;max-height:72dvh;
  /* 極端情況（2 倍文字＋矮螢幕）連 72dvh 都裝不下時，#act 要肯讓（預設 flex:none 不讓），否則整塊
     還是會從 #app 底部被裁掉。flex-shrink 刻意給一個極小值：flex 的收縮量跟 shrink×basis 成正比，
     字卡區（#scroll-region，shrink 1）會先讓到 min-height:0，閘門最後才縮——正常手機上閘門一個
     像素都不會被壓（實測 360×640 維持 298px）。 */
  flex:0 0.001 auto}
/* 只有起手武器那個變體要保底高度（標題＋sticky 按鈕那一截，格線自己捲）；單顆按鈕的閘門本來就矮
   （回歸 4.50 鎖它「遠矮於一般選項畫面」），不能被這條撐高。 */
#app #act.act-wpick{min-height:150px}
/* 小標題：跟一般選項畫面的 .title 同一種語言（使用者：單一顆按鈕在那邊看起來很怪），
   但字級與間距都壓到最小——整塊連標題帶按鈕約 85px，一般選項畫面是 380~500px。 */
#act.act-gate .title.gate-title{margin:0 0 6px;font-size:12.5px;letter-spacing:1.5px;opacity:.85}
#act.act-gate .btn.gate-btn{margin:0;text-align:center;letter-spacing:1px;position:sticky;bottom:0;z-index:2;box-shadow:0 -8px 14px -6px #0008}

/* 開局起手武器（startingWeaponPick()，2026-09-16）：閘門的變體——標題與「開始旅程」
   中間多一塊可挑選的武器格線。
   ⚠ **這塊擠掉的是「球員誕生」那張歡迎卡的可視空間**（見 9.13：#act 與 #scroll-region
   是平行的 flex 兄弟，#act 的高度是零和的），所以：晶片壓成兩行、格線自己滾動
   （.wp-grid 的 max-height），讓標題與確認鈕不管清單多長都永遠看得到。
   二刀流的清單最長（投球 7 ＋ 打擊／守備 5），這個上限就是衝著它設的。 */
#act.act-wpick{padding:10px 14px calc(10px + var(--safe-b))}
#act.act-wpick .wp-lead{margin:0 0 8px;font-size:12.5px;line-height:1.65;color:var(--dim)}
#act.act-wpick .wp-lead b{color:var(--amber);font-weight:700}
#act.act-wpick .wp-grid{display:grid;gap:6px;grid-template-columns:repeat(auto-fit,minmax(158px,1fr));
  max-height:33vh;max-height:33dvh;overflow-y:auto;margin:0 0 10px;padding-right:2px;
  scrollbar-width:thin;scrollbar-color:var(--amber) transparent}
#act.act-wpick .wp-grid::-webkit-scrollbar{width:6px}
#act.act-wpick .wp-grid::-webkit-scrollbar-thumb{background:var(--edge);border-radius:3px}
/* ⚠ 晶片是 <span role="button">，**不是 <button>**（#act 裡的 <button> 語意是「玩家的
   選項」，自動點擊會在它上面打轉，見 5.9），所以按鈕該有的外觀與焦點框要自己補齊。 */
#act.act-wpick .wp-chip{display:flex;flex-direction:column;gap:2px;align-items:flex-start;text-align:left;
  padding:8px 10px;min-height:44px;border:1px solid var(--edge);border-radius:var(--r-s);
  background:var(--panel2);color:var(--chalk);cursor:pointer;user-select:none;
  transition:border-color .12s,background .12s}
#act.act-wpick .wp-chip b{font-size:14px;letter-spacing:.5px;font-weight:700}
#act.act-wpick .wp-chip small{font-size:11.5px;line-height:1.45;color:var(--dim)}
#act.act-wpick .wp-chip.on{border-color:var(--amber);background:#d99a2426;box-shadow:inset 0 0 0 1px var(--amber)}
#act.act-wpick .wp-chip.on small{color:var(--chalk)}
#act.act-wpick .wp-chip:focus-visible{outline:2px solid var(--amber);outline-offset:1px}
/* 四縫線：看得到、點不動。虛線框是「這不是一個選項」的視覺語言。 */
#act.act-wpick .wp-chip.locked{opacity:.52;cursor:default;border-style:dashed;background:transparent}
/* 矮螢幕（iPhone SE 375×667 那一類）：33dvh 的格線會讓 #act 吃掉 54% 的畫面，
   「球員誕生」那張歡迎卡只剩 152px（實測）。這種螢幕上格線本來就一定要捲，把上限收窄
   換回約 47px 給字卡區，是划算的——捲一下看得完的清單，跟讀不到的歡迎詞，後者比較痛。
   ⚠ 桌機不受影響：ui.css 的 @media (min-width:1100px) 排在這之後載入，同權重時它贏。 */
@media (max-height:720px){
  #act.act-wpick .wp-grid{max-height:24vh;max-height:24dvh}
  #act.act-wpick .wp-chip{min-height:40px;padding:7px 9px}
  #act.act-wpick .wp-lead{margin-bottom:6px;line-height:1.55}
}

/* 淺色主題（2026-09-16 使用者回報「淺色主題下太不容易閱讀」）。三個各自獨立的成因：
   ① **`#act` 在淺色是暖色的**——手機是 `#fff → #eef3f5`、電腦是 `#fdf6e6 → #f7f1e2`
      的奶油色（ui.css 的桌機區塊），而晶片底用的 `--panel2` 是**冷色**的 `#dfe9ec`，
      疊在奶油色上又濁又灰。
   ② **選取狀態讀反了**：未選的灰晶片比選取的（白底＋幾乎看不見的 `#d99a2426` 琥珀霧）
      **更重**，眼睛會把灰的那些當成「被選中」。
   ③ 副標 10.5px 的 `--dim` 疊在淺底只有 4.4，小字級下實際上讀不動。
   修法是把明暗關係整個翻過來：**未選＝白底卡片、選取＝暖琥珀底＋深金描邊**，選取的
   那張永遠是整排裡最暖、最重的一張，不管背後是白的還是奶油色的。
   ⚠ 深色主題一個字都沒動——那邊的明暗關係本來就是對的。 */
body:has(#app[data-theme="light"]) #act.act-wpick .wp-lead{color:#4a5a63}
body:has(#app[data-theme="light"]) #act.act-wpick .wp-chip{background:#fff;border-color:#bfd2d8;color:#0f2338}
body:has(#app[data-theme="light"]) #act.act-wpick .wp-chip small{color:#4a5a63}
body:has(#app[data-theme="light"]) #act.act-wpick .wp-chip.on{background:#fbe8c2;border-color:#8a5a10;
  box-shadow:inset 0 0 0 1px #8a5a10}
body:has(#app[data-theme="light"]) #act.act-wpick .wp-chip.on b{color:#5e3c07}
body:has(#app[data-theme="light"]) #act.act-wpick .wp-chip.on small{color:#3d3016}
/* 鎖定的四縫線：淺色下不要用 opacity 壓（會把字壓到讀不動），改用明確的灰底灰字——
   看得出來「這不是一個選項」，但那行「預設就有，不用選」仍然讀得到。 */
body:has(#app[data-theme="light"]) #act.act-wpick .wp-chip.locked{opacity:1;background:#e9eff1;
  border-color:#c3d5d9;color:#56666e}
body:has(#app[data-theme="light"]) #act.act-wpick .wp-chip.locked small{color:#6b7b83}
body:has(#app[data-theme="light"]) #act.act-wpick .wp-grid::-webkit-scrollbar-thumb{background:#bfd2d8}
/* 閘門小標題在淺色底下 opacity:.85 會糊掉，改用實色。 */
body:has(#app[data-theme="light"]) #act.act-gate .title.gate-title{opacity:1;color:#3c5560}

#act #al-btm{position:sticky;bottom:0;margin-top:10px;padding-top:8px;
  background:linear-gradient(180deg,#0d2032f5 0%,#0d2032f5 30%,#081420 100%);
  border-top:1px solid #3c658066}
/* 收合列：曾經是 position:fixed;bottom:58px 用寫死的視窗座標定位，#act 矮的時候
   常常落在 #act 內部（蓋住選項）而不是它的上緣，而且文字被 font-size:0 藏起來，
   只剩一個沒有說明的小灰色橫條。改成 #act 的正常 flex 手足（它在 DOM 裡本來就緊鄰
   在 #act 前面，flex:none 讓它精確貼在 #act 上緣，不用再猜座標），文字也還原成
   看得懂的「收合／展開」，手機/桌機共用同一個元素，不用分開改。 */
#act-toggle{flex:none;display:block;width:auto;margin:0 -12px -1px;background:#0d2032;
  border:1px solid #2f5266;border-bottom:none;color:#9cbdcf;font-size:12px;font-weight:700;
  letter-spacing:.04em;padding:7px 0;border-radius:var(--r-m) var(--r-m) 0 0;cursor:pointer;
  text-align:center;transition:color .15s,background .15s}
#act-toggle:active{background:#0f2333;color:var(--amber)}
.btn{position:relative;overflow:hidden;display:block;width:100%;background:linear-gradient(135deg,#1a3c56,#12293a);border:1px solid #355971;color:var(--chalk);
  font-family:var(--sans);font-size:15px;font-weight:700;border-radius:var(--r-m);padding:12px 14px;margin-top:8px;
  cursor:pointer;text-align:left;transition:border-color .15s,transform .1s,box-shadow .15s;box-shadow:inset 0 1px #ffffff0c}
.btn:active{transform:scale(.98)} .btn:hover{border-color:var(--amber);box-shadow:inset 0 1px #ffffff0c,0 0 0 1px #e0ac4c30}
.btn small,.choice-detail{display:block;font-weight:400;font-size:12px;color:var(--dim);margin-top:2px}
.btn.main{background:linear-gradient(135deg,#276353,#1b453a);border-color:#5fb28f;text-align:center;
  clip-path:polygon(0 0,calc(100% - 12px) 0,100% 12px,100% 100%,12px 100%,0 calc(100% - 12px))}
.btn.warn{border-color:#8a4b52}
/* 選項橫向排列，省掉直向堆疊佔的高度（見 CLAUDE.md 9.14）。auto-fit+minmax 讓欄數
   自己隨可用寬度決定：手機版窄，落在 2 欄；≥480px（含桌機）欄位下限拉高到 210px，
   落在 3 欄左右——選項變多、變擠時會自動退回更少欄，不用另外寫斷點判斷選項數量。
   落單的最後一項是否要橫跨整排，交給 script.js 的 layoutOptsGrid() 渲染後量測決定
   （CSS 選不出「這是不是最後一排唯一一個」，欄數又是流動的，純 CSS 沒辦法可靠處理）。
   .btn 自己的 margin-top 在這裡歸零，間距全部交給 grid 的 gap 統一控制。 */
.opts-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:8px;margin-top:8px}
@media (min-width:480px){.opts-grid{grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}}
.opts-grid>.btn{margin-top:0}
/* 背號選擇盤（assignJerseyNumber()，見 script.js）：1-99 固定切成 10 欄，跟現實中
   球衣號碼常見的「十位數/個位數」視覺分組一樣，opts-grid 給文字選項用的 150px 最小欄寬
   在這裡會拉出很長一串單欄清單，改用自己的緊湊欄位。 */
.num-grid{display:grid;grid-template-columns:repeat(10,1fr);gap:5px;margin-top:8px}
.num-grid>.btn{margin-top:0;padding:7px 2px;font-size:13px;min-height:34px}
/* 換隊時的「沿用 N 號」主按鈕（2026-10-09）：橫跨整排、放在號碼盤最上面，一鍵帶過。 */
.num-grid>.btn.main{grid-column:1/-1;padding:9px 6px;font-size:14px}
.ripple{position:absolute;border-radius:50%;background:#ffffff2e;transform:scale(0);animation:rippleOut .55s ease-out;pointer-events:none}
@keyframes rippleOut{to{transform:scale(2.4);opacity:0}}

/* 訓練擲骰與能力分配列 */
#dice{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:10px}
.die{width:42px;height:42px;border-radius:9px;background:var(--cream);color:#12251a;font-family:var(--mono);
  font-size:21px;font-weight:700;display:flex;align-items:center;justify-content:center;
  box-shadow:inset 0 -3px 0 #0003;position:relative}
.die::after{content:'';position:absolute;inset:4px;border-radius:6px;border:1.5px dashed #c1432f55}
.die.used{opacity:.2;transform:scale(.9)} .die.active{outline:3px solid var(--amber);outline-offset:2px}
.die.six{color:#b3402f}
.die.die-in{animation:diceIn .34s var(--ease-pop) backwards}
/* 桌機分頁面板整體放大後，42px 的骰子跟旁邊放大過的能力列不成比例（版面審視
   回報），桌機加大一級；手機維持 42px 不動。 */
@media (min-width:1100px){
  .die{width:54px;height:54px;border-radius:11px;font-size:26px}
  .die::after{inset:5px;border-radius:7px}
}
@keyframes diceIn{from{opacity:0;transform:scale(.35) rotate(-18deg)}to{opacity:1;transform:none}}
.pool{font-family:var(--mono);font-size:14px;color:var(--amber);margin-bottom:10px}
.abrow{display:flex;align-items:center;gap:8px;background:var(--panel);border:1px solid var(--edge);
  border-radius:var(--r-s);padding:9px 11px;margin-top:6px;cursor:pointer;user-select:none;min-height:44px;transition:background .15s,border-color .15s}
.abrow:active{background:var(--panel2)}
.abrow .nm{width:70px;font-size:13px;font-weight:700;flex:none}
.abrow .bar{flex:1;height:8px;background:#0a1826;border-radius:4px;overflow:hidden}
.abrow .bar i{display:block;height:100%;background:linear-gradient(90deg,#3f6c50,var(--amber));border-radius:4px;transition:width .25s var(--ease-pop)}
.abrow .val{font-family:var(--mono);width:56px;text-align:right;font-size:13.5px;flex:none;font-variant-numeric:tabular-nums}
.abrow .val b{color:var(--good)}
.abrow.capped{opacity:.42}
.abrow.no-pts{opacity:.55;cursor:default}
.abrow.no-pts:active{background:var(--panel)}
/* 訓練分配改兩欄＋每列一顆「＋」（2026-08-24 使用者要求）：捕手 9 項能力單欄要一直往下滑，
   手機端更明顯。斷點沿用 .v2-grid 的 399px；兩欄下名稱欄與數值欄縮窄，長條自己吃剩餘寬度。
   「＋」刻意用 span[role=button] 不用 <button>——#act 裡的 <button> 語意保留給「玩家的選項」，
   回歸 smoke test 與自動化都抓 #act button，用真 button 會讓它們在這一列上無限打轉。 */
#al-rows.al-2col{display:grid;grid-template-columns:1fr 1fr;gap:6px}
#al-rows.al-2col .abrow{margin:0}
#al-rows.al-2col .nm{width:56px;font-size:12.5px}
#al-rows.al-2col .val{width:48px;font-size:12.5px}
/* 手機端才是「要一直往下滑」最痛的地方，所以兩欄要一路撐到很窄才收回單欄（只有 <340px
   這種極窄裝置才單欄）。窄螢幕下把名稱／數值／＋ 再縮一階，長條吃剩餘寬度。 */
@media (max-width:520px){
  #al-rows.al-2col{gap:5px}
  #al-rows.al-2col .abrow{gap:6px;padding-left:8px;padding-right:8px}
  /* 兩欄下每欄只剩約 176px，名稱＋長條＋數值＋按鈕擠同一行的話長條只剩 20px、讀不出東西，
     還會把「守備範圍」擠成兩行。改成**每格兩行**：上排名稱與「目前值/潛力」，下排長條佔滿
     整格寬度（配合右側的 ＋）。長條因此有約 140px 可用，潛力刻度看得出來，列高只多一點點，
     整體仍遠比單欄九列少滑很多。 */
  #al-rows.al-2col .abrow{flex-wrap:wrap;row-gap:5px;padding-top:7px;padding-bottom:7px}
  /* DOM 順序是 名稱→長條→數值→＋，直接換行會變成「名稱＋長條」一行、「數值＋＋」一行，
     數值跟名稱被拆開。用 order 重排成「名稱＋數值」一行、「長條＋＋」一行，讀起來才連得上。 */
  #al-rows.al-2col .nm{order:1;width:auto;flex:1 1 auto;font-size:12px;white-space:nowrap}
  #al-rows.al-2col .val{order:2;width:auto;flex:0 0 auto;font-size:12px;text-align:right}
  #al-rows.al-2col .bar{order:3;flex:1 1 calc(100% - 30px);min-width:0;height:7px}
  #al-rows.al-2col .al-plus{order:4;width:24px;height:24px;line-height:22px;font-size:14px}
}
@media (max-width:339px){#al-rows.al-2col{grid-template-columns:1fr}}
.al-plus{flex:none;width:26px;height:26px;line-height:24px;text-align:center;border-radius:7px;
  border:1px solid var(--edge);background:var(--panel2);color:var(--amber);font-weight:700;
  font-size:15px;cursor:pointer;user-select:none;transition:transform .12s var(--ease-pop)}
.al-plus:active{transform:scale(.9)}
/* 開季投球規劃的手肘負荷量表（2026-08-24）：畫在 choose() 的標題裡，不另外發一張卡片
   ——投法選的就是手肘負荷，量表跟選項擺在一起玩家才能當場衡量。 */
.tj-gauge{margin:7px 0 2px;font-weight:400}
.tj-gauge>span{display:block;font-size:12px;opacity:.85;letter-spacing:.2px}
.tj-gauge .v2-bar{margin:5px 0 0}
.abrow.capped .al-plus,.abrow.no-pts .al-plus{display:none}
/* 面板內的唯讀能力條（2026-08-24）：跟訓練分配的 .abrow 共用長條與刻度的視覺，
   但不可點、不要有按壓回饋，名稱欄多一行比重／說明文字，所以行高與寬度略放寬。 */
.abrow.static{cursor:default;padding-top:5px;padding-bottom:5px}
.abrow.static:active{background:var(--panel)}
.abrow.static .nm{width:70px}
.abrow.static .nm small{display:block;font-weight:400;font-size:10px;opacity:.72}
.v2-abwrap{display:flex;flex-direction:column;gap:4px;margin-top:6px}
/* 養成分頁的兩欄版面（2026-08-24）：左欄是能力值（項目多、很長），右欄把健康狀態、
   專長、熟練度疊起來——原本專長／熟練度另外排一列，右欄下半整片空白。
   .locker-side 自己是 grid 的一格，內部再垂直堆疊；窄螢幕時 v2-grid 本來就會收成單欄。 */
/* 兩欄高度會差很多（捕手 9 項能力 vs 右欄三張卡，實測 560px vs 262px），
   若讓右欄只長到內容高度，下面 298px 會露出 .v2-grid 的格線底色，看起來就是一塊灰色空白。
   改成右欄整欄撐滿（grid 預設 stretch），並讓最後一張卡吃掉剩餘高度——整欄都是面板底色，
   沒有裸露的格線。**之後在這個兩欄版面加卡片時，維持「最後一張 flex:1」這個收尾。** */
.locker-side{display:flex;flex-direction:column;gap:1px;padding:0!important;background:#2f5266}
.locker-side>div{background:#0b1f2e;padding:12px}
.locker-side>div:last-child{flex:1}

/* ============================================================
   分頁版面骨架（2026-09-07 重新設計：養成／賽季／檔案）
   ------------------------------------------------------------
   舊版三個分頁各自用 .v2-grid（寫死兩欄）加上一堆 style="margin-top:9px" 的裸 div
   疊出來，而且 .v2-grid 有一條 max-height:640px——**展開狀態也被壓在 640px**，
   超過的部分 overflow:hidden 直接消失，沒有捲軸也沒有提示。實測檔案分頁內容
   1689px、只露得出 640px（人際網絡／球探報告／逐年紀錄／時間線／特性／足跡全部
   看不到），養成分頁 9 項能力只看得到 4 項。這一段就是在修這件事。

   新骨架：12 欄格線，每個區塊自己宣告要吃幾欄（.c4/.c5/.c6/.c7/.c8/.c12），手機一律
   收成整版。**顏色全部走主題變數**（--panel/--panel2/--edge/--chalk/--dim/--amber…），
   深淺色主題自動跟著切，不必再為這一段維護第二份淺色覆寫。
   ============================================================ */
.v2-board{display:grid;grid-template-columns:repeat(12,1fr);gap:1px;background:var(--edge)}
.v2-board>.v2-sec,.v2-board>.v2-col{grid-column:span 12}
.v2-board>.c3{grid-column:span 3}
.v2-board>.c4{grid-column:span 4}
.v2-board>.c5{grid-column:span 5}
.v2-board>.c6{grid-column:span 6}
.v2-board>.c7{grid-column:span 7}
.v2-board>.c8{grid-column:span 8}
.v2-sec{background:var(--panel);padding:13px 14px;min-width:0}
/* .v2-col：一欄裡疊好幾個區塊（例如養成頁右側的健康＋本季計畫）。
   最後一個吃掉剩餘高度，整欄才不會在旁邊那個高欄下方露出格線底色。 */
.v2-col{display:flex;flex-direction:column;gap:1px;background:var(--edge);min-width:0}
.v2-col>.v2-sec:last-child{flex:1}
#v2-panel .v2-sec h5{display:flex;align-items:center;gap:6px;margin:0 0 9px;
  border-left:0;padding-left:0;font-size:11px;font-weight:800;letter-spacing:.1em;color:var(--dim)}
#v2-panel .v2-sec h5 em{margin-left:auto;font-style:normal;font-weight:600;font-size:10.5px;color:var(--dim);opacity:.8;display:flex;align-items:center;gap:4px}
.v2-ic{width:14px;height:14px;flex:0 0 14px;color:var(--amber)}
/* KPI 列：auto-fit，桌機自動 4 格、手機 2 格，不寫死欄數 */
.v2-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(122px,1fr));gap:1px;background:var(--edge);padding:0}
.v2-kpis>div{background:var(--panel);padding:11px 13px;min-width:0}
.v2-kpis span{display:block;font-size:10.5px;letter-spacing:.06em;color:var(--dim)}
.v2-kpis b{display:block;margin:2px 0 1px;font:700 21px/1.25 var(--mono);color:var(--amber);
  font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.v2-kpis b.ok{color:var(--good)}
.v2-kpis b.warn{color:var(--amber)}
.v2-kpis b.bad{color:var(--bad)}
.v2-kpis small{display:block;font-size:10.5px;color:var(--dim);line-height:1.4}
/* 名稱／數值成對的小清單（合約條件、本季計畫…） */
.v2-kv{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:6px 14px}
.v2-kv>div{min-width:0}
.v2-kv span{display:block;font-size:10.5px;color:var(--dim)}
.v2-kv b{font-size:13px;color:var(--chalk);overflow-wrap:anywhere}
/* 賽季頁的主數據 */
.v2-bignum{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.v2-bignum b{font:700 34px/1 var(--mono);color:var(--amber);font-variant-numeric:tabular-nums}
.v2-bignum span{font-size:12px;color:var(--dim);letter-spacing:.08em}
.v2-bignum em{margin-left:auto;font-style:normal;font-size:11px;color:var(--dim)}
.v2-statline{margin-top:9px;padding:8px 10px;border:1px dashed var(--edge);border-radius:var(--r-s);
  font:12px/1.6 var(--mono);color:var(--chalk);overflow-x:auto;white-space:nowrap}
.v2-statline.tw{margin-top:6px;color:var(--dim)}
.v2-note{margin:10px 0 0;font-size:11.5px;color:var(--dim)}
/* 能力值：項目數依守位 4~10 項不等（投手 4、野手 9、捕手 10、二刀另計）。
   auto-fill 自動決定欄數——投手排成 2×2、捕手 2×5，兩邊高度差不會再像舊版那樣
   差到 298px（舊版靠「右欄最後一張卡 flex:1」硬補那塊空白）。 */
.v2-abwrap{display:grid;grid-template-columns:repeat(auto-fill,minmax(196px,1fr));gap:4px 10px;margin-top:6px}
/* 武器卡：數量 0 → 十幾張都可能，auto-fill 網格，不預設固定高度或筆數 */
.v2-wp-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px;margin-top:2px}
/* 150 不是 166：390px 手機扣掉面板邊距＋區塊內距只剩約 338px，166 會差 2px 排不成兩欄（實測只排出一欄，七張武器卡要滑很久）。 */
.v2-wp{border:1px solid var(--edge);border-radius:var(--r-s);padding:9px 10px;background:var(--panel2);min-width:0}
.v2-wp.max{border-color:var(--gold-deep)}
.v2-wp-h{display:flex;align-items:center;gap:6px}
.v2-wp-h svg{width:16px;height:16px;flex:0 0 16px;color:var(--amber)}
.v2-wp-h b{font-size:12.5px;color:var(--chalk);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.v2-wp-h i{margin-left:auto;font-style:normal;font:700 10.5px var(--mono);color:var(--dim)}
.v2-wp-lv{display:flex;gap:2px;margin:7px 0 6px}
.v2-wp-lv i{flex:1;height:4px;border-radius:2px;background:var(--edge)}
.v2-wp-lv i.f{background:var(--amber)}
.v2-wp.max .v2-wp-lv i.f{background:var(--gold-deep)}
.v2-wp small{display:block;font-size:10.5px;color:var(--dim);line-height:1.45}
/* 走勢圖在整版區塊裡不再被 560px 卡住（桌機主欄有 1100px，舊版右半邊整片空白） */
.v2-sec .ovr-trend{max-width:none;overflow:visible}
/* overflow:visible：巔峰／目前的文字標籤畫在資料點正上方，最後一個點貼著右邊界時會被切掉 */
/* 摺疊：grid-template-rows 0fr↔1fr，內容多長都不會被切掉，也不用猜高度 */
/* minmax(0,…) 不能省：`0fr` 這種 fr 軌道的**自動最小值是內容大小**，內容一旦有明確高度
   就收不起來（實測 grid-template-rows 算出來是 900px、面板照樣全開）。寫成 minmax(0,0fr)
   才是真的把軌道最小值鎖成 0。 */
.v2-body{display:grid;grid-template-rows:minmax(0,1fr);transition:grid-template-rows .3s var(--ease-pop)}
.v2-body>div{overflow:hidden;min-height:0}
#v2-panel.collapsed .v2-body{grid-template-rows:minmax(0,0fr)}
@media(max-width:699px){
  .v2-board>.v2-sec,.v2-board>.v2-col{grid-column:span 12!important}
  .v2-sec{padding:12px}
  .v2-bignum b{font-size:30px}
}

/* ============================================================
   生涯中控台（底部分頁與面板）
   ============================================================ */
#v2-nav{position:fixed;z-index:30;bottom:0;left:50%;transform:translateX(-50%);width:min(760px,100%);display:flex!important;
  justify-content:space-around;background:#08141ff7;border-top:1px solid #3c6580;border-radius:16px 16px 0 0;
  padding:6px 8px calc(6px + var(--safe-b));backdrop-filter:blur(14px);box-shadow:0 -4px 18px #0005}
#v2-nav[style*="display:none"],#v2-nav[style*="display: none"]{display:none!important}
#v2-nav button{position:relative;z-index:1;overflow:hidden;border:0;background:transparent;color:#84a5b6;min-width:56px;min-height:44px;padding:2px 8px;font-size:18px;cursor:pointer;border-radius:var(--r-s);transition:color .15s}
#v2-nav button span{display:block;font:10px var(--sans);margin-top:1px}
#v2-nav button.on{color:#ffda81;text-shadow:0 0 14px #e0ac4c66}
/* 分頁圖示改用跟桌機 #dsk-hubtabs 同一組 emoji（2026-08-20 使用者要求跟電腦版
   一致）。emoji 不吃 color 屬性，選中/未選中的區分改用灰階+透明度：未選中的
   圖示降成灰階半透明，選中的恢復全彩——比舊版純文字符號換色更一目了然。 */
#v2-nav button i{font-style:normal;display:block;filter:grayscale(1) opacity(.55);transition:filter .15s}
#v2-nav button.on i{filter:none}
.nav-ind{position:absolute;top:4px;left:0;width:56px;height:calc(100% - 8px);
  background:#6fb8ea16;border:1px solid #6fb8ea3a;border-radius:12px;
  transition:transform .3s var(--ease-pop),width .3s var(--ease-pop);pointer-events:none;z-index:0}
#v2-panel{margin:12px 2px 0;background:linear-gradient(135deg,#132a3d,#0d1f2c);border:1px solid #2f5266;border-radius:var(--r-l);
  overflow:hidden;box-shadow:var(--sh-s);
  clip-path:polygon(0 0,calc(100% - 18px) 0,100% 18px,100% 100%,18px 100%,0 calc(100% - 18px))}
.v2-hero{padding:14px 76px 14px 16px;background:radial-gradient(circle at 85% 20%,#2a6b4e80,transparent 37%),linear-gradient(135deg,#13324a,#0d2131);
  cursor:pointer;position:relative}
.v2-hero::after{content:'詳情 ▾';position:absolute;top:14px;right:14px;font:10px var(--mono);letter-spacing:.04em;color:#0c2030;
  background:var(--amber);border-radius:999px;padding:3px 9px;transition:transform .2s}
#v2-panel:not(.collapsed) .v2-hero::after{content:'收合 ▴'}
.v2-grid,.v2-list{overflow:hidden;max-height:640px;opacity:1;transition:max-height .32s var(--ease-pop),opacity .25s ease}
#v2-panel.collapsed .v2-grid,#v2-panel.collapsed .v2-list{max-height:0;opacity:0;transition:max-height .22s ease,opacity .12s ease}
.v2-kicker{font:10px var(--mono);letter-spacing:.14em;color:#8fcdb5}
.v2-hero h3{font-size:17px;margin:3px 0;color:var(--cream)}
.v2-grid{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:#2f5266}
.v2-grid>div{background:#0b1f2e;padding:12px}
/* 分類標題統一樣式（手機/桌機共用，2026-08-20 使用者要求「分類清楚、一目了然」）：
   原本只有 .v2-grid 裡的 h5 有樣式，career view 那些直接掛在 #v2-panel 底下的
   裸區塊（生涯綜合力走勢/生涯稱號/生涯時間線…）h5 沒人管、也沒有內距，內容
   貼著面板邊緣，分類視覺上糊在一起。改成 #v2-panel 全域統一：amber 左框線當
   分類記號，所有區塊標題同一套視覺語言。 */
#v2-panel h5{font-size:11px;letter-spacing:.12em;color:#a8cbdd;margin:0 0 6px;
  border-left:3px solid var(--amber);padding-left:8px}
/* career view 的裸區塊補內距；details.v2-fold 直接子項也對齊同一條左緣 */
/* .v2-body 是新骨架的外殼，內距由各區塊（.v2-sec）自己出——不排除的話收合之後
   還會留下 14px 的上下內距，看起來像收不乾淨。 */
#v2-panel>div:not(.v2-hero):not(.v2-grid):not(.v2-list):not(.v2-body){padding:10px 14px 4px}
#v2-panel>details.v2-fold{margin-left:14px;margin-right:14px}
.home-grid .v2-primary{background:linear-gradient(145deg,#163a4a,#102a3b)}
.home-grid .v2-primary b{font-size:13px;color:#f4d493;line-height:1.5}.home-grid .v2-secondary{background:#0a1b28}
.home-grid .v2-secondary b{font-size:12px;color:#bfd3dd}.home-grid .v2-secondary small{color:#7e9cab}
.v2-metric{font:700 20px var(--mono);color:#ffda81;font-variant-numeric:tabular-nums}
.v2-chip{display:inline-block;border:1px solid #3f7189;background:#142d40;border-radius:999px;padding:2px 7px;font-size:12px;margin:2px 2px 0 0;color:#d8e9f0}
.v2-chip.gold{border-color:#c8963e;color:#ffe09d}
/* 特性清單超過折疊上限時的「展開全部」按鈕，跟一般特性 chip 拉開視覺差異(虛線邊框) */
.v2-chip-toggle{display:inline-block;border:1px dashed #3f7189;background:transparent;border-radius:999px;
  padding:2px 8px;font-size:12px;margin:4px 0 0;color:#8bacbd;cursor:pointer;font-family:var(--sans)}
.v2-chip-toggle:hover{border-color:var(--amber);color:var(--amber)}
.v2-bar{height:6px;background:#08141f;border-radius:99px;overflow:hidden;margin:4px 0 8px}
.v2-bar i{display:block;height:100%;background:linear-gradient(90deg,#4bb38b,#ffcf66);transition:width .4s var(--ease-pop)}
/* 風險型進度條（2026-08-24）：健康狀態的長條代表「受傷風險」，越長越糟——沿用原本
   綠→黃的漸層會讓人讀成「越滿越好」，方向剛好相反。改成綠→橘→紅：風險低時只有一小截
   綠色，風險高才會一路吃到紅色，長度與顏色同時傳達同一件事。 */
.v2-bar.risk i{background:linear-gradient(90deg,#4bb38b,#e0a33c 55%,#d9534f)}
.v2-list{padding:12px}
/* 生涯綜合力走勢：單一數列折線圖，只用站內既有的 amber 強調色，不另外引入調色盤 */
/* SVG 用 viewBox 等比縮放，容器一變寬（桌機非主頁分頁 #log 隱藏後主欄整個讓給
   面板）整張圖連同 9px 標籤文字都會巨大化、視覺失衡——加 max-width 讓它維持
   合理尺寸，手機寬度本來就窄於這個上限，不受影響。 */
.ovr-trend{display:block;width:100%;max-width:560px;height:auto;margin-top:2px}
.ovr-trend-base{stroke:#ffffff16;stroke-width:1}
.ovr-trend-area{fill:#e0ac4c1e;stroke:none}
.ovr-trend-line{fill:none;stroke:var(--amber);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.ovr-trend-max{fill:var(--amber)}
.ovr-trend-now{fill:var(--chalk)}
.ovr-trend-label{font:9px var(--mono);fill:var(--dim);letter-spacing:.02em}
.v2-list p{border-left:2px solid #4c7688;padding:5px 8px;margin:5px 0;font-size:13px;color:#c2d6de}
/* 行動版預設先交代重點；合約、武器與榮譽的完整清單由玩家主動展開。使用者反映
   「檔案」「賽季」分頁文字偏小、「展開xxx」這類摺疊觸發鈕不夠醒目——原本只是
   純文字+三角形 marker，跟旁邊 <h5> 標題視覺上分不出主次。改成跟既有
   .v2-chip-toggle（特性清單「展開全部」按鈕）同一種虛線膠囊按鈕語彙，拿掉原生
   ::marker 改用可以隨開合旋轉的 ::before 三角形，讓玩家一眼就看得出這是可以
   點的互動元件，不是單純的區塊分隔線。 */
.v2-fold{margin-top:9px;padding-top:9px;border-top:1px solid #2f5266}
.v2-fold summary{cursor:pointer;color:#c9dce5;font-size:13px;font-weight:700;list-style:none;
  display:inline-flex;align-items:center;gap:6px;padding:5px 12px;border:1px dashed #3f7189;
  border-radius:999px;transition:.15s border-color,.15s color}
.v2-fold summary::-webkit-details-marker{display:none}
.v2-fold summary::before{content:'▸';color:var(--amber);font-size:11px;transition:transform .2s var(--ease-pop)}
.v2-fold[open]>summary::before{transform:rotate(90deg)}
.v2-fold summary:hover{border-color:var(--amber);color:var(--amber)}
.v2-fold p{margin:9px 0 0;line-height:1.65;font-size:13px}
.v2-weapon-row+.v2-weapon-row{margin-top:6px}
/* 檔案頁的時間線與球探報告：延續球探筆記感，不做另一個沉重的大面板。 */
/* 生涯時間線的分類篩選（2026-09-09）：沿用 .v2-chip-toggle 的膠囊語彙，
   選中的那顆用實色底，讓「現在在看哪一類」不用讀文字就看得出來。 */
.tl-filter{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 4px}
.tlf{border:1px solid #3f7189;background:transparent;color:#9ebbc9;border-radius:999px;
  padding:3px 11px;font-size:11.5px;font-weight:700;cursor:pointer;font-family:inherit;
  letter-spacing:.02em;transition:border-color .15s,color .15s,background .15s}
.tlf:hover{border-color:var(--amber);color:var(--amber)}
.tlf.on{background:var(--amber);border-color:var(--amber);color:#0a1420}
.career-time-item{position:relative;margin:8px 0 0 7px;padding:0 0 8px 13px;border-left:1px solid #426579}
.career-time-item::before{content:'';position:absolute;left:-4px;top:3px;width:7px;height:7px;border-radius:50%;background:var(--amber);box-shadow:0 0 0 3px #0b1f2e}
.career-time-item span{display:block;color:#e4bd66;font:10.5px var(--mono);margin-bottom:2px}.career-time-item b{display:block;color:#dbe9ee;font-size:13px}
.career-time-item small{display:block;color:#89a5b2;font-size:12.5px;line-height:1.6;margin-top:2px}
.scout-report{margin:10px 0}.scout-report summary{color:#f1cf7c}.scout-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-top:8px}
/* 桌機（≥1100px）：非主頁分頁不再顯示 #log 之後（見 renderV2Panel() 對應修正），
   主欄空出一大片，面板內容顯得又小又擠——使用者附截圖要求把資料卡放大（含
   文字），設計主軸「資訊完整、分類清楚、敘述明瞭」。這整塊只在桌機生效，
   手機版維持緊湊字級不受影響（手機的字級已在同一天稍早那輪調整過）。
   mockup 階段抓到一個坑：生涯綜合力走勢的 SVG 是 width:100% 等比縮放，容器
   一變寬就會巨大化，已在 .ovr-trend 加 max-height:190px 封頂（全域，不只
   桌機——手機直向大螢幕理論上也可能撐大）。 */
@media (min-width:1100px){
  #v2-panel{font-size:14px}
  .v2-hero{padding:20px 90px 20px 22px}
  .v2-hero h3{font-size:22px}
  .v2-hero small{font-size:13.5px}
  .v2-kicker{font:11px var(--mono);letter-spacing:.16em}
  .v2-grid>div{padding:18px 20px}
  #v2-panel h5{font-size:13px;margin-bottom:9px}
  .v2-metric{font:700 28px var(--mono);font-variant-numeric:tabular-nums}
  .v2-chip{font-size:13.5px;padding:4px 11px;margin:3px 3px 0 0}
  .v2-chip-toggle{font-size:13.5px;padding:4px 12px}
  .v2-list{padding:18px 20px}
  .v2-list p{font-size:14px;padding:7px 11px;margin:7px 0}
  .v2-fold{margin-top:12px;padding-top:12px}
  .v2-fold summary{font-size:14px;padding:7px 16px}
  .v2-fold p{font-size:14px}
  #v2-panel table.fin,#v2-panel table.st{font-size:13.5px}
  #v2-panel table.fin th,#v2-panel table.fin td,#v2-panel table.st th,#v2-panel table.st td{padding:7px 7px}
  .career-time-item{margin:12px 0 0 8px;padding:0 0 12px 16px}
  .career-time-item span{font:11.5px var(--mono)}
  .career-time-item b{font-size:14.5px}
  .career-time-item small{font-size:13.5px;line-height:1.65}
  .scout-grid{grid-template-columns:repeat(3,1fr);gap:8px}
  .scout-grid>div{padding:11px}
  .scout-grid span{font:12px var(--mono)}
  .scout-grid b{font-size:13.5px}
  .scout-weapons{font-size:13.5px;padding:10px 12px}
  #v2-panel>div:not(.v2-hero):not(.v2-grid):not(.v2-list){padding:14px 20px 6px}
  #v2-panel>details.v2-fold{margin-left:20px;margin-right:20px}
  .home-grid .v2-primary b{font-size:15px}
  .home-grid .v2-secondary b{font-size:14px}
}
.scout-grid>div{background:#0a1b28;border:1px solid #294d61;border-radius:7px;padding:7px}.scout-grid span{display:block;color:#e2be6e;font:11px var(--mono)}
.scout-grid b{display:block;color:#b9d0da;font-size:12.5px;line-height:1.55;margin-top:3px}.scout-weapons{margin-top:7px;padding:7px 8px;border-left:2px solid #c9973e;background:#c9973e12;color:#adc4cd;font-size:12.5px;line-height:1.65}
/* 多隊報價必須能橫向比較：金額、年限、定位與球隊方向分行呈現。 */
.offer-compare{margin-top:7px;border-top:1px solid #396078;padding-top:7px;text-align:left}
.offer-top{display:flex;justify-content:space-between;gap:8px;color:#e6f1f4;font-size:12px}.offer-top span{color:#f2cd77;font:10px var(--mono)}
.offer-money,.offer-terms{display:grid;grid-template-columns:1fr 1fr;gap:5px;margin-top:6px}
.offer-money span,.offer-terms span{display:block;background:#091925;border:1px solid #28485c;border-radius:6px;padding:5px;color:#9ebbc9;font-size:10.5px;line-height:1.45}
.offer-money b{display:block;color:#ffe09a;font-size:12px}.offer-terms span:first-child{border-color:#5b826b;color:#c7e4d0}
.offer-fit{margin-top:6px;color:#86a6b5;font-size:10.5px;line-height:1.55}
/* 報價的正／負向訊號（2026-09-09）：綠＝確定收益／橙＝要權衡／紅＝明確風險。
   **每一枚都一定帶文字**，顏色只是加速掃讀，不是唯一的資訊來源（色盲／淺色主題）。
   金色留給金額本身，不要再拿來表達「好」——那正是原本讓玩家只看數字大小的原因。 */
/* 多隊報價的排序列（2026-09-09）。**不是 <button>**——`#act` 裡的 button 語意是
   「玩家的選項」，放真的 button 進去會被回歸 smoke test 當成選項無限點擊。
   排序列跟著 choose() 的標題一起畫，所以樣式掛在 .title 底下。 */
.offer-sort{display:flex;align-items:center;flex-wrap:wrap;gap:6px;margin-top:8px;
  font-weight:400;letter-spacing:0}
.offer-sort .lb{color:var(--dim);font-size:11px;letter-spacing:.08em}
.offer-sort .os{border:1px solid #3f7189;border-radius:999px;padding:3px 11px;
  font-size:11.5px;font-weight:700;color:#9ebbc9;cursor:pointer;user-select:none;
  transition:border-color .15s,color .15s,background .15s}
.offer-sort .os:hover{border-color:var(--amber);color:var(--amber)}
.offer-sort .os.on{background:var(--amber);border-color:var(--amber);color:#0a1420}
.offer-sort .os:focus-visible{outline:2px solid var(--amber);outline-offset:2px}
.offer-sort .pin-note{color:var(--dim);font-size:10.5px;letter-spacing:.02em}
.offer-sig{display:flex;flex-wrap:wrap;gap:5px;margin-top:6px}
.offer-sig span{border-radius:999px;padding:2px 9px;font-size:10.5px;font-weight:700;
  border:1px solid;letter-spacing:.02em}
.offer-sig .good{border-color:#4f9c74;background:#0e2a1e;color:#a6e3c2}
.offer-sig .warn{border-color:#a3762c;background:#2b2010;color:#f0cf8e}
.offer-sig .risk{border-color:#b25340;background:#2c1613;color:#f6ab97}
/* 合約比較卡出現在 .btn.main（飽和綠色底）上時的專屬配色（2026-08-21 玩家截圖回報
   「這怎麼閱讀」）：上面那組 .offer-* 顏色是為「一般按鈕的深藍/淺灰底」調的，疊在
   綠色主按鈕上對比嚴重不足——淺色主題尤其明顯（.offer-fit #5b6b74 中灰疊在中彩度
   綠上幾乎看不見，fmtMoneyOrg() 的 (≈…台幣) small 又額外 opacity:.7 再淡一層）。
   .btn.main 在深色/淺色主題都是綠底，所以這組改用「綠底專用」的高對比淺色系；
   淺色主題那份要另外再寫一次，因為 body:has(...) 的 specificity 比 .btn.main 高
   （見本檔案「淺色主題」章節開頭的既有說明，同一個坑踩過好幾次）。 */
.btn.main .offer-compare{border-top-color:rgba(255,255,255,.34)}
.btn.main .offer-top{color:#f2fbf6}
.btn.main .offer-top span{color:#ffe9b0}
.btn.main .offer-money span,.btn.main .offer-terms span{background:rgba(4,26,16,.40);border-color:rgba(255,255,255,.26);color:#dff3e6}
.btn.main .offer-money b{color:#ffe4a6}
.btn.main .offer-terms span:first-child{border-color:#9fe0bd;color:#eafff2}
.btn.main .offer-fit{color:#d9f0e2}
.btn.main .offer-compare small{opacity:.92}
/* 訊號疊在飽和綠底上時，深底色會糊掉——改成淺底深字，維持三種語氣的區別。 */
.btn.main .offer-sig .good{border-color:#bdf0d5;background:rgba(255,255,255,.9);color:#12603d}
.btn.main .offer-sig .warn{border-color:#ffe3a8;background:rgba(255,248,232,.94);color:#7a5310}
.btn.main .offer-sig .risk{border-color:#ffc3b4;background:rgba(255,240,236,.95);color:#8f3323}
@media (max-width:399px){.v2-grid{grid-template-columns:1fr}}
@media (max-width:399px){.recap-grid,.offer-money,.offer-terms{grid-template-columns:1fr}}
@media (max-width:399px){.scout-grid{grid-template-columns:1fr}}

@media (min-width:700px){.card{padding:16px 18px}}

/* ---------- 稱號／特性說明浮框（2026-09-07，src/ui/tooltip.js）----------
   玩家在左欄與「檔案」分頁看得到一堆標籤，卻沒有地方講得出「怎麼拿的」「負面的怎麼解除」。
   **只用 --panel/--edge/--chalk/--dim/--amber/--good 這幾個主題變數上色**，淺色主題那一段
   重新定義同一組變數，所以這裡不用再寫一份淺色規則（唯一的例外是陰影：深色用的黑影在
   淺色底上會髒，下面淺色區塊有一條覆寫）。
   浮框掛在 <body> 底下而不是面板裡——面板有 overflow 捲動，放進去會被裁掉。 */
#trait-tip{position:fixed;z-index:9999;max-width:min(320px,calc(100vw - 16px));
  background:var(--panel);border:1px solid var(--edge);border-radius:var(--r-m);
  box-shadow:var(--sh-m);padding:10px 12px;color:var(--chalk);
  font-size:12.5px;line-height:1.62;pointer-events:none}
#trait-tip[hidden]{display:none}
#trait-tip .tt-hd{display:flex;align-items:center;gap:6px;flex-wrap:wrap;
  margin-bottom:7px;padding-bottom:6px;border-bottom:1px solid var(--edge)}
#trait-tip .tt-hd b{font-size:13.5px;font-weight:800;color:var(--amber);letter-spacing:.01em}
#trait-tip .tt-hd i{font-style:normal;font:600 10.5px/1.5 var(--sans);color:var(--dim);
  border:1px solid var(--edge);border-radius:99px;padding:1px 7px;white-space:nowrap}
#trait-tip .tt-flavor{margin:0 0 7px;color:var(--dim)}
#trait-tip .tt-r{display:grid;grid-template-columns:auto 1fr;gap:4px 8px;margin-top:5px}
#trait-tip .tt-r span{font-size:11px;font-weight:800;color:var(--dim);white-space:nowrap;padding-top:2px}
#trait-tip .tt-r p{margin:0}
#trait-tip .tt-r.ok span{color:var(--good)}
/* 有說明的標籤：滑鼠變成問號游標，正在看的那一枚描邊highlight（觸控裝置只看得到後者） */
[data-tip]{cursor:help}
[data-tip].tip-on{outline:1px solid var(--amber);outline-offset:1px}
/* 欄位標題旁的「?」提示 */
.tip-q{display:inline-flex;align-items:center;justify-content:center;
  width:14px;height:14px;margin-left:4px;border-radius:99px;
  border:1px solid var(--edge);background:transparent;color:var(--dim);
  font:700 10px/1 var(--sans);vertical-align:middle;cursor:help;user-select:none}
.tip-q:hover,.tip-q.tip-on{border-color:var(--amber);color:var(--amber);outline:none}

/* ============================================================
   淺色主題「球場正午」— body:has(#app[data-theme="light"])
   ============================================================
   涵蓋遊戲主畫面 #app（桌機側欄／記分板／事件卡／操作區／生涯中控台）、開場
   設定畫面 #start（角色卡／精靈／版本公告），以及 6 個獨立掛在 body 底下的
   彈窗（種子說明／系統介紹／更新日誌／感謝名單／LINE 社群／創造角色說明——
   這幾個不是 #start 的子孫，是 body 的直接子節點，見「開場畫面」一節的說明）。

   全部規則統一用 `body:has(#app[data-theme="light"]) 選擇器` 這個形式，不是
   分別掛在 `#app[data-theme="light"]`／`#start[data-theme="light"]`——
   `data-theme` 屬性同時掛在 #app 跟 #start 兩個元素上（見 script.js 的
   applyTheme()），但兩者是手足節點，各自的 CSS 自訂屬性作用域互不相通；而且
   前面提到的 6 個彈窗既不在 #app 底下也不在 #start 底下，如果照兩個容器各自
   掛一份的寫法，這些彈窗會被漏掉（**這裡踩過一次真的上線前才發現的坑**：
   `#about-modal` 的確認鈕第一版用 `#app[data-theme="light"] .btn,#start[
   data-theme="light"] .btn` 這種「兩邊都寫一份」的寫法，結果彈窗本身是 body
   的直接子節點、兩個選擇器都選不到，截圖比對時發現彈窗還是深色）。改成統一
   用 `body:has(...)`：body 是 #app／#start／這 6 個彈窗共同的祖先，一個
   選擇器涵蓋全部情境，不用逐一列出容器，之後新增任何跟主題相關的元件（不管
   掛在哪個容器下）都直接照抄這個模式即可。

   色票方向取自「球場正午」提案：冷白背景＋實色色塊，天空藍（--blue）升格跟
   老金同等重要，取代深色主題偏重的柔和漸層——大量 text-shadow 光暈效果在淺色
   底下會變成一層髒污，這裡多半直接拿掉，不是漏掉。

   #dsk-btn-theme／#bd-btn-theme／#btn-theme-mobile／#start-theme-btn（桌機
   開場畫面右上角圖示，見「開場畫面」一節）四顆入口共用同一份切換邏輯，見
   script.js 的 applyTheme()/toggleTheme()/syncThemeBtns()；偏好存在
   localStorage（THEME_KEY），不是存進 S（跟裝置/瀏覽器綁定的設定，不是角色
   存檔的一部分，比照既有的 LINE 社群提醒不再顯示同一種模式）。

   `#app`／`#start` 的基礎規則都明講 `color:var(--chalk)`（不是只靠繼承 body
   算好的值）——CSS 自訂屬性重新定義只在「重新定義的元素自己與其子孫」的作用域
   內生效，但 color 這個屬性走的是「繼承已經算好的值」，不是「繼承時重新解析
   var()」。token 定義在 body 上，body 自己的 color 也會正確重新解析，理論上
   #app/#start 不寫這行也能透過繼承拿到正確結果，但保留這行當一層防線（之後
   如果又有人在 body 跟 #app/#start 中間插入新的容器層、且那層自己設了
   color，這行能避免淺色主題又变回白字配白底）。 */
body:has(#app[data-theme="light"]){
  --bg:#eef3f5; --panel:#ffffff; --panel2:#dfe9ec; --edge:#c3d5d9;
  --chalk:#0f2338; --dim:#5b6b74; --amber:#c47f12; --clay:#b23a26;
  --good:#1f9153; --bad:#cf4632; --blue:#1f6faa;
  --cream:#fff8ea; --gold-deep:#8a5a10; --stitch:#b23a26;
  --sh-s:0 2px 8px #0f233814; --sh-m:0 8px 22px #0f23381c; --sh-l:0 14px 36px #0f233824;
  background-color:#eef3f5;
  background-image:
    radial-gradient(1.2px 1.2px at 12px 18px,#0f233812 100%,transparent),
    radial-gradient(1.2px 1.2px at 46px 52px,#0f23380c 100%,transparent),
    linear-gradient(135deg,#c3d5d966 0%,transparent 35%),
    radial-gradient(ellipse 95% 48% at 50% -10%,#ffffffdd 0%,transparent 70%);
}
/* 桌機側欄 #dsk-side */
body:has(#app[data-theme="light"]) #dsk-side{background:linear-gradient(135deg,#ffffff,#f3f8f9);border-color:#c3d5d9}
body:has(#app[data-theme="light"]) .dsk-sec+.dsk-sec{border-top-color:#d3e2e5}
body:has(#app[data-theme="light"]) .dsk-hero{background:radial-gradient(circle at 50% 20%,#1f915330,transparent 60%),linear-gradient(135deg,#f3f8f9,#e7f0f2)}
body:has(#app[data-theme="light"]) .dsk-avatar{border-color:#1f6faa;box-shadow:0 6px 18px #0f23381f}
body:has(#app[data-theme="light"]) .dsk-team{background:#c47f1218;border-color:#c47f1250;color:#7c530f}
body:has(#app[data-theme="light"]) #dsk-jersey{border-left-color:#c47f1250;color:var(--gold-deep)}
body:has(#app[data-theme="light"]) .dsk-stat{background:linear-gradient(180deg,#f4f9fa,#e7eef0);border-color:#c9dade}
body:has(#app[data-theme="light"]) .dsk-stat b{text-shadow:none}
body:has(#app[data-theme="light"]) .dsk-pstatus.grow b{color:#1f6faa;text-shadow:none}
body:has(#app[data-theme="light"]) .dsk-pstatus.peak b{text-shadow:none}
body:has(#app[data-theme="light"]) .dsk-pstatus.decline b{color:var(--bad);text-shadow:none}
body:has(#app[data-theme="light"]) .dsk-btn{background:linear-gradient(135deg,#ffffff,#eef3f5);border-color:#c3d5d9}
body:has(#app[data-theme="light"]) .dsk-btn.warn{border-color:var(--bad)}
body:has(#app[data-theme="light"]) .dsk-group+.dsk-group{border-top-color:#d3e2e5}
body:has(#app[data-theme="light"]) .dsk-group-h{color:#1f7a49}
body:has(#app[data-theme="light"]) .dsk-theme-row{background:#eef3f5;border-color:#c9dade;color:#3c5560}
body:has(#app[data-theme="light"]) .dsk-theme-row button{border-color:#1f6faa;color:#1f6faa;background:#ffffff}
body:has(#app[data-theme="light"]) .fs-row{background:#eef3f5;border-color:#c9dade}
body:has(#app[data-theme="light"]) .fs-row .fs-head{color:#3c5560}
body:has(#app[data-theme="light"]) .dsk-meta-row{background:#eef3f5;border-color:#c9dade}
body:has(#app[data-theme="light"]) .dsk-meta-row b{color:#1f2f3a}
body:has(#app[data-theme="light"]) .dsk-meta-row button{border-color:#1f6faa;color:#1f6faa}
body:has(#app[data-theme="light"]) #dsk-hubtabs button{background:#eef3f5;border-color:#c3d5d9;color:#3c5560}
body:has(#app[data-theme="light"]) #dsk-hubtabs button.on{color:#7c530f;border-color:#c47f12;background:#fff3d6;box-shadow:0 0 0 1px #c47f1230}

/* 記分板 #board（手機版） */
body:has(#app[data-theme="light"]) #board{background:linear-gradient(135deg,#ffffff,#f5f9fa 68%,#eaf5ee);border-bottom-color:#c3d5d9}
body:has(#app[data-theme="light"]) .board-badge{background:#eef3f5}
body:has(#app[data-theme="light"]) #bd-jersey{background:#ffffff;border-color:var(--amber);color:var(--amber)}
body:has(#app[data-theme="light"]) .status-label{color:#5b6b74}
body:has(#app[data-theme="light"]) #bd-detail-toggle b{color:#5b6b74}
body:has(#app[data-theme="light"]) #bd-detail-toggle:active b{color:var(--amber)}
body:has(#app[data-theme="light"]) #bd-menu-btn{background:#eef3f5;border-color:#c9dade;color:#3c5560}
body:has(#app[data-theme="light"]) #bd-menu-btn:active{background:#dfe9ec}
body:has(#app[data-theme="light"]) #bd-menu-panel{background:linear-gradient(135deg,#ffffff,#f3f8f9);border-color:#c3d5d9}
body:has(#app[data-theme="light"]) #bd-menu-panel button{background:#eef3f5;border-color:#c9dade;color:var(--chalk)}
body:has(#app[data-theme="light"]) #bd-menu-panel button.warn{border-color:var(--bad)}
body:has(#app[data-theme="light"]) #bd-menu-panel button:active{background:#dfe9ec}
body:has(#app[data-theme="light"]) .bd-cell{background:linear-gradient(180deg,#f4f9fa,#e7eef0);border-color:#c9dade}
body:has(#app[data-theme="light"]) .bd-cell:nth-child(3){background:linear-gradient(160deg,#fff3d6,#f3dfae);border-color:#d8c48a;box-shadow:0 4px 14px #0f233814}
body:has(#app[data-theme="light"]) .bd-cell:nth-child(3) span{color:#6b5a33}
body:has(#app[data-theme="light"]) .bd-cell:nth-child(3) b{color:#3d2c0c}
body:has(#app[data-theme="light"]) #lamps{background:#e7eef0;border-bottom-color:#c9dade}
body:has(#app[data-theme="light"]) .lamp i{background:#c3d5d9;border-color:#a9c0c5}

/* 事件卡 .card 家族／標籤／統計列／年表 */
body:has(#app[data-theme="light"]) .card{background:#ffffff;border-color:#c3d5d9}
body:has(#app[data-theme="light"]) .card::before{background:linear-gradient(115deg,transparent 30%,#0f233810 45%,#0f233818 50%,#0f233810 55%,transparent 70%)}
body:has(#app[data-theme="light"]) .card.gold::before{background:linear-gradient(115deg,transparent 30%,#c47f1230 45%,#c47f1240 50%,#c47f1230 55%,transparent 70%)}
body:has(#app[data-theme="light"]) .card.major{box-shadow:var(--sh-m),0 0 0 1px #c47f1240}
body:has(#app[data-theme="light"]) .card.major::after{text-shadow:none}
body:has(#app[data-theme="light"]) .card h4{background:linear-gradient(120deg,#dfe9ec,#cddbe0);color:#274a63}
body:has(#app[data-theme="light"]) .npc-line{background:linear-gradient(90deg,#0f23380b,#0f238803 70%,transparent)}
body:has(#app[data-theme="light"]) .npc-k-mentor{--npc-c:#1f6faa} body:has(#app[data-theme="light"]) .npc-k-friend{--npc-c:#1f7a49}
body:has(#app[data-theme="light"]) .npc-k-partner{--npc-c:#b5476f} body:has(#app[data-theme="light"]) .npc-k-agent{--npc-c:#c47f12}
body:has(#app[data-theme="light"]) .npc-ava{box-shadow:0 0 0 1.5px var(--npc-c),0 2px 5px #0f233826}
body:has(#app[data-theme="light"]) .npc-fx{color:#1f7a49}
body:has(#app[data-theme="light"]) .npc-rollcall{border-top-color:#0f233826}
body:has(#app[data-theme="light"]) .npc-rollcall-h{color:#9a6510}
body:has(#app[data-theme="light"]) .card.gold h4{background:linear-gradient(120deg,var(--amber),var(--gold-deep));color:#fff8ea}
body:has(#app[data-theme="light"]) .card.bad h4{background:linear-gradient(120deg,#d9695a,#b23a26);color:#fff3ef}
body:has(#app[data-theme="light"]) .card.good h4{background:linear-gradient(120deg,#3daa71,#1f7a49);color:#ecfff3}
body:has(#app[data-theme="light"]) .card.info h4{background:linear-gradient(120deg,#4a92c4,#1f6faa);color:#eef8ff}
body:has(#app[data-theme="light"]) .impact-tags span{border-color:#a9c0c5;background:#eef3f5;color:#3c5560}
body:has(#app[data-theme="light"]) .impact-tags span:nth-child(2){border-color:#b19ed6;color:#5b4a80}
body:has(#app[data-theme="light"]) .impact-tags span:nth-child(3){border-color:#c9a765;color:#6b4f1f}
body:has(#app[data-theme="light"]) .card.recap{border-color:#a9c0c5;background:#ffffff}
body:has(#app[data-theme="light"]) .share-card{border-color:#a9c0c5;background:#ffffff}
body:has(#app[data-theme="light"]) .share-preview{background:#f3f8f9;border-color:#c9a76580}
body:has(#app[data-theme="light"]) .share-preview img{border-color:#c3d5d9;background:var(--bg)}
body:has(#app[data-theme="light"]) .recap-grid>div{background:#f3f8f9;border-color:#c9dade}
body:has(#app[data-theme="light"]) .recap-grid span{color:#5b6b74}
body:has(#app[data-theme="light"]) .recap-grid b{color:#1f2f3a}
body:has(#app[data-theme="light"]) .recap-sub{color:#8a5a10}
body:has(#app[data-theme="light"]) .recap-honors{background:#c47f1218;color:#6b4f1f}
body:has(#app[data-theme="light"]) .tag{background:#eef3f5}
body:has(#app[data-theme="light"]) .statline{background:#f3f8f9;border-color:#a9c0c580}
body:has(#app[data-theme="light"]) .stat-full summary{border-bottom-color:#a9c0c580}
body:has(#app[data-theme="light"]) .yr-head::before,body:has(#app[data-theme="light"]) .yr-head::after{border-top-color:#b23a2650}
body:has(#app[data-theme="light"]) .yr-head:hover::before,body:has(#app[data-theme="light"]) .yr-head:hover::after{border-color:#c47f1270}
body:has(#app[data-theme="light"]) .bar em{background:#c47f1280}

/* 操作區 #act／按鈕／擲骰分配 */
body:has(#app[data-theme="light"]) #act{background:linear-gradient(180deg,#ffffff 0%,#eef3f5 100%);border-top-color:#c3d5d9;box-shadow:0 -10px 26px #0f23381a}
body:has(#app[data-theme="light"]) #act #al-btm{background:linear-gradient(180deg,#ffffff00 0%,#ffffffee 30%,#eef3f5 100%);border-top-color:#c3d5d966}
body:has(#app[data-theme="light"]) #act-toggle{background:#eef3f5;border-color:#c3d5d9;color:#3c5560}
body:has(#app[data-theme="light"]) #act-toggle:active{background:#dfe9ec;color:var(--amber)}
body:has(#app[data-theme="light"]) .choice-kind{background:#8b5cf61c;border-color:#8b5cf655;color:#5b3fa0}
/* .btn／.btn.main／.btn.warn／.choice-detail 這幾個是 #app（遊戲操作區）跟
   #start（開場精靈的「下一步」／「開始」等按鈕、彈窗內的確認鈕）共用的元件，
   兩邊都要接，不能只寫 #app。 */
body:has(#app[data-theme="light"]) .btn{background:linear-gradient(135deg,#ffffff,#eef3f5);border-color:#c3d5d9;box-shadow:inset 0 1px #0f233808}
body:has(#app[data-theme="light"]) .btn:hover{box-shadow:inset 0 1px #0f233808,0 0 0 1px #c47f1230}
body:has(#app[data-theme="light"]) .btn.main{background:linear-gradient(135deg,#2fa066,#1f7a49);border-color:#166b3c;color:#fff8ea}
/* .choice-detail／small 的說明文字全站統一用 color:var(--dim)（見 style.css
   .btn small,.choice-detail 那行），這在深色主題的 .btn.main（深綠底）上還讀得
   出來，但淺色主題的 .btn.main 換成中彩度綠底之後，var(--dim) 在淺色主題是
   偏中灰的 #5b6b74，疊在綠底上對比度太低、幾乎被顏色吃掉（使用者截圖回報的
   問題）。.btn.main 是全站唯一背景本身是飽和色塊、卻共用這行全域說明文字色的
   按鈕變體，直接在這裡蓋掉即可，不用改動全域規則本身（.btn.warn 淺色主題下
   背景維持淺色，說明文字沿用 var(--dim) 沒有這個問題，不用一起改）。 */
body:has(#app[data-theme="light"]) .btn.main .choice-detail,body:has(#app[data-theme="light"]) .btn.main small,body:has(#app[data-theme="light"]) .btn.main .choice-detail .muted{color:#dbf3e2}
body:has(#app[data-theme="light"]) .btn.warn{border-color:var(--bad)}
body:has(#app[data-theme="light"]) .ripple{background:#0f233820}
body:has(#app[data-theme="light"]) .die{background:#fff8ea;color:#1f2f0f;box-shadow:inset 0 -3px 0 #0f23381a}
body:has(#app[data-theme="light"]) .die::after{border-color:#b23a2650}
body:has(#app[data-theme="light"]) .die.six{color:#a23420}
body:has(#app[data-theme="light"]) .abrow .bar{background:#e2eaec}
body:has(#app[data-theme="light"]) .al-plus{background:#f2f7f8;border-color:#c7d6da;color:#8a6413}
body:has(#app[data-theme="light"]) .abrow .bar i{background:linear-gradient(90deg,#4f9e6b,var(--amber))}

/* 生涯中控台 #v2-nav／#v2-panel／養成・賽季・檔案 */
body:has(#app[data-theme="light"]) #v2-nav{background:#ffffffe6;border-top-color:#c3d5d9;box-shadow:0 -4px 18px #0f23381a}
body:has(#app[data-theme="light"]) #v2-nav button{color:#5b6b74}
body:has(#app[data-theme="light"]) #v2-nav button.on{color:var(--gold-deep);text-shadow:none}
body:has(#app[data-theme="light"]) .nav-ind{background:#1f6faa14;border-color:#1f6faa3a}
body:has(#app[data-theme="light"]) #v2-panel{background:#ffffff;border-color:#c3d5d9}
body:has(#app[data-theme="light"]) .v2-hero{background:radial-gradient(circle at 85% 20%,#1f915330,transparent 37%),linear-gradient(135deg,#f3f8f9,#e7f0f2)}
body:has(#app[data-theme="light"]) .v2-hero::after{color:#fff8ea;background:var(--amber)}
body:has(#app[data-theme="light"]) .v2-kicker{color:#1f7a49}
body:has(#app[data-theme="light"]) .v2-hero h3{color:#1f2f3a}
body:has(#app[data-theme="light"]) .v2-grid{background:#c3d5d9}
body:has(#app[data-theme="light"]) .v2-grid>div{background:#ffffff}
/* .locker-side 是養成分頁右欄的容器（它自己是 .v2-grid 的一格，內部再堆卡片），
   所以它的底色與內部卡片底色都不會被上面那兩條 .v2-grid / .v2-grid>div 覆寫到——
   深色值寫死在 .locker-side 上，淺色主題就會整欄變成深底深字（實測整片看不到內容）。
   **在面板裡新增任何自訂容器、只要寫死了底色，就一定要在這裡補一組淺色主題的對應規則。** */
body:has(#app[data-theme="light"]) .locker-side{background:#c3d5d9}
body:has(#app[data-theme="light"]) .locker-side>div{background:#ffffff}
body:has(#app[data-theme="light"]) #v2-panel h5{color:#3c5560}
body:has(#app[data-theme="light"]) .home-grid .v2-primary{background:linear-gradient(145deg,#f3f8f9,#e7eef0)}
body:has(#app[data-theme="light"]) .home-grid .v2-primary b{color:#6b4f1f}
body:has(#app[data-theme="light"]) .home-grid .v2-secondary{background:#f7fafb}
body:has(#app[data-theme="light"]) .home-grid .v2-secondary b{color:#1f2f3a}
body:has(#app[data-theme="light"]) .home-grid .v2-secondary small{color:#5b6b74}
body:has(#app[data-theme="light"]) .v2-metric{color:var(--gold-deep)}
body:has(#app[data-theme="light"]) .v2-chip{background:#dfe9ec;border-color:#a9c0c5;color:#3c5560}
body:has(#app[data-theme="light"]) .v2-chip.gold{border-color:#c8963e;color:#6b4f1f;background:#fff3d6}
body:has(#app[data-theme="light"]) .v2-chip-toggle{border-color:#a9c0c5;color:#5b6b74}
body:has(#app[data-theme="light"]) .v2-chip-toggle:hover{border-color:var(--amber);color:var(--amber)}
body:has(#app[data-theme="light"]) .v2-bar{background:#dfe9ec}
body:has(#app[data-theme="light"]) .v2-bar i{background:linear-gradient(90deg,#2f9153,#c47f12)}
body:has(#app[data-theme="light"]) .v2-bar.risk i{background:linear-gradient(90deg,#2f9153,#c47f12 55%,#b23c38)}
body:has(#app[data-theme="light"]) .ovr-trend-base{stroke:#0f233820}
body:has(#app[data-theme="light"]) .ovr-trend-area{fill:#c47f1220}
body:has(#app[data-theme="light"]) .ovr-trend-now{fill:var(--chalk)}
body:has(#app[data-theme="light"]) .v2-list p{border-left-color:#5b6b74;color:#3c5560}
body:has(#app[data-theme="light"]) .v2-fold{border-top-color:#c3d5d9}
body:has(#app[data-theme="light"]) .v2-fold summary{color:#3c5560;border-color:#a9c0c5}
body:has(#app[data-theme="light"]) .v2-fold summary:hover{border-color:var(--amber);color:var(--amber)}
body:has(#app[data-theme="light"]) .career-time-item{border-left-color:#a9c0c5}
body:has(#app[data-theme="light"]) .career-time-item::before{background:var(--amber);box-shadow:0 0 0 3px #ffffff}
body:has(#app[data-theme="light"]) .career-time-item span{color:#8a5a10}
body:has(#app[data-theme="light"]) .career-time-item b{color:#1f2f3a}
body:has(#app[data-theme="light"]) .career-time-item small{color:#5b6b74}
body:has(#app[data-theme="light"]) .scout-report summary{color:#8a5a10}
body:has(#app[data-theme="light"]) .scout-grid>div{background:#f3f8f9;border-color:#c9dade}
body:has(#app[data-theme="light"]) .scout-grid span{color:#8a5a10}
body:has(#app[data-theme="light"]) .scout-grid b{color:#3c5560}
body:has(#app[data-theme="light"]) .scout-weapons{background:#c9973e14;border-left-color:#c9973e;color:#5b4a1f}
body:has(#app[data-theme="light"]) .offer-compare{border-top-color:#c3d5d9}
body:has(#app[data-theme="light"]) .offer-top{color:#1f2f3a}
body:has(#app[data-theme="light"]) .offer-top span{color:#8a5a10}
body:has(#app[data-theme="light"]) .card.result .receipt{
  border-left-color:#c47f12;
  background:linear-gradient(90deg,rgba(196,127,18,.15),rgba(196,127,18,.04) 60%,transparent)}
body:has(#app[data-theme="light"]) .card.result .receipt span{color:#8a5a10;opacity:1}
body:has(#app[data-theme="light"]) .card.result .receipt b{color:#0f2338}
body:has(#app[data-theme="light"]) .offer-sort .os{border-color:#a9c0c5;color:#4a5f6b}
body:has(#app[data-theme="light"]) .offer-sort .os.on{background:#c47f12;border-color:#c47f12;color:#fff}
body:has(#app[data-theme="light"]) .offer-sig .good{border-color:#2f8a5f;background:#e6f4ec;color:#1a5c3c}
body:has(#app[data-theme="light"]) .offer-sig .warn{border-color:#a3762c;background:#fbf1dc;color:#7a5310}
body:has(#app[data-theme="light"]) .offer-sig .risk{border-color:#c0523c;background:#fbeae7;color:#93331f}
body:has(#app[data-theme="light"]) .tlf{border-color:#a9c0c5;color:#4a5f6b}
body:has(#app[data-theme="light"]) .tlf.on{background:#c47f12;border-color:#c47f12;color:#fff}
body:has(#app[data-theme="light"]) .offer-money span,body:has(#app[data-theme="light"]) .offer-terms span{background:#f3f8f9;border-color:#c9dade;color:#3c5560}
body:has(#app[data-theme="light"]) .offer-money b{color:var(--gold-deep)}
body:has(#app[data-theme="light"]) .offer-terms span:first-child{border-color:#7cb996;color:#1f6b3f}
body:has(#app[data-theme="light"]) .offer-fit{color:#5b6b74}
/* 淺色主題也要有一份 .btn.main 綠底專用覆寫（理由見基礎規則區同一組的說明：
   body:has(...) specificity 較高，不另寫一份會蓋掉那組修正）。 */
body:has(#app[data-theme="light"]) .btn.main .offer-compare{border-top-color:rgba(255,255,255,.42)}
body:has(#app[data-theme="light"]) .btn.main .offer-top{color:#f4fbf7}
body:has(#app[data-theme="light"]) .btn.main .offer-top span{color:#ffeec2}
body:has(#app[data-theme="light"]) .btn.main .offer-money span,body:has(#app[data-theme="light"]) .btn.main .offer-terms span{background:rgba(255,255,255,.94);border-color:rgba(255,255,255,.7);color:#1f3a2b}
body:has(#app[data-theme="light"]) .btn.main .offer-money b{color:#8a5a10}
body:has(#app[data-theme="light"]) .btn.main .offer-terms span:first-child{border-color:#bdead2;color:#14562f}
body:has(#app[data-theme="light"]) .btn.main .offer-fit{color:#f0fbf4}
body:has(#app[data-theme="light"]) .btn.main .offer-compare small{opacity:.95}

/* #notice-modal 是唯一在 #app 底下的彈窗；其餘 6 個 .modal-overlay/.modal-box
   （種子說明／系統介紹／更新日誌／感謝名單／LINE 社群／創造角色說明）都掛在
   #start 底下，兩邊都要接。 */
body:has(#app[data-theme="light"]) .modal-overlay{background:#0f233833}
body:has(#app[data-theme="light"]) .modal-box{background:linear-gradient(160deg,#ffffff,#f7fafb);border-color:#c3d5d9;box-shadow:var(--sh-l)}
body:has(#app[data-theme="light"]) .modal-box h3{color:#1f2f3a}
body:has(#app[data-theme="light"]) .modal-box p{color:#3c5560}

/* ============================================================
   淺色主題「球場正午」— #start（開場設定畫面）
   ============================================================
   使用者確認「球場正午」方向後，第一版刻意把範圍限定在 #app（見上面章節開頭
   說明），#start 維持固定深色。使用者後續要求「開局創造角色那邊也要支援淺色
   主題」，才補上這個區塊——跟 #app 那塊一樣，逐一处理 #start 底下沒有走
   var() 的元件；電腦版新增 #start-theme-btn（右上角圖示，只在 ≥1100px 顯示，
   手機版開局已經有收合選單裡的「主題切換」項目，不需要重複一顆）。 */
#start[data-theme="light"]{
  background-image:radial-gradient(circle at 20% 0%,#1f915322,transparent 30%),radial-gradient(circle at 85% 18%,#c47f1218,transparent 34%),radial-gradient(ellipse 70% 40% at 50% 100%,#1f6faa1a,transparent 60%),linear-gradient(135deg,#eef3f5,#f7fafb);
}
body:has(#app[data-theme="light"]) .feature-tags span{color:#5b3fa0;background:#8b5cf614;border-color:#8b5cf640}
body:has(#app[data-theme="light"]) .release-note{background:#8b5cf60f;border-left-color:#8b5cf6}
body:has(#app[data-theme="light"]) .release-line{color:#5b3fa0}
body:has(#app[data-theme="light"]) .forum-link{background:#c47f1220;border-color:#c47f1260;color:#7c530f}
body:has(#app[data-theme="light"]) .forum-link:hover{background:#c47f1240;border-color:#c47f12}
body:has(#app[data-theme="light"]) .rl-check{background:#c47f1220;border-color:#c47f1260;color:#7c530f}
body:has(#app[data-theme="light"]) .rl-check:hover{background:#c47f1240;border-color:#c47f12}
body:has(#app[data-theme="light"]) .about-btn{background:#8b5cf614;border-color:#8b5cf650;color:#5b3fa0}
body:has(#app[data-theme="light"]) .about-btn:hover{background:#8b5cf630;border-color:#8b5cf6}
/* 淺色主題：一樣走金藍色票，不要回到紫色（見上面 .mobile-menu-btn 的說明）。 */
body:has(#app[data-theme="light"]) .mobile-menu-btn{background:#fffffff0;border-color:#8a5a10;color:#7c530f}
body:has(#app[data-theme="light"]) .mobile-menu-btn:active{background:#fdf3dd}
body:has(#app[data-theme="light"]) .about-btn{color:#0f2338}
body:has(#app[data-theme="light"]) .about-btn:active{background:#8a5a1a1f}
/* .about-actions 在桌機是「行內攤開的四顆按鈕」、沒有自己的底色（見 233 行）；
   只有 <1100px 時才變成 position:fixed 的收合選單，那時才需要面板底色。
   這條淺色覆寫原本寫在全域，白底就外溢到桌機，變成米白頁面上一塊格格不入的白色方塊
   （2026-09-09 使用者圈出）。改成只在收合選單那個斷點內生效——見 @media (max-width:1099px)。
   順帶：容器的 color 原本繼承深色主題的 --cream，白底上等於白字；桌機沒有裸文字所以
   看不出來，但改天在容器裡加任何文字就會中招，一起指定。 */
body:has(#app[data-theme="light"]) .about-actions{color:var(--dim)}
body:has(#app[data-theme="light"]) .about-btn:active{background:#8b5cf61c}
body:has(#app[data-theme="light"]) .about-actions-divider{border-top-color:#c3d5d9}
body:has(#app[data-theme="light"]) .about-btn-dev{color:#6b4fa0}
body:has(#app[data-theme="light"]) .dev-tag{color:#5b6b74;background:#0f233810;border-color:#c3d5d9}
body:has(#app[data-theme="light"]) .title-credits{color:#5b6b74}
body:has(#app[data-theme="light"]) .title-credits b{color:#1f2f3a}
body:has(#app[data-theme="light"]) .title-credits a{color:#8a5a10;border-bottom-color:#8a5a1055}
body:has(#app[data-theme="light"]) .update-banner{
  background:linear-gradient(100deg,#b23a2618,#ffffffcc);border-color:#b23a2666}
body:has(#app[data-theme="light"]) .update-banner-text{color:#0f2338}
body:has(#app[data-theme="light"]) .update-banner-text b{color:#a3301c}
body:has(#app[data-theme="light"]) .continue-banner{background:linear-gradient(100deg,#c47f1218,#ffffffcc);border-color:#c47f1250}
body:has(#app[data-theme="light"]) .continue-text{color:#1f2f3a}
body:has(#app[data-theme="light"]) .cloud-bar{background:linear-gradient(100deg,#1f6faa16,#ffffffcc);border-color:#1f6faa4a}
body:has(#app[data-theme="light"]) .cloud-text{color:#1f2f3a}
body:has(#app[data-theme="light"]) .cloud-text b{color:#1f6faa}
body:has(#app[data-theme="light"]) .cloud-career{background:linear-gradient(160deg,#ffffffdd,#f3f8f9dd);border-color:#c3d5d9}
body:has(#app[data-theme="light"]) .cc-head b{color:#0f2338}
body:has(#app[data-theme="light"]) .cc-fact dd{color:#1f2f3a}
body:has(#app[data-theme="light"]) .cc-fact .v2-ic,body:has(#app[data-theme="light"]) .cc-fact dt{color:#5b6b74}
body:has(#app[data-theme="light"]) .cc-tier{background:#eef3f5;border-color:#c3d5d9;color:#5b6b74}
body:has(#app[data-theme="light"]) .cc-tier.cc-t-hof{background:#fdf4e2;border-color:#c47f1288;color:#8a5a10}
body:has(#app[data-theme="light"]) .cc-tier.cc-t-star{background:#eef1f6;border-color:#9aa6bb88;color:#3c4a5a}
body:has(#app[data-theme="light"]) .cloud-career .btn.cc-seed{border-color:#c47f1288;color:#8a5a10}
body:has(#app[data-theme="light"]) .cloud-career .btn.cc-art{color:#3c5560}
body:has(#app[data-theme="light"]) .career-art-wait{color:#5b6b74}
body:has(#app[data-theme="light"]) .cloud-face{border-color:#1f6faa44;background:#eef3f5}
body:has(#app[data-theme="light"]) .cloud-hint-link{color:#8a5a10}
body:has(#app[data-theme="light"]) .cloud-hint-link:hover{color:#0f2338}
body:has(#app[data-theme="light"]) .cloud-fold{border-color:#9fbecd;color:#3c5560}
body:has(#app[data-theme="light"]) .cloud-fold:hover{border-color:#c47f12;color:#8a5a10}
body:has(#app[data-theme="light"]) .cloud-priv:hover{color:#1f6faa}
body:has(#app[data-theme="light"]) .cloud-panel{border-top-color:#1f6faa33}
body:has(#app[data-theme="light"]) .cloud-panel .btn.cloud-danger{border-color:#cf463288;color:#a3301c;background:#cf46320f}
body:has(#app[data-theme="light"]) .cloud-resume{border-color:#c47f1288;color:#8a5a10}
body:has(#app[data-theme="light"]) .cloud-resume-info b{color:#0f2338}
body:has(#app[data-theme="light"]) .field label{color:#3c5560}
body:has(#app[data-theme="light"]) .hand-preview{border-color:#c3d5d9;background:#f3f8f9;color:#3c5560}
body:has(#app[data-theme="light"]) .section-title{color:#1f2f3a}
body:has(#app[data-theme="light"]) .field input{background:#ffffff;border-color:#c3d5d9}
body:has(#app[data-theme="light"]) .field input:focus{box-shadow:0 0 0 3px #c47f1222}
body:has(#app[data-theme="light"]) .seg button{background:#ffffff;border-color:#c3d5d9}
body:has(#app[data-theme="light"]) .seg button.on{background:linear-gradient(135deg,#e3f5ea,#d3ecdc);box-shadow:0 0 0 1px #c47f1230,inset 0 0 0 1px #c47f1218}
body:has(#app[data-theme="light"]) .dice-btn{background:#ffffff;border-color:#c3d5d9}
body:has(#app[data-theme="light"]) .info-btn{background:#dfe9ec;color:#3c5560}
body:has(#app[data-theme="light"]) .seed-row{background:#f3f8f9;border-color:#c9dade}
body:has(#app[data-theme="light"]) #wizard{background:linear-gradient(160deg,#ffffffcc,#f3f8f9cc);border-color:#c3d5d9}
body:has(#app[data-theme="light"]) .wiz-dot{background:#c3d5d9}
body:has(#app[data-theme="light"]) .wiz-dot.done{background:var(--good)}
body:has(#app[data-theme="light"]) .wiz-label{color:#5b6b74}
body:has(#app[data-theme="light"]) .start-disclaimer{border-color:#8b5cf640;border-left-color:#8b5cf6;background:linear-gradient(100deg,#8b5cf612,#ffffffcc);color:#3c5560}
body:has(#app[data-theme="light"]) .start-disclaimer b{color:#5b3fa0}
body:has(#app[data-theme="light"]) .line-community-modal{border-color:#c47f12a0;background:linear-gradient(155deg,#ffffff,#f7fafb)}
body:has(#app[data-theme="light"]) .modal-x{border-color:#c3d5d9;background:#eef3f5b8;color:#3c5560}
body:has(#app[data-theme="light"]) .modal-x:hover{border-color:#c47f12;color:#7c530f;background:#c47f1220}
body:has(#app[data-theme="light"]) .line-community-modal h3{color:#7c530f}
body:has(#app[data-theme="light"]) .line-community-modal>p{color:#3c5560}
body:has(#app[data-theme="light"]) .line-community-join{border-color:#8a5a10;background:linear-gradient(135deg,#e0a838,#c47f12);color:#2c1c05}
body:has(#app[data-theme="light"]) .line-community-join:hover{background:linear-gradient(135deg,#eab850,#d68a1a)}
body:has(#app[data-theme="light"]) .line-qr-label{color:#5b6b74!important}
body:has(#app[data-theme="light"]) .line-no-remind{color:#5b6b74}
body:has(#app[data-theme="light"]) .credit-block{background:#f3f8f9;border-color:#c3d5d9}
body:has(#app[data-theme="light"]) .credit-row+.credit-row{border-top-color:#c9dade}
body:has(#app[data-theme="light"]) .credit-label{color:#3c5560;background:#dfe9ec}
body:has(#app[data-theme="light"]) .credit-row b{color:#1f2f3a}
body:has(#app[data-theme="light"]) .credit-row a{color:#8a5a10}
body:has(#app[data-theme="light"]) .modal-divider{color:#5b6b74;border-top-color:#c3d5d9}
body:has(#app[data-theme="light"]) .update-brief li{color:#3c5560}
body:has(#app[data-theme="light"]) .update-brief h4{color:#8a5a10}
body:has(#app[data-theme="light"]) .update-brief b{color:#1d3a49}
/* 桌機整合面板（≥1100px） */
body:has(#app[data-theme="light"]) .start-panel{border-color:#c3d5d9;background:linear-gradient(160deg,#ffffffcc,#f7fafbcc)}
body:has(#app[data-theme="light"]) .start-side{border-right-color:#c3d5d9;background:linear-gradient(165deg,#eef3f580,#dfe9ec80)}
body:has(#app[data-theme="light"]) .start-disclaimer b{color:#5b6b74}
body:has(#app[data-theme="light"]) .start-disclaimer span:not(:first-of-type){border-left-color:#c3d5d9}
/* 角色檔案預覽 .cp-* */
body:has(#app[data-theme="light"]) .cp-kicker{color:#3c5560}
body:has(#app[data-theme="light"]) .cp-avatar{box-shadow:0 6px 16px #0f233830;background:#eef3f5}
body:has(#app[data-theme="light"]) .cp-name{color:#1f2f3a}
body:has(#app[data-theme="light"]) .cp-sub{color:#3c5560}
body:has(#app[data-theme="light"]) .cp-rows{border-top-color:#c9dade}
body:has(#app[data-theme="light"]) .cp-row span{color:#3c5560}
body:has(#app[data-theme="light"]) .cp-seedrow{border-top-color:#c9dade;color:#3c5560}

/* 桌機開場畫面右上角主題切換圖示（只在 ≥1100px 顯示——手機版開局已經有收合
   選單裡的「主題切換」項目，不需要重複一顆；跟 .mobile-menu-btn 用同一種
   position:fixed 圓角浮動按鈕語彙，但這裡是純圖示、圓形、不佔文字空間，靠
   title/aria-label 補文字提示）。圖示顯示「目前所在的主題」（🌙=深色／
   ☀️=淺色），跟 #dsk-btn-theme／#bd-btn-theme／#btn-theme-mobile 三顆既有
   按鈕同一套「顯示現況、點了才切換」的語彙一致。 */
.start-theme-btn{display:none}
@media (min-width:1100px){
  /* right:20px（不是貼齊邊緣的 12px）：#start 沒有套用站內細版捲軸樣式，瀏覽器
     原生捲軸在 Windows Chrome 大約 15-17px 寬，貼太近會卡進捲軸裡——使用者
     截圖回報過這個問題，比照 .mobile-menu-btn 拉開同樣的距離。尺寸也從
     40px/18px 放大到 52px/24px，使用者反映「主題切換放大一點」。 */
  .start-theme-btn{display:flex;position:fixed;top:14px;right:20px;z-index:56;align-items:center;
    justify-content:center;width:52px;height:52px;border-radius:50%;background:#16213099;
    backdrop-filter:blur(4px);border:1px solid #a78bfa66;color:#e2d9fa;font-size:24px;line-height:1;
    cursor:pointer;box-shadow:0 4px 12px #00000040;transition:transform .15s,border-color .15s}
  .start-theme-btn:hover{transform:scale(1.08);border-color:#a78bfa}
  .start-theme-btn:active{transform:scale(.94)}
}
body:has(#app[data-theme="light"]) .start-theme-btn{background:#ffffffcc;border-color:#c47f1260;color:#7c530f;box-shadow:0 4px 12px #0f233820}
body:has(#app[data-theme="light"]) .start-theme-btn:hover{border-color:#c47f12}

/* 說明浮框在淺色主題下的陰影（深色那條黑影壓在白底上會髒） */
body:has(#app[data-theme="light"]) #trait-tip{box-shadow:0 10px 28px #0f233824}

/* ===================================================================
   更新日誌彈窗 #update-modal 改版（2026-10-24）
   跟 about／how2play／install／update.html 同一套「開場配色」：深色＝夜場＋暖金、淺色＝米白＋墨綠
   （數值取自 css/opening.css 的 --op-*、css/guide.css 的 token）。
   版面：頂部標題列（kicker／標題／版本·日期膠囊／右上角 ×）固定，摘要在中間自己捲，底部是
   「完整日誌」連結＋「我知道了」。#update-modal 是 body 的直接子節點（不在 #start／#app 裡），
   所以用 #update-modal#update-modal 拉高 specificity 蓋過上面 .modal-box／.update-brief／.btn.main
   以及 body:has(#app[data-theme="light"]) 那幾條舊規則；淺色一樣跟著 #app 的 data-theme 走。
   ⚠ .modal-divider 那一行的「v2.8.5 · 日期」格式被回歸 0.05 鎖住（四處版號一致），不要改寫法。
   =================================================================== */
#update-modal#update-modal{
  --um-panel:#0b2230;--um-head:#0e2a39;--um-text:#fff6df;--um-muted:#c3d1d0;--um-edge:#4f6a6c;--um-soft:rgba(105,128,128,.38);
  --um-accent:#f7d57c;--um-ink:#112f35;--um-shadow:0 24px 60px rgba(0,0,0,.5);
  padding:20px;background:rgba(3,12,20,.66);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)
}
body:has(#app[data-theme="light"]) #update-modal#update-modal{
  --um-panel:#fffaeb;--um-head:#f6efdb;--um-text:#183d35;--um-muted:#4c6359;--um-edge:#b7ae8b;--um-soft:rgba(183,174,139,.5);
  --um-accent:#145443;--um-ink:#fff8e6;--um-shadow:0 24px 60px rgba(65,57,33,.28);
  background:rgba(60,52,30,.32)
}
#update-modal#update-modal .modal-box{
  position:relative;display:flex;flex-direction:column;width:100%;max-width:560px;padding:0;overflow:hidden;
  max-height:calc(100vh - 40px);max-height:calc(100dvh - 40px);
  background:var(--um-panel);border:1px solid var(--um-edge);border-radius:20px;box-shadow:var(--um-shadow);color:var(--um-text)
}
#update-modal#update-modal .um-head{flex:none;padding:22px 64px 18px 24px;background:var(--um-head);border-bottom:1px solid var(--um-soft)}
#update-modal#update-modal .um-kicker{display:block;font:700 11px var(--mono);letter-spacing:.18em;color:var(--um-accent)}
#update-modal#update-modal .modal-box h3{margin:4px 0 10px;font-size:22px;font-weight:900;line-height:1.3;color:var(--um-text)}
#update-modal#update-modal .modal-divider{
  display:inline-flex;align-items:center;margin:0;padding:4px 12px;border:1px solid color-mix(in srgb,var(--um-accent) 55%,transparent);border-radius:999px;
  background:color-mix(in srgb,var(--um-accent) 12%,transparent);color:var(--um-accent);
  font:700 12.5px var(--mono);letter-spacing:.06em;text-transform:none
}
#update-modal#update-modal .modal-x{
  top:18px;right:18px;width:36px;height:36px;border:1px solid var(--um-edge);border-radius:50%;
  background:transparent;color:var(--um-text);font:400 24px/1 var(--sans)
}
#update-modal#update-modal .modal-x:hover{border-color:var(--um-accent);color:var(--um-accent);background:color-mix(in srgb,var(--um-accent) 12%,transparent)}
#update-modal#update-modal :is(.modal-x,.btn,a):focus-visible{outline:3px solid var(--um-accent);outline-offset:3px}
#update-modal#update-modal .update-brief{flex:1 1 auto;min-height:0;margin:0;padding:6px 24px 20px;overflow-y:auto;overscroll-behavior:contain;scrollbar-width:thin}
#update-modal#update-modal .update-brief h4{
  display:flex;align-items:center;gap:8px;margin:18px 0 9px;font-size:14.5px;font-weight:800;letter-spacing:.04em;color:var(--um-text)
}
#update-modal#update-modal .update-brief h4::after{content:"";flex:1;height:1px;background:var(--um-soft)}
#update-modal#update-modal .update-brief ul{
  gap:0;padding:4px 14px;border:1px solid var(--um-soft);border-radius:14px;background:color-mix(in srgb,var(--um-text) 4%,transparent)
}
#update-modal#update-modal .update-brief li{padding:10px 0 10px 18px;font-size:14px;line-height:1.75;color:var(--um-muted)}
#update-modal#update-modal .update-brief li+li{border-top:1px dashed var(--um-soft)}
#update-modal#update-modal .update-brief li::before{left:2px;top:calc(10px + .66em);width:7px;height:7px;border-radius:2px;background:var(--um-accent)}
#update-modal#update-modal .update-brief b{color:var(--um-text);font-weight:800}
#update-modal#update-modal .um-foot{
  flex:none;display:flex;align-items:center;gap:14px;padding:14px 24px 18px;border-top:1px solid var(--um-soft);background:var(--um-head)
}
#update-modal#update-modal .um-foot p{flex:1;min-width:0;margin:0;font-size:13px;line-height:1.7;color:var(--um-muted)}
#update-modal#update-modal .um-foot .forum-link{
  display:inline;margin:0 0 0 2px;padding:0;border:0;border-radius:0;background:none;box-shadow:none;transform:none;
  color:var(--um-accent);font:800 13px var(--sans);text-decoration:underline;text-underline-offset:3px
}
#update-modal#update-modal .modal-box .btn.main{
  position:static;flex:none;width:auto;min-width:140px;min-height:46px;margin:0;padding:0 26px;border:1px solid var(--um-accent);border-radius:999px;clip-path:none;
  background:var(--um-accent);color:var(--um-ink);font:800 15px var(--sans);text-align:center;
  box-shadow:0 0 0 4px color-mix(in srgb,var(--um-accent) 18%,transparent)
}
#update-modal#update-modal .modal-box .btn.main:hover{filter:brightness(1.06)}
@media (max-width:560px){
  #update-modal#update-modal{padding:16px;align-items:flex-end}
  #update-modal#update-modal .modal-box{max-height:calc(100vh - 32px);max-height:calc(100dvh - 32px);border-radius:18px}
  #update-modal#update-modal .um-head{padding:18px 58px 14px 18px}
  #update-modal#update-modal .modal-x{top:14px;right:14px}
  #update-modal#update-modal .modal-box h3{font-size:20px}
  #update-modal#update-modal .update-brief{padding:4px 18px 16px}
  #update-modal#update-modal .update-brief ul{padding:2px 12px}
  #update-modal#update-modal .um-foot{flex-direction:column;align-items:stretch;gap:10px;padding:12px 18px calc(16px + env(safe-area-inset-bottom))}
  #update-modal#update-modal .um-foot p{text-align:center}
  #update-modal#update-modal .modal-box .btn.main{width:100%}
}
