﻿/* ?곗냽濡?ROM 愿????쒕낫?????ㅽ겕 愿???ㅽ???   ?좏겙: bg #0b0f14 / surface #111820 / surface2 #16202b / border #24313f
   ink #e2e9f0 / ink2 #93a4b5 / muted #5b6b7a
   ?쒕━利?寃利앸맖): ?섎떒 肄붿뼱 cyan #2a8fc9, ?곷떒 肄붿뼱 amber #cd7f2a
   ?곹깭: ok #3fae6a / warn #d9a13b / danger #d95c4a */

/* ?쒖씤??媛쒖꽑 (2026-08-11): ?먭굅由??먮룆 ?꾪빐 紐낆븫鍮??ㅼ륫 ???곹뼢.
   ?⑤꼸(#111820) ?鍮???ink 14.6:1 / ink2 6.99??.83 / muted 3.26??.74(蹂몃Ц 理쒖냼 4.5 異⑹”)
   / border 1.35??.07(援ъ“?좎씠 蹂댁씠??理쒖냼) / grid 1.14??.54(蹂댁“?좎? ???섎릺 蹂댁씠寃?
   ?쒕━利덉깋(cyan/amber)? 寃利??듦낵蹂몄씠??遺덈? */
:root {
  --bg: #0b0f14;
  --surface: #111820;
  --surface2: #16202b;
  --border: #3b4d63;
  --ink: #e2e9f0;
  --ink2: #b3c2d1;
  --muted: #8394a6;
  --grid: #2b3a4a;      /* 李⑦듃 蹂댁“??*/
  --axis: #56697e;      /* 李⑦듃 異빧룸늿湲?*/
  --cyan: #2a8fc9;
  --amber: #cd7f2a;
  --ok: #3fae6a;
  --warn: #d9a13b;
  --danger: #d95c4a;
  --mono: "Cascadia Mono", Consolas, monospace;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: "Malgun Gothic", "Segoe UI", sans-serif;
  font-size: 17px;
  height: 100vh;
  display: flex; flex-direction: column;
  overflow: hidden;
}

/* 부팅 가림막 (2026-08-27): JS 가 UI 를 조립하기 전에는 본문을 숨긴다 —
   페이지 전환 때 옛 골격(빈 카드·옛 문구)이 찰나 보이는 문제 방지.
   상단바는 남겨 전환이 이어져 보이게 한다. */
body.boot .layout { visibility: hidden; }

/* ?? ?곷떒諛???????????????????????????????? */
.topbar {
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.brand { display: flex; align-items: baseline; gap: 12px; min-width: 200px; }
.brand h1 { font-size: 20px; font-weight: 700; letter-spacing: .04em; }
.brand .sub { color: var(--muted); font-size: 13.5px; }
.led {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--danger); align-self: center;
}
.led.on { background: var(--ok); box-shadow: 0 0 6px var(--ok); animation: pulse 2s ease-in-out infinite; }
@keyframes pulse { 50% { box-shadow: 0 0 12px var(--ok); opacity: .65; } }
.readouts { display: flex; gap: 22px; margin-left: auto; }

/* ?섏씠吏 ?대퉬 ??(愿????DOE) */
.nav-tabs { display: flex; gap: 6px; margin-left: 22px; }
.nav-tab {
  padding: 5px 14px; border-radius: 6px; border: 1px solid transparent;
  color: var(--ink2); text-decoration: none; font-size: 14px;
  font-weight: 700;   /* ??긽 ?숈씪 援듦린 ???쒖꽦/鍮꾪솢????李⑥씠濡???씠 ?吏곸씠吏 ?딄쾶 */
}
.nav-tab:hover { color: var(--ink); border-color: var(--border); }
.nav-tab.active {
  color: #fff; background: var(--surface2);
  border-color: var(--border);
}
.readout { display: flex; flex-direction: column; align-items: flex-end; }
.ro-label { font-size: 12.5px; color: var(--muted); letter-spacing: .12em; }
.ro-value { font-family: var(--mono); font-size: 16.5px; color: var(--ink); }

/* ?? ?덉씠?꾩썐 ????????????????????????????? */
.layout {
  display: grid;
  grid-template-columns: 330px 1fr 340px;
  gap: 12px;
  padding: 12px 10px;
  width: 100%;
  flex: 1; min-height: 0;
}
.content { display: flex; min-width: 0; min-height: 0; }
.content > .panel {
  flex: 1; min-width: 0; min-height: 0;
  display: flex; flex-direction: column;
}

.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px 16px;
}
.panel-title {
  font-size: 18px; font-weight: 800; letter-spacing: .14em;
  color: #ffffff; text-transform: uppercase;
  margin-bottom: 12px;
}
/* 以묒븰 而⑦뀒?대꼫 ?곷떒: ?뱀뀡 ?쒕ぉ 3媛?媛濡??섏뿴 */
.section-titles { display: flex; gap: 32px; }
.section-titles .panel-title { margin: 0 0 12px; }
.panel-title .hint, .group-title .hint {
  font-weight: 400; letter-spacing: 0; text-transform: none;
  color: var(--muted); font-size: 12.5px; margin-left: 6px;
}
/* ?낅젰 ???쇰꺼(.in-label)怨??숈씪???ш린쨌??(2026-08-09 ?ъ슜???붿껌) */
.group-title {
  font-size: 15.5px; font-weight: 400;
  color: var(--ink2); margin: 16px 0 8px;
}

/* ?? ?낅젰 ?⑤꼸 ???????????????????????????? */
.inputs { overflow-y: auto; min-height: 0; }

.in-row { margin-bottom: 10px; }
.in-head { display: flex; justify-content: space-between; align-items: baseline;
           white-space: nowrap; }
.in-label { font-size: 15.5px; color: var(--ink2); }
.in-value { font-family: var(--mono); font-size: 17px; color: var(--ink); }
/* 媛뮻룸떒??怨좎젙 ??-> 紐⑤뱺 ?됱쓽 媛??댁씠 ?몃줈濡?以꾨쭪異?(mono 湲곗? ch).
   ??愿???ㅼ젙/怨꾩륫)? ?숈뒿 踰붿쐞(?섑븳/?곹븳)??**媛숈? 移섏닔**瑜??대떎 ?????붾㈃??   ?섎???蹂???媛??댁씠 ?닿툔?섎㈃ ???쒕떎(2026-08-12 ?ъ슜???붿껌?쇰줈 ?듭씪).
   4ch 濡?異⑸텇: ?쒖떆媛?理쒕? 4?먮━("0.37"쨌"1.05"쨌"800"). 諛붽씀?ㅻ㈃ ?묒そ ???뺤씤??寃? */
.in-value .sp, .in-value .pv { display: inline-block; min-width: 4ch; text-align: right; }
.in-value .unit { color: var(--muted); font-size: 13px; margin-left: 2px;
                  display: inline-block; min-width: 4ch; text-align: left; }  /* 'm/hr' 4?먭퉴吏 ?섏슜 */
.in-value .lbl { color: var(--muted); font-size: 12.5px; font-family: "Malgun Gothic", sans-serif; margin: 0 3px 0 6px; }
.in-value .sp { color: var(--ink2); }
.in-value .sp.pending { color: var(--warn); }   /* ?곸슜 ?湲?以묒씤 ?ㅼ젙 蹂寃?*/
.in-value .pv { color: var(--ink); }
.in-value .pv.chasing { color: var(--warn); }   /* 怨꾩륫移섍? ?ㅼ젙移섎? ?곕씪媛??以?*/

.track-wrap { position: relative; }
.pv-marker {
  position: absolute; bottom: -3px; width: 2px; height: 8px;
  background: var(--ok); transform: translateX(-1px);
  transition: left .8s linear; pointer-events: none; border-radius: 1px;
}
.pv-marker.chasing { background: var(--warn); }

input[type="range"] {
  width: 100%; height: 18px; margin-top: 2px;
  appearance: none; -webkit-appearance: none;
  background: transparent; cursor: pointer;
}
input[type="range"]::-webkit-slider-runnable-track {
  height: 6px; border-radius: 3px;
  background: var(--track, var(--surface2));
  border: 1px solid var(--border);
}
input[type="range"]::-webkit-slider-thumb {
  appearance: none; -webkit-appearance: none;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--ink); border: 2px solid var(--bg);
  margin-top: -5px;
}
input[type="range"]:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

/* 議??щ씪?대뜑: ?몃옓???덊듃 洹몃씪?곗씠??(醫?????대몢?, ??怨좎삩 amber) */
.zone-row .in-label { display: flex; align-items: center; gap: 6px; }
/* .zone-badge ?먭린 (2026-08-11 ?ъ슜???붿껌) ??議??쇰꺼???ㅻⅨ ?낅젰怨?媛숈? ?쇰컲 ?띿뒪??*/
.zone-row input[type="range"]::-webkit-slider-runnable-track {
  background: linear-gradient(to right, #1c2836, #6b4a1e, #cd7f2a);
}

.warn-box {
  margin-top: 10px; padding: 8px 10px;
  border: 1px solid var(--warn); border-radius: 6px;
  background: rgba(217,161,59,.08);
  color: var(--warn); font-size: 13.5px; line-height: 1.5;
}
.warn-box::before { content: "⚠ "; }

.btn-row { display: flex; gap: 8px; margin-top: 12px; }
.btn {
  flex: 1; padding: 9px 12px; font-size: 15px; font-family: inherit;
  border-radius: 6px; border: 1px solid var(--border);
  background: var(--surface2); color: var(--ink); cursor: pointer;
  white-space: nowrap;
}
#btnRevert { flex: 0 0 auto; }
.btn:hover:not(:disabled) { border-color: var(--ink2); }
.btn:disabled { opacity: .4; cursor: default; }
.btn.primary { background: #1b3a52; border-color: var(--cyan); font-weight: 700; }
.btn.primary:hover { background: #21495f; }
.btn.ghost { color: var(--ink2); }

/* ?? 吏꾨떒 KPI 移대뱶 (2026-08-11: ?댁꽍 vs 痢≪젙, ?몄감媛 ?좏샇) ??????
   ???レ옄 = ?댁꽍媛?ROM). min-height 怨좎젙 ???쇱씠釉뚢넄誘몃━蹂닿린 ?꾪솚 ??   移대뱶 ?믪씠媛 蹂?섎㈃ ?꾨옒 李⑦듃媛 ?꾨떎. ?????놁쓬. */
.kpi-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px;
}
.kpi-card {
  background: var(--surface2); border: 1px solid var(--border);
  border-radius: 6px; padding: 10px 12px; min-height: 104px;
}
.kpi-head { display: flex; justify-content: space-between; align-items: baseline; gap: 6px; }
.kpi-name { font-size: 14.5px; color: var(--ink2); margin-bottom: 4px; }
.kpi-flag { font-size: 12.5px; color: var(--warn); visibility: hidden; white-space: nowrap; }
.kpi-flag.on { visibility: visible; }
.kpi-value { font-family: var(--mono); font-size: 32px; font-weight: 600; }
.kpi-value .unit { font-size: 15px; color: var(--muted); margin-left: 3px; }
/* 怨꾩륫쨌?몄감????以?(移대뱶 ?믪씠 異뺤냼 ??2026-08-11 ?ъ슜???붿껌) */
.kpi-foot { display: flex; align-items: baseline; gap: 14px; margin-top: 3px; }
.kpi-meas { font-family: var(--mono); font-size: 17px; color: var(--ink); }
.kpi-gap { font-family: var(--mono); font-size: 17px; color: var(--ink2); }
.kpi-gap.alert { color: var(--warn); }
.kpi-at { font-family: var(--mono); font-size: 13px; color: var(--muted); margin-left: 4px; }
.kpi-meas .lbl, .kpi-gap .lbl {
  font-family: "Malgun Gothic", sans-serif; font-size: 13px;
  color: var(--muted); margin-right: 6px;
}
.kpi-note { font-size: 13px; color: var(--muted); margin-top: 6px; }

/* ?? ?⑤룄???????????????????????????????? */
/* 而⑦뀒?대꼫 ?꾩껜 ???ъ슜 (李⑦듃 x異??뺣젹 ?붽뎄???먭린 ??2026-08-02) */
.field-align {
  margin-top: 12px;
}
.field-wrap { position: relative; }
.field-wrap img { width: 100%; display: block; }

/* ?꾨줈?뚯씪 ?믪씠(y) ?쒖떆 ?쇱씤 ??濡쒕궡 ?꾨줈?뚯씪 紐⑤뱶???뚮쭔 */
#profileLine {
  position: absolute; left: 0; right: 0; height: 0;
  border-top: 2px dashed rgba(232, 238, 244, .85);
  filter: drop-shadow(0 1px 1px rgba(11, 15, 20, .9));
  pointer-events: none; z-index: 4;          /* ?뗫낫湲?z 6)蹂대떎 ?꾨옒 */
}
#profileLineTag {
  position: absolute; left: 8px; top: -24px;
  font-family: var(--mono); font-size: 12.5px; color: var(--ink);
  background: rgba(17, 24, 32, .85); border: 1px solid var(--border);
  border-radius: 4px; padding: 1px 7px; white-space: nowrap;
}

/* ?뗫낫湲?(而⑦닾??hover) */
.loupe {
  position: absolute; width: 190px; height: 190px;
  border-radius: 50%; border: 2px solid var(--ink2);
  background-repeat: no-repeat; background-color: var(--surface);
  pointer-events: none; z-index: 6;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .55);
}
.loupe-label {
  position: absolute; bottom: -30px; left: 50%; transform: translateX(-50%);
  font-family: var(--mono); font-size: 13.5px; color: var(--ink);
  background: var(--surface2); border: 1px solid var(--border);
  border-radius: 4px; padding: 2px 9px; white-space: nowrap;
}

.cbar-row {
  display: flex; align-items: center; gap: 8px;
  margin-top: 6px;
}
.cbar {
  flex: 1; height: 8px; border-radius: 4px;
  /* matplotlib turbo 洹쇱궗 洹몃씪?곗씠??*/
  background: linear-gradient(to right,
    #30123b, #4458cb, #3e9bfe, #18d6cb, #46f884,
    #a2fc3c, #e1dd37, #fda631, #ef5a11, #7a0403);
}
.cb-label { font-family: var(--mono); font-size: 15px; color: var(--ink); }
.empty {
  padding: 40px 0; text-align: center; color: var(--muted);
  border: 1px dashed var(--border); border-radius: 6px;
}

/* ?? ?⑤룄?대젰 李⑦듃 ??????????????????????? */
.chart-wrap { position: relative; flex: 1; min-height: 0; margin-top: 8px; }
#histChart { width: 100%; height: 100%; display: block; }
.tooltip {
  position: absolute; pointer-events: none;
  background: var(--surface2); border: 1px solid var(--border);
  border-radius: 6px; padding: 9px 12px; font-size: 13.5px;
  line-height: 1.55; white-space: nowrap; z-index: 5;
}
.tooltip .tt-title { color: var(--muted); font-size: 11px; }
.tooltip .val { font-family: var(--mono); }

/* ?? ?낅젰 ?ㅻ챸 ?댄똻 (2026-08-12) ????????????????
   釉뚮씪?곗? 湲곕낯 ?댄똻(title=)? ?곗? ?딅뒗????寃? ?곸옄媛 ?붾㈃??媛由곕떎??   ?ъ슜??吏?곸쑝濡??먭린?? 而ㅼ뒪? 諛뺤뒪留??대떎.
   醫뚯륫 ?⑤꼸??overflow-y:auto ??fixed 濡??꾩슦怨?JS 媛 ?꾩튂瑜??〓뒗?? */
.tip-info {
  position: fixed; width: 320px; white-space: normal; z-index: 40;
  padding: 12px 14px; box-shadow: 0 8px 24px rgba(0,0,0,.45);
}
.tip-info[hidden] { display: none; }
.tip-info .tip-head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 10px; font-size: 15.5px; color: var(--ink); margin-bottom: 8px;
}
.tip-info .tip-range { font-family: var(--mono); font-size: 13px; color: var(--muted); }
.tip-info .tip-desc { color: var(--ink2); font-size: 13.5px; line-height: 1.6; }
.tip-info .tip-desc b { color: var(--ink); font-weight: 700; }
.tip-info .tip-now {
  font-family: var(--mono); font-size: 13px; color: var(--ink);
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border);
}
/* 紐⑥떇????湲곕낯? ???섍쾶, ?대떦 蹂?섏쓽 遺遺꾨쭔 cyan ?쇰줈 媛뺤“ */
.tip-svg { width: 100%; height: auto; display: block; margin-bottom: 9px; }
.tip-svg text { font-size: 9px; fill: var(--muted); font-family: "Malgun Gothic", sans-serif; }
.tip-svg .body { fill: none; stroke: var(--border); stroke-width: 1.2; }
.tip-svg .heat rect { fill: #3a2c18; }
.tip-svg .prod rect { fill: none; stroke: var(--muted); stroke-width: 1.2; }
.tip-svg .ar { fill: none; stroke: var(--muted); stroke-width: 1.4; }
.tip-svg .edge { fill: var(--muted); font-size: 8.5px; }
.tip-svg .meas circle { fill: none; stroke: var(--muted); stroke-width: 1.4; }
.tip-svg .hl text { fill: var(--cyan); font-weight: 700; }
.tip-svg .hl .ar { stroke: var(--cyan); stroke-width: 2.2; }
.tip-svg .hl rect, .tip-svg .hl circle { stroke: var(--cyan); stroke-width: 2; }

/* ?댄똻???덈뒗 ?쇰꺼쨌移대뱶?꾩쓣 ?뚮━???쒖떆.
   ?먯꽑 諛묒쨪? 2026-08-12 ?ъ슜???붿껌?쇰줈 ?쒓굅 ???쒖떆??而ㅼ꽌(help)? hover ?됰쭔. */
.in-label.has-tip { cursor: help; }
.in-label.has-tip:hover { color: var(--ink); }
.kpi-card.has-tip { cursor: help; }
.kpi-card.has-tip:hover { border-color: var(--ink2); }
.legend { display: flex; gap: 18px; margin-top: 8px; font-size: 12px; color: var(--ink2); flex-wrap: wrap; }
.legend .key { display: inline-block; width: 16px; height: 3px; border-radius: 2px; vertical-align: middle; margin-right: 5px; }
.legend .key.dash { background: repeating-linear-gradient(90deg, currentColor 0 4px, transparent 4px 7px); height: 2px; }

/* ?? 梨쀫큸 ?⑤꼸 ??????????????????????????? */
.chat {
  display: flex; flex-direction: column;
  min-height: 0;
}
.chat-msgs {
  flex: 1; overflow-y: auto;
  display: flex; flex-direction: column; gap: 8px;
  padding-right: 4px; margin-bottom: 10px;
}
.msg {
  max-width: 88%; padding: 9px 12px; border-radius: 10px;
  font-size: 15.5px; line-height: 1.55; white-space: pre-wrap;
}
.msg.bot {
  align-self: flex-start;
  background: var(--surface2); border: 1px solid var(--border);
  border-bottom-left-radius: 3px;
}
.msg.user {
  align-self: flex-end;
  background: #1b3a52; border: 1px solid var(--cyan);
  border-bottom-right-radius: 3px;
}
.chat-input { display: flex; gap: 8px; }
.chat-input input {
  flex: 1; min-width: 0; padding: 8px 10px;
  background: var(--surface2); border: 1px solid var(--border);
  border-radius: 6px; color: var(--ink);
  font-family: inherit; font-size: 14.5px;
}
.chat-input input:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
.chat-input input::placeholder { color: var(--muted); }
.chat-send { flex: 0 0 auto; }

/* ?? DOE ?ㅺ퀎쨌?ㅽ뻾 ?섏씠吏 ???????????????? */
/* 以묒븰: ?⑤꼸 3媛??몃줈 ?ㅽ깮 + ?먯껜 ?ㅽ겕濡?*/
.content.doe-col { flex-direction: column; gap: 12px; overflow-y: auto; }
.content.doe-col > .panel { flex: none; display: block; }

/* 醫? ?숈뒿 踰붿쐞 ?꾪솴????愿?쒖쓽 .in-row瑜?洹몃?濡??곕뒗 ?쎄린 ?꾩슜 ??
   .range-view = 愿???щ씪?대뜑 ?몃옓怨??숈씪??紐⑥뼇??諛?(?숈뒿??踰붿쐞 ?쒖떆, 議곗옉 ?놁쓬)
   ??媛믪뭏 ??룸씪踰??щ갚쨌以꾨컮轅?湲덉???2026-08-12 遺??.in-value 湲곕낯 洹쒖튃?쇰줈 ?щ씪媛붾떎
     (愿?쒖? 移섏닔瑜??듭씪) ???ш린???ㅼ떆 ??뼱?곗? 留?寃? */
/* 愿?쒖쓽 ?щ씪?대뜑 ?곸뿭? ?몃씪??以꾩긽???ы븿 ?ㅼ륫 24px ???숈씪 ?믪씠 ?곸옄??6px 諛붾? 以묒븰 諛곗튂 */
.rv-wrap { height: 24px; display: flex; align-items: center; }
.range-view {
  flex: 1; height: 6px; border-radius: 3px;
  background: var(--surface2); border: 1px solid var(--border);
}
.zone-view {
  background: linear-gradient(to right, #1c2836, #6b4a1e, #cd7f2a);
}

/* ?レ옄 ?낅젰 (?꾨낫 媛쒖닔 ?? */
.rng-in {
  width: 70px; padding: 4px 6px; text-align: right;
  background: var(--surface2); border: 1px solid var(--border); border-radius: 5px;
  color: var(--ink); font-family: var(--mono); font-size: 13.5px;
}
.rng-in:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }

/* ?뚯씠釉????섏젙 紐⑤뱶 ?낅젰移?*/
.cell-in {
  width: 58px; padding: 2px 5px; text-align: right;
  background: var(--surface2); border: 1px solid var(--cyan); border-radius: 4px;
  color: var(--ink); font-family: var(--mono); font-size: 12.5px;
}
.cell-in.z { width: 44px; }
.cell-in:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }

/* 誘몃땲 踰꾪듉 (?뚯씠釉????≪뀡) */
.mini-btn {
  font-size: 11px; padding: 1px 8px; border-radius: 4px; cursor: pointer;
  border: 1px solid var(--border); background: var(--surface2); color: var(--muted);
  font-family: inherit; white-space: nowrap;
}
.mini-btn:hover { color: var(--ink2); border-color: var(--ink2); }
.mini-btn:disabled { opacity: .4; cursor: default; }
.sel {
  background: var(--surface2); border: 1px solid var(--border); border-radius: 5px;
  color: var(--ink); padding: 4px 8px; font-family: inherit; font-size: 13.5px;
}
.sel:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }

/* 以묒븰 而⑦뀒?대꼫 ?섏씠吏 ?꾪솚 (?숈뒿 ?곗씠????異붽? ?댁꽍 Case) */
/* min-height 怨좎젙 ??踰꾪듉 ?좊Т濡??쒕ぉ 以??믪씠媛 ?щ씪???쒕ぉ???吏곸씠??寃?諛⑹? */
.page-head { display: flex; align-items: center; justify-content: space-between;
             min-height: 32px; margin-bottom: 12px; }
.page-head .panel-title { margin-bottom: 0; }
/* ?곗륫 洹몃９?쇰줈 臾띠뼱 ?붾떎 ??踰꾪듉???④꺼?몃룄 ?섏씠吏 ?붿궡???꾩튂媛 ?붾뱾由ъ? ?딄쾶 */
.head-right { display: flex; align-items: center; gap: 14px; }
.head-actions { display: flex; gap: 8px; }
/* ?쒕ぉ 以??덉쓽 踰꾪듉? 以??믪씠瑜??섏? ?딄쾶 ?묎쾶 */
.head-actions .btn { padding: 3px 12px; font-size: 14px; border-radius: 5px; }
.head-actions[hidden] { display: none; }
.page-nav #pgInd, .page-nav #mvInd { min-width: 4ch; text-align: center; }
/* 愿??以묒븰 ?⑤꼸???섏씠吏 (二쇱슂 KPI ??2?섏씠吏, 2026-08-13) ???쒕ぉ 以???쓣
   .section-titles 媛 李⑥??섎?濡??섏씠吏 ?쒖떆??.head-right 濡??곗륫 怨좎젙 */
.mv-page.page-body { flex: 1 1 auto; min-height: 0; }
.page-empty { display: flex; align-items: center; justify-content: center;
              flex: 1 1 auto; color: var(--muted); font-size: 15.5px; }
.page-nav {
  display: flex; align-items: center; gap: 6px;
  color: var(--muted); font-size: 12.5px; font-family: var(--mono);
}
.page-body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.page-body[hidden] { display: none; }

/* 醫뚯륫(議곗뾽 ?쒖뼱) ?⑤꼸???섏씠吏 ???ш린??flex 而щ읆???꾨땲???먮옒?濡?釉붾줉 ?먮쫫.
   .inputs ??overflow-y:auto 濡??ㅽ겕濡ㅽ븯?붾뜲, flex 而щ읆?대㈃ ?꾩씠?쒖씠 ?뚮젮??   ?ㅽ겕濡?????댁슜??李뚭렇?ъ쭊??
   ??:not([hidden]) ?꾩닔 ??`.page-body[hidden]{display:none}` 怨??뱀씠?꾧? 媛숈븘??   洹몃깷 ?곕㈃ ?ㅼ뿉 ????洹쒖튃???닿꺼 ?④릿 ?섏씠吏媛 洹몃?濡?蹂댁씤???ㅼ젣濡?寃れ쓬). */
.inputs .page-body:not([hidden]) { display: block; }
.inputs .page-head { min-height: 28px; margin-bottom: 10px; }

/* ?μ엯臾?臾쇱꽦 ??議곗뾽 ?쒖뼱??.in-row 瑜?洹몃?濡??곌퀬 湲고샇쨌遺?쒕쭔 ?㏓텤?몃떎 */
/* 臾쇱꽦 ?됱? ?⑥쐞媛 湲몃떎('J/(kg쨌K)' 8?? ??洹몃쭔???쇰꺼쨌媛?移몄쓣 ?꾧뺨??330 px ?⑤꼸??   ?ㅼ뼱媛꾨떎. ?숈뒿 踰붿쐞 履쎌? ?섑븳쨌?곹븳 2媛쒕씪 ?뱁엳 鍮좊벏?댁꽌 湲고샇(?/Cp/k)瑜?類먮떎. */
.prop-row .in-value .unit { min-width: 8ch; }
.group-title .sub { color: var(--muted); font-weight: 400; font-size: 13px;
                    font-family: var(--mono); }
/* ?꾩쭅 ?숈뒿?섏? ?딆? 臾쇱꽦(踰붿쐞 lo==hi)? 議곗옉 遺덇? ??諛붽? 媛?대뜲 怨좎젙?쒕떎 */
.prop-row input[type="range"]:disabled { opacity: .45; cursor: default; }

/* ?꾨낫 ?뚯씠釉?*/
.tbl-wrap { overflow-x: auto; }
.tbl-wrap.grow { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.tbl-wrap.grow thead th {
  position: sticky; top: 0; background: var(--surface); z-index: 1;
}
.tbl { width: 100%; border-collapse: collapse; font-size: 14.5px; }
.tbl th {
  color: var(--ink2); font-weight: 700; font-size: 13px; letter-spacing: .06em;
  text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.tbl td {
  padding: 6px 8px; border-bottom: 1px solid var(--surface2);
  font-family: var(--mono); white-space: nowrap; vertical-align: middle;
}
.tbl td.txt { font-family: "Malgun Gothic", "Segoe UI", sans-serif; }
/* ???ㅻ뜑???⑥쐞???꾨옯以꾨줈 ???대쫫+?⑥쐞瑜???以꾩뿉 ?먮㈃ 移몄씠 遺덊븘?뷀븯寃??볦뼱吏꾨떎
   (2026-08-13 ?ъ슜???붿껌). CSV ?대낫?닿린????span ??"?대쫫 (?⑥쐞)" 濡??섎룎由곕떎. */
.tbl th .u { display: block; font-weight: 400; font-size: 12px;
             letter-spacing: 0; color: var(--muted); }
.tbl tr:hover td { background: rgba(42, 143, 201, .06); }
.tbl .zone-off-mark { color: var(--danger); }
/* 議곗뾽 湲곕줉留?12?댁씠??1920 酉고룷?몄뿉??媛濡쒕줈 諛由곕떎 ?????쒕쭔 ???④퀎 ?묎쾶
   (2026-08-13 ?ъ슜???붿껌). ?ㅻⅨ ?쒖쓽 移섏닔??嫄대뱶由ъ? ?딅뒗?? */
#mvPage2 .tbl { font-size: 13px; }
#mvPage2 .tbl th { font-size: 12px; padding: 6px 5px; }
#mvPage2 .tbl th .u { font-size: 11px; }
#mvPage2 .tbl td { padding: 6px 5px; }

/* ?곹깭 pill */
.pill {
  display: inline-block; padding: 2px 10px; border-radius: 10px;
  font-size: 13px; border: 1px solid;
  font-family: "Malgun Gothic", "Segoe UI", sans-serif;
}
/* ???덉쓽 ?묒? ?ㅽ뻾 踰꾪듉 ??媛숈? 移몄쓽 `.pill` 怨??ш린쨌紐⑥뼇??留욎텣??(2026-08-15) */
.pill-btn {
  display: inline-block; padding: 2px 10px; border-radius: 10px;
  font-size: 13px; border: 1px solid var(--border);
  font-family: "Malgun Gothic", "Segoe UI", sans-serif;
  background: none; color: var(--ink2); cursor: pointer;
}
.pill-btn:hover:not(:disabled) { color: var(--cyan); border-color: var(--cyan); }
.pill-btn:disabled { opacity: .4; cursor: default; }
.pill.ok { color: var(--ok); border-color: var(--ok); }
.pill.run { color: var(--cyan); border-color: var(--cyan); }
.pill.warn { color: var(--warn); border-color: var(--warn); }
.pill.danger { color: var(--danger); border-color: var(--danger); }
.pill.muted { color: var(--muted); border-color: var(--border); }

/* 諛곗튂 蹂대뱶 */
.count-row { display: flex; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
.count {
  background: var(--surface2); border: 1px solid var(--border); border-radius: 6px;
  padding: 6px 14px; font-size: 13px; color: var(--muted);
}
.count b { font-family: var(--mono); font-size: 20px; margin-left: 7px; color: var(--ink); }
.count.c-run b { color: var(--cyan); }
.count.c-ok b { color: var(--ok); }
.count.c-fail b { color: var(--danger); }
.prog {
  display: inline-block; width: 120px; height: 6px; vertical-align: middle;
  background: var(--surface2); border: 1px solid var(--border);
  border-radius: 3px; overflow: hidden;
}
.ro-prog { display: flex; align-items: center; gap: 8px; }
.readout.ro-left { align-items: flex-start; }   /* ?쇰꺼(吏꾪뻾瑜???媛?釉붾줉???쇱そ ?앹뿉 ?뺣젹 */
/* ?곷떒 ?꾩옱 ?댁꽍쨌吏꾪뻾瑜?移???怨좎젙 ??媛믪씠 梨꾩썙吏????뺣젹???붾뱾由щ뒗 ?붿긽 諛⑹? */
#roCurRun { min-width: 9ch; text-align: right; display: inline-block; }
#roCurProg { min-width: 12ch; }
#topProgBar { transition: none; }   /* ?섏씠吏 吏꾩엯 ??0?믫쁽?ш컪 李⑥삤瑜대뒗 ?좊땲硫붿씠???앸왂 */
.prog-bar { display: block; height: 100%; background: var(--cyan); transition: width .8s linear; }
.logbox {
  background: #0a0e13; border: 1px solid var(--border); border-radius: 6px;
  padding: 8px 10px; margin-top: 10px;
  font-family: var(--mono); font-size: 13.5px; line-height: 1.6; color: var(--ink2);
  max-height: 130px; overflow-y: auto; white-space: pre-wrap;
}
/* ?댁꽍 ?곕???(?숈뒿 ?곗씠???섏씠吏 ?섎떒) ??2026-08-11 ?믪씠 1.2諛?*/
.logbox.term { max-height: 264px; min-height: 132px; flex: 0 0 auto; }

/* ?좊ː??吏??*/
.umap-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
.umap-head[hidden] { display: none; }
.umap-head .gap-l { margin-left: 28px; }   /* ?꾧뎄 以꾩뿉??洹몃９ ?ъ씠 媛꾧꺽 ?뺣낫 */
/* ?꾧뎄 以?踰꾪듉? ?⑹옉?섍쾶 ??踰꾪듉??以??믪씠瑜?醫뚯슦?섏? ?딅룄濡?(2026-08-11 ?ъ슜???붿껌,
   湲곗?: ?숈뒿 ?곗씠???섏씠吏??'?댁꽍 以묒?'. 以??믪씠??select/?낅젰移?~27px)???뺥븳?? */
.umap-head .btn { padding: 3px 12px; font-size: 14px; border-radius: 5px; }
.umap-head .s-label { font-size: 13.5px; color: var(--ink2); }
.size-info {
  margin: -4px 0 10px; padding: 6px 10px;
  background: var(--surface2); border-left: 3px solid var(--cyan); border-radius: 4px;
  color: var(--ink2);
}
.size-info[hidden] { display: none; }
.chk-label {
  display: flex; align-items: center; gap: 6px;
  font-size: 13.5px; color: var(--ink2); cursor: pointer;
}
.chk-label input[disabled] { cursor: default; }
.hint-inline { color: var(--muted); font-size: 12.5px; }
.umap-wrap { position: relative; }
#umapSvg { width: 100%; display: block; border: 1px solid var(--border); border-radius: 6px; }
.umap-cbar-row { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.umap-cbar {
  flex: 1; height: 8px; border-radius: 4px; max-width: 300px;
  background: linear-gradient(to right, rgba(42,143,201,.06), rgba(42,143,201,.95));
}
.umap-legend { display: flex; gap: 16px; margin-top: 6px; font-size: 12px; color: var(--ink2); }
.umap-legend .dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  vertical-align: middle; margin-right: 5px;
}

/* ?좎뒪??(?곕え ?덈궡) */
/* 현장 보정 배지 (2026-08-29) — 조업 기록이 찾은 계통오차를 반영 중임을 표시 */
.kpi-cal {
  font-size: 10.5px; color: #7ee08b; border: 1px solid #2e5c3a;
  border-radius: 4px; padding: 1px 5px; margin-left: auto; margin-right: 6px;
  white-space: nowrap;
}

/* ── ROM 정보 모달 (2026-08-29) — hidden 토글 관례, 배경 클릭으로 닫힘 ── */
.modal-ov {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(5, 8, 12, 0.62);
  display: flex; align-items: center; justify-content: center;
}
.modal-ov[hidden] { display: none; }
.modal-card {
  background: var(--panel, #121a24); border: 1px solid #33465c;
  border-radius: 12px; padding: 18px 22px; width: min(560px, 92vw);
  max-height: 82vh; overflow-y: auto;
  box-shadow: 0 14px 44px rgba(0, 0, 0, 0.55);
}
.modal-card h3 {
  margin: 0 0 4px; font-size: 17px; display: flex; align-items: center;
}
.modal-card h3 .x {
  margin-left: auto; cursor: pointer; border: 0; background: none;
  color: var(--muted, #8aa0b5); font-size: 18px; line-height: 1;
}
.modal-card h3 .x:hover { color: #fff; }
.modal-sec {
  margin-top: 12px; font-size: 12.5px; color: var(--muted, #8aa0b5);
  letter-spacing: 0.4px;
}
.modal-card table.tbl td, .modal-card table.tbl th { padding: 5px 8px; }

.toast {
  position: fixed; bottom: 18px; right: 18px; z-index: 9;
  background: var(--surface2); border: 1px solid var(--warn); color: var(--ink);
  padding: 10px 14px; border-radius: 8px; font-size: 14px; max-width: 380px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .5);
}

/* ?? 議곗뾽議곌굔 蹂寃? ?띾룄 ?낅젰 쨌 ?덉륫 ?ъ깮 (2026-08-11) ?????????
   ?????놁쓬 ??--cyan on --surface 4.96:1, .pill.warn 7.71:1 (怨꾩궛媛? */

/* ?됰퀎 蹂寃??띾룄 (dirty ???됱뿉留??쒖떆). ?⑤꼸 媛?⑺룺 ~284px ?덉뿉??以꾨컮轅?湲덉? */
.rate-row {
  display: flex; align-items: center; gap: 6px;
  margin-top: 4px; font-size: 12.5px; white-space: nowrap;
}
.rate-row[hidden] { display: none; }
.rate-lbl { color: var(--muted); }
.rate-in { width: 62px; padding: 2px 6px; font-size: 13.5px; }
.rate-unit { color: var(--muted); font-family: var(--mono); }
.rate-eta { flex: 1; text-align: right; color: var(--muted); font-family: var(--mono); }
.rng-in.bad { border-color: var(--danger); }

/* 蹂寃??붿빟 / ?⑦봽 吏꾪뻾 ?덈궡 */
.stage-info { font-size: 13.5px; color: var(--muted); margin-top: 10px; }
.stage-info.warn { color: var(--warn); }
.stage-info[hidden] { display: none; }
.in-value .sp.ramping { color: var(--cyan); }   /* ?⑦봽 以묒씤 ?ㅼ젙移?*/

/* ?덉륫 ?ъ깮 ?몃옖?ㅽ룷??/ ?ъ쟾怨꾩궛 吏꾪뻾諛???以묒븰 ?⑤꼸 KPI ??*/
.pv-bar, .pv-prog {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 10px; padding: 6px 10px;
  background: var(--surface2); border: 1px solid var(--border); border-radius: 6px;
}
.pv-bar[hidden], .pv-prog[hidden] { display: none; }
/* ?꾩뿭 input[type=range]{width:100%} 瑜?諛섎뱶????뼱?⑥빞 ??*/
.pv-bar input[type="range"] { width: auto; flex: none; margin-top: 0; }
.pv-bar .pv-seek { flex: 1; min-width: 160px; }
.pv-bar .pv-speed { width: 130px; }
.pv-time, .pv-mult {
  font-family: var(--mono); font-size: 14px; color: var(--ink);
  text-align: right;
}
.pv-time { min-width: 13ch; }
.pv-mult { min-width: 5ch; }
.pv-note { margin-left: auto; font-size: 12.5px; color: var(--muted); }
.pv-prog .prog { flex: 1; height: 8px; }
.pv-prog .pv-msg { font-family: var(--mono); font-size: 13.5px; color: var(--ink2); min-width: 22ch; }

/* ?? 諛섏쓳???????????????????????????????? */
@media (max-width: 1420px) {
  body { height: auto; overflow: auto; }
  .layout { grid-template-columns: 280px 1fr; flex: none; }
  .chat { grid-column: 1 / -1; height: 380px; }
  .chart-wrap { flex: none; }
  #histChart { height: auto; }
}
@media (max-width: 1100px) {
  .layout { grid-template-columns: 1fr; }
  .kpi-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* 怨좎젙 議곌굔 (2026-08-26): ??DOE ?먯꽌 ?좉릿 ?낅젰 ???붾㈃??蹂댁씠??議곗옉 遺덇?.
   ?숈뒿 踰붿쐞媛 ?뺤옣?섎㈃ ?쒕쾭 硫뷀???fixed 媛 吏?뚯?硫???덈줈 ?由곕떎. */
.fixed-row input[type=range] { opacity: .45; cursor: not-allowed; }

/* 해석 진행 터미널 (2026-08-26): 항상 보이는 창 — 비어 있으면 안내 문구 */
#batchLog:empty::before {
  content: "대기 중 — 해석이 시작되면 여기에 진행 로그가 실시간으로 표시됩니다.";
  color: var(--muted);
}

/* 議대퀎 KPI 移대뱶 (2026-08-26): 異쒓뎄 ?좊웾/?⑤룄 ??議?1~3 媛곴컖 ?쒖떆 */
.kpi-zones { margin: 2px 0 1px; }
.kpi-zline { display: flex; align-items: baseline; gap: 7px;
  font-size: 14.5px; line-height: 1.45; font-family: var(--mono); }
.kpi-zline .kpi-zlab { color: var(--muted); font-family: var(--sans);
  font-size: 12.5px; min-width: 34px; }
.kpi-zline b { color: var(--ink); font-weight: 600; }
.kpi-zline .kpi-zmeas { color: var(--ink2); opacity: .75; }
.kpi-card .kpi-head .unit { color: var(--muted); font-size: 12px; }


/* ── 3D ISO View 무대 (C안 몰입형 오버레이, 2026-08-27 사용자 확정) ── */
.stage3d {
  position: relative; flex: 1; min-height: 420px; margin-top: 10px;
  border: 1px solid var(--border); border-radius: 10px; overflow: hidden;
  background: var(--bg);
}
.stage3d iframe {
  position: absolute; inset: 0; width: 100%; height: 100%;
  border: 0; display: block; background: var(--bg);
}
/* 뷰 컨트롤 카드 제거 (2026-08-27) — 우상단 온도 레전드는 뷰어(iframe) 안에서 그린다 */
/* 기본 카메라 버튼 (우측 하단, 2026-08-27) */
/* 카메라 버튼(.cam-ctl)은 2026-08-28 제거 — 뷰 전환은 챗 명령 */
.chart-overlay {
  position: absolute; left: 12px; bottom: 12px; width: 54%;
  min-width: 420px; max-width: 720px; z-index: 3;
  background: rgba(17, 24, 32, .82); border: 1px solid var(--border);
  border-radius: 10px; backdrop-filter: blur(5px); padding: 8px 10px;
}
.co-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 13px; color: var(--ink2); margin-bottom: 2px;
}
.chart-overlay .chart-wrap { height: 228px; flex: none; margin-top: 2px; }
#chartPill {
  position: absolute; left: 12px; bottom: 12px; z-index: 3;
  background: rgba(17, 24, 32, .9); border: 1px solid var(--border);
  color: var(--ink2); border-radius: 16px; font-size: 13px;
  padding: 5px 14px; cursor: pointer;
}
#chartPill:hover { color: var(--ink); }

/* KPI 카드 축소 (2026-08-27 사용자 요청): 계측·편차를 예측값 우측 작은 글씨로 */
.kpi-card { min-height: 0; padding: 8px 12px 9px; }
.kpi-value { display: flex; align-items: baseline; gap: 12px; font-size: 28px; }
.kpi-side { display: flex; align-items: baseline; gap: 10px; font-weight: 400;
  white-space: nowrap; overflow: hidden; }
.kpi-side .kpi-meas, .kpi-side .kpi-gap { font-size: 13.5px; }
.kpi-side .lbl { font-size: 11.5px; margin-right: 4px; }
.kpi-side .kpi-at { font-size: 11px; margin-left: 2px; }
.kpi-side.kpi-note { margin-top: 0; font-size: 12.5px; }

/* 그래프 오버레이 손질 (2026-08-27 사용자 요청): 제목·테두리 제거, 1.5배, 더 투명 */
.chart-overlay { width: auto; right: 12px; min-width: 480px; max-width: none;  /* 우측 끝까지 (2026-08-28 사용자 지시) */
  background: transparent; backdrop-filter: none; border: 0; padding: 6px 8px;  /* 투명도 100% (2026-08-27) */ }
.chart-overlay .chart-wrap { height: 342px; margin-top: 0; }
.co-fold { position: absolute; top: 8px; right: 10px; z-index: 2; opacity: .75; }
.co-fold:hover { opacity: 1; }


