/* 冷卻水監控系統 —— 版面與主題
 *
 * 原則：
 *  - 不用漸層、玻璃擬態、陰影。遠距離觀看時任何降低對比的裝飾都是負分。
 *  - 一份 HTML 同時服務手機、桌機、55 吋大螢幕，靠 clamp() 與 grid，不寫兩套版面。
 *  - 全域 tabular-nums：否則 39.8 → 41.1 更新時大數字會左右抖動，大螢幕上非常明顯。
 */

/* ── 越南文字型子集 ────────────────────────────────────────────────
 * 只 vendored 越南文，中文交給系統字型（Windows / Android 都有足夠的 CJK）。
 * 11 KB 精準修掉唯一的真 bug，不必打包 210 個 CJK 分塊。
 *
 * ★ Microsoft JhengHei 絕不放第一位 —— 它缺 ệ ự ỗ ằ ữ 全部越南文附加符號以及 Đ
 *   （Độ = 度，高頻字）。放第一位會讓每個帶符號的字母掉進不同 fallback，
 *   基線與字重不一致，而且不是 tofu 方塊所以 code review 看不出來。
 */
@font-face {
  font-family: "CoolingVN";
  src: url("fonts/noto-sans-vn-400.woff2") format("woff2");
  font-weight: 400; font-display: swap;
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169,
                 U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304,
                 U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
@font-face {
  font-family: "CoolingVN";
  src: url("fonts/noto-sans-vn-700.woff2") format("woff2");
  font-weight: 700; font-display: swap;
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169,
                 U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304,
                 U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}

:root {
  --font: "CoolingVN", "Segoe UI", Roboto, "Helvetica Neue",
          "Microsoft JhengHei", "PingFang TC", system-ui, sans-serif;

  --bg: #F7F8FA;
  --panel: #FFFFFF;
  --ink: #111418;
  --ink-2: #4A5058;
  --ink-3: #6B7280;
  --line: #DFE3E8;

  --hot: #C2261F;
  --cool: #1A5FB4;
  --hot-soft: rgba(194, 38, 31, .12);
  --cool-soft: rgba(26, 95, 180, .12);

  --c-latest: #A61E6B;
  --c-max: #C2261F;
  --c-min: #1A5FB4;
  --c-avg: #1B6B3A;

  --ok: #1E7A46;      --ok-bg: #EAF6EF;
  --warn: #B26A00;    --warn-bg: #FFF4E0;
  --alarm: #C2261F;   --alarm-bg: #FDEAEA;
  --sensor: #6D28D9;  --sensor-bg: #F3EDFC;
  --unknown: #6B7280; --unknown-bg: #F1F2F4;

  --radius: 10px;
  --gap: 12px;

  font-size: clamp(14px, 0.55vw + 11px, 20px);
}

/* 深色：移工在宿舍用手機看時較舒服。kiosk 硬鎖淺色（見底部）。 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #12151A; --panel: #1A1F26; --ink: #F2F4F7; --ink-2: #B8C0CC; --ink-3: #8A94A3;
    --line: #2C333D;
    --hot: #FF7B72; --cool: #6FA8FF;
    --hot-soft: rgba(255,123,114,.16); --cool-soft: rgba(111,168,255,.16);
    --c-latest: #F19FD0; --c-max: #FF7B72; --c-min: #6FA8FF; --c-avg: #5DD39E;
    --ok: #5DD39E;    --ok-bg: #10291D;
    --warn: #E8B057;  --warn-bg: #2C2313;
    --alarm: #FF7B72; --alarm-bg: #2E1614;
    --sensor: #B48CF2; --sensor-bg: #221A33;
    --unknown: #8A94A3; --unknown-bg: #20252C;
  }
}
:root[data-theme="dark"] {
  --bg: #12151A; --panel: #1A1F26; --ink: #F2F4F7; --ink-2: #B8C0CC; --ink-3: #8A94A3;
  --line: #2C333D;
  --hot: #FF7B72; --cool: #6FA8FF;
  --hot-soft: rgba(255,123,114,.16); --cool-soft: rgba(111,168,255,.16);
  --c-latest: #F19FD0; --c-max: #FF7B72; --c-min: #6FA8FF; --c-avg: #5DD39E;
  --ok: #5DD39E;    --ok-bg: #10291D;
  --warn: #E8B057;  --warn-bg: #2C2313;
  --alarm: #FF7B72; --alarm-bg: #2E1614;
  --sensor: #B48CF2; --sensor-bg: #221A33;
  --unknown: #8A94A3; --unknown-bg: #20252C;
}

* { box-sizing: border-box; }

/* 本檔多處用 display:flex/grid 排版，會蓋掉 [hidden] 的 UA 樣式（display:none）。
   沒有這一條，所有 hidden 的元素（過期橫幅、跟隨按鈕、資料品質提示）都會空著顯示出來。 */
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: var(--font);
  background: var(--bg);
  color: var(--ink);
  /* 數字等寬：溫度更新時大數字不會左右抖動 */
  font-variant-numeric: tabular-nums;
  -webkit-text-size-adjust: 100%;
}

button { font: inherit; color: inherit; cursor: pointer; }

/* ── 頁首 ─────────────────────────────────────────────────────── */
.hdr {
  display: flex; align-items: center; gap: var(--gap); flex-wrap: wrap;
  padding: 10px clamp(10px, 2vw, 22px);
  background: var(--panel); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 30;
}
.hdr-logo { height: 2.2em; width: auto; flex: none; }
.hdr-title { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hdr-name { font-weight: 700; font-size: 1.15em; }
.hdr-sub { font-weight: 400; color: var(--ink-2); font-size: .95em; }
.hdr-clock { margin-left: auto; font-size: 1.05em; color: var(--ink-2); white-space: nowrap; }
.hdr-actions { display: flex; align-items: center; gap: 8px; flex: none; }

.freshness { display: flex; align-items: center; gap: 7px; white-space: nowrap; }
.freshness-text { font-weight: 600; font-size: .92em; }
.dot { width: .7em; height: .7em; border-radius: 50%; background: var(--unknown); flex: none; }
.dot.live { background: var(--ok); }
.dot.delayed { background: var(--warn); }
.dot.stale { background: var(--warn); }
.dot.offline { background: var(--alarm); }

/* 語言選單：地球圖標 + 彈出清單 */
.menu-wrap { position: relative; }
.menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 60;
  margin: 0; padding: 5px; list-style: none; min-width: 190px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 6px 24px rgba(0,0,0,.14);
}
.menu li { margin: 0; }
.menu button {
  display: flex; align-items: center; gap: 9px; width: 100%;
  background: transparent; border: 0; border-radius: 7px; text-align: left;
  padding: 0 10px; min-height: 48px; color: var(--ink);
}
.menu button:hover { background: var(--unknown-bg); }
.menu button.is-on { font-weight: 700; }
.menu .tickmark { width: 1em; flex: none; color: var(--ok); }

.icon-btn {
  background: transparent; border: 1px solid var(--line); border-radius: 8px;
  min-width: 48px; min-height: 48px; color: var(--ink-2);
}
.netbar {
  font-size: .78em; color: var(--warn); background: var(--warn-bg);
  padding: 4px 9px; border-radius: 6px; white-space: nowrap;
}

/* ── 過期／離線橫幅 ──────────────────────────────────────────── */
.banner {
  display: flex; align-items: center; gap: 12px;
  padding: 11px clamp(10px, 2vw, 22px);
  background: var(--warn-bg); color: var(--warn);
  border-bottom: 2px solid currentColor; font-weight: 600;
}
.banner.offline {
  background: var(--alarm); color: #fff; border-bottom-color: #7A1410;
  /* 3 秒週期的緩慢呼吸。★ 絕不用閃爍 —— 大螢幕上閃爍會讓現場的人把螢幕關掉。 */
  animation: breathe 3s ease-in-out infinite;
}
@keyframes breathe { 0%, 100% { opacity: 1; } 50% { opacity: .75; } }
@media (prefers-reduced-motion: reduce) { .banner.offline { animation: none; } }
.banner-icon { font-size: 1.5em; flex: none; }
.banner-body { min-width: 0; line-height: 1.35; }
.banner-action {
  margin-left: auto; flex: none; background: transparent;
  border: 1.5px solid currentColor; border-radius: 8px;
  padding: 0 .9em; min-height: 44px; font-weight: 600;
}

/* ── 系統狀態帶 ──────────────────────────────────────────────── */
.statusbar {
  display: flex; align-items: center; gap: 8px;
  padding: 7px clamp(10px, 2vw, 22px);
  background: var(--unknown-bg); color: var(--unknown);
  font-weight: 700; border-bottom: 1px solid var(--line);
}
.statusbar[data-level="ok"]     { background: var(--ok-bg);     color: var(--ok); }
.statusbar[data-level="warn"]   { background: var(--warn-bg);   color: var(--warn); }
.statusbar[data-level="alarm"]  { background: var(--alarm-bg);  color: var(--alarm); }
.statusbar[data-level="sensor"] { background: var(--sensor-bg); color: var(--sensor); }
.st-icon { font-size: 1.15em; }

/* ── 版面 ────────────────────────────────────────────────────── */
.wrap {
  max-width: 1500px; margin: 0 auto;
  padding: var(--gap) clamp(10px, 2vw, 22px) 28px;
  display: flex; flex-direction: column; gap: var(--gap);
}
.panel {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 12px 14px;
}
.panel-h {
  margin: 0 0 8px; font-size: .95em; font-weight: 700;
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
}
.bucket-note { margin-left: auto; font-size: .75em; font-weight: 400; color: var(--ink-3); }

/* ── 控制列 ──────────────────────────────────────────────────── */
.controls { display: flex; flex-wrap: wrap; gap: var(--gap); align-items: center; }
.chips { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; }
.chips::-webkit-scrollbar { display: none; }
.chip {
  background: var(--panel); border: 1px solid var(--line); border-radius: 999px;
  padding: 0 1em; min-height: 48px; white-space: nowrap; color: var(--ink-2);
}
.chip.is-on { background: var(--ink); color: var(--panel); border-color: var(--ink); font-weight: 600; }
.daterange { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-left: auto; }
.daterange label { display: flex; gap: 5px; align-items: center; font-size: .85em; color: var(--ink-2); }
.daterange input {
  font: inherit; font-size: .95em; padding: 0 .5em; min-height: 44px;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel); color: var(--ink);
}
.btn {
  background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
  padding: 0 .9em; min-height: 44px; color: var(--ink-2); white-space: nowrap;
}

/* ── 三張狀態卡 ──────────────────────────────────────────────── */
.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gap); }
.card {
  background: var(--panel); border: 1px solid var(--line);
  border-left: 5px solid var(--unknown);
  border-radius: var(--radius); padding: 12px 14px;
  display: flex; flex-direction: column; gap: 5px;
}
.card[data-level="ok"]     { border-left-color: var(--ok); }
.card[data-level="warn"]   { border-left-color: var(--warn); }
.card[data-level="alarm"]  { border-left-color: var(--alarm); }
.card[data-level="sensor"] { border-left-color: var(--sensor); }
.card-hd { display: flex; align-items: center; gap: 8px; }
.card-ico { font-size: 1.15em; }
.card-name { font-weight: 600; }
.card-value { display: flex; align-items: baseline; gap: .18em; }
.card-value .num { font-size: clamp(2.4rem, 5.2vw, 4rem); font-weight: 700; line-height: 1; }
/* 離線時的破折號：用原尺寸會變成一條粗灰橫槓，看起來像載入中的骨架畫面 */
.card-value .num.is-dash { font-size: 2rem; color: var(--ink-3); }
.card-value .unit { font-size: 1em; color: var(--ink-3); }
#cardHot .num { color: var(--hot); }
#cardCool .num { color: var(--cool); }
.card-trend { font-size: .82em; color: var(--ink-2); min-height: 1.2em; }
.card-band { font-size: .76em; color: var(--ink-3); }
.card-stats { font-size: .76em; color: var(--ink-3); display: flex; gap: .9em; flex-wrap: wrap; }
.card-stats b { font-weight: 600; color: var(--ink-2); }
.spark { height: 34px; margin: 2px 0; }

/* 狀態徽章：色 + 形（圖示）+ 詞，三重編碼。
   工廠男性色盲比例約 8%，而移工中文閱讀能力不一 —— 三個通道缺一不可。 */
.verdict {
  display: inline-flex; align-items: center; gap: 5px; align-self: flex-start;
  font-size: .8em; font-weight: 700; padding: 3px 9px; border-radius: 999px;
  background: var(--unknown-bg); color: var(--unknown);
}
.verdict[data-level="ok"]     { background: var(--ok-bg);     color: var(--ok); }
.verdict[data-level="warn"]   { background: var(--warn-bg);   color: var(--warn); }
.verdict[data-level="alarm"]  { background: var(--alarm-bg);  color: var(--alarm); }
.verdict[data-level="sensor"] { background: var(--sensor-bg); color: var(--sensor); }

/* ★ 資料過期時「整片灰掉」。5 公尺外一眼就知道這不是即時值，不需要讀任何字 ——
   這比加一個小圖示有效一百倍，對越南籍同仁尤其重要。 */
body.is-stale .cards,
body.is-stale .panel-kpi { filter: grayscale(1); opacity: .45; }
body.is-offline .cards,
body.is-offline .panel-kpi { filter: grayscale(1); opacity: .38; }

/* ── KPI 表 ──────────────────────────────────────────────────── */
.tbl-scroll { overflow-x: auto; }
.kpi-tbl { width: 100%; border-collapse: collapse; font-size: .92em; white-space: nowrap; }
.kpi-tbl th, .kpi-tbl td { padding: 6px 10px; text-align: right; border-bottom: 1px solid var(--line); }
.kpi-tbl th:first-child, .kpi-tbl td:first-child { text-align: left; font-weight: 600; }
.kpi-tbl thead th { font-size: .82em; font-weight: 600; color: var(--ink-2); }
.kpi-tbl td.v-latest { color: var(--c-latest); font-weight: 700; }
.kpi-tbl td.v-max { color: var(--c-max); }
.kpi-tbl td.v-min { color: var(--c-min); }
.kpi-tbl td.v-avg { color: var(--c-avg); }
.kpi-tbl tbody tr:last-child td { border-bottom: 0; }
.coverage { margin-top: 8px; font-size: .8em; color: var(--ink-3); }
.quality {
  margin-top: 8px; font-size: .8em; padding: 8px 10px; border-radius: 8px;
  background: var(--sensor-bg); color: var(--sensor); line-height: 1.45;
}

/* ── 圖表 ────────────────────────────────────────────────────── */
.tabs { display: none; gap: 6px; }
.tab {
  flex: 1; background: var(--panel); border: 1px solid var(--line);
  border-radius: 8px; min-height: 48px; color: var(--ink-2);
}
.tab.is-on { background: var(--ink); color: var(--panel); font-weight: 600; }
.charts { display: grid; grid-template-columns: 1fr 1.4fr; gap: var(--gap); }
.panel-chart { position: relative; display: flex; flex-direction: column; }
.chart { width: 100%; height: clamp(260px, 34vh, 420px); }
.follow-btn {
  position: absolute; right: 18px; top: 40px;
  background: var(--ink); color: var(--panel); border: 0; border-radius: 999px;
  padding: 0 1em; min-height: 40px; font-weight: 600; font-size: .82em; z-index: 5;
}

/* ── 事件時間軸 ──────────────────────────────────────────────── */
.events { list-style: none; margin: 0; padding: 0; max-height: 260px; overflow-y: auto; }
.events li {
  display: flex; align-items: baseline; gap: 10px; padding: 7px 4px;
  border-bottom: 1px solid var(--line); font-size: .86em; cursor: pointer;
}
.events li:last-child { border-bottom: 0; }
.events li:hover { background: var(--unknown-bg); }
.ev-dot { font-size: .8em; flex: none; }
.ev-when { color: var(--ink-3); flex: none; font-size: .9em; }
.ev-what { font-weight: 600; }
.ev-dur { margin-left: auto; color: var(--ink-2); flex: none; }
.events .empty { color: var(--ink-3); cursor: default; justify-content: center; }

/* ── 頁尾 ────────────────────────────────────────────────────── */
.ftr {
  padding: 14px clamp(10px, 2vw, 22px) 22px; text-align: center;
  font-size: .76em; color: var(--ink-3); line-height: 1.6;
}

/* ── 手機 ────────────────────────────────────────────────────── */
@media (max-width: 860px) {
  .hdr-clock { display: none; }
  /* 375px 塞不下「logo + 標題 + 新鮮度 + 兩顆按鈕」，硬塞會把標題壓成 0 寬度整個消失。
     讓新鮮度換到第二行，標題與按鈕各自拿到夠用的寬度。 */
  .hdr { padding-bottom: 6px; }
  .hdr-sub { display: none; }
  /* flex-basis 要給小值：用 auto（= 內容寬度）時標題會獨占整行、把按鈕擠到第二行，
     頁首就變成三行。給 120px 基準讓它先讓位、再長大填滿剩餘空間。 */
  .hdr-title { flex: 1 1 120px; }
  .freshness { order: 10; width: 100%; }
  .hdr-actions { margin-left: auto; }
  .cards { grid-template-columns: 1fr; }
  .card-value .num { font-size: clamp(2.6rem, 13vw, 3.4rem); }
  .charts { grid-template-columns: 1fr; }
  .tabs { display: flex; }
  /* tab 模式：一次只顯示一張圖 */
  .charts .panel-chart { display: none; }
  .charts .panel-chart.is-on { display: flex; }
  .daterange { margin-left: 0; width: 100%; }
  .spark { display: none; }
}

/* ── Kiosk（?kiosk=1）─────────────────────────────────────────
 * 硬鎖淺色高對比，不跟隨系統。保麗龍發泡廠房是明亮日光燈/天窗環境（500–1000 lux），
 * 深色背景會把螢幕變成鏡子、反射燈管把白字洗掉。廠房有粉塵、螢幕會蒙灰，
 * 實際對比比帳面低，所以目標是 WCAG AAA 7:1 起跳而非 4.5:1。
 */
body.kiosk {
  --bg: #F7F8FA; --panel: #FFFFFF; --ink: #111418; --ink-2: #3B424B; --ink-3: #5A626C;
  --line: #D6DBE1;
  font-size: clamp(18px, 1.05vw + 10px, 30px);
  overflow: hidden;
}
body.kiosk .controls,
body.kiosk .tabs,
body.kiosk #themeBtn,
body.kiosk .panel-events,
body.kiosk .follow-btn,
body.kiosk #panelDaily { display: none; }
/* 用 flex 撐滿高度，不要用「100vh 減一個猜出來的 chrome 高度」——
   那個魔術數字一旦頁首因為告警橫幅變高就會把頁尾擠出畫面。 */
body.kiosk { display: flex; flex-direction: column; height: 100vh; }
body.kiosk .wrap {
  max-width: none; flex: 1; min-height: 0;
  padding-bottom: 0; gap: 10px;
}
body.kiosk .cards { flex: none; }
body.kiosk .card-value .num { font-size: clamp(3rem, 6.5vw, 7rem); }
body.kiosk .charts { grid-template-columns: 1fr; flex: 1; min-height: 0; }
body.kiosk .panel-chart { display: flex; min-height: 0; }
body.kiosk .chart { height: 100%; flex: 1; min-height: 180px; }
body.kiosk .panel-kpi { display: none; }
body.kiosk .statusbar { font-size: 1.15em; padding: 10px clamp(10px, 2vw, 22px); }
body.kiosk .banner { font-size: 1.1em; }
body.kiosk .ftr { padding: 8px; }
