html, body { margin: 0; padding: 0; background: #06223f; color: #fff;
  font-family: "Microsoft YaHei", "PingFang SC", "Noto Sans SC", sans-serif; }

/* 画面：1920x1080 坐标用百分比定位，字号用容器宽度单位，整屏随宽度等比缩放 */
.screen { position: relative; width: 100%; max-width: calc(100vh * 16 / 9); margin: 0 auto;
  container-type: inline-size; overflow: hidden; user-select: none; }
.screen-bg { position: absolute; inset: 0; width: 100%; height: 100%; }
.screen-flow { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.screen-loading { padding: 2rem; text-align: center; color: #9cc; }
.el { position: absolute; box-sizing: border-box; }
.value { background: #0000e0; color: #fff; display: flex; align-items: center; justify-content: flex-end;
  padding-right: .15cqw; white-space: nowrap; overflow: hidden; line-height: 1; }
.value.bad { background: #555; color: #bbb; }
.value.plain { background: transparent; justify-content: center; overflow: visible; padding: 0; }
.value.plain.bad { background: transparent; color: #9ab; }
.brush.round { border-radius: 50%; }
/* 按钮是透明的点击区，组态王常把指示灯、文字图片叠在按钮上面，所以按钮放到最上层 */
.button { cursor: pointer; border-radius: 4px; z-index: 1; }
.button.nav:hover { box-shadow: 0 0 0 2px rgba(255, 255, 255, .6) inset; }
.button.locked { cursor: not-allowed; }
/* 水泵画面的远程冷热水按钮（组态王里没有，自己画框和字，样式仿右栏的按钮） */
.remote-heat { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .3em; color: #fff;
  white-space: nowrap; border: 1px solid rgba(160, 210, 255, .7); background: rgba(10, 60, 110, .6); }
.remote-heat i { display: inline-block; width: .9em; height: .9em; margin-right: .4em; border-radius: 50%; vertical-align: -.1em; }
.m-heat { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.m-heat button { padding: 12px 18px; font-size: 16px; }
.blink { animation: blink 1s steps(1) infinite; }
@keyframes blink { 50% { visibility: hidden; } }
.flow { stroke: #7fffd4; stroke-width: 6; stroke-dasharray: 18 22; animation: flow linear infinite; }
@keyframes flow { to { stroke-dashoffset: -40; } }

.statusbar { position: fixed; top: 6px; left: 6px; z-index: 10; display: flex; gap: 6px; font-size: 13px; }
.statusbar .conn { margin: 0; padding: 2px 8px; border-radius: 10px; background: rgba(0, 0, 0, .5); }  /* margin: 0 防止被 .ok 的外边距撑高 */
.statusbar .conn.ok::before { content: "● "; color: #3f3; }
.statusbar .conn.bad::before { content: "● "; color: #f33; }
.statusbar .alarm-count { padding: 2px 8px; border-radius: 10px; background: #c00; color: #fff; text-decoration: none;
  animation: blink 1s steps(1) infinite; }

#blazor-error-ui { background: #ffe; color: #000; bottom: 0; display: none; left: 0; padding: .6rem 1.25rem; position: fixed; width: 100%; z-index: 1000; }
#blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: .75rem; top: .5rem; }
#error-detail { display: block; margin-top: .3rem; color: #666; font-size: 11px; word-break: break-all; }
.loading-progress { position: absolute; display: block; width: 8rem; height: 8rem; inset: 20vh 0 auto 0; margin: 0 auto; }
.loading-progress circle { fill: none; stroke: #234; stroke-width: .6rem; transform-origin: 50% 50%; transform: rotate(-90deg); }
.loading-progress circle:last-child { stroke: #4af; stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%; transition: stroke-dasharray .05s ease-in-out; }
.loading-progress-text { position: absolute; text-align: center; font-weight: bold; inset: calc(20vh + 3.25rem) 0 auto .2rem; }
.loading-progress-text:after { content: var(--blazor-load-percentage-text, "加载中"); }

/* 手机列表页 */
.m { max-width: 720px; margin: 0 auto; padding: 0 12px 24px; font-size: 15px; }
.m-head { position: sticky; top: 0; z-index: 5; display: flex; justify-content: space-between; align-items: center;
  padding: 38px 0 10px; background: #06223f; font-weight: bold; }  /* 顶部留给固定的状态栏（连接、报警、账号） */
.m-head a { color: #7cf; text-decoration: none; font-weight: normal; }
.m-links { display: flex; gap: 14px; }
.m-sec h2 { font-size: 15px; color: #9cf; margin: 18px 0 8px; }
.m-sec.alarm h2 { color: #f66; }
.m-alarm { display: flex; justify-content: space-between; gap: 8px; padding: 8px 10px; margin-bottom: 6px;
  background: rgba(200, 0, 0, .25); border-left: 3px solid #f33; border-radius: 4px; }
.m-alarm span { color: #ccc; white-space: nowrap; }
.m-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip { padding: 3px 10px; border-radius: 12px; font-size: 13px; }
.chip.ok { background: #145a32; } .chip.bad { background: #922; }
.m-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.m-card, .m-unit { background: rgba(255, 255, 255, .07); border-radius: 6px; padding: 8px 10px; }
.m-unit { display: block; margin-bottom: 8px; color: inherit; text-decoration: none; }
.m-name { font-size: 13px; color: #cde; margin-bottom: 4px; }
.m-vals { display: flex; justify-content: space-between; font-size: 17px; font-variant-numeric: tabular-nums; }
.m-vals small { font-size: 11px; color: #9ab; margin-left: 1px; }
.m-row { display: flex; justify-content: space-between; padding: 2px 0; font-size: 14px; }
.m-row b { font-weight: normal; font-variant-numeric: tabular-nums; }
.statusbar .mode { padding: 2px 8px; border-radius: 10px; background: rgba(0, 0, 0, .5); color: #7cf; text-decoration: none; }

/* 登录与账号页 */
.login { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 16px; box-sizing: border-box; }
.login-box { width: 100%; max-width: 340px; background: rgba(255, 255, 255, .06); border-radius: 8px; padding: 24px; }
.login-box h1 { font-size: 18px; line-height: 1.5; text-align: center; margin: 0 0 20px; color: #bde; }
.login-box label, .form label { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; font-size: 14px; color: #bcd; }
/* 字号不能小过 16px，否则 iPhone 点输入框会自动放大页面，登录后也缩不回来 */
input, select { font: inherit; font-size: 16px; padding: 8px 10px; border-radius: 4px; border: 1px solid #357; background: #0b2e52; color: #fff; }
button { font: inherit; padding: 8px 14px; border: 0; border-radius: 4px; background: #1e6fd9; color: #fff; cursor: pointer; }
button:disabled { opacity: .6; }
button.danger { background: #a33; }
.login-box button { width: 100%; margin-top: 4px; }
.login-error { color: #ff8a8a; margin: 4px 0 10px; font-size: 14px; }
.ok { color: #7f7; margin: 6px 0 10px; }
.notice { background: rgba(255, 200, 0, .15); border-left: 3px solid #fc0; padding: 8px 10px; margin: 10px 0; }
.page { max-width: 420px; margin: 0 auto; padding: 48px 16px 24px; }
.page.wide { max-width: 980px; }
.page h1 { font-size: 20px; } .page h2 { font-size: 16px; margin-top: 24px; }
.page a { color: #7cf; }
.form.row { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; }
.form.row label { margin: 0; }
.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th, .table td { padding: 6px 8px; border-bottom: 1px solid #234; text-align: left; }
.table .actions { white-space: nowrap; display: flex; gap: 6px; }
label.inline { display: inline-flex; align-items: center; gap: 4px; }
.statusbar .user { display: inline-flex; gap: 8px; padding: 2px 8px; border-radius: 10px; background: rgba(0, 0, 0, .5); }
.statusbar .user a { color: #cde; text-decoration: none; }

/* 报警：画面里嵌入时字号随画面宽度缩放（cqw），独立页面用固定字号 */
.alarm-panel { height: 100%; display: flex; flex-direction: column; gap: .6em; box-sizing: border-box; color: #dfe9f5; }
.screen .alarm-panel { font-size: .85cqw; padding: .8em; background: rgba(4, 24, 48, .78); border-radius: 6px; }
.screen .alarm-panel input, .screen .alarm-panel select, .screen .alarm-panel button { font-size: 1em; padding: .25em .5em; }
.page .alarm-panel { font-size: 14px; margin-bottom: 16px; }
.alarm-title { color: #9cf; }
.alarm-title b { color: #fff; }
.alarm-empty { color: #8fb; padding: .5em 0; }
.alarm-filter { display: flex; flex-wrap: wrap; align-items: center; gap: .6em 1em; }
.alarm-filter label { display: inline-flex; align-items: center; gap: .4em; }
.alarm-scroll { flex: 1; min-height: 0; overflow: auto; }
.alarm-table { width: 100%; border-collapse: collapse; }
.alarm-table th { position: sticky; top: 0; background: #0b2e52; text-align: left; font-weight: normal; color: #9cf; }
.alarm-table th, .alarm-table td { padding: .35em .6em; border-bottom: 1px solid #234; white-space: nowrap; }
.alarm-table td:first-child { white-space: normal; min-width: 9em; }   /* 报警内容（已带设备名）放第一列，可换行 */
.alarm-table tr.active td { color: #ff8a8a; }

/* 曲线和报表 */
.seg { display: inline-flex; }
.seg button { background: #123a63; border-radius: 0; }
.seg button:first-child { border-radius: 4px 0 0 4px; }
.seg button:last-child { border-radius: 0 4px 4px 0; }
.seg button.on { background: #1e6fd9; }
.screen .alarm-panel .seg button { padding: .25em .8em; }
.pen-picker { display: flex; flex-wrap: wrap; gap: .4em 1.6em; padding: .6em; background: rgba(0, 0, 0, .35); border-radius: 4px; max-height: 45%; overflow: auto; }
.pen-group { display: flex; flex-direction: column; gap: .15em; }
.pen-group b { color: #9cf; font-weight: normal; }
.trend-legend { display: flex; flex-wrap: wrap; gap: .3em 1.4em; }
.trend-legend i { display: inline-block; width: 1em; height: .25em; vertical-align: middle; margin-right: .4em; }
.trend-legend b { margin-left: .4em; font-weight: normal; color: #fff; font-variant-numeric: tabular-nums; }
.trend-box { flex: 1; min-height: 0; }
.page .trend-box { height: 60vh; min-height: 260px; }
.trend-chart { width: 100%; height: 100%; display: block; }
.trend-chart .plot { fill: rgba(0, 10, 30, .45); stroke: #2c5680; }
.trend-chart .grid { stroke: #23486d; stroke-width: 1; }
.trend-chart text { fill: #9fc0e0; font-size: 13px; }
.trend-chart text.empty { fill: #8aa; font-size: 18px; }
.trend-chart .line { fill: none; stroke-width: 2; vector-effect: non-scaling-stroke; }
.alarm-table.report th { white-space: normal; min-width: 4.5em; line-height: 1.3; }
.alarm-table.report th small { display: block; color: #7a9cbf; }
.alarm-table.report td { text-align: right; font-variant-numeric: tabular-nums; }
.alarm-table.report td:first-child { text-align: left; white-space: nowrap; min-width: 0; }
.screen .report-panel { background: #041830; }   /* 不透明：盖住底图上组态王报表面板的文字 */
.report-pages { display: flex; flex-wrap: wrap; gap: .4em; }
.report-pages a { padding: .2em .8em; border-radius: 4px; border: 1px solid #2f5f8f; color: #9cf; text-decoration: none; }
.report-pages a.on { background: #1d6fb8; border-color: #1d6fb8; color: #fff; }
a.button-link { padding: .25em .7em; border-radius: 4px; background: #2a7d4f; color: #fff; text-decoration: none; }

/* 画面右上角「系统管理」菜单 */
.sys-menu-mask { z-index: 20; }
.sys-menu { z-index: 21; height: auto !important; display: flex; flex-direction: column; font-size: 1cqw;
  background: #0b2e52; border: 1px solid #4a7fb0; border-radius: 4px; box-shadow: 0 4px 12px rgba(0, 0, 0, .5); }
.sys-menu a { padding: .45em .8em; color: #e6f0fa; text-decoration: none; white-space: nowrap; }
.sys-menu a:hover { background: #1e6fd9; }

/* 主界面：机组、冷热源卡片和各楼层房间一览 */
.dash { max-width: 1680px; margin: 0 auto; padding: 0 16px 24px; font-size: 15px; }
.dash a { color: inherit; text-decoration: none; }
.dash-head { position: sticky; top: 0; z-index: 5; display: flex; flex-wrap: wrap; justify-content: space-between;
  align-items: baseline; gap: 8px; padding: 38px 0 8px; background: #06223f; }  /* 顶部留给固定的状态栏，吸顶以免滚动时状态栏压住内容 */
.dash-head h1 { margin: 0; font-size: 20px; color: #bfe0ff; }
.dash-head nav { display: flex; gap: 16px; }
.dash-head nav a { color: #7cf; }
.dash-top { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin: 8px 0 12px; }
.dash-alarm { padding: 4px 14px; border-radius: 6px; background: #145a32; }
.dash-alarm.on { background: #c00; }
.dash-comm { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.dash-label { color: #9ab; font-size: 13px; }
.dash-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 10px; }
.dash-card { display: block; background: rgba(255, 255, 255, .07); border: 1px solid rgba(124, 204, 255, .18);
  border-radius: 8px; padding: 10px 12px; }
.dash-card:hover { border-color: rgba(124, 204, 255, .6); }
.dash-card-head { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
.dash-card-head b { font-size: 16px; margin-right: auto; }
.badge { padding: 1px 8px; border-radius: 10px; font-size: 12px; background: #555; white-space: nowrap; }
.badge.run { background: #1e8449; } .badge.duty { background: #2471a3; } .badge.stop { background: #555; }
.badge.off { background: #7b241c; } .badge.alarm { background: #c00; color: #fff; font-weight: normal; }
.dash-row { display: grid; grid-template-columns: 5.6em 1fr auto; align-items: baseline; gap: 6px; padding: 2px 0; }
.dash-row span { color: #cde; font-size: 13px; white-space: nowrap; }
.dash-row b { text-align: right; font-size: 17px; font-weight: normal; font-variant-numeric: tabular-nums; }
.dash-row small, .dash-room-vals small { font-size: 11px; color: #9ab; margin-left: 2px; }
.dash-row i { font-style: normal; font-size: 12px; color: #9ab; min-width: 5.5em; text-align: right; font-variant-numeric: tabular-nums; }
.dash-lamps { display: flex; flex-wrap: wrap; gap: 4px 10px; margin-top: 6px; font-size: 12px; color: #9ab; }
.lamp::before { content: "●"; margin-right: 3px; color: #666; }
.lamp.run { color: #cde; } .lamp.run::before { color: #3f3; }
.lamp.fault { color: #f88; } .lamp.fault::before { color: #f33; }
.dash-floor h2 { display: flex; align-items: center; gap: 10px; font-size: 16px; color: #9cf; margin: 18px 0 8px; }
.dash-floor h2 a { color: #9cf; }
.dash-rooms { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.dash-room { background: rgba(255, 255, 255, .07); border: 1px solid transparent; border-radius: 6px; padding: 6px 10px; }
.dash-room.over { border-color: #e33; background: rgba(200, 0, 0, .18); }
.dash-room-name { font-size: 13px; color: #cde; margin-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dash-room-vals { display: flex; justify-content: space-between; gap: 6px; font-size: 16px; font-variant-numeric: tabular-nums; }
.dash-room-vals .bad { color: #ff6b6b; font-weight: bold; }
.dash-room-diff { font-size: 12px; color: #9ab; margin-top: 2px; white-space: nowrap; }
.dash-room-diff.bad { color: #ff6b6b; font-weight: bold; }
@media (max-width: 420px) {   /* 手机：房间一行两格 */
  .dash { padding: 0 10px 24px; }
  .dash-room { padding: 5px 7px; }
  .dash-room-vals { font-size: 14px; gap: 3px; }
  .dash-room-vals small { margin-left: 1px; }
}

/* 修正设置页 */
.offsets h2 { color: #9cf; }
.off-hint { color: #9ab; font-size: 13px; }
.off-tabs { display: flex; gap: 6px; margin: 12px 0 4px; }
.off-tabs button { padding: 6px 16px; border: 1px solid #2a5a8a; border-radius: 6px; background: transparent; color: #cde; font-size: 14px; cursor: pointer; }
.off-tabs button.on { background: #1e6fd9; border-color: #1e6fd9; color: #fff; }
.off-scroll { overflow-x: auto; }
.off-table td, .off-table th { white-space: nowrap; }
.off-table th { color: #9cf; font-weight: normal; }
.off-table td b { font-weight: normal; font-variant-numeric: tabular-nums; display: inline-block; min-width: 3.2em; }
.off-table td small { color: #7a9cbf; margin-left: 8px; font-variant-numeric: tabular-nums; }
.off-table td.nz b { color: #ffcc33; font-weight: bold; }
.off-groups { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 0 24px; }
.off-edit { margin-left: 8px; padding: 1px 8px; border: 1px solid #2a5a8a; border-radius: 4px; background: transparent; color: #7cf; font-size: 12px; cursor: pointer; }
.off-edit:hover { background: #1e6fd9; color: #fff; }
.off-fail { color: #ff6b6b; white-space: normal !important; }
.off-mask { position: fixed; inset: 0; z-index: 30; background: rgba(0, 0, 0, .55); }
.off-dialog { position: fixed; z-index: 31; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(440px, calc(100vw - 32px));
  box-sizing: border-box; padding: 18px 20px; border-radius: 8px; background: #0b2e52; border: 1px solid #2a5a8a; font-size: 14px; }
.off-dialog h3 { margin: 0 0 12px; font-size: 17px; }
.off-info { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; margin-bottom: 14px; }
.off-info span { color: #9ab; } .off-info b { font-weight: normal; }
.off-dialog label { display: flex; align-items: center; gap: 8px; }
.off-dialog input { width: 9em; padding: 4px 6px; }
.off-change { font-size: 20px; margin: 4px 0 8px; } .off-change b { color: #ffcc33; }
.off-error { color: #ff6b6b; min-height: 1.2em; margin: 8px 0; }
.off-ok { color: #6f6; }
.off-buttons { display: flex; justify-content: flex-end; gap: 8px; margin-top: 10px; }
.off-buttons button { padding: 6px 16px; border-radius: 6px; border: 1px solid #2a5a8a; background: transparent; color: #cde; cursor: pointer; }
.off-buttons button.primary { background: #1e6fd9; border-color: #1e6fd9; color: #fff; }
.off-buttons button:disabled { opacity: .5; cursor: default; }
.off-matrix th:not(:first-child) { min-width: 13em; }
.off-none { color: #4a6a8a; }
.off-unlock { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 13px; color: #9ab; }
.off-unlock .on { color: #6f6; }
.off-mask.top { z-index: 40; }
.off-dialog.top { z-index: 41; }

/* 钉钉推送页 */
.nt-status { margin: 8px 0; } .nt-status .on { color: #6f6; } .nt-status .bad { color: #ff9a6b; }
.nt-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 8px 0; font-size: 14px; }
.nt-table td:first-child { width: 45%; white-space: normal; }
.nt-table select, .nt-row input[type=time], .nt-min { padding: 3px 6px; }
.nt-min { width: 5em; margin: 0 4px 0 8px; }
.nt-saved { color: #6f6; font-size: 12px; width: 4em; }
.nt-text { white-space: pre-line !important; font-size: 12px; max-width: 40em; }
