/* ═══════════════════════════════════════════════════════════
 * Dashboard 專屬樣式 — A 方案 Step 3b 從 style.css 抽出
 * 載入順序:在 style.css 之後(讓 dashboard 的 specifically 規則排在後面)
 *
 * 範圍:
 *   - Dashboard Hero Flow Card(.hero-flow-card / .flow-zone / .flow-dot 等)
 *   - 深色版點群 / 光暈螢光化(Phase 3E)
 *
 * 注意:選擇器名沒改,只是換了檔案位置。
 * ═══════════════════════════════════════════════════════════ */

/* ═════════════════════════════════════════════════════════════
 * 🌟 Dashboard Hero Flow Card
 * ═════════════════════════════════════════════════════════════ */

.hero-flow-card {
  /* 整卡純色,內外不分層,平面圖視覺直接接到卡片邊
     淺色:純白(跟 floor PNG 白底融成一塊)
     深色:純黑(跟反相後的 floor 黑底融成一塊)*/
  background: var(--surface);
  border-radius: 22px;
  padding: 18px 18px 16px;
  box-shadow: var(--card-shadow);
  position: relative;
  overflow: hidden;
}
[data-theme="dark"] .hero-flow-card {
  background: #000;
  /* 黑底就不需要 shadow,但保留淡邊框讓卡片不會跟背景糊在一起 */
  box-shadow: none;
  border: 1px solid rgba(255, 255, 255, 0.06);
}

/* 歷史模式(選過去日期)隱藏即時專屬區塊:
 *   .hero-flow-card    即時人流動態圖
 *   #cardDensity       人流密度 KPI(基於「現在 vs 上限」)
 *   #cardVisitorLog    最新訪客紀錄(latest/present 都是「現在」概念)
 * 過去日期看歷史 KPI + 趨勢圖 + 熱力圖就好,即時相關全部隱藏。
 * 由 api.js:updateAllPagesBySnapshot 偵測 !isToday 自動 toggle body class。 */
body.historical-mode .hero-flow-card,
body.historical-mode #cardDensity,
body.historical-mode #cardVisitorLog {
  display: none;
}
/* 密度卡隱藏後剩兩張,所有螢幕尺寸都改成 2 欄 grid 平均分 —
 *   桌機 ≥1280:預設是 flex column 縱向堆疊,改 2 欄 grid 才橫向均分整行
 *   tablet/mobile <1280:預設 3-col grid,改成 2-col 讓剩兩張不留空欄
 * gap 沿用上方 .kpi-row 預設 16px(mobile <768 的 8px 也會繼續生效) */
body.historical-mode .kpi-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* .hero-grid / .hero-kpi-col 已被 Phase 4 grid-cols-12 重排取代,規則移除。
 * 若有舊 querySelector('.hero-kpi-col') 也找不到,但 api.js 已不再依賴它。 */

.hero-big-num {
  font-size: 68px;
  font-weight: 900;
  line-height: 0.95;
  letter-spacing: -2px;
  color: var(--hero-num-color);
  font-family: 'Plus Jakarta Sans', sans-serif;
}

.hero-kpi-side {
  background: var(--card-tint);
  border-left: 3px solid;
  border-radius: 8px;
  padding: 8px 12px;
}

.hero-flow-canvas {
  /* 透明 → 跟外層 hero-flow-card 接成同一塊白底 */
  background: transparent;
  border-radius: 14px;
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;     /* 圖被 max-height 縮窄時水平置中 */
}

.flow-canvas-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px 0;
  z-index: 2;
}

.flow-canvas-pill {
  padding: 3px 10px;
  background: var(--overlay-glass);
  border: 0.5px solid var(--line);
  border-radius: 12px;
  font-size: 14px;
  color: var(--muted);
  font-weight: 600;
  backdrop-filter: blur(4px);
}

/* global .flow-canvas-body 還原:devices/coverage 也吃這個,前面 width/margin 改動
   只給 dashboard 的 hero,底下 #page-dashboard .flow-canvas-body 個別覆寫。 */
.flow-canvas-body {
  position: relative;
  flex: 1;
  margin: 8px 16px;
  /* aspect-ratio 由 _layoutDashboardFlow / _layoutDevicesFloorplan 依 boxKey 動態設定 */
  max-height: 400px;
  isolation: isolate;     /* 讓 ::before 用 z-index: -1 不會逃出去蓋到外層 */
}

/* 只有 dashboard 的 hero 要「等比例放大、邊距小」 */
#page-dashboard .flow-canvas-body {
  flex: none;
  width: 100%;
  max-height: 480px;
  margin: 4px 0;
}

/* Phase 3E:底圖移到 ::before 的目的 — CSS filter: invert() 會 cascade 到子元素,
 * 把背景圖從本體拆出來,點群 / 光暈 / SVG 才不會跟著被反相。
 * _layoutDashboardFlow() 改成 element.style.setProperty('--flow-bg-image', url('...')),
 * 切 box 時 ::before 跟著吃新值,不必 querySelector 偽元素。 */
.flow-canvas-body::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: var(--flow-bg-image);
  background-position: center;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  transition: filter 0.3s ease;
}

/* 深色版自動把黑線白底 PNG 轉成白線黑底,不必另外塞圖檔 */
[data-theme="dark"] .flow-canvas-body::before {
  filter: invert(1) hue-rotate(180deg) saturate(0.4) brightness(0.85) contrast(1.1);
}

.flow-path {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}


.flow-canvas-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 14px 12px;
}

.flow-canvas-cta {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 12px;
  background: var(--btn-primary-bg);
  color: var(--btn-primary-fg);
  border: none;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  transition: transform 0.15s;
}

.flow-canvas-cta:hover {
  transform: translateX(2px);
}

.flow-zone {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
  animation: zoneBreathe 4s ease-in-out infinite;
  /* Phase 3J:亮塊光暈關閉,只留點點。要復原把這行拿掉 */
  display: none;
}

/* Phase 3I (P2):.flow-zone 三色光暈改吃 var(--heat-*-rgb)
 * 淺色版透明度跟原本完全一樣(0.45 / 0.4 / 0.4 → 0.1 → 0)
 * 深色版透明度由 [data-theme="dark"] .flow-zone.* 區塊覆寫,降到 0.40 / 0.32 / 0.28 */
.flow-zone.zone-hot {
  width: 80px;
  height: 80px;
  background: radial-gradient(circle,
    rgba(var(--heat-hot-rgb), 0.45) 0%,
    rgba(var(--heat-hot-rgb), 0.1) 65%,
    transparent 100%);
}

.flow-zone.zone-warm {
  width: 95px;
  height: 95px;
  background: radial-gradient(circle,
    rgba(var(--heat-warm-rgb), 0.4) 0%,
    rgba(var(--heat-warm-rgb), 0.1) 65%,
    transparent 100%);
  animation-delay: 0.8s;
}

.flow-zone.zone-cool {
  width: 65px;
  height: 65px;
  background: radial-gradient(circle,
    rgba(var(--heat-cool-rgb), 0.4) 0%,
    rgba(var(--heat-cool-rgb), 0.1) 65%,
    transparent 100%);
  animation-delay: 1.6s;
}

/* Phase 3J:同學光暈 = 藍,訪客光暈 = 洋紅,雙主題自動切 */
.flow-zone.zone-student {
  width: 95px;
  height: 95px;
  background: radial-gradient(circle,
    rgba(59, 130, 246, 0.32) 0%,
    rgba(59, 130, 246, 0.08) 65%,
    transparent 100%);
  animation-delay: 0.4s;
}
.flow-zone.zone-visitor {
  width: 75px;
  height: 75px;
  background: radial-gradient(circle,
    rgba(217, 70, 239, 0.32) 0%,
    rgba(217, 70, 239, 0.08) 65%,
    transparent 100%);
  animation-delay: 1.2s;
}

@keyframes zoneBreathe {
  0%, 100% { transform: scale(1); opacity: 0.9; }
  50% { transform: scale(1.1); opacity: 1; }
}

.flow-dot {
  position: absolute;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  pointer-events: none;
  /* drift 仍當 fallback;有 .roaming class 的點改用 JS 改 left/top + transition 走長距離 */
  animation: dotDrift 3.2s ease-in-out infinite;
  box-shadow: 0 0 0 2px rgba(255,255,255,0.6);
  transition: left 1.8s cubic-bezier(.4,0,.2,1), top 1.8s cubic-bezier(.4,0,.2,1);
  will-change: left, top;
}
/* roaming 點不要有 dotDrift 抖動,完全交給 left/top transition */
.flow-dot.roaming { animation: none; }

/* Phase 3I (P2):.flow-dot 三色改吃 var(--heat-*),淺色 = 原本 hex(視覺不變),
 * 深色 = 自動換成 [data-theme="dark"] 內的螢光值 */
.flow-dot.dot-hot  { background: var(--heat-hot); }
.flow-dot.dot-warm { background: var(--heat-warm); }
.flow-dot.dot-cool { background: var(--heat-cool); }

/* Phase 3J:訪客 / 同學 兩色 — 依停留時間分類(短=訪客,長=同學)
 * 取代原本「擠/普通/鬆」密度語意。色用既有 accent 變數,雙主題自動切。
 * 深色版稍微加 box-shadow 螢光化,跟 hot/warm/cool 那組一致 */
/* 點點 / Legend 配色 — 跟右下 KPI 卡的 dwell-tag 顏色完全一致:
 *   訪客/同學 / 同學   = 藍   (.dot-student / .legend-student)
 *   訪客 / 工作人員    = 洋紅 (.dot-visitor / .dot-staff,兩者同色)
 *   機器              = 琥珀 (.dot-machine,新增)
 */
.flow-dot.dot-visitor,
.flow-dot.dot-staff   { background: var(--accent-magenta); }
.flow-dot.dot-student { background: var(--accent-blue); }
.flow-dot.dot-machine { background: var(--accent-amber); }

[data-theme="dark"] .flow-dot.dot-visitor,
[data-theme="dark"] .flow-dot.dot-staff {
  box-shadow: 0 0 10px rgba(217, 70, 239, 0.7);
  border: 1px solid rgba(217, 70, 239, 0.9);
}
[data-theme="dark"] .flow-dot.dot-student {
  box-shadow: 0 0 10px rgba(59, 130, 246, 0.7);
  border: 1px solid rgba(59, 130, 246, 0.9);
}
[data-theme="dark"] .flow-dot.dot-machine {
  box-shadow: 0 0 10px rgba(239, 159, 39, 0.7);
  border: 1px solid rgba(239, 159, 39, 0.9);
}

.legend-dot.legend-visitor,
.legend-dot.legend-staff   { background: var(--accent-magenta); }
.legend-dot.legend-student { background: var(--accent-blue); }
.legend-dot.legend-machine { background: var(--accent-amber); }

[data-theme="dark"] .legend-dot.legend-visitor,
[data-theme="dark"] .legend-dot.legend-staff {
  box-shadow: 0 0 5px rgba(217, 70, 239, 0.6);
}
[data-theme="dark"] .legend-dot.legend-student {
  box-shadow: 0 0 5px rgba(59, 130, 246, 0.6);
}
[data-theme="dark"] .legend-dot.legend-machine {
  box-shadow: 0 0 5px rgba(239, 159, 39, 0.6);
}

/* ─────────────────────────────────────────────
 * Phase 3E:深色版點群 / 光暈螢光化(淺色版規則完全保留在上方,只增不改)
 *   - .flow-dot 換成更亮的螢光色 + box-shadow 模擬發光,白色描邊去掉(在黑底
 *     會變成奇怪的灰邊)
 *   - .flow-zone 三色 radial-gradient 換成相同色系的螢光半透
 *   - 圖例 .legend-dot 跟著螢光化
 * ───────────────────────────────────────────── */
/* Phase 3I (P2):背景色已由 var(--heat-*) 在亮 / 暗自動切,這裡只剩
 * 「螢光發光」效果(box-shadow + border)。蓋掉淺色版的白描邊。
 * box-shadow / border 用 var(--heat-*-rgb) 拼 rgba */
[data-theme="dark"] .flow-dot {
  box-shadow: none;
}
[data-theme="dark"] .flow-dot.dot-hot {
  box-shadow: 0 0 12px rgba(var(--heat-hot-rgb), 0.7);
  border: 1px solid rgba(var(--heat-hot-rgb), 0.9);
}
[data-theme="dark"] .flow-dot.dot-warm {
  box-shadow: 0 0 10px rgba(var(--heat-warm-rgb), 0.6);
  border: 1px solid rgba(var(--heat-warm-rgb), 0.9);
}
[data-theme="dark"] .flow-dot.dot-cool {
  box-shadow: 0 0 8px rgba(var(--heat-cool-rgb), 0.5);
  border: 1px solid rgba(var(--heat-cool-rgb), 0.9);
}

/* Phase 3I (P2):.flow-zone 深色版透明度比淺色版稍淡一點(0.40 / 0.32 / 0.28
 * 比淺色 0.45 / 0.4 / 0.4 略低),才不會在黑底蓋過點群 */
[data-theme="dark"] .flow-zone.zone-hot {
  background: radial-gradient(circle,
    rgba(var(--heat-hot-rgb), 0.40) 0%,
    rgba(var(--heat-hot-rgb), 0.08) 65%,
    transparent 100%);
}
[data-theme="dark"] .flow-zone.zone-warm {
  background: radial-gradient(circle,
    rgba(var(--heat-warm-rgb), 0.32) 0%,
    rgba(var(--heat-warm-rgb), 0.08) 65%,
    transparent 100%);
}
[data-theme="dark"] .flow-zone.zone-cool {
  background: radial-gradient(circle,
    rgba(var(--heat-cool-rgb), 0.28) 0%,
    rgba(var(--heat-cool-rgb), 0.06) 65%,
    transparent 100%);
}

/* flow-canvas-footer 的圖例 dot — 拿掉 inline #hex,改吃 class
 * 淺色用原本紅黃綠,深色換螢光 + 微微外光暈 */
.legend-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex-shrink: 0;
}
/* Phase 3I (P2):legend-dot 同樣吃 var(--heat-*),淺色 = 原 hex,深色自動切 */
.legend-dot.legend-hot  { background: var(--heat-hot); }
.legend-dot.legend-warm { background: var(--heat-warm); }
.legend-dot.legend-cool { background: var(--heat-cool); }
[data-theme="dark"] .legend-dot.legend-hot  {
  box-shadow: 0 0 5px rgba(var(--heat-hot-rgb), 0.6);
}
[data-theme="dark"] .legend-dot.legend-warm {
  box-shadow: 0 0 5px rgba(var(--heat-warm-rgb), 0.55);
}
[data-theme="dark"] .legend-dot.legend-cool {
  box-shadow: 0 0 4px rgba(var(--heat-cool-rgb), 0.5);
}

.flow-dot.f2 { animation-delay: 0.3s; animation-duration: 3.6s; }
.flow-dot.f3 { animation-delay: 0.6s; animation-duration: 2.8s; }
.flow-dot.f4 { animation-delay: 0.9s; animation-duration: 3.4s; }
.flow-dot.f5 { animation-delay: 1.2s; animation-duration: 3.0s; }
.flow-dot.f6 { animation-delay: 1.5s; animation-duration: 3.3s; }
.flow-dot.f7 { animation-delay: 1.8s; animation-duration: 2.9s; }
.flow-dot.f8 { animation-delay: 2.1s; animation-duration: 3.5s; }
.flow-dot.f9 { animation-delay: 0.4s; animation-duration: 3.1s; }
.flow-dot.f10 { animation-delay: 1.0s; animation-duration: 3.4s; }

@keyframes dotDrift {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(4px, -2px); }
  50% { transform: translate(7px, 2px); }
  75% { transform: translate(3px, 4px); }
}
/* settled 小球微抖 — 多套小幅軌跡(形狀各不同),JS 隨機挑一套 + 隨機相位/週期,
 * 讓每顆「各自亂晃」不規律。範圍都壓在 ~±8px(點本身才 7px,等於原地微抖)。 */
@keyframes dotDrift1 {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(5px, -3px); }
  50% { transform: translate(8px, 2px); }
  75% { transform: translate(2px, 5px); }
}
@keyframes dotDrift2 {
  0%, 100% { transform: translate(0, 0); }
  18% { transform: translate(-4px, 2px); }
  42% { transform: translate(2px, 6px); }
  64% { transform: translate(6px, -1px); }
  85% { transform: translate(-2px, -4px); }
}
@keyframes dotDrift3 {
  0%, 100% { transform: translate(0, 0); }
  33% { transform: translate(-5px, -2px); }
  66% { transform: translate(4px, -5px); }
}
@keyframes dotDrift4 {
  0%, 100% { transform: translate(0, 0); }
  15% { transform: translate(3px, 3px); }
  38% { transform: translate(-3px, 5px); }
  60% { transform: translate(-6px, -1px); }
  80% { transform: translate(2px, -4px); }
}

@keyframes numberPop {
  0% { transform: scale(1); }
  30% { transform: scale(1.08); opacity: 0.7; }
  100% { transform: scale(1); }
}

.hero-big-num.pop {
  animation: numberPop 0.5s ease-out;
}


/* ═══════════════════════════════════════════════════════════
 * 以下為 A 方案 Step 3b2 追加 — 從 style.css 抽出剩餘 dashboard 段落
 *
 * 範圍:
 *   - Dashboard LIVE / 歷史 / 全日 三態(原 style.css 1075-1087)
 *   - dashboard 深色主題補完(Phase 3B,原 1284-1344)
 *   - dashboard 雙欄骨架(Phase 3D-pre,原 1345-1389)
 *   - 右欄 gauge 卡 + 精簡 KPI 卡(Phase 3D,原 1390-1624)
 *   - 時間選擇器 + 日期下拉(Phase 3F,原 1625-2053)
 *   - 整日人流密度色條(Phase 3G,原 2054-2130)
 * ═══════════════════════════════════════════════════════════ */

/* ─── (Chunk A)Dashboard LIVE/歷史/全日 三態 ─── */
/* ─────────────────────────────────────────────
 * Dashboard — Phase 1:LIVE / 歷史 / 全日 三態
 * ───────────────────────────────────────────── */
/* LIVE 從卡片內搬到卡片標題列右側,改成 pill 外觀 */
#heroLiveStatus {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.06em;
  flex-shrink: 0;
  background: rgba(29, 158, 117, 0.14);
}
#heroLiveStatus.live-on  { color: #2f8b55; }
#heroLiveStatus.live-off { color: var(--muted); background: rgba(0, 0, 0, 0.05); }
#heroLiveStatus.live-off .live-dot { background: var(--muted); }
#heroLiveStatus.live-off .live-dot::after {
  animation: none;
  opacity: 0;
}
[data-theme="dark"] #heroLiveStatus { background: rgba(29, 158, 117, 0.22); }
[data-theme="dark"] #heroLiveStatus.live-off { background: rgba(255, 255, 255, 0.06); }


/* ─── (Chunk B)Phase 3B / 3D-pre / 3D / 3F / 3G ─── */
/* ═══════════════════════════════════════════════════════════
 * Phase 3B:dashboard 深色主題補完
 *   - 範圍鎖在 #page-dashboard,不波及其他 5 個 tab
 *   - 處理 Tailwind utility(bg-white / text-* arbitrary 等)在深色版的白塊
 *   - delta-up / delta-down / live-dot 改吃變數版的 accent
 *   - body 預設背景吃變數,確保切深色時整個底色都改
 * ═══════════════════════════════════════════════════════════ */
[data-theme="dark"] body {
  /* 防止外層出現殘留亮底 */
  background: var(--bg);
  color: var(--ink);
}

[data-theme="dark"] #page-dashboard .bg-white {
  background-color: var(--surface-2) !important;
}

[data-theme="dark"] #page-dashboard .time-quick-btn {
  color: var(--ink-2);
}
[data-theme="dark"] #page-dashboard .time-quick-btn:hover {
  border-color: var(--ink) !important;
  color: var(--ink);
}

/* delta pill / 趨勢色塊 — 深色版改用半透螢光配色 */
[data-theme="dark"] #page-dashboard .delta-up {
  color: var(--accent-green);
  background: rgba(27,209,126,0.16);
}
[data-theme="dark"] #page-dashboard .delta-down {
  color: var(--accent-red);
  background: rgba(240,68,56,0.16);
}
[data-theme="dark"] #page-dashboard .delta-flat {
  color: var(--muted);
  background: var(--surface-2);
}

/* alert 列 hover 從 var(--bg)(深色 = #0a0b0d 比卡片還深)改成 surface-2,層次比較順 */
[data-theme="dark"] #page-dashboard .hover\:bg-\[var\(--bg\)\]:hover {
  background-color: var(--surface-2) !important;
}

/* live-dot 在深色版用 accent-green,光暈稍微亮一點 */
[data-theme="dark"] .live-dot {
  background: var(--accent-green);
}
[data-theme="dark"] .live-dot::after {
  background: rgba(27,209,126,0.45);
}

/* 時間滑桿軌道 — Tailwind .bg-[var(--bg)] 在深色版會吃到新的 --bg(#0a0b0d),
 * 對深色卡片來說已經夠深,不額外處理。但加 thumb 質感補強 */
[data-theme="dark"] #timeSlider {
  background: var(--surface-2) !important;
}

/* heroLiveStatus 在深色版的 LIVE 字色 — 原本 #2f8b55 在深底太暗 */
[data-theme="dark"] #heroLiveStatus.live-on { color: var(--accent-green); }

/* ═══════════════════════════════════════════════════════════
 * Phase 3D-pre:dashboard 雙欄骨架
 *   左欄 1fr  → 平面圖容器(.hero-flow-card 內含 .hero-flow-canvas)
 *   右欄 380px → Hero 大數字直排(.hero-flow-card 內含 .hero-kpi-col)
 *   - 純 layout container,沒有自己的背景/邊框,雙主題自然繼承
 *   - 1280 以下 RWD 回單欄,平面圖在上、大數字在下
 *   - .hero-flow-card 既有的漸層 / 陰影 / padding 由 Phase 3B 變數版接管
 * ═══════════════════════════════════════════════════════════ */
/* Phase 4:.dash-grid / .dash-left / .dash-right 已被 grid-cols-12 重排取代。
 * 原規則:
 *   .dash-grid     display:grid; grid-template-columns: 1fr 380px; gap:16px;
 *   .dash-left/.dash-right  flex column gap:12px
 *   @media 1280-      → grid-template-columns: 1fr (回單欄)
 * 改用 Tailwind:
 *   <div class="grid grid-cols-12 gap-5">
 *     <div class="col-span-12 lg:col-span-8 space-y-5">  (lg 是 1024px,比原 1280 早一點)
 *     <div class="col-span-12 lg:col-span-4 space-y-4">
 * 規則移除。 */

/* ═══════════════════════════════════════════════════════════
 * Phase 3D:右欄 3 張 gauge 卡(現在人數 / 累積 / 平均停留)
 *   - 顏色全用 var(--*),Phase 3B 變數雙主題自動跟著切
 *   - 字型沿用 Noto Sans TC + 系統字型(不用 IBM Plex Mono)
 *   - 大數字 tabular-nums 防數字跳動時抖動
 *   - 容量上限從 zones.json 拿(_getZoneCapacity 處理)
 * ═══════════════════════════════════════════════════════════ */
.indicators-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 0 4px 4px;
}
.indicators-title {
  font-size: 14px;
  letter-spacing: 0.1em;
  color: var(--muted);
  text-transform: uppercase;
  font-weight: 600;
}
.indicators-meta {
  font-size: 14px;
  color: var(--muted);
  font-family: 'JetBrains Mono', monospace;
}

.dash-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 20px 22px;          /* Phase 4:padding 加大至約 p-5,跟支援中心側欄卡片呼吸感一致 */
  position: relative;
  /* overflow visible:讓 .info-icon .popover 從卡片頂部突出時不被切掉
     (原 overflow:hidden 設來擋 sparkline / gauge 的 SVG,但那些都用內部容器
     自己控,不靠卡片 overflow) */
  overflow: visible;
  box-shadow: var(--card-shadow);
}

/* 卡內 popover:
 * - white-space:normal + position:absolute 沒給寬度,瀏覽器會把它縮到「最窄可能」
 *   (中文一字一行慘狀),所以加 width:max-content 讓它先按文字實際長度展開
 * - max-width:240px 是上限,長句才換行
 * - text-align:center 配合中央上方箭頭 ::after */
.dash-card .info-icon .popover {
  width: max-content;
  max-width: 240px;
  white-space: normal;
  line-height: 1.45;
  text-align: center;
}

.dash-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}
.dash-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.2;
}
.dash-sub {
  font-size: 14px;
  color: var(--muted);
  font-family: 'JetBrains Mono', monospace;
  margin-top: 2px;
  letter-spacing: 0.06em;
}
.dash-status {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  color: var(--accent-green);
  font-family: 'JetBrains Mono', monospace;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.dash-status .pip {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent-green);
  box-shadow: 0 0 6px var(--accent-green);
}

.dash-card-body {
  display: flex;
  align-items: center;
  gap: 16px;
}

.gauge {
  width: 78px;
  height: 78px;
  flex-shrink: 0;
  position: relative;
}
.gauge svg {
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
}
.gauge-track {
  stroke: var(--surface-2);
  fill: none;
  stroke-width: 8;
}
.gauge-fill {
  fill: none;
  stroke-width: 8;
  stroke-linecap: round;
  transition: stroke-dashoffset 0.8s cubic-bezier(.4,0,.2,1), stroke 0.4s;
}
.gauge-pct {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.dash-numbers {
  flex: 1;
  text-align: right;
  min-width: 0;
}
.delta {
  font-size: 14px;
  color: var(--muted);
  margin-bottom: 4px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
}
.delta.up   { color: var(--accent-green); }
.delta.down { color: var(--accent-red); }
.delta.flat { color: var(--muted); }

.big-num {
  font-size: 36px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.unit {
  font-size: 14px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-top: 4px;
  font-family: 'JetBrains Mono', monospace;
}
/* 平均停留卡的 m / s 單位:接在數字尾巴 */
.unit-inline {
  font-size: 24px;
  color: var(--muted);
  margin-left: 1px;
  margin-right: 6px;
}

/* 累積卡的 sparkline:寬度撐滿,接在卡片底部 */
.sparkline {
  height: 36px;
  margin-top: 14px;
  width: 100%;
}
.sparkline-fill { fill: url(#spark-grad); opacity: 0.5; }
.sparkline-line { fill: none; stroke-width: 1.5; stroke: var(--accent-blue); }

/* 累積卡 dash-card-body 主數字靠左排,gauge 卡靠右,差別 */
#cardCumulative .dash-card-body { align-items: flex-start; }
#cardCumulative .dash-numbers { text-align: left; }
#cardCumulative .delta { justify-content: flex-start; }

/* Phase 3J:精簡版 KPI 卡 — 拿掉 gauge / sparkline / delta,只留大數字 */
.kpi-slim .dash-card-head {
  align-items: flex-start;
  margin-bottom: 8px;
}
.kpi-slim .dash-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--ink);
}
.kpi-slim-body {
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.kpi-slim-body .big-num {
  font-size: 42px;
  font-weight: 700;
  line-height: 1;
}
.kpi-slim-body .unit { margin-top: 0; }

/* 平均停留:訪客 / 同學 兩列 */
.dwell-split {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.dwell-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.dwell-tag {
  font-size: 14px;
  font-weight: 700;
  padding: 3px 10px;
  border-radius: 999px;
  letter-spacing: 0.04em;
}
/* 同學 — 藍 */
.dwell-tag-student {
  background: rgba(59, 130, 246, 0.14);
  color: var(--accent-blue);
  border: 1px solid rgba(59, 130, 246, 0.30);
}
/* 工作人員 — 洋紅(沿用原 visitor 配色,但語意換) */
.dwell-tag-staff {
  background: rgba(217, 70, 239, 0.14);
  color: var(--accent-magenta);
  border: 1px solid rgba(217, 70, 239, 0.30);
}
/* 機器 — 琥珀(IoT / 久駐裝置) */
.dwell-tag-machine {
  background: rgba(239, 159, 39, 0.14);
  color: var(--accent-amber);
  border: 1px solid rgba(239, 159, 39, 0.30);
}
/* 舊 .dwell-tag-visitor 名稱保留作 alias,免得 partial 升版前 reload 看到沒樣式 */
.dwell-tag-visitor { background: rgba(217, 70, 239, 0.14); color: var(--accent-magenta); border: 1px solid rgba(217, 70, 239, 0.30); }
.dwell-num {
  font-family: 'JetBrains Mono', monospace;
  font-size: 24px;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.dwell-unit {
  font-size: 14px;
  color: var(--muted);
  margin: 0 1px 0 0;
}

/* ═══════════════════════════════════════════════════════════
 * Phase 3F:時間選擇器卡(.time-selector)+ 日期下拉(.date-popup)
 *   - 取代頂部時間滑桿卡(#timeSliderCard 在 dashboard 上 hidden)
 *   - 點 .date-btn 展開 .date-popup,popup 內含 LIVE / 14 天歷史 pill /
 *     自訂日期 input / DAY SCRUB 時間滑桿
 *   - 滑桿改 #scrubSlider,但 onTimeSliderChange / setSnapshotTime 既有
 *     handler 都 reuse,setSnapshotTime() 同步寫進舊 #timeSlider 防呆
 *   - 顏色用 Phase 3B 既有變數,雙主題自動切;<input type="date"> 跟
 *     <input type="time"> 在深色版用 color-scheme: dark 讓原生 picker 是黑底
 * ═══════════════════════════════════════════════════════════ */
.time-selector {
  padding: 14px 16px;
  overflow: visible;
}
.ts-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
.ts-row + .ts-row {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
.ts-icon {
  font-size: 14px;
  color: var(--muted);
  width: 14px;
  text-align: center;
  flex-shrink: 0;
}
.date-wrap {
  flex: 1;
  position: relative;
  min-width: 0;
}
.date-btn {
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 7px 10px;
  color: var(--ink);
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  cursor: pointer;
  text-align: left;
  display: flex;
  align-items: center;
  justify-content: space-between;
  transition: border-color 0.15s, background 0.15s;
}
.date-btn:hover { border-color: var(--ink-2); }
.date-btn .caret {
  color: var(--muted);
  font-size: 14px;
  margin-left: 8px;
}

.live-pill {
  background: rgba(34, 197, 94, 0.16);
  color: var(--accent-green);
  border: 1px solid rgba(34, 197, 94, 0.30);
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  padding: 4px 8px;
  border-radius: 4px;
  letter-spacing: 0.08em;
  flex-shrink: 0;
  font-weight: 700;
}
.live-pill.history {
  background: rgba(245, 158, 11, 0.14);
  color: var(--accent-amber);
  border-color: rgba(245, 158, 11, 0.30);
}
.live-pill.snapshot {
  background: rgba(59, 130, 246, 0.14);
  color: var(--accent-blue);
  border-color: rgba(59, 130, 246, 0.30);
}

.time-input {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 6px 8px;
  color: var(--ink);
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  outline: none;
  flex: 1;
  min-width: 0;
  transition: border-color 0.15s;
}

/* Phase 3J:DAY SCRUB 從 popup 拉出來放卡片內,外面一層 wrap 限制寬 */
.ts-row.scrub-row { align-items: flex-start; }
.scrub-wrap { flex: 1; min-width: 0; padding-top: 2px; }
.scrub-wrap .scrub-marks {
  display: flex;
  justify-content: space-between;
  font-size: 14px;
  color: var(--muted);
  font-family: 'JetBrains Mono', monospace;
  margin: 2px 4px 8px;
}
.scrub-wrap .scrub-quicks {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
  margin-bottom: 6px;
}
.scrub-wrap .scrub-quicks button {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 5px;
  padding: 5px 4px;
  color: var(--muted);
  font-family: inherit;
  font-size: 14px;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
  white-space: nowrap;
}
.scrub-wrap .scrub-quicks button:hover {
  color: var(--ink);
  border-color: var(--ink-2);
}
.scrub-wrap .scrub-quicks button.primary {
  background: rgba(34, 197, 94, 0.16);
  border-color: rgba(34, 197, 94, 0.30);
  color: var(--accent-green);
  font-weight: 700;
}
.scrub-wrap .scrub-quicks button.primary:hover {
  background: rgba(34, 197, 94, 0.24);
}
.scrub-wrap .scrub-time-display {
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 2px;
}
.scrub-wrap .scrub-time-display .scrub-live-mark {
  font-size: 14px;
  color: var(--accent-green);
  letter-spacing: 0.12em;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.scrub-wrap .scrub-time-display .scrub-live-mark::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent-green);
  box-shadow: 0 0 6px var(--accent-green);
  animation: pulse 2s ease-in-out infinite;
}
.scrub-wrap .scrub-time-display.snap .scrub-live-mark { display: none; }
.time-input:focus { border-color: var(--accent-blue); }
.time-sep { color: var(--muted); font-size: 14px; flex-shrink: 0; }

[data-theme="dark"] .time-input,
[data-theme="dark"] .date-btn,
[data-theme="dark"] .dp-custom { color-scheme: dark; }

/* ─── date popup ─── */
.date-popup {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 14px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.18);
  z-index: 60;
  display: none;
  max-height: 460px;
  overflow-y: auto;
}
[data-theme="dark"] .date-popup {
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.65);
}
.date-popup.open { display: block; animation: dpFade 0.18s ease-out; }
@keyframes dpFade {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.dp-section { margin-bottom: 14px; }
.dp-section:last-child { margin-bottom: 0; }
.dp-title {
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  color: var(--muted);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.dp-title-ico { font-size: 14px; }

.dp-live {
  background: linear-gradient(90deg, rgba(34,197,94,0.14), rgba(34,197,94,0.04));
  border: 1px solid rgba(34,197,94,0.28);
  border-radius: 8px;
  padding: 11px 13px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  cursor: pointer;
  transition: filter 0.15s;
}
.dp-live:hover { filter: brightness(1.05); }
.dp-live.active {
  box-shadow: 0 0 0 2px rgba(34,197,94,0.5);
}
.dp-live-text {
  font-size: 14px;
  color: var(--ink);
  font-family: 'JetBrains Mono', monospace;
}
.dp-live-tag {
  background: rgba(34,197,94,0.22);
  color: var(--accent-green);
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  padding: 3px 8px;
  border-radius: 4px;
  letter-spacing: 0.1em;
  font-weight: 700;
}

.dp-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
}
.dp-pill {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 8px 10px;
  text-align: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  color: var(--ink-2);
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
  user-select: none;
}
.dp-pill:hover {
  background: var(--bg);
  color: var(--ink);
  border-color: var(--ink-2);
}
.dp-pill.active {
  background: var(--accent-blue);
  color: #fff;
  border-color: var(--accent-blue);
}

.dp-custom {
  width: 100%;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 8px 10px;
  color: var(--ink);
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  outline: none;
}
.dp-custom:focus { border-color: var(--accent-blue); }

.dp-footer {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  color: var(--muted);
  text-align: left;
  line-height: 1.5;
}

/* ─── DAY SCRUB slider(藏在 popup 內) ─── */
.scrub-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 22px;
  background: transparent;
  cursor: grab;
  margin: 0;
  padding: 0;
}
.scrub-slider:active { cursor: grabbing; }
.scrub-slider:focus { outline: none; }
/* 軌道改成單色低調灰(原本紅橘漸層太衝),整體呼應 dashboard 的 mint 系 */
.scrub-slider::-webkit-slider-runnable-track {
  height: 3px;
  background: var(--line);
  border-radius: 2px;
}
.scrub-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  height: 14px;
  width: 14px;
  border-radius: 50%;
  background: var(--ink);
  border: 2px solid var(--surface);
  margin-top: -5.5px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);
  cursor: grab;
  transition: transform 0.12s, box-shadow 0.12s;
}
.scrub-slider::-webkit-slider-thumb:hover {
  transform: scale(1.18);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.28);
}
.scrub-slider::-moz-range-track {
  height: 3px;
  background: var(--line);
  border-radius: 2px;
  border: none;
}
.scrub-slider::-moz-range-thumb {
  height: 14px;
  width: 14px;
  border-radius: 50%;
  background: var(--ink);
  border: 2px solid var(--surface);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);
  cursor: grab;
}
[data-theme="dark"] .scrub-slider::-webkit-slider-thumb {
  background: #F4F5F6;     /* 深底要亮 thumb 才看得到 */
}
[data-theme="dark"] .scrub-slider::-moz-range-thumb {
  background: #F4F5F6;
}

.scrub-marks {
  display: flex;
  justify-content: space-between;
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  color: var(--muted);
  margin: 2px 4px 10px;
  letter-spacing: 0.04em;
}

.scrub-quicks {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
}
.scrub-quicks button {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 6px 4px;
  color: var(--ink-2);
  font-family: 'Plus Jakarta Sans', 'Noto Sans TC', sans-serif;
  font-size: 14px;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
  white-space: nowrap;
}
.scrub-quicks button:hover {
  border-color: var(--ink-2);
  color: var(--ink);
}
.scrub-quicks button.primary {
  background: rgba(34,197,94,0.14);
  border-color: rgba(34,197,94,0.32);
  color: var(--accent-green);
  font-weight: 600;
}
.scrub-quicks button.primary:hover {
  background: rgba(34,197,94,0.22);
}

.scrub-time-display {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-top: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.scrub-time-display .scrub-live-mark {
  font-size: 14px;
  color: var(--accent-green);
  letter-spacing: 0.12em;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.scrub-time-display .scrub-live-mark::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent-green);
  box-shadow: 0 0 6px var(--accent-green);
}
/* snapshot 模式時 LIVE 字樣藏起來 */
.scrub-time-display.snap .scrub-live-mark { display: none; }

/* ═══════════════════════════════════════════════════════════
 * Phase 3G:左欄平面圖底下的整日人流密度色條
 *   - 24 個 .timeline-bar-item,grid 按小時分格
 *   - 高度 = count / max,顏色依密度 ( <50% 綠 / 50-75% 橘 / >75% 紅 )
 *   - 沒人 / 未來小時用 var(--surface-2) 灰底
 *   - 當前小時 outline 藍框,深色版加 glow
 *   - 點 bar 跳到那小時(JS 用 click delegation)
 * ═══════════════════════════════════════════════════════════ */
.timeline-bar-card {
  padding: 12px 16px;
}
.timeline-bar-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 8px;
  font-size: 14px;
}
.timeline-bar-title {
  color: var(--ink);
  font-weight: 600;
}
.timeline-bar-time {
  color: var(--muted);
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}
.timeline-bar-grid {
  display: grid;
  grid-template-columns: repeat(24, 1fr);
  gap: 2px;
  height: 56px;          /* 回到固定 px 高度;flex-grow 會讓 bar 用 % 算到 0px 看不見 */
  align-items: flex-end;
  position: relative;
  margin-top: auto;      /* card flex-col 時,grid 推到底部,卡片高度延伸的空間留在頭尾 */
}
.timeline-bar-item {
  background: var(--surface-2);
  border-radius: 2px;
  cursor: pointer;
  transition: opacity 0.15s, transform 0.12s;
  min-height: 2px;
}
/* Phase 3I (P1):色條三色用 var(--heat-*),跟 .flow-dot / .legend-dot 共用同一組
 * 色票。淺色版 = 原本紅 / 橘 / 綠,深色版 [data-theme="dark"] 內 --heat-* 自動換成
 * 螢光紅 / 螢光橘 / 螢光綠,看起來跟點群一致 */
.timeline-bar-item.bar-tone-high { background: var(--heat-hot); }
.timeline-bar-item.bar-tone-mid  { background: var(--heat-warm); }
.timeline-bar-item.bar-tone-low  { background: var(--heat-cool); }
.timeline-bar-item:hover {
  transform: scaleY(1.06);
  opacity: 0.92;
}
.timeline-bar-item.active {
  outline: 2px solid var(--accent-blue);
  outline-offset: 1px;
}
.timeline-bar-marks {
  display: flex;
  justify-content: space-between;
  margin-top: 4px;
  font-size: 14px;
  color: var(--muted);
  font-family: 'JetBrains Mono', monospace;
}

/* 深色版:bar 微透 + active 加螢光發光,跟 Phase 3E 風格一致 */
[data-theme="dark"] .timeline-bar-item {
  opacity: 0.85;
}
[data-theme="dark"] .timeline-bar-item:hover {
  opacity: 1;
}
[data-theme="dark"] .timeline-bar-item.active {
  opacity: 1;
  box-shadow: 0 0 8px var(--accent-blue);
}

/* ═══════════════════════════════════════════════════════════
 * Phase 4M:Dashboard RWD
 *   斷點:
 *     Desktop ≥1280  → 雙欄(8/4),3 張 KPI 卡縱向堆疊
 *     Tablet 768-1279 → 單欄,時間軸 dense 橫條,3 張 KPI 卡 3-col 並排
 *     Mobile <768    → 單欄,3 張 KPI 卡仍 3-col 但更壓縮 + dwell 卡 inline expand
 *   主要靠 .kpi-row 容器(包 3 張 KPI 卡)+ .time-selector 內部 grid template areas
 * ═══════════════════════════════════════════════════════════ */

/* 預設(桌機 ≥1280):3 張 KPI 卡縱向堆疊,跟原本 .space-y-4 行為一致 */
.kpi-row {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Phase 4N(A 案):.time-selector 預設 .collapsed,scrub-row 收起來,
   ts-row 加一條 .ts-current-time(鏡射 #scrubTimeText)+ .ts-toggle 展開鈕 */
.time-selector.collapsed .ts-row.scrub-row {
  display: none;
}
.time-selector .ts-current-time {
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}
.time-selector .ts-toggle {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  padding: 0;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.time-selector .ts-toggle:hover {
  border-color: var(--ink);
  color: var(--ink);
  background: var(--surface-2);
}
.time-selector .ts-toggle:focus-visible {
  outline: 2px solid var(--accent-blue);
  outline-offset: 2px;
}
.time-selector .ts-toggle svg {
  display: block;
  transition: transform 0.2s ease;
}
.time-selector:not(.collapsed) .ts-toggle svg {
  transform: rotate(180deg);
}

/* ── Tablet & Mobile 共用:3 張 KPI 卡並排 + 卡內 label 上、數字下 ── */
@media (max-width: 1279px) {
  .kpi-row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
  }

  /* KPI 卡身體:label 上、數字下(原本是 head 一行 + body 一行的 baseline 排) */
  .kpi-row .kpi-slim {
    padding: 14px 14px;
  }
  .kpi-row .kpi-slim .dash-card-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    margin-bottom: 10px;
  }
  .kpi-row .kpi-slim .dash-status {
    font-size: 14px;
  }
  .kpi-row .kpi-slim-body {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }
  .kpi-row .kpi-slim-body .big-num {
    font-size: 32px;
  }
  .kpi-row .kpi-slim-body .unit {
    font-size: 14px;
    margin-top: 2px;
  }

  /* 平均停留卡 — 壓縮模式:
   *   - 同學(mid)主數字大字
   *   - 機器(long)小字 muted,前面加「機器 」prefix
   *   - 隱藏 tag、訪客/同學(short)、秒數
   *   - 點卡片切 .dwell-expanded 可展開完整 3 列 */
  .kpi-row #cardDwell {
    cursor: pointer;
  }
  .kpi-row #cardDwell .dwell-split {
    gap: 4px;
  }
  .kpi-row #cardDwell:not(.dwell-expanded) .dwell-row[data-bucket="short"] {
    display: none;  /* 走廊才會 show 的 short bucket,壓縮模式直接 hide */
  }
  .kpi-row #cardDwell:not(.dwell-expanded) .dwell-tag {
    display: none;
  }
  /* 隱藏秒數:dwell-num 結構 <M-span><m-unit><S-span><s-unit>,
     S-span 跟它相鄰的下一個 .dwell-unit(s)一起隱藏 */
  .kpi-row #cardDwell:not(.dwell-expanded) .dwell-num [id$="S"],
  .kpi-row #cardDwell:not(.dwell-expanded) .dwell-num [id$="S"] + .dwell-unit {
    display: none;
  }
  .kpi-row #cardDwell:not(.dwell-expanded) .dwell-row[data-bucket="mid"] .dwell-num {
    font-size: 30px;
    font-weight: 700;
  }
  .kpi-row #cardDwell:not(.dwell-expanded) .dwell-row[data-bucket="mid"] .dwell-unit {
    font-size: 14px;
  }
  .kpi-row #cardDwell:not(.dwell-expanded) .dwell-row[data-bucket="long"] .dwell-num {
    font-size: 14px;
    color: var(--muted);
    font-weight: 500;
  }
  .kpi-row #cardDwell:not(.dwell-expanded) .dwell-row[data-bucket="long"] .dwell-unit {
    font-size: 14px;
  }
  .kpi-row #cardDwell:not(.dwell-expanded) .dwell-row[data-bucket="long"]::before {
    content: '機器 ';
    font-size: 14px;
    color: var(--muted);
    margin-right: 4px;
    font-family: 'Noto Sans TC', sans-serif;
  }
  /* 展開 hint(壓縮模式右上角小箭頭) */
  .kpi-row #cardDwell:not(.dwell-expanded)::after {
    content: '⌄';
    position: absolute;
    top: 12px;
    right: 14px;
    font-size: 14px;
    color: var(--muted);
    pointer-events: none;
  }
  .kpi-row #cardDwell.dwell-expanded::after {
    content: '×';
    position: absolute;
    top: 10px;
    right: 14px;
    font-size: 14px;
    color: var(--muted);
    pointer-events: none;
  }
}

/* ── Tablet only(768-1279):時間軸卡 dense 橫條 ──
 * .scrub-wrap 內部原本垂直堆 slider / marks / quicks / time,
 * tablet 寬度夠塞橫條,改 grid template areas:
 *   slider (上, 撐滿) | quicks | time
 *   marks  (下, 對齊上方 slider) | quicks | time
 * 4 顆快捷按鈕跟 LIVE 字樣移到右側,跟日期 + slider 同高 */
@media (min-width: 768px) and (max-width: 1279px) {
  .time-selector .scrub-wrap {
    display: grid;
    grid-template-columns: 1fr auto auto;
    grid-template-areas:
      "slider quicks time"
      "marks  quicks time";
    column-gap: 16px;
    row-gap: 0;
    align-items: center;
  }
  .time-selector .scrub-wrap > .scrub-slider {
    grid-area: slider;
    align-self: end;
    margin: 0;
  }
  .time-selector .scrub-wrap > .scrub-marks {
    grid-area: marks;
    margin: 2px 4px 0;
  }
  .time-selector .scrub-wrap > .scrub-quicks {
    grid-area: quicks;
    grid-template-columns: repeat(4, auto);
    margin: 0;
    align-self: center;
  }
  .time-selector .scrub-wrap > .scrub-time-display {
    grid-area: time;
    margin: 0;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
  }
}

/* ── Mobile only(<768):進一步壓縮 KPI 卡,塞下 3-col 並排 ── */
@media (max-width: 767px) {
  .kpi-row {
    gap: 8px;
  }
  .kpi-row .kpi-slim {
    padding: 12px 10px;
  }
  .kpi-row .kpi-slim .dash-title {
    font-size: 14px;
    line-height: 1.25;
  }
  .kpi-row .kpi-slim .dash-status {
    display: none;  /* LIVE / SINCE 09:00 太擠藏掉,info-icon 還在 */
  }
  .kpi-row .kpi-slim-body .big-num {
    font-size: 26px;
  }
  .kpi-row .kpi-slim-body .unit {
    font-size: 14px;
    letter-spacing: 0.06em;
  }
  /* dwell 卡進一步縮 */
  .kpi-row #cardDwell:not(.dwell-expanded) .dwell-row[data-bucket="mid"] .dwell-num {
    font-size: 24px;
  }
  .kpi-row #cardDwell:not(.dwell-expanded) .dwell-row[data-bucket="mid"] .dwell-unit {
    font-size: 14px;
  }
  .kpi-row #cardDwell:not(.dwell-expanded) .dwell-row[data-bucket="long"] .dwell-num {
    font-size: 14px;
  }
}

/* ═══════════════════════════════════════════════════════════
 * 2026-05 大改版:dashboard 增補
 *   - hero-corner-occupancy:hero card 左下角浮卡(當下館內 X 人)
 *   - hero-business-hours:hero card 底部 09:00-21:00 progress bar
 *   - kpi-slim-foot / kpi-delta-pill / kpi-density-tone:3-cell KPI strip
 *   - dash-mini-card + weather-mini + ai-mini:中段兩張 mini card(導向 tab)
 *   - trend-legend-line:今日人流時間軸 chart 上的圖例小線段
 *   - visitor-zone-dot:訪客表「區域」欄位前面的小圓點
 * ═══════════════════════════════════════════════════════════ */

/* ── hero card 左下角浮卡 ── */
.hero-flow-canvas { position: relative; }
.hero-corner-occupancy {
  position: absolute;
  right: 16px;             /* 從左下改右下 */
  bottom: 56px;            /* 留空間給 .flow-canvas-footer */
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 14px 20px;
  min-width: 120px;
  text-align: right;
  box-shadow: 0 8px 20px -10px rgba(0,0,0,0.18);
  z-index: 3;
}
[data-theme="dark"] .hero-corner-occupancy {
  background: var(--surface-2);
  box-shadow: 0 8px 20px -8px rgba(0,0,0,0.6);
}
.hero-corner-label {
  font-size: 14px;
  color: var(--muted);
  font-weight: 600;
  letter-spacing: 0.04em;
  margin-bottom: 4px;
}
.hero-corner-num {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  color: var(--ink);
}
.hero-corner-num #heroCornerNum {
  font-size: 42px;
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.hero-corner-num .hero-corner-unit {
  font-size: 16px;
  color: var(--muted);
  font-weight: 600;
}

/* MAC 分流副資訊(真實 / 隨機)— 用在 hero 浮卡跟今日累積卡 */
.hero-corner-breakdown,
.kpi-mac-breakdown {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-top: 4px;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}
.hero-corner-breakdown .mac-real,
.kpi-mac-breakdown .mac-real {
  color: var(--accent-blue);
}
.hero-corner-breakdown .mac-random,
.kpi-mac-breakdown .mac-random {
  color: var(--accent-amber);
}
.hero-corner-breakdown .mac-rnd-sep,
.kpi-mac-breakdown .mac-rnd-sep {
  opacity: 0.4;
}
/* hero 角落浮卡在 .hero-flow-canvas(overflow:hidden)裡 — .info-icon .popover 預設置中
 * 展開會撞到畫布右邊被裁。這裡 override 成「靠右對齊、往左展開」,popover 整個落在
 * 畫布內部,不被裁掉。箭頭也跟著移到右側對齊 ? 圖示。 */
.hero-corner-breakdown .info-icon .popover {
  left: auto;
  right: 0;
  transform: none;
  text-align: left;       /* 條列文字靠左讀起來順 */
}
.hero-corner-breakdown .info-icon .popover::after {
  left: auto;
  right: 5px;
  transform: none;
}

/* ── hero card 底部營業時間 progress ── */
.hero-business-hours {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 14px;
  padding: 10px 12px;
  background: var(--card-tint);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.hero-business-hours .bh-icon {
  color: var(--muted);
  display: inline-flex;
  flex-shrink: 0;
}
.hero-business-hours .bh-label {
  font-size: 14px;
  color: var(--ink-2);
  font-weight: 600;
  white-space: nowrap;
}
.hero-business-hours .bh-track {
  flex: 1;
  height: 6px;
  background: var(--line);
  border-radius: 999px;
  overflow: hidden;
  min-width: 80px;
}
.hero-business-hours .bh-fill {
  height: 100%;
  width: 0;
  background: linear-gradient(90deg, var(--mint-strong), var(--accent-green));
  border-radius: 999px;
  transition: width 0.4s ease;
}
.hero-business-hours .bh-status {
  font-size: 14px;
  font-weight: 700;
  white-space: nowrap;
  font-family: 'JetBrains Mono', monospace;
}
.hero-business-hours .bh-status.open   { color: var(--accent-green); }
.hero-business-hours .bh-status.before { color: var(--accent-amber); }
.hero-business-hours .bh-status.after  { color: var(--muted); }

/* 手機 / 小平板(≤600):一橫排塞不下 label + track + 狀態(label/狀態都 nowrap),
   把 track 換到第二行、label 與狀態維持一行兩端對齊。
   斷點放到 600 是因為部分大尺寸手機橫向約 430-500px,留 buffer 比較保險 */
@media (max-width: 600px) {
  .hero-business-hours { flex-wrap: wrap; row-gap: 8px; }
  .hero-business-hours .bh-status { margin-left: auto; }
  .hero-business-hours .bh-track { order: 99; flex-basis: 100%; }
}

/* ── 3-cell KPI strip 補丁 ──
   .kpi-slim-body 在新版會 align baseline + gap;
   foot / delta-pill / density-tone 都是新加的小元件 */
.kpi-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}
.kpi-slim-body {
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
}
.kpi-slim-foot {
  margin-top: 8px;
  font-size: 14px;
  color: var(--muted);
  letter-spacing: 0.04em;
}
.kpi-delta-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 700;
  font-family: 'JetBrains Mono', monospace;
  letter-spacing: 0.02em;
  background: var(--surface-2);
  color: var(--muted);
}
.kpi-delta-pill.up   { background: rgba(34,197,94,0.14); color: var(--accent-green); }
.kpi-delta-pill.down { background: rgba(240,68,56,0.14); color: var(--accent-red); }
.kpi-delta-pill.flat { background: var(--surface-2); color: var(--muted); }

/* density 等級主數字配色 */
.big-num.tone-low  { color: var(--accent-green); }
.big-num.tone-mid  { color: var(--accent-amber); }
.big-num.tone-high { color: var(--accent-red); }
.kpi-density-tone {
  font-size: 14px;
  font-weight: 700;
  color: var(--muted);
}
.kpi-density-tone.tone-low  { color: var(--accent-green); }
.kpi-density-tone.tone-mid  { color: var(--accent-amber); }
.kpi-density-tone.tone-high { color: var(--accent-red); }

/* dwell 主數字 — 用 mono、mm:ss */
.kpi-dwell-body .big-num {
  font-size: 36px;
  letter-spacing: 0.02em;
}

/* ── tablet/mobile RWD 覆寫:3-cell 在小螢幕仍 3 欄,夠就好 ── */
@media (max-width: 767px) {
  .kpi-row { gap: 8px; }
  .kpi-slim-body .big-num { font-size: 26px; }
  .kpi-slim-foot { font-size: 14px; }
  .kpi-delta-pill { font-size: 14px; padding: 2px 7px; }
  .hero-corner-occupancy {
    right: 10px;
    bottom: 48px;
    padding: 8px 10px;
    min-width: 78px;
  }
  .hero-corner-num #heroCornerNum { font-size: 24px; }
}

/* 訪客表 mobile:6 欄塞不下會擠成圓形 pill / 字串被切兩行,改成水平滾動
 * + 隱藏「區域」欄(同一個 box 內這欄都一樣,給寬度給其他欄用) */
@media (max-width: 767px) {
  /* footer「目前 N 筆 · 清單上限 50 筆」+「查看完整清單 →」:窄螢幕兩端互擠,垂直堆疊讓兩段都完整 */
  #cardVisitorLog > div.flex.items-center.justify-between:last-child {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }
  #cardVisitorLog > div.flex.items-center.justify-between:last-child .visitor-table-footer {
    white-space: normal;
    line-height: 1.5;
  }
  #cardVisitorLog > div.flex.items-center.justify-between:last-child button {
    text-align: left;
  }
  #cardVisitorLog .overflow-x-auto {
    -webkit-overflow-scrolling: touch;
    overflow-x: auto;
  }
  #cardVisitorLog table { min-width: 360px; }
  #cardVisitorLog table th,
  #cardVisitorLog table td {
    white-space: nowrap;
    padding-left: 6px;
    padding-right: 6px;
  }
  #cardVisitorLog table th:first-child,
  #cardVisitorLog table td:first-child { padding-left: 4px; }
  #cardVisitorLog table th:last-child,
  #cardVisitorLog table td:last-child { padding-right: 4px; }
  /* pill 在窄欄裡別被擠成圓 */
  #cardVisitorLog table .pill { white-space: nowrap; flex-shrink: 0; }
}

/* 手機(<480):浮卡會蓋住平面圖座位,改放畫布外當獨立列 */
@media (max-width: 480px) {
  .hero-corner-occupancy {
    position: static;
    right: auto;
    bottom: auto;
    width: 100%;
    margin-top: 10px;
    padding: 10px 14px;
    text-align: center;
    min-width: 0;
    box-shadow: none;
  }
  .hero-corner-num,
  .hero-corner-breakdown { justify-content: center; }
  /* popover 預設靠右會跑到畫布外,還原置中 */
  .hero-corner-breakdown .info-icon .popover {
    left: 50%;
    right: auto;
    transform: translateX(-50%);
  }
  .hero-corner-breakdown .info-icon .popover::after {
    left: 50%;
    right: auto;
    transform: translateX(-50%);
  }
}

/* ── dash-mini-card:天氣對照 + AI 彙報 ── */
.dash-mini-card {
  width: 100%;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 16px 18px;
  cursor: pointer;
  transition: border-color 0.15s, transform 0.12s, box-shadow 0.15s;
  display: flex;
  flex-direction: column;
  gap: 10px;
  font: inherit;
  color: inherit;
}
.dash-mini-card:hover {
  border-color: var(--ink-2);
  transform: translateY(-1px);
  box-shadow: var(--card-shadow);
}
.dash-mini-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.dash-mini-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.dash-mini-arrow { color: var(--muted); flex-shrink: 0; }
.dash-mini-card:hover .dash-mini-arrow { color: var(--ink); }

/* weather mini 內容 */
.weather-mini-body {
  display: flex;
  align-items: center;
  gap: 14px;
}
.weather-mini-icon {
  font-size: 36px;
  line-height: 1;
  filter: drop-shadow(0 4px 8px rgba(0,0,0,0.08));
}
.weather-mini-info { display: flex; flex-direction: column; gap: 2px; }
.weather-mini-temp {
  font-size: 32px;
  font-weight: 800;
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.weather-mini-temp-unit { font-size: 18px; color: var(--muted); margin-left: 1px; }
.weather-mini-cond {
  font-size: 14px;
  color: var(--muted);
  font-weight: 500;
}
.weather-mini-note {
  font-size: 14px;
  color: var(--accent-blue);
  background: rgba(59,130,246,0.10);
  padding: 6px 10px;
  border-radius: 8px;
  font-weight: 600;
}
[data-theme="dark"] .weather-mini-note {
  background: rgba(59,130,246,0.18);
  color: var(--accent-blue);
}

/* AI mini 內容 */
.ai-mini { background: linear-gradient(180deg, var(--surface) 0%, rgba(155,137,201,0.08) 100%); }
.ai-mini-icon { font-size: 14px; }
.ai-mini-text {
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-2);
  font-weight: 500;
  min-height: 40px;
}
.ai-mini-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  color: var(--muted);
  letter-spacing: 0.02em;
}
.ai-mini-meta b { color: var(--ink); font-weight: 700; }

/* ── 今日人流時間軸 chart 圖例小線段 ── */
.trend-legend-line {
  display: inline-block;
  width: 22px;
  height: 0;
  border-top-width: 2px;
  border-top-style: solid;
}
.trend-legend-line.trend-today     { border-top-color: var(--ink); border-top-style: solid; }
.trend-legend-line.trend-yesterday { border-top-color: var(--muted); border-top-style: dashed; }
.trend-legend-line.trend-7d        { border-top-color: var(--muted); border-top-style: dotted; }

/* ── 訪客表區域欄位的小圓點 ── */
.visitor-zone-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: middle;
}
