/* YM Digital Twin - tokens synced with DESIGN.md (DESIGN.md wins on drift) */
:root {
  /* typography */
  --font-display: 'Space Grotesk', 'PingFang SC', 'Microsoft YaHei', sans-serif;
  --font-body: 'PingFang SC', 'Microsoft YaHei', 'Noto Sans CJK SC', sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, Consolas, 'Courier New', monospace;
  --text-xs: 12px; --text-sm: 13px; --text-body: 14px; --text-lg: 17px;
  --text-xl: 21px; --text-2xl: 26px; --text-metric: 40px;
  /* space / radius */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-6: 24px; --sp-8: 32px;
  --r-1: 3px; --r-2: 6px;
  /* palette (from DESIGN.md oklch, sRGB fallbacks inline) */
  --bg: #17181c;   /* 石墨青：冷石墨底 */
  --bg-raised: #1d1f24;
  --bg-inset: #111216;
  --surface: #1d1f24;
  --surface2: #24272c;
  --line: #34383f;
  --border: #34383f;
  --txt: #e8e9e7;
  --txt-2: #9aa1a8;
  --txt-3: #6d747b;
  --fg: #e8e9e7;
  --muted: #9aa1a8;
  --accent: #5fa8d3;   /* 钢青 */
  --kraft: #5fa8d3;
  --tag-fg: #0d1a24;   /* 深海军字（配钢青/深钢底） */
  --heat: oklch(72% .18 40);
  --humid: oklch(75% .1 230);
  --ok: oklch(80% .16 155);
  --warn: oklch(82% .15 95);
  --bad: oklch(63% .2 25);
  --err: oklch(63% .2 25);
  --info: oklch(75% .11 210);
  --steel: oklch(70% .04 235);
  /* motion */
  --ease-out: cubic-bezier(.2,.8,.2,1);
  --ease-io: cubic-bezier(.4,0,.2,1);
  --t-fast: 140ms; --t-normal: 240ms; --t-slow: 400ms;
  --edge: inset 0 1px 0 rgba(255,255,255,.05);
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body {
  background: var(--bg); color: var(--txt);
  font: 400 var(--text-body)/1.55 var(--font-body);
  -webkit-font-smoothing: antialiased;
}
button, input { font-family: inherit; color: inherit; }
button { background: none; border: none; cursor: pointer; }
svg.lucide { width: 1em; height: 1em; stroke-width: 1.75; flex: none; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-1); }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* ---------- app shell ---------- */
#app {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(320px, 30vw, 430px);
  grid-template-rows: 48px minmax(0, 64fr) minmax(0, 36fr);
  grid-template-areas: "top top" "stage rail" "dock rail";
  height: 100dvh; min-height: 0; background: var(--bg);
}
#topbar {
  grid-area: top; z-index: 5;
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 0 var(--sp-3);
  background: var(--bg-raised); border-bottom: 1px solid var(--line);
  box-shadow: var(--edge);
}
.brand { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; }
.brand-tag {
  display: flex; align-items: center; gap: 6px;
  background: #243038; color: #bfe2f5; border-radius: var(--r-1);
  font: 600 var(--text-sm)/1 var(--font-display); letter-spacing: .04em;
  padding: 7px 9px; white-space: nowrap;
}
.brand-tag svg.lucide { width: 15px; height: 15px; }
.brand-sub { font-size: var(--text-xs); color: var(--txt-2); letter-spacing: .06em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chips { margin-left: auto; display: flex; align-items: center; gap: var(--sp-2); }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line); border-radius: var(--r-1);
  background: var(--bg-inset); padding: 5px 9px;
  font: 500 var(--text-xs)/1.2 var(--font-display); letter-spacing: .04em;
  color: var(--txt-2); white-space: nowrap;
}
.chip .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--txt-3); }
.chip.online .dot { background: var(--ok); }
.chip.offline .dot { background: var(--bad); }
.chip.connecting .dot { background: var(--warn); }
.chip.demo .dot { background: var(--info); }
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  width: 34px; height: 34px; border: 1px solid var(--line); border-radius: var(--r-2);
  background: var(--surface2); box-shadow: var(--edge); font-size: var(--text-lg); color: var(--txt);
  transition: background var(--t-fast) var(--ease-out), border-color var(--t-fast), color var(--t-fast);
}
.icon-btn:hover { background: var(--line); }
.icon-btn.active { border-color: var(--accent); color: var(--accent); }
#stage {
  grid-area: stage; position: relative; overflow: hidden; min-width: 0; min-height: 0;
  background: radial-gradient(130% 100% at 50% 8%, #17140f 0%, #0c0a08 70%);
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
#scene-host { position: absolute; inset: 0; }
#scene-host canvas { display: block; }
#hud { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
#viewbar { position: absolute; left: var(--sp-3); bottom: var(--sp-3); display: flex; gap: 6px; z-index: 3; }
#toast-root { position: absolute; right: var(--sp-4); bottom: var(--sp-4); z-index: 40; display: flex; flex-direction: column; gap: var(--sp-2); max-width: min(360px, calc(100vw - 32px)); }
#panel {
  grid-area: rail; min-height: 0; overflow: auto;
  padding: var(--sp-3); display: flex; flex-direction: column; gap: var(--sp-3);
  background: var(--bg-raised);
  scrollbar-width: thin; scrollbar-color: var(--line) transparent;
}
#panel section { min-width: 0; }
#dock {
  grid-area: dock; min-width: 0; min-height: 0; display: flex; gap: var(--sp-3);
  padding: var(--sp-3); background: var(--bg-raised);
}
#dock > section { min-width: 0; min-height: 0; overflow: auto; }
#panel-trend { flex: 1; }
#panel-trend .panel { height: 100%; }
#panel-trend .chart-wrap { height: auto; flex: 1; min-height: 120px; margin: 8px 8px 0; }
#panel-table { min-width: 0; }

/* ---------- panels ---------- */
.panel {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-2); box-shadow: var(--edge); overflow: hidden;
}
.panel-head {
  display: flex; align-items: center; gap: var(--sp-2);
  height: 30px; padding: 0 var(--sp-2);
  background: #232830; color: #9ed0ef;
  box-shadow: inset 0 -2px 0 #3c7ba6;
  font: 600 var(--text-xs)/1 var(--font-display); letter-spacing: .08em;
}
.panel-head .perf { flex: 1; height: 1px; border-bottom: 2px dotted rgba(158,208,239,.35); }
.panel-head .barcode {
  width: 54px; height: 11px; opacity: .35;
  background: repeating-linear-gradient(90deg, #9ed0ef 0 2px, transparent 2px 3px, #9ed0ef 3px 6px, transparent 6px 8px, #9ed0ef 8px 9px, transparent 9px 12px);
}
.panel-body { padding: var(--sp-3); }

/* ---------- telemetry ---------- */
.metrics { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); padding: var(--sp-3); }
.metric { padding: var(--sp-2); border: 1px dashed var(--line); border-radius: var(--r-2); background: var(--bg-inset); min-width: 0; }
.m-label { display: flex; align-items: center; gap: 6px; font: 500 var(--text-xs)/1 var(--font-display); letter-spacing: .08em; color: var(--txt-2); margin-bottom: 6px; }
.m-label svg.lucide { width: 14px; height: 14px; }
.m-value { font: 600 var(--text-metric)/1 var(--font-mono); font-variant-numeric: tabular-nums; color: var(--heat); transition: opacity var(--t-normal), color var(--t-slow); white-space: nowrap; }
.m-value .unit { font-size: var(--text-lg); color: var(--txt-2); margin-left: 2px; }
.metric.humi .m-value { color: var(--humid); }
.m-sub { margin-top: 6px; font-size: var(--text-xs); color: var(--txt-2); }
.m-sub b { color: var(--txt); font-weight: 500; font-family: var(--font-mono); }
.metric.stale .m-value { opacity: .35; }
.sensor-line { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2) var(--sp-3); border-top: 1px dashed var(--line); font-size: var(--text-sm); color: var(--txt-2); flex-wrap: wrap; }
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  font: 500 var(--text-xs)/1 var(--font-mono); letter-spacing: .02em;
  border-radius: var(--r-1); padding: 4px 7px; border: 1px solid var(--line); color: var(--txt-2);
}
.badge.ok { color: var(--ok); border-color: color-mix(in oklab, var(--ok) 55%, transparent); }
.badge.warn { color: var(--warn); border-color: color-mix(in oklab, var(--warn) 55%, transparent); }
.badge.err { color: var(--bad); border-color: color-mix(in oklab, var(--bad) 55%, transparent); }

/* ---------- chart ---------- */
.chart-panel { display: flex; flex-direction: column; }
.chart-head-extra { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; }
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: var(--r-1); overflow: hidden; }
.seg button { padding: 4px 9px; font: 500 var(--text-xs)/1.2 var(--font-display); letter-spacing: .04em; color: var(--txt-2); }
.seg button + button { border-left: 1px solid var(--line); }
.seg button.on { background: #2f4f63; color: #dff1fc; }
.seg.plain { border-color: var(--line); }
.seg.plain button { color: var(--txt-2); }
.seg.plain button + button { border-color: var(--line); }
.seg.plain button.on { background: var(--accent); color: var(--tag-fg); }
.chart-wrap { position: relative; height: 170px; margin: var(--sp-2) var(--sp-2) 0; }
.chart-wrap canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.chart-legend { display: flex; gap: var(--sp-3); padding: var(--sp-2) var(--sp-3); font-size: var(--text-xs); color: var(--txt-2); flex-wrap: wrap; }
.chart-legend i { display: inline-block; width: 14px; height: 3px; border-radius: 2px; vertical-align: middle; margin-right: 5px; }
.chart-legend i.t { background: var(--heat); }
.chart-legend i.h { background: var(--humid); }
.chart-legend i.g { height: 0; border-top: 2px dashed var(--txt-3); }
.chart-stats { display: flex; gap: var(--sp-4); flex-wrap: wrap; padding: var(--sp-2) var(--sp-3) 0; font: 500 12px/1.5 var(--font-mono); color: var(--txt-2); }
.chart-stats b { color: var(--txt); font-weight: 600; }
.chart-stats .t b { color: var(--heat); }
.chart-stats .h b { color: var(--humid); }
.chart-stats .tt { color: var(--heat); }
.chart-stats .hh { color: var(--humid); }

/* ---------- status rows ---------- */
.srow {
  display: grid; grid-template-columns: 12px minmax(74px, 1fr) auto; align-items: center; gap: var(--sp-2);
  padding: 8px var(--sp-3); border-bottom: 1px dashed var(--line); font-size: var(--text-sm);
}
.srow:last-child { border-bottom: none; }
.srow .name { display: flex; align-items: center; gap: 8px; min-width: 0; color: var(--txt); }
.srow .name svg.lucide { width: 15px; height: 15px; color: var(--txt-2); }
.srow .right { display: flex; align-items: center; gap: var(--sp-2); }
.srow .val { font: 500 var(--text-sm)/1 var(--font-mono); color: var(--txt); font-variant-numeric: tabular-nums; white-space: nowrap; }
.srow .val .muted { color: var(--txt-2); }
.led { width: 9px; height: 9px; border-radius: 50%; background: var(--txt-3); flex: none; box-shadow: inset 0 0 0 1px rgba(0,0,0,.4); transition: background var(--t-normal) var(--ease-out), box-shadow var(--t-normal); }
.led.on-ok { background: var(--ok); box-shadow: 0 0 6px var(--ok); }
.led.on-heat { background: var(--heat); box-shadow: 0 0 6px var(--heat); }
.led.on-humid { background: var(--humid); box-shadow: 0 0 6px var(--humid); }
.led.on-steel { background: var(--steel); box-shadow: 0 0 6px var(--steel); }
.led.bad { background: var(--bad); box-shadow: 0 0 6px var(--bad); }
.led.warn { background: var(--warn); box-shadow: 0 0 6px var(--warn); }
@keyframes ledflash { 0%,100% { filter: brightness(1); } 50% { filter: brightness(2.1); } }
.led.flash { animation: ledflash 260ms var(--ease-io) 2; }
.bar { width: 88px; height: 6px; background: var(--bg-inset); border: 1px solid var(--line); border-radius: 2px; overflow: hidden; }
.bar i { display: block; height: 100%; width: 0%; background: var(--steel); transition: width var(--t-slow) var(--ease-out); }

/* ---------- controls ---------- */
.mode-row { display: flex; align-items: center; gap: var(--sp-2); padding: 0 var(--sp-3) var(--sp-3); margin-bottom: var(--sp-2); border-bottom: 1px dashed var(--line); flex-wrap: wrap; }
.mode-row .lbl, .field .lbl { font: 500 var(--text-xs)/1 var(--font-display); letter-spacing: .08em; color: var(--txt-2); }
.mode-row .note { margin-left: auto; font-size: var(--text-xs); color: var(--txt-3); text-align: right; }
.seg.wide button { padding: 8px 18px; font-size: var(--text-sm); }
.act-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); padding: 0 var(--sp-3); }
.act { min-width: 0; }
.act-btn {
  width: 100%; display: flex; align-items: center; gap: 8px;
  border: 1px solid var(--line); border-radius: var(--r-2); background: var(--surface2);
  box-shadow: var(--edge); padding: 10px; min-height: 44px;
  font: 500 var(--text-sm)/1.2 var(--font-display); letter-spacing: .02em; color: var(--txt);
  transition: border-color var(--t-fast), background var(--t-fast), color var(--t-fast);
}
.act-btn svg.lucide { width: 18px; height: 18px; }
.act-btn .st { margin-left: auto; font: 500 var(--text-xs)/1 var(--font-mono); color: var(--txt-2); }
.act-btn:hover:not(:disabled) { border-color: var(--txt-2); }
.act-btn.on { background: var(--accent); border-color: var(--accent); color: var(--tag-fg); }
.act-btn.on.heatbtn { background: var(--heat); border-color: var(--heat); color: oklch(24% .04 55); }
.act-btn.on.mistbtn { background: var(--humid); border-color: var(--humid); color: oklch(24% .03 220); }
.act-btn.on .st { color: inherit; }
.act-btn.pending { border-style: dashed; }
.act-btn:disabled { opacity: .45; cursor: not-allowed; }
@keyframes shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }
.act-btn.deny { animation: shake 200ms var(--ease-io) 2; border-color: var(--bad); }
.slider-row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 6px; margin: 6px 2px 2px; }
.slider-row .pct { font: 500 var(--text-sm)/1 var(--font-mono); color: var(--txt); min-width: 46px; text-align: right; }
input[type=range] { -webkit-appearance: none; appearance: none; width: 100%; height: 26px; background: transparent; cursor: pointer; }
input[type=range]:disabled { cursor: not-allowed; opacity: .45; }
input[type=range]::-webkit-slider-runnable-track {
  height: 6px; border-radius: 2px; border: 1px solid var(--line);
  background: linear-gradient(90deg, var(--steel) var(--p,0%), var(--bg-inset) var(--p,0%));
}
input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; margin-top: -7px;
  width: 18px; height: 18px; border-radius: 3px;
  background: var(--txt); border: 3px solid var(--accent); box-shadow: 0 1px 4px rgba(0,0,0,.4);
}
input[type=range]::-moz-range-track { height: 6px; border-radius: 2px; border: 1px solid var(--line); background: var(--bg-inset); }
input[type=range]::-moz-range-progress { height: 6px; border-radius: 2px; background: var(--steel); }
input[type=range]::-moz-range-thumb { width: 16px; height: 16px; border-radius: 3px; background: var(--txt); border: 3px solid var(--accent); }
.set-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); margin-top: var(--sp-3); padding: var(--sp-3) var(--sp-3) 0; border-top: 1px dashed var(--line); }
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.stepper { display: flex; align-items: stretch; border: 1px solid var(--line); border-radius: var(--r-2); overflow: hidden; background: var(--surface2); }
.stepper button { width: 40px; font-size: var(--text-lg); font-weight: 500; color: var(--txt); }
.stepper button:hover:not(:disabled) { background: var(--line); }
.stepper button:disabled { opacity: .4; cursor: not-allowed; }
.stepper input {
  flex: 1; min-width: 0; text-align: center; background: transparent; border: none;
  font: 500 var(--text-lg)/1 var(--font-mono); font-variant-numeric: tabular-nums; color: var(--txt);
}
.stepper .u { align-self: center; font-size: var(--text-xs); color: var(--txt-2); padding-right: 6px; }
.control-foot { padding: var(--sp-2) var(--sp-3) var(--sp-3); font-size: var(--text-xs); color: var(--txt-3); }

/* ---------- data table ---------- */
.topic-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.topic-table th, .topic-table td { text-align: left; padding: 6px var(--sp-3); border-bottom: 1px dashed var(--line); }
.topic-table th { color: var(--txt-2); font: 500 var(--text-xs)/1.4 var(--font-display); letter-spacing: .05em; }
.topic-table td { font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--txt); }
.topic-table td.name { color: var(--txt-2); }
.topic-table td.num, .topic-table th.num { text-align: right; }
.topic-table tr:last-child td { border-bottom: none; }

/* ---------- hud tags (3D anchored) ---------- */
.hud-tag {
  position: absolute; left: 0; top: 0; transform: translate(-50%, -110%);
  background: rgba(13,11,7,.82); border: 1px solid var(--line); border-radius: 3px;
  padding: 2px 7px; font: 500 11px/1.45 var(--font-mono); color: var(--txt-2);
  white-space: nowrap; opacity: 0; transition: opacity 160ms var(--ease-out); pointer-events: none;
}
.hud-tag.on { opacity: 1; }
.hud-tag b { color: var(--txt); font-weight: 600; }
.hud-tag.warm { border-color: rgba(255,118,67,.55); }
.hud-tag.cool { border-color: rgba(101,186,225,.55); }
.hud-tag.alert { border-color: rgba(233,70,70,.65); color: var(--bad); }

/* ---------- settings dialog ---------- */
#modal-root dialog {
  border: 1px solid var(--line); border-radius: var(--r-2); background: var(--bg-raised); color: var(--txt);
  box-shadow: 0 18px 50px rgba(0,0,0,.6); padding: 0; width: min(440px, calc(100vw - 32px));
}
#modal-root dialog::backdrop { background: rgba(0,0,0,.55); }
.dlg-body { padding: var(--sp-4); }
.f-row { display: flex; flex-direction: column; gap: 5px; margin-bottom: var(--sp-3); }
.f-row label { font: 500 var(--text-xs)/1 var(--font-display); letter-spacing: .08em; color: var(--txt-2); }
.f-row input[type=text] {
  border: 1px solid var(--line); border-radius: var(--r-2); background: var(--bg-inset);
  padding: 9px 10px; font: 400 var(--text-body)/1.3 var(--font-mono); color: var(--txt); width: 100%;
}
.f-row .hint { font-size: var(--text-xs); color: var(--txt-3); }
.f-check { display: flex; align-items: center; gap: 8px; font-size: var(--text-sm); color: var(--txt-2); margin-bottom: var(--sp-3); }
.f-check input { width: 16px; height: 16px; accent-color: var(--accent); }
.f-actions { display: flex; gap: var(--sp-2); justify-content: flex-end; margin-top: var(--sp-4); flex-wrap: wrap; }
.btn {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--line); border-radius: var(--r-2); background: var(--surface2);
  color: var(--txt); padding: 9px 14px; font: 500 var(--text-sm)/1 var(--font-body);
  transition: border-color var(--t-fast), background var(--t-fast);
}
.btn:hover { border-color: var(--txt-2); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--tag-fg); }
.btn.primary:hover { filter: brightness(1.06); }

/* ---------- toasts ---------- */
.toast {
  display: flex; align-items: center; gap: 8px;
  background: var(--surface2); border: 1px solid var(--line); border-left: 3px solid var(--txt-3);
  border-radius: var(--r-2); padding: 10px 12px; font-size: var(--text-sm);
  box-shadow: 0 10px 28px rgba(0,0,0,.5);
  animation: toast-in var(--t-normal) var(--ease-out);
}
.toast.err { border-left-color: var(--bad); }
.toast.ok { border-left-color: var(--ok); }
.toast.warn { border-left-color: var(--warn); }
.toast svg.lucide { width: 15px; height: 15px; }
@keyframes toast-in { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }

/* ---------- responsive ---------- */
@media (max-width: 1100px) {
  #app { grid-template-columns: minmax(0, 1fr) clamp(300px, 34vw, 360px); grid-template-rows: 48px minmax(0, 62fr) minmax(0, 38fr); }
  #dock { padding: var(--sp-2); gap: var(--sp-2); }
  #panel { padding: var(--sp-2); }
  .topic-table th:nth-child(2), .topic-table td:nth-child(2) { display: none; }
}
@media (max-width: 720px) {
  :root { --text-metric: 32px; }
  #app { height: auto; min-height: 100dvh; grid-template-columns: 1fr; grid-template-rows: auto; grid-template-areas: "top" "stage" "rail" "dock"; }
  #stage { height: 36dvh; border-right: none; }
  #panel, #dock { overflow: visible; }
  #dock { flex-direction: column; padding: var(--sp-2); }
  #panel-trend .panel { height: auto; }
  #panel-trend .chart-wrap { height: 170px; flex: none; }
  .topic-table th:nth-child(2), .topic-table td:nth-child(2) { display: table-cell; }
  .brand-sub { display: none; }
  #viewbar { left: var(--sp-2); bottom: var(--sp-2); }
  #panel { padding: var(--sp-2); }
  .metrics { padding: var(--sp-2); }
  .act-grid { padding: 0 var(--sp-2); }
  .set-row { padding: var(--sp-3) var(--sp-2) 0; }
}
@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 1ms !important; animation-duration: 1ms !important; }
}
