/* 海風股市 — 全站樣式（唯一樣式來源）
   分節：tokens → reset → layout → header/rail → panel → controls → 元件 → overlay → breakpoints
   注意：深/淺色由 <head> 內的預繪腳本一律寫入 data-theme，故淺色只需定義一份。 */

/* ══════════════ tokens ══════════════ */
:root {
  --bg: #0f1117; --bg2: #1a1f2e; --bg3: #242938;
  --border: #2e3347; --text: #e2e8f0; --muted: #64748b;
  --green: #22c55e; --red: #ef4444; --blue: #3b82f6; --gold: #f59e0b; --accent: #3b82f6;
  --pill-pend-bg: #3a2f12; --pill-fill-bg: #14532d; --pill-fill-fg: #4ade80;
  --pill-canc-bg: #334155; --pill-canc-fg: #94a3b8;
  --badge-open-bg: #14532d; --badge-closed-bg: #450a0a;
  --chart-grid: #2e3347;
  --news-tk-bg: #1e3a5f;
  /* 台股慣例：紅漲綠跌。要改漲跌色只需改這兩行。 */
  --up: var(--red); --down: var(--green);
  /* 版面尺寸 */
  --rail-w: 56px; --col-a: 300px; --col-c: 340px;
}
:root[data-theme="light"] {
  --bg: #eef1f7; --bg2: #ffffff; --bg3: #e7ecf4;
  --border: #d3dbe8; --text: #1b2434; --muted: #6b7688;
  --green: #16a34a; --red: #dc2626; --blue: #2563eb; --gold: #b45309; --accent: #2563eb;
  --pill-pend-bg: #fdecc8; --pill-fill-bg: #d1f0dc; --pill-fill-fg: #166534;
  --pill-canc-bg: #e2e8f0; --pill-canc-fg: #64748b;
  --badge-open-bg: #d1f0dc; --badge-closed-bg: #fadadd;
  --chart-grid: #dce3ee;
  --news-tk-bg: #dbeafe;
}
/* 賽季主題色：只重新著色強調色，與深/淺色獨立疊加。置於各主題區塊之後。 */
:root[data-season="ocean"] { --blue: #3b82f6; --gold: #f59e0b; --accent: #38bdf8; }
:root[data-season="storm"] { --blue: #8b5cf6; --gold: #c4b5fd; --accent: #a78bfa; }
:root[data-season="neon"]  { --blue: #06b6d4; --gold: #f472b6; --accent: #22d3ee; }
:root[data-season="ember"] { --blue: #f97316; --gold: #fbbf24; --accent: #fb923c; }
:root[data-season="jade"]  { --blue: #10b981; --gold: #a3e635; --accent: #34d399; }
:root[data-season="rose"]  { --blue: #ec4899; --gold: #fda4af; --accent: #f472b6; }
/* S3「星海啟示錄」：軌道藍 × 星塵金 × 星雲紫。
   取色與賽季預覽頁同源，兩邊看起來是同一個世界。 */
:root[data-season="stellar"] { --blue: #38bdf8; --gold: #f5c451; --accent: #9d7bff; }

/* ══════════════ reset ══════════════ */
* { box-sizing: border-box; margin: 0; padding: 0; }
body { background: var(--bg); color: var(--text);
  font-family: 'Inter', 'Segoe UI', -apple-system, 'Noto Sans TC', sans-serif;
  font-size: 14px; -webkit-font-smoothing: antialiased; }
a { color: inherit; text-decoration: none; }
/* 數字統一等寬，避免跳動 */
.stock-price, .stock-change, .chart-price, .rank-assets, .pbar-stat .val,
#liveClock, #priceCountdown, #divCountdown { font-variant-numeric: tabular-nums; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 8px; border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: var(--muted); }

/* ══════════════ layout：rail + header + 三欄工作台 ══════════════
   .app 用 grid 分成「左側 rail」與「右側內容堆疊」，右側再以 rows 切出
   header / ticker / playerBar / 工作區。工作區吃 1fr 並自行內捲，
   故不再需要 calc(100vh - 57px) 這種硬編碼 header 高度。 */
.app {
  display: grid;
  grid-template-columns: var(--rail-w) 1fr;
  height: 100vh; height: 100dvh;
}
.app > .rail { grid-row: 1; }
/* flex column 而非固定列數的 grid：各頁子元素數量不同（首頁 4 個、藏品頁 2 個），
   讓最後的內容區以 flex:1 吃滿剩餘高度即可，不必寫死列數。 */
.app > .app-body {
  display: flex; flex-direction: column;
  min-width: 0; min-height: 0;
}
.app > .app-body > header,
.app > .app-body > #newsTicker,
.app > .app-body > #playerBar { flex: 0 0 auto; }
.layout, .page { flex: 1 1 auto; min-height: 0; }

/* 左側工具軌 */
.rail {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 10px 0; background: var(--bg2);
  border-right: 1px solid var(--border); overflow: hidden;
}
.rail .rail-mark { font-size: 20px; line-height: 1; margin-bottom: 4px; }
.rail .rail-spacer { flex: 1; }
/* rail 內的按鈕改成正方形圖示鈕（沿用 .toggle-btn 的顏色與狀態） */
.rail .toggle-btn {
  width: 38px; height: 38px; padding: 0; font-size: 16px;
  display: flex; align-items: center; justify-content: center;
  border-color: transparent; border-radius: 10px;
}
.rail .toggle-btn:hover { border-color: var(--border); }
#langToggle { font-size: 12px !important; font-weight: 700; }

/* 三欄工作台 */
.layout {
  display: grid;
  grid-template-columns: var(--col-a) minmax(0, 1fr) var(--col-c);
  min-height: 0;   /* 關鍵：grid 子項預設 min-height:auto 會被內容撐破 */
}
/* .work 在 XL 用 display:contents 讓 col-b / col-c 直接成為 .layout 的格子；
   窄螢幕時它變成真正的容器，讓兩者堆疊並「一起」捲動。 */
.work { display: contents; }
.col-a, .col-b, .col-c { min-width: 0; min-height: 0; overflow-y: auto; }
.col-a { border-right: 1px solid var(--border); }
.col-b { display: flex; flex-direction: column; padding: 18px; gap: 18px; }
.col-c { border-left: 1px solid var(--border); padding: 18px; display: flex; flex-direction: column; gap: 18px; }
/* 情報欄兩個面板各自內捲，不讓整欄無限長 */
.col-c > .panel { display: flex; flex-direction: column; min-height: 0; }
.col-c > .panel > div:last-child { overflow-y: auto; min-height: 0; }
#newsPanel { flex: 1 1 60%; }
#rankPanel { flex: 1 1 40%; }
/* S3 新面板：沒資料時 JS 會整塊隱藏，有資料時與其他面板一起分配高度 */
#honorPanel { flex: 0 1 auto; max-height: 40%; }
#rocketPanel { flex: 0 1 auto; max-height: 45%; }

/* ══════════════ header ══════════════ */
header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding: 10px 20px; border-bottom: 1px solid var(--border);
  background: var(--bg2); position: relative;
}
/* 賽季主題色細頂條 */
header::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px;
  height: 2px; background: linear-gradient(90deg, var(--accent), transparent 70%);
  transition: background .35s ease; }
header h1 { font-size: 17px; font-weight: 800; letter-spacing: .5px; white-space: nowrap; }
.hdr-group { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.hdr-sep { width: 1px; height: 20px; background: var(--border); margin: 0 2px; }
#liveClock { color: var(--text); font-size: 12px; font-weight: 700; }
.season-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px 3px 4px; border-radius: 20px; font-size: 12px; font-weight: 600;
  background: var(--bg3); color: var(--text); border: 1px solid var(--border);
  cursor: pointer;
}
.season-badge .sb-tag {
  background: var(--gold); color: #1b2434; font-weight: 800; border-radius: 20px;
  padding: 1px 8px; font-size: 11px; letter-spacing: .5px;
}
/* 開市/收市：改用 class，讓樣式可完全脫離 Jinja 進入靜態 CSS */
.status-badge { padding: 4px 12px; border-radius: 20px; font-size: 12px; font-weight: 600; }
.status-badge.open { background: var(--badge-open-bg); color: var(--green); }
.status-badge.closed { background: var(--badge-closed-bg); color: var(--red); }

/* ══════════════ 側欄清單 ══════════════ */
.sidebar-section { border-bottom: 1px solid var(--border); }
.sidebar-title { padding: 10px 16px; font-size: 11px; font-weight: 700; letter-spacing: 1px; color: var(--muted); text-transform: uppercase;
  position: sticky; top: 0; z-index: 5; background: var(--bg2); border-bottom: 1px solid var(--border);
  display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.stock-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 9px 16px; cursor: pointer; transition: background .12s;
  border-bottom: 1px solid var(--border);
  border-left: 3px solid transparent;   /* 預留，避免 active 時位移 */
}
.stock-row:hover { background: var(--bg3); }
.stock-row.active { background: var(--bg3); border-left-color: var(--blue); }
.stock-ticker { font-weight: 700; font-size: 13px; color: var(--blue); width: 48px; }
.stock-ticker.s1 { color: #06b6d4; }   /* S1 專屬公司代號：深海青色 */
.market-group-hd { font-size: 11px; font-weight: 700; color: #06b6d4; letter-spacing: .5px;
  padding: 8px 10px 4px; margin-top: 4px; border-top: 1px dashed var(--border); }
.stock-name { flex: 1; color: var(--muted); font-size: 12px; }

/* ══════════════ 主分頁 ══════════════
   .tabpane 用 display:none 而不是 visibility/opacity —— 隱藏的分頁必須完全
   不佔版面，否則 .layout 的高度計算會把行情頁撐歪。
   行情頁本身是 flex 撐滿高度的工作台，其餘分頁單純可捲。 */
.maintabs {
  display: flex; gap: 4px; padding: 6px 16px 0; flex: none;
  border-bottom: 1px solid var(--border);
}
.mtab {
  padding: 7px 16px; border: 0; background: transparent; cursor: pointer;
  color: var(--muted); font-size: 13px; font-weight: 600;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color .12s, border-color .12s;
}
.mtab:hover { color: var(--text); }
.mtab.active { color: var(--accent); border-bottom-color: var(--accent); }
.tabpane { display: none; min-height: 0; }
.tabpane.active { display: flex; flex-direction: column; flex: 1; }
#paneMarket.active { display: flex; }
/* 這裡漏掉任何一個分頁，它就會沿用 .tabpane.active 的 flex column，
   內層容器被當成 flex item 壓縮成內容寬度，整頁只剩中間細細一條。 */
#paneNews.active, #paneCollect.active, #paneSeason.active, #paneDex.active {
  display: block; overflow-y: auto; padding: 14px 16px 40px;
}
@media (max-width: 639px) {
  /* 分頁列在手機上必須完整可見、不能橫滑 —— 會滑的導覽列等於把分頁藏起來，
     使用者不會知道右邊還有東西。改成五等分填滿寬度。 */
  .maintabs { padding: 4px 4px 0; overflow-x: hidden; gap: 0; }
  .mtab {
    flex: 1 1 0; min-width: 0; padding: 7px 2px; font-size: 12px;
    white-space: nowrap; text-align: center; overflow: hidden;
  }
}
/* 很窄的機型（iPhone SE 等）再縮一級，仍然五個都塞得下 */
@media (max-width: 359px) {
  .mtab { font-size: 11px; letter-spacing: -.02em; }
}

/* ══════════════ 藏品分頁 ══════════════
   類別一律加 c 前綴：這些樣式跟行情頁共存於同一份 CSS，
   用 .card / .grid / .tag 這種通用名稱一定會撞到既有規則。 */
.cwrap { max-width: 1100px; margin: 0 auto; }
.cfilters { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.fbtn { padding: 6px 14px; border-radius: 999px; border: 1px solid var(--border);
  background: var(--bg2); color: var(--text); font-size: 13px; cursor: pointer; transition: all .15s; }
.fbtn:hover { border-color: var(--muted); }
.fbtn.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.cgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; }
.ccard { background: var(--bg2); border: 1px solid var(--border); border-left-width: 4px;
  border-radius: 12px; padding: 12px 14px; box-shadow: 0 1px 2px rgba(0,0,0,.18); }
.ccard .cnm { font-weight: 700; font-size: 15px; margin-bottom: 4px; }
.ccard .cmeta { color: var(--muted); font-size: 12px; line-height: 1.7; }
.ccard .cscore { color: var(--gold); font-weight: 700; font-size: 15px; margin-top: 6px; }
.ctag { display: inline-block; font-size: 11px; font-weight: 700; padding: 1px 7px;
  border-radius: 10px; margin-left: 4px; }
.ctag.season { background: var(--accent); color: #fff; }
.ctag.auction { background: var(--gold); color: #1b2434; }
.ctag.traded { background: var(--muted); color: #fff; }
.ctag.mystery { background: var(--bg3); color: var(--text); border: 1px solid var(--accent); }
.cempty { color: var(--muted); text-align: center; padding: 60px 0; }

/* ── 迷你走勢線 ───────────────────────────────────────────────────────────
   純數字的清單要一檔一檔點開才知道形狀；一條 52px 的走勢線，
   整個市場的樣貌掃一眼就讀完了 —— 這正是網頁相對 Discord 的核心優勢。
   flex:none 是必要的：沒有它，走勢線會在窄欄位被壓扁成一條垂直線。 */
.spark { width: 52px; height: 20px; flex: none; margin: 0 8px; opacity: .85; }
.spark svg { display: block; overflow: visible; }
.stock-row:hover .spark, .stock-row.active .spark { opacity: 1; }
@media (max-width: 639px) { .spark { width: 44px; } }

/* ── 查封標示 ─────────────────────────────────────────────────────────────
   查封是突發事件，且期間完全不能買賣 —— 標示必須在掃一眼清單時就看得到，
   所以整列染色，而不是只加一個小圖示。 */
.stock-row.frozen { background: rgba(239, 68, 68, .10); border-left-color: #ef4444; }
.stock-row.frozen:hover { background: rgba(239, 68, 68, .16); }
.stock-row.frozen .stock-ticker { color: #ef4444; }
.seize-tag {
  display: none; font-size: 10px; font-weight: 700; color: #fff;
  background: #b91c1c; border-radius: 4px; padding: 1px 5px; margin-left: 6px;
  white-space: nowrap; vertical-align: middle;
}
.stock-row.frozen .seize-tag { display: inline-block; }
/* 圖表標題旁的查封橫幅：選到該公司時說明還要多久解封、天花板在哪 */
.seize-banner {
  display: none; margin: 6px 0 2px; padding: 8px 12px; border-radius: 8px;
  background: rgba(239, 68, 68, .12); border: 1px solid rgba(239, 68, 68, .45);
  color: #ef4444; font-size: 12px; line-height: 1.6;
}
.seize-banner.on { display: block; }
.seize-banner b { color: #fca5a5; }
.stock-price { font-weight: 600; text-align: right; }
.stock-change { font-size: 11px; text-align: right; min-width: 58px; }
.up { color: var(--up); }
.down { color: var(--down); }

/* ══════════════ 卡片 / 面板 ══════════════ */
.chart-card, .panel {
  background: var(--bg2); border: 1px solid var(--border); border-radius: 12px; padding: 18px;
  box-shadow: 0 1px 2px rgba(0,0,0,.18);
}
/* col-b 內只有圖表卡可伸縮；其餘（IPO 等）保持自然高度，
   否則圖表卡的 min-height 壓不下去，被擠掉的會是它們，內容就會溢出疊到圖上。
   空間真的不足時由 col-b 自己捲動。 */
.col-b > * { flex: 0 0 auto; }
/* 圖表卡吃滿 col-b 剩餘高度，圖本身再 flex:1。
   min-height 用 min-content：卡片絕不會被壓到小於「標題+統計列+內距+圖表最小高」，
   否則 flex 會把卡片壓扁而圖表壓不下去，圖就會溢出卡片疊到下方面板上。
   （前一行 px 值僅供不支援 min-content 的舊瀏覽器回退。） */
#singleChartCard { display: flex; flex-direction: column; flex: 1 1 auto;
  min-height: 460px; min-height: min-content; }
/* overflow:hidden 是安全網：lightweight-charts 的 canvas 是 position:absolute，
   內部尺寸一旦與容器不同步就會畫到容器外、蓋住下方的 IPO 面板。裁掉即可結構性杜絕重疊。 */
#priceChart { flex: 1 1 auto; min-height: 320px; width: 100%; overflow: hidden; }
/* 卡片內除了圖以外的區塊都不參與伸縮，否則會跟圖搶高度 */
#singleChartCard > .chart-header, #singleChartCard > #statRow, #etfPanel { flex: 0 0 auto; }
#etfPanel { margin-top: 12px; border-top: 1px solid var(--border); padding-top: 10px; }
/* 情報欄面板：標題列固定，只有內容區捲動 */
#newsPanel > .row, #newsPanel > #newsTabs, .col-c > .panel > h2 { flex: 0 0 auto; }
.chart-header { display: flex; align-items: baseline; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.chart-title { font-size: 16px; font-weight: 700; }
.chart-price { font-size: 26px; font-weight: 800; letter-spacing: -.5px; }
.chart-subtitle { color: var(--muted); font-size: 12px; }
.chart-toggle { margin-left: auto; display: flex; gap: 4px; }
.chart-stats { display: flex; gap: 18px; flex-wrap: wrap; margin-bottom: 12px;
  font-size: 12px; color: var(--muted); }
.chart-stats b { color: var(--text); font-weight: 700; }
.panel h2 { font-size: 12px; font-weight: 700; margin-bottom: 12px; color: var(--muted);
  text-transform: uppercase; letter-spacing: 1.2px;
  display: flex; align-items: center; gap: 8px; }
.panel h2::after { content: ""; flex: 1; height: 1px; background: var(--border); }

/* ══════════════ controls ══════════════ */
.toggle-btn {
  background: transparent; color: var(--muted); border: 1px solid var(--border);
  border-radius: 8px; padding: 5px 12px; font-size: 12px; font-weight: 600;
  cursor: pointer; transition: all .15s; line-height: 1.4;
}
.toggle-btn:hover { color: var(--text); background: var(--bg3); border-color: var(--muted); }
.toggle-btn.active { background: var(--blue); color: #fff; border-color: var(--blue); }
.news-filter { background: var(--bg3); color: var(--text); border: 1px solid var(--border);
  border-radius: 6px; padding: 4px 8px; font-size: 12px; max-width: 200px; cursor: pointer; }
.pid-input { background: var(--bg3); color: var(--text); border: 1px solid var(--border);
  border-radius: 6px; padding: 4px 8px; font-size: 13px; width: 100px; }
.tbl-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }

/* ══════════════ 玩家資訊列 ══════════════ */
#playerBar { display: flex; gap: 20px; align-items: center; padding: 10px 20px;
  background: var(--bg2); border-bottom: 1px solid var(--border); flex-wrap: wrap; }
#playerBar .pbar-stat + .pbar-stat { padding-left: 20px; border-left: 1px solid var(--border); }
.pbar-name { font-weight: 700; font-size: 15px; color: var(--blue); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pbar-badge { display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--gold); border-radius: 7px; padding: 1px 7px; background: rgba(245,158,11,.12); font-size: 15px; line-height: 1.4; }
.pbar-title { color: var(--gold); }
.pbar-stat { display: flex; flex-direction: column; }
.pbar-stat .label { font-size: 11px; color: var(--muted); }
.pbar-stat .val { font-size: 16px; font-weight: 700; }
.pbar-link { cursor: pointer; }
.pbar-link .val { text-decoration: underline; }

/* ══════════════ 持倉 / 訂單 ══════════════ */
.hold-row { padding: 10px 16px; border-bottom: 1px solid var(--border); cursor: pointer; }
.hold-row:hover { background: var(--bg3); }
.hold-top { display: flex; justify-content: space-between; align-items: center; }
.hold-tk { font-weight: 700; color: var(--blue); }
.hold-sub { font-size: 11px; color: var(--muted); margin-top: 2px; }
.ord-row { padding: 9px 16px; border-bottom: 1px solid var(--border); font-size: 12px; }
.ord-top { display: flex; justify-content: space-between; align-items: center; }
.ord-side-buy { color: var(--up); font-weight: 700; }
.ord-side-sell { color: var(--down); font-weight: 700; }
.ord-st { font-size: 11px; padding: 1px 6px; border-radius: 8px; }
.ord-st.pend { background: var(--pill-pend-bg); color: var(--gold); }
.ord-st.fill { background: var(--pill-fill-bg); color: var(--pill-fill-fg); }
.ord-st.canc { background: var(--pill-canc-bg); color: var(--pill-canc-fg); }
.ord-sub { color: var(--muted); margin-top: 2px; }

/* ══════════════ IPO ══════════════ */
.ipo-card { border: 1px solid var(--border); border-radius: 8px; padding: 14px; margin-bottom: 12px; background: var(--bg3); }
.ipo-card.upcoming { opacity: 0.6; filter: grayscale(0.5); }   /* 公告期：灰色 */
.ipo-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.ipo-title { font-size: 15px; font-weight: 700; }
.ipo-badge { font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 10px; }
.ipo-badge.sub { background: var(--pill-fill-bg); color: var(--green); }
.ipo-badge.up { background: var(--pill-canc-bg); color: var(--pill-canc-fg); }
.ipo-meta { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin: 8px 0; }
.ipo-meta div { font-size: 12px; }
.ipo-meta .label { color: var(--muted); font-size: 11px; }
.ipo-meta .val { font-weight: 600; }
.ipo-prospectus { font-size: 12px; color: var(--text); line-height: 1.6; white-space: pre-wrap;
  border-top: 1px solid var(--border); padding-top: 8px; margin-top: 8px; display: none; }
.ipo-toggle { font-size: 12px; color: var(--blue); cursor: pointer; user-select: none; }

/* ══════════════ 新聞 / 排行 ══════════════ */
.news-item { padding: 10px 0; border-bottom: 1px solid var(--border); }
.news-item:last-child { border-bottom: none; }
.news-ticker { font-size: 10px; font-weight: 700; color: var(--blue); background: var(--news-tk-bg); padding: 2px 6px; border-radius: 4px; }
.news-title { font-size: 13px; font-weight: 600; margin: 4px 0 2px; }
.news-body { font-size: 12px; color: var(--muted); line-height: 1.5; }
.news-time { font-size: 11px; color: var(--muted); margin-top: 4px; }
/* 霓虹市場廣播：發源地 + 可信度條 */
.news-cred { display: flex; align-items: center; gap: 8px; margin: 4px 0 2px; font-size: 11px; flex-wrap: wrap; }
.news-src { color: var(--muted); }
.cred-bar { flex: 1; min-width: 60px; height: 4px; border-radius: 3px; background: var(--bg3); overflow: hidden; }
.cred-bar i { display: block; height: 100%; border-radius: 3px; }
.rank-row { display: flex; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--border); gap: 10px; }
.rank-row:last-child { border-bottom: none; }
.rank-num { width: 24px; font-weight: 700; color: var(--muted); }
.rank-name { flex: 1; font-weight: 500; }
.rank-assets { font-weight: 700; }
.rank-pnl { font-size: 11px; color: var(--muted); }

/* ══════════════ 新聞跑馬燈 ══════════════ */
#newsTicker { background: var(--bg2); border-bottom: 1px solid var(--border); display: flex; align-items: stretch; overflow: hidden; }
#newsTicker .nt-label { flex: 0 0 auto; background: var(--red); color: #fff; font-size: 12px; font-weight: 700; padding: 6px 12px; display: flex; align-items: center; z-index: 2; }
#newsTicker .nt-viewport { flex: 1 1 auto; overflow: hidden; position: relative; }
#newsTicker .nt-track { display: inline-block; white-space: nowrap; padding-left: 100%; animation: nt-scroll 60s linear infinite; font-size: 13px; line-height: 30px; }
#newsTicker:hover .nt-track { animation-play-state: paused; }
#newsTicker .nt-item { margin: 0 26px; color: var(--text); }
#newsTicker .nt-item b { color: var(--blue); }
@keyframes nt-scroll { 0% { transform: translateX(0); } 100% { transform: translateX(-100%); } }

/* ══════════════ 遮罩 / 彈窗 ══════════════ */
.overlay { position: fixed; inset: 0; background: rgba(0,0,0,.6); z-index: 50; display: none; align-items: flex-start; justify-content: center; padding: 40px 16px; overflow-y: auto; }
.overlay.show { display: flex; }
.modal { background: var(--bg2); border: 1px solid var(--border); border-radius: 14px; max-width: 900px; width: 100%; padding: 22px 26px; }
.modal h2 { margin-top: 0; }
.modal .close-x { float: right; cursor: pointer; color: var(--muted); font-size: 22px; line-height: 1; }
.faq-sec { margin: 16px 0; }
.faq-sec h3 { color: var(--blue); font-size: 15px; margin: 12px 0 6px; border-left: 3px solid var(--blue); padding-left: 8px; }
.faq-sec p, .faq-sec li { font-size: 13px; line-height: 1.7; color: var(--text); }
.faq-sec code { background: var(--bg3); padding: 1px 6px; border-radius: 5px; color: var(--red); font-size: 12px; }
.calc-box { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 6px; margin-top: 6px; font-size: 12px; color: var(--muted); }
.calc-box .calc-out { word-break: break-all; }
.calc-box input { width: 52px; background: var(--bg3); border: 1px solid var(--border); border-radius: 6px; color: var(--text); padding: 3px 6px; font-size: 12px; }

/* ══════════════ 多圖比較 ══════════════ */
/* 比較卡與單圖卡互斥顯示。內部各圖高度由 renderCompare 以 JS 計算，
   故這裡維持 block 排版（同原設計），只讓卡片本身吃滿 col-b 剩餘高度。 */
#compareCard { flex: 1 1 auto; }
.cmp-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-top: 10px; }
.cmp-cell { border: 1px solid var(--border); border-radius: 10px; padding: 8px; min-width: 0; overflow: hidden; }
.cmp-cell .cmp-h { font-size: 13px; font-weight: 700; margin-bottom: 4px; }
.cmp-pick { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.cmp-pick label { font-size: 12px; background: var(--bg3); border: 1px solid var(--border); border-radius: 8px; padding: 4px 8px; cursor: pointer; }

/* ══════════════ utilities ══════════════ */
.hidden { display: none !important; }
.row { display: flex; align-items: center; }
.gap-6 { gap: 6px; } .gap-10 { gap: 10px; } .gap-12 { gap: 12px; }
.wrap { flex-wrap: wrap; }
.muted { color: var(--muted); }
.fs-11 { font-size: 11px; } .fs-12 { font-size: 12px; }
.ta-r { text-align: right; }
.spread { justify-content: space-between; }

/* ══════════════ breakpoints ══════════════
   XL ≥1440 用上方預設；以下逐級降級。 */
@media (max-width: 1439px) {
  :root { --col-a: 280px; --col-c: 300px; }
}
/* M：情報欄降級為工作區底部的 2 欄 grid，與圖表區一起捲動。
   必須限定在區間內：低於 860px 由 S 區塊整個換掉版面，若這裡用 max-width 單邊寫法，
   底下的 height:420px 會一路洩漏到手機，把圖表卡壓成固定 420px 而內容溢出疊到下方。 */
@media (min-width: 860px) and (max-width: 1099px) {
  .layout { grid-template-columns: var(--col-a) minmax(0, 1fr); }
  .work { display: flex; flex-direction: column; min-width: 0; min-height: 0; overflow-y: auto; }
  .col-b, .col-c { overflow: visible; flex: 0 0 auto; }
  .col-c { border-left: none; padding: 0 18px 18px;
    display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
  .col-c > .panel > div:last-child { overflow: visible; }
  #newsPanel, #rankPanel { flex: initial; }
  .col-b { padding-bottom: 0; }
  #singleChartCard { flex: 0 0 auto; height: 420px; }
}
/* S：rail 收成頂部橫向列 */
@media (max-width: 859px) {
  /* 手機改回「整頁自然捲動 + 固定高度圖表」（同舊版）。
     桌機把 app 鎖在 100dvh 內分區捲動很合適，但手機只要多出一列（例如查詢玩家後
     出現的 #playerBar，實測高達 155px）就會把圖表整個擠出視窗且搆不到。
     這裡解除高度鎖定，讓內容自然往下排、整頁捲動。 */
  .app { height: auto; min-height: 100dvh; }
  .app > .app-body { min-height: 0; }
  .layout, .page { flex: 0 0 auto; }
  /* 注意：.col-a 不可設 overflow:visible —— 它有 max-height 限高，
     取消內捲會讓清單被裁掉且捲不到。只有不限高的容器才放行。 */
  .work, .col-b, .col-c { overflow: visible; }
  /* 圖表固定高度，不再與其他區塊搶空間。height:auto 是必要的：
     要抵銷 M 區塊可能殘留的固定高度，讓卡片永遠撐到內容所需高度。 */
  #singleChartCard, #compareCard { flex: 0 0 auto; height: auto; min-height: 0; }
  #priceChart { flex: 0 0 auto; height: 300px; min-height: 0; }
  /* 情報欄在手機上單欄直排（不依賴 M 區塊的 grid 設定） */
  .col-c { display: flex; flex-direction: column; border-left: none; }
  .col-c > .panel > div:last-child { overflow: visible; }
  #newsPanel, #rankPanel { flex: 0 0 auto; }

  .app { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .rail { flex-direction: row; justify-content: flex-start;
    border-right: none; border-bottom: 1px solid var(--border);
    padding: 6px 10px; overflow-x: auto; }
  .rail .rail-mark { margin: 0 6px 0 0; }
  .rail .rail-spacer { display: none; }
  /* 標頭次要資訊提早收起，讓 header 維持單列 */
  #priceCountdown, #divCountdown { display: none; }
  .layout { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr); }
  .col-a { border-right: none; border-bottom: 1px solid var(--border); max-height: 40vh; }
}
/* XS：單欄堆疊 */
@media (max-width: 639px) {
  header { padding: 10px 12px; gap: 8px 10px; }
  header h1 { font-size: 16px; }
  .season-badge { font-size: 11px; padding: 2px 8px 2px 3px; }
  .season-badge .sb-tag { font-size: 10px; padding: 1px 6px; }
  #liveClock { font-size: 11px; }
  .pid-input { width: 82px; }
  .toggle-btn { padding: 4px 9px; }
  /* 手機：行情清單原本吃掉 44vh，把圖表擠到摺線以下只剩不到一半可見。
     壓到 28vh，讓圖表卡在首屏就能完整顯示（清單本身仍可內捲）。 */
  .col-a { max-height: 28vh; }
  .col-b { padding: 12px; gap: 14px; }
  .col-c { grid-template-columns: 1fr; padding: 0 12px 12px; gap: 14px; }
  .chart-card, .panel { padding: 12px; }
  /* 手機不設卡片最小高，讓它單純吃滿 col-b 剩餘空間；圖表自身的最小高才是底線 */
  #singleChartCard { min-height: 0; }
  #priceChart { min-height: 220px; }
  /* 標頭與工具軌收緊，把高度讓給圖表 */
  header { padding: 8px 12px; gap: 6px 10px; }
  .rail { padding: 4px 10px; }
  .rail .toggle-btn { width: 34px; height: 34px; font-size: 15px; }
  .chart-header { flex-wrap: wrap; gap: 6px 10px; }
  .chart-price { font-size: 20px; }
  .chart-toggle { margin-left: 0; }
  #playerBar { gap: 8px 16px; padding: 10px 14px; }
  #playerBar .pbar-stat + .pbar-stat { padding-left: 0; border-left: none; }
  .pbar-stat { flex: 1 1 40%; }
  .pbar-name { font-size: 14px; }
  #statRow { gap: 10px 14px; }
  .ipo-meta { grid-template-columns: repeat(2, 1fr); }
  .cmp-grid { grid-template-columns: 1fr; }
  .overlay { padding: 16px 8px; }
  .modal { padding: 18px 14px; border-radius: 12px; }
  .modal h2 { font-size: 18px; }
  .faq-sec h3 { font-size: 14px; }
}

/* ══════════════ S2「霓虹永夜」氛圍層 ══════════════
   只在「深色 + 賽季主題 neon」時套用；淺色模式與其他賽季色完全不受影響。
   放在檔案最後，靠後置順序覆蓋前面的 token 與元件樣式（不用 !important）。
   選擇器故意寫成 :not([data-theme="light"])，因為預繪腳本一定會寫入 data-theme，
   所以「非 light」等同「dark」，之後若新增第三種色調也不會漏掉。 */
:root[data-season="neon"]:not([data-theme="light"]) {
  --bg: #07050f; --bg2: #100b1e; --bg3: #191029;
  --border: #2c1f4d; --text: #ece7ff; --muted: #8b7cb8;
  /* 漲跌改用霓虹螢光色（仍是台股慣例紅漲綠跌，只是更亮） */
  --green: #2bf5a5; --red: #ff3d7f;
  --blue: #22d3ee; --gold: #f472b6; --accent: #22d3ee;
  --chart-grid: #241a3d;
  --news-tk-bg: #2a1145;
  --pill-pend-bg: #3d1a3a; --pill-fill-bg: #0d3b34; --pill-fill-fg: #2bf5a5;
  --pill-canc-bg: #241a3d; --pill-canc-fg: #8b7cb8;
  --badge-open-bg: #0d3b34; --badge-closed-bg: #3d0f28;
  /* 霓虹光暈的兩個色相，元件只引用這兩個變數 */
  --glow-c: rgba(34,211,238,.55); --glow-m: rgba(244,114,182,.45);
}

/* 永夜天空：兩盞遠處的霓虹（青／洋紅）打在畫面角落。
   固定在 body 上而非 .app，捲動時光暈不會跟著跑。 */
:root[data-season="neon"]:not([data-theme="light"]) body {
  background:
    radial-gradient(900px 620px at 88% -12%, rgba(244,114,182,.13), transparent 62%),
    radial-gradient(820px 640px at 4% 108%, rgba(34,211,238,.11), transparent 60%),
    var(--bg);
  background-attachment: fixed;
}
/* 掃描線：極低對比、4px 週期。pointer-events:none 確保不吃點擊，
   z-index 0 搭配下方 .app 的 z-index 1，永遠壓在介面底下。 */
:root[data-season="neon"]:not([data-theme="light"]) body::before {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background: repeating-linear-gradient(180deg,
    rgba(255,255,255,.022) 0 1px, transparent 1px 4px);
}
:root[data-season="neon"]:not([data-theme="light"]) .app { position: relative; z-index: 1; }

/* 半透明面板：讓底下的霓虹微微透出來，才有「城市夜景」的層次 */
:root[data-season="neon"]:not([data-theme="light"]) header,
:root[data-season="neon"]:not([data-theme="light"]) #newsTicker,
:root[data-season="neon"]:not([data-theme="light"]) #playerBar,
:root[data-season="neon"]:not([data-theme="light"]) .rail {
  background: rgba(16,11,30,.82); backdrop-filter: blur(6px);
}
:root[data-season="neon"]:not([data-theme="light"]) .chart-card,
:root[data-season="neon"]:not([data-theme="light"]) .panel {
  background: rgba(16,11,30,.78);
  box-shadow: 0 0 0 1px rgba(34,211,238,.06), 0 8px 26px rgba(0,0,0,.45);
}
:root[data-season="neon"]:not([data-theme="light"]) .sidebar-title {
  background: rgba(16,11,30,.92); color: #b39ddb;
}

/* 招牌字：標題與代號帶光暈。字級小的地方（stock-ticker）用弱光暈，
   否則等寬數字會糊掉。 */
:root[data-season="neon"]:not([data-theme="light"]) header h1 {
  color: #fff; text-shadow: 0 0 10px var(--glow-c), 0 0 26px rgba(244,114,182,.35);
}
:root[data-season="neon"]:not([data-theme="light"]) header::after {
  height: 2px;
  background: linear-gradient(90deg, var(--accent), var(--gold) 42%, transparent 78%);
  box-shadow: 0 0 12px var(--glow-c);
}
:root[data-season="neon"]:not([data-theme="light"]) .chart-price,
:root[data-season="neon"]:not([data-theme="light"]) .pbar-name {
  text-shadow: 0 0 12px rgba(34,211,238,.28);
}
:root[data-season="neon"]:not([data-theme="light"]) .stock-ticker {
  text-shadow: 0 0 8px rgba(34,211,238,.35);
}
:root[data-season="neon"]:not([data-theme="light"]) .market-group-hd {
  color: var(--gold); text-shadow: 0 0 8px var(--glow-m);
}
:root[data-season="neon"]:not([data-theme="light"]) .up { text-shadow: 0 0 9px rgba(255,61,127,.4); }
:root[data-season="neon"]:not([data-theme="light"]) .down { text-shadow: 0 0 9px rgba(43,245,165,.35); }

/* 互動元件：選中狀態發光 */
:root[data-season="neon"]:not([data-theme="light"]) .stock-row.active {
  background: linear-gradient(90deg, rgba(34,211,238,.10), transparent 60%);
  border-left-color: var(--accent);
  box-shadow: inset 3px 0 12px -4px var(--glow-c);
}
:root[data-season="neon"]:not([data-theme="light"]) .toggle-btn.active {
  background: var(--accent); color: #07050f; border-color: var(--accent);
  box-shadow: 0 0 14px var(--glow-c);
}
:root[data-season="neon"]:not([data-theme="light"]) .rail .toggle-btn.active {
  background: transparent; color: var(--accent);
  border-color: var(--accent); box-shadow: 0 0 12px var(--glow-c);
}
:root[data-season="neon"]:not([data-theme="light"]) .rail .rail-mark {
  filter: drop-shadow(0 0 8px var(--glow-c));
}
:root[data-season="neon"]:not([data-theme="light"]) .season-badge .sb-tag {
  color: #150a1e; box-shadow: 0 0 12px var(--glow-m);
}
:root[data-season="neon"]:not([data-theme="light"]) .pbar-badge {
  border-color: var(--gold); background: rgba(244,114,182,.12);
  box-shadow: 0 0 10px rgba(244,114,182,.22);
}
:root[data-season="neon"]:not([data-theme="light"]) .status-badge.open {
  box-shadow: 0 0 12px rgba(43,245,165,.28);
}

/* 跑馬燈：紅底 LED 招牌感；標籤加緩慢呼吸而非閃爍，長時間看不刺眼 */
:root[data-season="neon"]:not([data-theme="light"]) #newsTicker .nt-label {
  background: linear-gradient(90deg, #ff3d7f, #b026ff);
  box-shadow: 0 0 16px rgba(255,61,127,.45);
  animation: neon-breathe 3.4s ease-in-out infinite;
}
:root[data-season="neon"]:not([data-theme="light"]) #newsTicker .nt-item b {
  color: var(--accent); text-shadow: 0 0 8px var(--glow-c);
}
@keyframes neon-breathe { 0%, 100% { filter: brightness(1); } 50% { filter: brightness(1.22); } }
/* 尊重系統的「減少動態」設定 */
@media (prefers-reduced-motion: reduce) {
  :root[data-season="neon"] #newsTicker .nt-label { animation: none; }
}

/* ── S3 火箭發射計劃 ────────────────────────────────────────────────────────
   進度條要一眼看出「離發射還有多遠」，所以用滿寬的長條而不是數字了事。 */
.rocket-row { padding: 7px 2px; border-bottom: 1px solid var(--border); }
.rocket-row:last-child { border-bottom: none; }
.rocket-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 12px; margin-bottom: 4px; gap: 8px;
}
.rocket-num { font-size: 11px; color: var(--muted); white-space: nowrap; }
.rocket-bar {
  height: 6px; border-radius: 3px; background: var(--bg3); overflow: hidden;
}
.rocket-bar > i { display: block; height: 100%; border-radius: 3px; transition: width .3s; }

/* ══════════════ 手機版 ══════════════
   直排順序維持「行情清單 → 圖表」：選股是手機上最高頻的動作，
   清單放在最上面才點得順手（曾經改成圖表在上，實際用起來選股反而變麻煩）。 */
@media (max-width: 639px) {
  .col-a { max-height: 34vh; }
  #priceChart { min-height: 260px; }

  /* 點擊目標：Apple 建議 44×44、Material 建議 48×48。
     原本工具鈕只有 34×34、ID 輸入框只有 25px 高 —— 手機上很容易按錯。
     桌機維持原尺寸，只在手機放大。 */
  .rail .toggle-btn { width: 44px; height: 44px; font-size: 17px; }
  .toggle-btn { padding: 10px 14px; min-height: 44px; }
  .pid-input { width: 96px; min-height: 44px; padding: 8px 10px; font-size: 16px; }
  .mtab { min-height: 44px; }
  .fbtn { min-height: 44px; padding: 10px 16px; }
  .news-filter { min-height: 44px; }
  /* 行情列每列也要好按：9px 內距在手機上偏窄 */
  .stock-row { padding: 12px 14px; }
}

/* ══════════════ 排行榜：高亮自己 ══════════════ */
.rank-row.me {
  background: linear-gradient(90deg, rgba(34,211,238,.16), transparent 75%);
  border-left: 3px solid var(--accent); margin-left: -3px;
  border-radius: 0 8px 8px 0;
}
.rank-row.me .rank-name { color: var(--text); font-weight: 700; }
.me-tag { display: inline-block; margin-left: 6px; padding: 0 6px; border-radius: 999px;
  background: var(--accent); color: #04121a; font-size: 10px; font-weight: 800; vertical-align: middle; }
/* 不在前 10 名時另外補上的那一列：用虛線隔開，表示中間有名次被略過 */
.rank-row.outside { margin-top: 8px; border-top: 1px dashed var(--border); padding-top: 10px; }

/* ══════════════ 藏品圖鑑 ══════════════ */
.dex-empty { color: var(--muted); text-align: center; padding: 56px 20px; line-height: 1.9; }
.dex-empty-i { font-size: 38px; margin-bottom: 10px; }
.dex-head { display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 8px; font-size: 15px; }
.dex-total { font-size: 20px; font-weight: 800; color: var(--accent); font-variant-numeric: tabular-nums; }
.dex-bar { display: inline-block; width: 90px; height: 5px; border-radius: 999px;
  background: var(--bg3); overflow: hidden; vertical-align: middle; }
.dex-bar.big { display: block; width: 100%; height: 8px; margin-bottom: 16px; }
.dex-bar i { display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--gold)); }
.dex-group { margin-bottom: 22px; }
.dex-gh { display: flex; align-items: center; gap: 10px; margin-bottom: 8px;
  padding-bottom: 6px; border-bottom: 1px solid var(--border); }
.dex-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); gap: 8px; }
.dex-cell { background: var(--bg2); border: 1px solid var(--border); border-left: 3px solid;
  border-radius: 8px; padding: 8px 10px; }
/* 未收集的格子壓暗但不隱藏 —— 圖鑑的樂趣有一半來自「還缺哪些」 */
.dex-cell.miss { opacity: .45; background: transparent; }
.dex-cell.gone .dex-nm { text-decoration: line-through; }
.dex-nm { font-size: 13px; font-weight: 600; margin-bottom: 2px; }
.dex-meta { font-size: 11px; color: var(--muted); }

/* ══════════════ 賽季預覽（資料驅動版）══════════════ */
.sp2 .sp-hero { text-align: center; padding: 26px 18px 22px; margin-bottom: 22px;
  border: 1px solid var(--border); border-radius: 16px;
  background: radial-gradient(120% 140% at 50% 0%, rgba(139,92,246,.16), transparent 62%), var(--bg2); }
.sp-kicker { font-size: 11px; letter-spacing: .22em; color: var(--muted); text-transform: uppercase; }
.sp-title { font-size: 30px; font-weight: 800; margin: 6px 0 12px; }
.sp-dates { display: flex; gap: 18px; justify-content: center; flex-wrap: wrap;
  font-size: 13px; color: var(--muted); }
.sp-cd { font-size: 24px; font-weight: 800; color: var(--gold); margin-top: 12px;
  font-variant-numeric: tabular-nums; }
.sp-titles { margin-top: 14px; font-size: 13px; color: var(--muted); }
.sp-h { font-size: 15px; font-weight: 700; margin: 24px 0 10px;
  padding-bottom: 6px; border-bottom: 1px solid var(--border); }
.sp-chips, .sp-tags { display: flex; flex-wrap: wrap; gap: 8px; }
.chip { display: inline-block; padding: 4px 12px; border-radius: 999px; font-size: 12px;
  background: var(--bg3); border: 1px solid var(--border); color: var(--text); }
.chip.warn { background: rgba(239,68,68,.12); border-color: rgba(239,68,68,.45); color: #fca5a5; }
.sp-cos { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 12px; }
.sp-co { background: var(--bg2); border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px; }
.sp-co.etf { border-color: var(--accent); }
.sp-co-hd { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.sp-tk { font-weight: 800; color: var(--accent); font-size: 14px; letter-spacing: .5px; }
.sp-nm { font-weight: 700; font-size: 14px; }
.sp-sec { font-size: 11px; color: var(--muted); border: 1px solid var(--border);
  border-radius: 999px; padding: 1px 8px; }
.sp-desc { font-size: 12px; color: var(--muted); line-height: 1.8; }
.sp-meta { font-size: 12px; margin-top: 8px; font-variant-numeric: tabular-nums; }
.sp-note { font-size: 12px; color: var(--muted); line-height: 1.8; margin-top: 10px;
  padding: 10px 12px; border-radius: 8px; background: rgba(239,68,68,.08);
  border: 1px solid rgba(239,68,68,.3); }
@media (max-width: 639px) {
  .sp-title { font-size: 22px; }
  .sp-cd { font-size: 19px; }
  .dex-grid { grid-template-columns: 1fr; }
  .sp-cos { grid-template-columns: 1fr; }
}

/* ══════════════ 圖鑑：寬螢幕要把空間用滿 ══════════════
   圖鑑有 400 多格，是全站最吃版面的一頁。1100px 置中在 1920 的螢幕上
   只用掉一半多，捲動距離變成兩倍 —— 這裡放寬到 1800 並縮小格寬，
   讓寬螢幕一次看到 8~9 欄。 */
#paneDex .cwrap { max-width: 1800px; }
#paneDex .dex-grid { grid-template-columns: repeat(auto-fill, minmax(186px, 1fr)); gap: 7px; }
/* 分類切換與總進度釘在頂端：400 多格捲到一半想換分類，不該再捲回最上面 */
#paneDex .dex-sticky {
  position: sticky; top: 0; z-index: 6; padding: 10px 0 8px;
  background: var(--bg); border-bottom: 1px solid var(--border); margin-bottom: 14px;
}
#paneDex .cfilters { margin-bottom: 0; }
#paneDex .dex-bar.big { margin-bottom: 10px; }
/* 分類標題也黏住，捲動時知道自己在看哪一區。
   偏移量不能寫死 —— 上方那塊的高度會隨分類數量與換行而變，寫死就會互相疊住。
   實際高度由 JS 量完寫進 --dex-sticky-h。 */
#paneDex .dex-gh {
  position: sticky; top: var(--dex-sticky-h, 104px); z-index: 5;
  background: var(--bg); padding-top: 6px;
}
@media (min-width: 1600px) { #paneDex .dex-grid { gap: 8px; } }
@media (max-width: 859px)  { #paneDex .dex-gh { position: static; } }

/* 藏品閣同樣是卡片格狀版面，寬螢幕一併放寬（賽季預覽以文字為主，維持 1100 較好讀） */
#paneCollect .cwrap { max-width: 1600px; }

/* ══════════════ S3「星海啟示錄」深色氛圍 ══════════════
   與 neon 同一套作法：放在檔案最後，靠後置順序覆蓋前面的 token 與元件樣式。
   選擇器寫成 :not([data-theme="light"])，預繪腳本一定會寫入 data-theme，
   所以「非 light」等同「dark」。 */
:root[data-season="stellar"]:not([data-theme="light"]) {
  --bg: #03050f; --bg2: #070b1c; --bg3: #121835;
  --border: #26305e; --text: #eef3ff; --muted: #98a4cf;
  /* 漲跌仍是台股慣例紅漲綠跌，調成適合深空背景的亮度 */
  --green: #34e0a1; --red: #ff5470;
  --blue: #38bdf8; --gold: #f5c451; --accent: #9d7bff;
  --chart-grid: #1b2450;
  --news-tk-bg: #17204a;
  --pill-pend-bg: #3a2f12; --pill-fill-bg: #0d3b34; --pill-fill-fg: #34e0a1;
  --pill-canc-bg: #1b2450; --pill-canc-fg: #98a4cf;
  --badge-open-bg: #0d3b34; --badge-closed-bg: #3d1024;
  /* 星雲光暈的兩個色相，元件只引用這兩個變數 */
  --glow-s: rgba(245,196,81,.5); --glow-n: rgba(157,123,255,.45);
}

/* 深空：星雲打在畫面角落。固定在 body 上而非 .app，捲動時光暈不跟著跑。 */
:root[data-season="stellar"]:not([data-theme="light"]) body {
  background:
    radial-gradient(1000px 700px at 78% -8%, rgba(139,92,246,.18), transparent 58%),
    radial-gradient(820px 820px at 8% 106%, rgba(56,189,248,.13), transparent 56%),
    radial-gradient(600px 420px at 50% 40%, rgba(245,196,81,.05), transparent 60%),
    var(--bg);
  background-attachment: fixed;
}
/* 星場：取代 neon 的掃描線。pointer-events:none 確保不吃點擊，
   z-index 0 搭配下方 .app 的 z-index 1，永遠壓在介面底下。 */
:root[data-season="stellar"]:not([data-theme="light"]) body::before {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background-image:
    radial-gradient(1px 1px at 20% 30%, rgba(255,255,255,.85), transparent),
    radial-gradient(1px 1px at 70% 15%, rgba(255,255,255,.6), transparent),
    radial-gradient(1px 1px at 45% 70%, rgba(255,255,255,.75), transparent),
    radial-gradient(1px 1px at 85% 60%, rgba(255,255,255,.5), transparent),
    radial-gradient(1px 1px at 12% 85%, rgba(255,255,255,.6), transparent),
    radial-gradient(2px 2px at 60% 45%, rgba(245,196,81,.45), transparent),
    radial-gradient(1px 1px at 33% 12%, rgba(56,189,248,.55), transparent);
  background-size: 340px 340px, 420px 420px, 300px 300px, 520px 520px,
                   380px 380px, 660px 660px, 480px 480px;
}
:root[data-season="stellar"]:not([data-theme="light"]) .app { position: relative; z-index: 1; }

/* 半透明面板：讓底下的星雲微微透出來 */
:root[data-season="stellar"]:not([data-theme="light"]) header,
:root[data-season="stellar"]:not([data-theme="light"]) #newsTicker,
:root[data-season="stellar"]:not([data-theme="light"]) #playerBar,
:root[data-season="stellar"]:not([data-theme="light"]) .maintabs,
:root[data-season="stellar"]:not([data-theme="light"]) .rail {
  background: rgba(7,11,28,.84); backdrop-filter: blur(6px);
}
:root[data-season="stellar"]:not([data-theme="light"]) .chart-card,
:root[data-season="stellar"]:not([data-theme="light"]) .panel {
  background: rgba(12,17,40,.78);
  box-shadow: 0 0 0 1px rgba(157,123,255,.07), 0 8px 26px rgba(0,0,0,.5);
}
:root[data-season="stellar"]:not([data-theme="light"]) .sidebar-title {
  background: rgba(7,11,28,.93); color: #b7c0e8;
}

/* 星光字：標題帶金色光暈。字級小的地方用弱光暈，否則等寬數字會糊掉。 */
:root[data-season="stellar"]:not([data-theme="light"]) header h1 {
  color: #fff; text-shadow: 0 0 10px var(--glow-s), 0 0 28px rgba(157,123,255,.35);
}
:root[data-season="stellar"]:not([data-theme="light"]) header::after {
  height: 2px;
  background: linear-gradient(90deg, var(--accent), var(--gold) 42%, transparent 78%);
  box-shadow: 0 0 12px var(--glow-n);
}
:root[data-season="stellar"]:not([data-theme="light"]) .chart-price,
:root[data-season="stellar"]:not([data-theme="light"]) .pbar-name {
  text-shadow: 0 0 12px rgba(157,123,255,.3);
}
:root[data-season="stellar"]:not([data-theme="light"]) .stock-ticker {
  text-shadow: 0 0 8px rgba(56,189,248,.35);
}
:root[data-season="stellar"]:not([data-theme="light"]) .market-group-hd {
  color: var(--gold); text-shadow: 0 0 8px rgba(245,196,81,.3);
}
:root[data-season="stellar"]:not([data-theme="light"]) .up { text-shadow: 0 0 9px rgba(255,84,112,.4); }
:root[data-season="stellar"]:not([data-theme="light"]) .down { text-shadow: 0 0 9px rgba(52,224,161,.35); }
:root[data-season="stellar"]:not([data-theme="light"]) .stock-row.active {
  background: linear-gradient(90deg, rgba(157,123,255,.12), transparent 60%);
  border-left-color: var(--accent);
  box-shadow: inset 3px 0 12px -4px var(--glow-n);
}
:root[data-season="stellar"]:not([data-theme="light"]) .toggle-btn.active,
:root[data-season="stellar"]:not([data-theme="light"]) .mtab.active {
  color: var(--gold); border-color: var(--gold);
  text-shadow: 0 0 8px rgba(245,196,81,.4);
}
:root[data-season="stellar"]:not([data-theme="light"]) .rail .toggle-btn.active {
  background: rgba(157,123,255,.14); box-shadow: 0 0 12px -2px var(--glow-n);
}
:root[data-season="stellar"]:not([data-theme="light"]) .rail .rail-mark {
  text-shadow: 0 0 12px var(--glow-n);
}
:root[data-season="stellar"]:not([data-theme="light"]) .season-badge .sb-tag {
  box-shadow: 0 0 10px rgba(245,196,81,.4);
}
:root[data-season="stellar"]:not([data-theme="light"]) .status-badge.open {
  box-shadow: 0 0 10px rgba(52,224,161,.28);
}
:root[data-season="stellar"]:not([data-theme="light"]) #newsTicker .nt-label {
  text-shadow: 0 0 8px var(--glow-s);
}
:root[data-season="stellar"]:not([data-theme="light"]) #newsTicker .nt-item b {
  color: var(--gold);
}

/* ══════════════ 字型切換 ══════════════
   刻意全部使用「系統已有的字型」，不下載任何網路字型：
   中文字型檔動輒數 MB，就算做了 unicode-range 分割也要多一個外部相依 ——
   K 線圖已經吊在 unpkg 上了，不該再多一個掛掉就毀版面的東西。
   代價是可選的中文字型受限於作業系統，這是划算的交換。

   表單元件（button/input/select）預設不繼承 font-family，
   沒有下面這條，切了字型後按鈕和輸入框會維持瀏覽器預設字型，看起來像沒切成功。 */
button, input, select, textarea { font-family: inherit; }

/* 字型堆疊集中在這裡：選單的預覽項目與實際套用共用同一份，
   不會出現「預覽長這樣、選下去變那樣」。
   每一組都刻意排進三個平台的對應字型（iOS／Android／Windows），
   排不到的平台會由 JS 偵測後在選單上標成「此裝置沒有」。 */
:root {
  --fp-sans: 'Inter', 'Segoe UI', -apple-system, 'PingFang TC',
    'Microsoft JhengHei', 'Noto Sans TC', 'Noto Sans CJK TC', sans-serif;
  --fp-system: -apple-system, BlinkMacSystemFont, 'PingFang TC', 'Noto Sans CJK TC',
    'Noto Sans TC', Roboto, 'Microsoft JhengHei', system-ui, sans-serif;
  --fp-mono: 'JetBrains Mono', 'Cascadia Mono', 'SF Mono', Menlo, 'Roboto Mono',
    Consolas, 'PingFang TC', 'Noto Sans CJK TC', 'Microsoft JhengHei', monospace;
  --fp-serif: Georgia, 'Songti TC', 'Noto Serif CJK TC', 'Noto Serif TC',
    PMingLiU, 'Times New Roman', serif;
  --fp-round: 'Yuanti TC', 'Hiragino Maru Gothic ProN', 'Quicksand',
    'PingFang TC', 'Microsoft JhengHei', sans-serif;
  --fp-kai: 'Kaiti TC', 'BiauKai', DFKai-SB, 標楷體, 'Noto Serif CJK TC', serif;
  --fp-jp: 'Hiragino Sans', 'Yu Gothic', 'Meiryo', 'Noto Sans JP',
    'PingFang TC', 'Microsoft JhengHei', sans-serif;
}
:root[data-font="system"] body { font-family: var(--fp-system); }
:root[data-font="mono"] body   { font-family: var(--fp-mono); }
:root[data-font="serif"] body  { font-family: var(--fp-serif); }
:root[data-font="round"] body  { font-family: var(--fp-round); }
:root[data-font="kai"] body    { font-family: var(--fp-kai); }
:root[data-font="jp"] body     { font-family: var(--fp-jp); }
:root[data-font="mono"] .stock-price, :root[data-font="mono"] .chart-price {
  font-variant-numeric: normal;
}

/* 字型選單：每一項用它自己的字型呈現，選之前就看得到長相 */
.font-list { display: flex; flex-direction: column; gap: 8px; margin-top: 6px; }
.font-opt {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  padding: 12px 14px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--bg2); color: var(--text); cursor: pointer; text-align: left;
  transition: border-color .15s, background .15s;
}
.font-opt:hover { border-color: var(--muted); }
.font-opt.active { border-color: var(--accent); background: var(--bg3); }
.font-opt .fo-name { font-weight: 700; font-size: 14px; }
.font-opt .fo-sample { color: var(--muted); font-size: 13px; }
.font-opt .fo-check { margin-left: auto; color: var(--accent); font-weight: 800; }

/* 這台裝置沒有的字型：標示出來但仍可點（有些系統會給出近似的替代字型，
   讓人自己看得到結果，比直接鎖住有用）。 */
.font-opt.na { opacity: .55; }
.font-opt .fo-na {
  font-size: 11px; font-weight: 700; color: var(--muted);
  border: 1px solid var(--border); border-radius: 999px; padding: 1px 8px;
}
.font-opt .fo-plat { font-size: 11px; color: var(--muted); }

/* 字型選單有 7 項，在矮螢幕（iPhone SE 等 667px）會超出視窗高度 ——
   限高並允許內捲，否則下面幾個選項按不到。 */
#fontModal { max-height: 82vh; overflow-y: auto; }
/* 每一項都要達到觸控標準：字型不同會讓行高差很多，實測有一項只有 42px */
.font-opt { min-height: 56px; align-items: center; }

/* 圖鑑評分：與收集進度並排。數字可能到「兆」等級，一律走 fmtBig 簡寫。 */
.dex-nums { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.dex-score { font-size: 20px; font-weight: 800; color: var(--gold);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.dex-gscore { margin-left: auto; font-size: 12px; font-weight: 700; color: var(--gold);
  font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (max-width: 639px) {
  .dex-nums { gap: 10px; }
  .dex-score { font-size: 17px; }
}
/* 曾經擁有但目前已不在手上：圖鑑仍算收集到，但沒有評分可算 */
.dex-sold { color: var(--muted); font-style: italic; }

/* 賽季預覽：背景故事與稱號卡 */
.sp-sub { font-size: 14px; color: var(--muted); margin-top: -6px; margin-bottom: 10px; letter-spacing: .08em; }
.sp-lore p { font-size: 14px; line-height: 2; color: var(--text); margin-bottom: 12px; }
.sp-lore p:last-child { margin-bottom: 0; }
.sp-co.title { border-color: var(--gold); }
.sp-rank { font-size: 12px; font-weight: 800; color: var(--gold); }
@media (max-width: 639px) { .sp-lore p { font-size: 13px; line-height: 1.95; } }
