:root {
  color-scheme: light;
  --ground: #e7f0ea;
  --surface: #f7faf7;
  --surface-raised: #ffffff;
  --surface-tint: #dceae2;
  --panel-deep: #16332d;
  --panel-mid: #20483f;
  --panel-line: #365a50;
  --on-deep: #f4fbf7;
  --on-deep-muted: #dceae2;
  --on-deep-line: #628279;
  --danger-soft: #ff9c94;
  --canvas: #eaf2ed;
  --action-ink: #173028;
  --line: #9eb9ad;
  --line-soft: #c9d9d1;
  --text: #13241f;
  --muted: #526e64;
  --signal: #b8e737;
  --signal-deep: #587d00;
  --amber: #9a5a00;
  --danger: #b83c34;
  --unknown: #697286;
  --cyan: #087d70;
  --font-ui: "Avenir Next", Avenir, "Segoe UI", sans-serif;
  --font-data: "SFMono-Regular", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }
html { background: var(--ground); scroll-behavior: smooth; }
body { margin: 0; min-width: 320px; background: var(--ground); color: var(--text); font-family: var(--font-ui); }
button, input { font: inherit; }
button { color: inherit; }
::selection { background: var(--signal); color: #0a120f; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--surface-tint); }
::-webkit-scrollbar-thumb { background: var(--line); border: 2px solid var(--surface-tint); }
:focus-visible { outline: 2px solid var(--signal); outline-offset: 3px; }

.skip-link { position: fixed; top: 8px; left: 8px; z-index: 100; transform: translateY(-150%); background: var(--signal); color: var(--ground); padding: 10px 14px; }
.skip-link:focus { transform: translateY(0); }
.app-shell { width: 100%; min-width: 0; height: 100vh; display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto auto auto auto 1fr; overflow-x: hidden; }
.app-shell > *, .comparison-panel { min-width: 0; }

.topbar { min-height: 72px; padding: 12px 22px; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 20px; border-bottom: 1px solid var(--panel-line); background: var(--panel-deep); color: var(--on-deep); }
.brand { display: flex; align-items: center; gap: 12px; }
.brand-mark { width: 36px; height: 36px; stroke: var(--signal); fill: var(--signal); stroke-width: 1.5; }
.brand strong, .brand span { display: block; }
.brand strong { font: 600 17px/1 var(--font-data); letter-spacing: .08em; }
.brand span { margin-top: 7px; color: var(--on-deep-muted); font: 500 9px/1 var(--font-data); letter-spacing: .13em; }
.run-state { min-width: 190px; display: flex; align-items: center; justify-content: center; gap: 10px; color: var(--signal); font: 600 11px/1 var(--font-data); letter-spacing: .08em; }
.status-lamp { width: 8px; height: 8px; background: currentColor; box-shadow: 0 2px 10px currentColor; }
.top-actions { justify-self: end; display: flex; gap: 8px; }
.text-button, .solid-button { min-height: 40px; border: 1px solid var(--line); padding: 0 15px; cursor: pointer; font: 600 11px/1 var(--font-data); letter-spacing: .04em; }
.text-button { background: transparent; border-color: var(--line); }
.solid-button { border-color: var(--signal); background: var(--signal); color: var(--action-ink); }
.text-button:hover { border-color: var(--signal); color: var(--signal); }
.solid-button:hover { background: color-mix(in srgb, var(--signal) 72%, var(--surface-raised)); }

.control-deck { min-height: 72px; padding: 12px 22px; display: grid; grid-template-columns: 1fr minmax(320px, 520px) auto; align-items: center; gap: 28px; border-bottom: 1px solid var(--line-soft); background: var(--surface); }
.scenario-copy { display: flex; align-items: center; gap: 18px; }
.scenario-copy strong, .scenario-copy span { display: block; }
.scenario-copy strong { margin-bottom: 5px; font-size: 17px; line-height: 1.2; }
.scenario-copy div span { color: var(--muted); font-size: 11px; }
.section-code { color: var(--signal-deep); font: 600 9px/1 var(--font-data); letter-spacing: .13em; white-space: nowrap; }
.scale-control { display: grid; grid-template-columns: auto 1fr 64px; align-items: center; gap: 14px; font: 500 11px/1 var(--font-data); }
.scale-control input { width: 100%; accent-color: var(--signal); cursor: pointer; }
.scale-control output { color: var(--signal-deep); text-align: right; font-weight: 600; }
.scenario-legend { display: flex; gap: 13px; flex-wrap: wrap; color: var(--muted); font: 500 9px/1 var(--font-data); }
.scenario-legend span::before { content: ''; display: inline-block; width: 7px; height: 7px; margin-right: 6px; background: var(--state-color); }
.scenario-legend i { font-style: normal; font-weight: 700; color: var(--state-color); }
[data-state="healthy"] { --state-color: var(--cyan); }
[data-state="warning"] { --state-color: var(--amber); }
[data-state="overloaded"] { --state-color: var(--danger); }
[data-state="unknown"] { --state-color: var(--unknown); }
[data-state="invalid"] { --state-color: var(--danger); }
[data-state="disabled"] { --state-color: var(--danger); }

.summary-strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-bottom: 1px solid var(--line); }
.summary-strip > div { min-height: 106px; padding: 15px 22px; display: grid; grid-template-columns: 1fr auto; grid-template-rows: auto auto 28px; align-content: center; gap: 7px 10px; border-right: 1px solid var(--line-soft); background: var(--surface); position: relative; overflow: hidden; }
.summary-strip > div:last-child { border-right: 0; }
.summary-strip span { color: var(--muted); font-size: 11px; }
.summary-strip strong { grid-row: 1 / span 2; color: var(--signal-deep); font: 600 30px/.95 var(--font-data); font-variant-numeric: tabular-nums; }
/* headroom 은 엔진의 판정 기준과 같은 색을 쓴다. 임계값을 넘었는데 초록이면 숫자가 거짓말이 된다. */
#summary-headroom[data-tone="danger"] { color: var(--danger); }
#summary-headroom[data-tone="amber"] { color: var(--amber); }
#summary-headroom[data-tone="unknown"] { color: var(--unknown); }
.summary-strip small { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 500 10px/1 var(--font-data); }
.metric-sparkline { grid-column: 1 / -1; width: 100%; height: 28px; overflow: visible; }
.metric-sparkline path { fill: none; stroke: var(--cyan); stroke-width: 1.7; vector-effect: non-scaling-stroke; }
.summary-metric:nth-child(2) .metric-sparkline path { stroke: var(--amber); }.summary-metric:nth-child(3) .metric-sparkline path { stroke: var(--danger); }.summary-metric:nth-child(4) .metric-sparkline path { stroke: var(--signal-deep); }
.metric-sparkline circle { fill: var(--surface-raised); stroke: currentColor; stroke-width: 1.5; }
/* 값을 모르는 계열은 선을 그리지 않는다. 마지막으로 안 값의 잔상도 남기지 않는다. */
.metric-sparkline[data-unknown] path, .metric-sparkline[data-unknown] circle { display: none; }
.metric-sparkline[data-unknown] { background: repeating-linear-gradient(90deg, var(--line-soft) 0 5px, transparent 5px 10px) center / 100% 2px no-repeat; }
/* 뒤처진 판정은 색으로 말하지 않는다. 등급 색(단일 장애점 빨강)을 덮으면 위험이 가려진다. */
/* 근거 상태. 색만으로 구분하지 않는다 — 라벨이 상태를 말하고 색은 거든다. */
.evidence-state { display: grid; gap: 2px; margin-top: 7px; padding: 7px 9px; border-left: 2px solid var(--line); background: var(--surface); font: 500 10px/1.45 var(--font-data); }
.evidence-head { display: block; }
.evidence-state b { font-weight: 700; }
.evidence-state small { color: var(--muted); font-size: 9px; overflow-wrap: anywhere; }
.evidence-state button { justify-self: start; margin-top: 4px; min-height: 22px; padding: 0 8px; border: 1px solid var(--line); background: var(--surface-raised); color: var(--text); font: 600 9px/1 var(--font-data); cursor: pointer; }
.evidence-state button:hover { border-color: var(--signal-deep); color: var(--signal-deep); }
.evidence-state[data-applicability="applicable"] { border-left-color: var(--signal-deep); }
.evidence-state[data-applicability="incompatible"] { border-left-color: var(--danger); }
.evidence-state[data-applicability="unknown"] { border-left-color: var(--unknown); border-left-style: dashed; }
.evidence-state[data-applicability="user-asserted"] { border-left-color: var(--amber); }
.source-correction { margin: 7px 0 0; font-weight: 700; }
.workload-features { margin: 0; padding: 9px 11px; border: 1px solid var(--line-soft); }
.workload-features legend { padding: 0 5px; color: var(--muted); font: 700 9px/1 var(--font-data); letter-spacing: .1em; text-transform: uppercase; }
.workload-features label.inline { display: inline-flex; align-items: center; gap: 5px; margin-right: 12px; font: 500 11px/1.6 var(--font-ui); }
/* 온보딩. 설명하는 대상에 실선 박스를 씌우고, 설명 상자는 그 반대편에 둔다. */
.tour { position: fixed; z-index: 45; inset-inline-end: 22px; bottom: 22px; width: min(360px, calc(100vw - 44px)); padding: 18px 20px 16px; border: 1px solid var(--panel-line); background: var(--panel-deep); color: var(--on-deep); box-shadow: 0 18px 44px color-mix(in srgb, var(--panel-deep) 45%, transparent); }
.tour-count { margin: 0; color: var(--signal); font: 700 10px/1 var(--font-data); letter-spacing: .14em; }
.tour h2 { margin: 8px 0 0; font: 600 16px/1.3 var(--font-ui); }
.tour-text { margin: 9px 0 0; color: var(--on-deep-muted); font: 400 12px/1.65 var(--font-ui); }
.tour-actions { display: flex; gap: 7px; margin-top: 15px; }
.tour-actions button { min-height: 32px; padding: 0 13px; border: 1px solid var(--on-deep-line); background: none; color: var(--on-deep); font: 600 11px/1 var(--font-ui); cursor: pointer; }
.tour-actions button:hover:not(:disabled) { border-color: var(--signal); color: var(--signal); }
.tour-actions button:disabled { opacity: .4; cursor: default; }
.tour-actions [data-tour="next"] { margin-left: auto; border-color: var(--signal); background: var(--signal); color: var(--action-ink); }
.tour-actions [data-tour="next"]:hover { color: var(--action-ink); }
.tour[data-side="left"] { inset-inline-end: auto; inset-inline-start: 22px; }
.tour[data-vertical="top"] { bottom: auto; top: 22px; }
/* 대상 옆에 설 때는 구석 고정을 푼다. 자리는 그릴 때마다 다시 재어 인라인으로 넣는다. */
.tour[data-anchored] { inset-inline-end: auto; inset-inline-start: auto; bottom: auto; transition: left 160ms ease-out, top 160ms ease-out; }
/* 설명하는 대상에 씌우는 실선 박스. 바깥을 그늘로 덮어 그 안만 남긴다. 클릭은 통과시킨다. */
.tour-spot { position: fixed; z-index: 44; border: 2px solid var(--signal); border-radius: 2px; box-shadow: 0 0 0 9999px color-mix(in srgb, var(--panel-deep) 42%, transparent); pointer-events: none; transition: left 160ms ease-out, top 160ms ease-out, width 160ms ease-out, height 160ms ease-out; }
@media (prefers-reduced-motion: reduce) { .tour-spot { transition: none; } }
@media (max-width: 760px) { .tour, .tour[data-side="left"] { inset-inline: 12px; bottom: 12px; top: auto; width: auto; } .tour[data-vertical="top"] { top: 12px; bottom: auto; } }

.failure-grade[data-stale] { text-decoration: underline dotted var(--unknown); text-underline-offset: 3px; }
#failure-list[data-stale] .failure-forecast { opacity: .45; text-decoration: line-through; }
.mobile-fault-tray { display: none; }
.visually-hidden { position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important; overflow: hidden !important; clip: rect(0 0 0 0) !important; white-space: nowrap !important; border: 0 !important; }
.editor-deck { position: relative; min-height: 54px; padding: 7px 22px; display: flex; align-items: center; justify-content: space-between; gap: 16px; border-bottom: 1px solid var(--line); background: var(--surface-raised); }
.editor-tools { min-width: 0; max-width: 100%; display: flex; align-items: center; gap: 6px; overflow-x: auto; }
.editor-tools button, .editor-panel button { min-height: 36px; padding: 0 11px; border: 1px solid var(--line); background: var(--surface); color: var(--text); cursor: pointer; font: 600 9px/1 var(--font-data); white-space: nowrap; }
.editor-tools button:hover, .editor-panel button:hover { border-color: var(--cyan); color: var(--cyan); }
.editor-tools button[aria-pressed="true"] { border-color: var(--signal-deep); background: var(--surface-tint); color: var(--signal-deep); }
.editor-tools button:disabled { opacity: .42; cursor: default; }
.tool-separator { width: 1px; height: 24px; background: var(--line); margin: 0 4px; }
.editor-mode { flex: none; display: flex; align-items: center; gap: 8px; color: var(--muted); font: 600 9px/1 var(--font-data); letter-spacing: .08em; }
.editor-mode span { width: 7px; height: 7px; background: var(--cyan); }
.editor-panel { position: absolute; top: 100%; left: 0; right: 0; z-index: 40; max-height: calc(100vh - 190px); overflow: auto; border-bottom: 1px solid var(--line); background: var(--surface-tint); box-shadow: 0 14px 34px color-mix(in srgb, var(--panel-deep) 22%, transparent); }
.editor-panel[hidden] { display: none; }
.editor-panel > header { min-height: 58px; padding: 10px 22px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid var(--line-soft); }
.editor-panel h2 { margin: 5px 0 0; font-size: 17px; }
.editor-panel-content { padding: 14px 22px 18px; }
.editor-form { display: grid; grid-template-columns: repeat(5, minmax(120px, 1fr)); gap: 12px; align-items: end; }
.editor-form label { display: grid; gap: 6px; color: var(--muted); font: 600 9px/1 var(--font-data); }
.editor-form input, .editor-form select { min-width: 0; height: 40px; padding: 0 10px; border: 1px solid var(--line); background: var(--surface-raised); color: var(--text); font: 500 11px/1 var(--font-data); }
.device-limit-fields { display: contents; }
.editor-form .form-actions { display: flex; gap: 7px; align-items: end; }
.editor-form .form-actions button[type="submit"] { border-color: var(--signal-deep); background: var(--signal); color: var(--action-ink); }
.verification-columns { display: grid; grid-template-columns: repeat(3, minmax(240px, 1fr)); gap: 18px; }
.verification-columns > section { min-width: 0; border-top: 1px solid var(--line); padding-top: 10px; }
.verification-columns ul { min-height: 34px; margin: 0 0 10px; padding-left: 18px; color: var(--muted); font-size: 10px; }
.verification-columns .editor-form { display: flex; flex-direction: column; align-items: stretch; }
.verification-columns fieldset { display: flex; flex-wrap: wrap; gap: 7px 12px; margin: 0; border: 1px solid var(--line-soft); padding: 9px; }
.verification-columns fieldset label { display: flex; align-items: center; gap: 5px; }
.verification-columns fieldset input { width: auto; height: auto; }
.editor-error { min-height: 18px; margin: 10px 0 0; color: var(--danger); font: 600 10px/1.4 var(--font-data); }
.editor-hint { margin: 0 0 12px; color: var(--muted); font-size: 11px; line-height: 1.5; }
.template-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-bottom: 12px; }
.template-search { flex: 0 1 420px; display: block; }
.template-search input { width: 100%; min-height: 38px; padding: 0 12px; border: 1px solid var(--line); background: var(--surface-raised); color: var(--text); font: 500 11px/1 var(--font-ui); }
.template-search input:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
.template-count { margin: 0; color: var(--muted); font: 500 9px/1 var(--font-data); letter-spacing: .1em; }
/* 카드는 폭에 맞춰 열 수가 정해진다. 한 줄에 하나씩 늘어놓으면 설명이 폭의 3분의 1만 쓰고 나머지는 빈칸이 된다. */
.template-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); gap: 10px; }
/* .editor-panel button 이 nowrap·좁은 padding·모노 폰트를 걸어 둔다. 카드는 본문을 접어야 하니 특정도를 한 단계 올려 되돌린다. */
.editor-panel .template-item[hidden] { display: none; }
.template-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: auto; padding-top: 4px; }
.template-tags i { padding: 2px 6px; background: var(--surface-tint); color: var(--muted); font: 500 9px/1.4 var(--font-data); font-style: normal; }
.template-grade { align-self: start; padding: 2px 7px; border: 1px solid currentColor; color: var(--muted); font: 600 8px/1.4 var(--font-data); letter-spacing: .06em; }
.template-grade[data-grade="single-point"] { color: var(--danger); }
.template-grade[data-grade="partial"] { color: var(--amber); }
.template-grade[data-grade="redundant"] { color: var(--signal-deep); }
.editor-panel .template-item { display: flex; flex-direction: column; align-items: stretch; gap: 7px; padding: 13px 14px; border: 1px solid var(--line-soft); background: var(--surface); color: var(--text); cursor: pointer; text-align: left; white-space: normal; font: 400 11px/1.5 var(--font-ui); }
.editor-panel .template-item:hover { border-color: var(--signal-deep); background: var(--surface-raised); box-shadow: 0 4px 12px color-mix(in srgb, var(--panel-deep) 12%, transparent); }
.editor-panel .template-item:focus-visible { outline: 2px solid var(--signal); outline-offset: -1px; }
.template-item strong { font: 600 13px/1.25 var(--font-ui); }
/* 지금 붙어 있는 값은 목록에서 바로 찾을 수 있어야 한다. 색만이 아니라 라벨로도 말한다. */
.editor-panel .template-item[data-current] { border-color: var(--signal-deep); background: var(--surface-raised); }
.template-grade[data-grade="current"] { color: var(--signal-deep); }
.template-item em { color: var(--text); font-style: normal; font: 500 10px/1.5 var(--font-data); }
.swap-note { color: var(--muted); font-size: 10px; line-height: 1.5; }
.swap-detach { margin-left: auto; min-height: 32px; padding: 0 12px; border: 1px solid var(--line); background: var(--surface); color: var(--muted); font: 500 11px/1 var(--font-ui); cursor: pointer; }
.swap-detach:hover { border-color: var(--line); color: var(--text); }
.template-item span { color: var(--muted); font-size: 11px; line-height: 1.5; }
.template-item em { color: var(--signal-deep); font-style: normal; font-size: 10px; line-height: 1.5; }
.demand-manager-head { display: flex; justify-content: space-between; align-items: center; gap: 16px; }.demand-manager-head .editor-hint { margin: 0; }.demand-manager-head button { border-color: var(--signal-deep); background: var(--signal); }
.demand-editor-list { display: grid; gap: 10px; margin-top: 14px; }
.demand-editor-row { display: grid; grid-template-columns: 1.2fr repeat(6, minmax(100px, 1fr)) auto; gap: 8px; align-items: end; padding: 12px; border: 1px solid var(--line); background: var(--surface); }
.demand-editor-row label { display: grid; gap: 5px; color: var(--muted); font: 600 9px/1 var(--font-data); }.demand-editor-row input, .demand-editor-row select { min-width: 0; height: 36px; padding: 0 8px; border: 1px solid var(--line); background: var(--surface-raised); color: var(--text); font: 500 10px/1 var(--font-data); }
.demand-pool { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 2px 0 0; color: var(--muted); font: 500 10px/1.4 var(--font-data); }
.demand-pool label { display: flex; align-items: center; gap: 5px; color: var(--text); font: 600 9px/1 var(--font-data); }
.demand-pool input { width: auto; height: auto; }
.demand-row-actions { display: flex; gap: 5px; }.demand-row-actions button:last-child { color: var(--danger); }.demand-editor-row .editor-error { grid-column: 1 / -1; margin: 0; }
.editor-empty { min-height: 100px; display: grid; align-content: center; gap: 7px; text-align: center; color: var(--muted); }.editor-empty strong { color: var(--text); }

.main-grid { min-height: 0; display: grid; grid-template-columns: 250px minmax(680px, 1fr) 330px; border-bottom: 1px solid var(--line); }
.failure-panel, .inspector-panel { overflow-y: auto; }
.main-grid > * { min-height: 0; }
.failure-panel, .inspector-panel { background: var(--surface); }
.failure-panel { border-right: 1px solid var(--line); }
.inspector-panel { border-left: 1px solid var(--line); }
.panel-heading { min-height: 80px; padding: 18px; display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; border-bottom: 1px solid var(--line-soft); }
.panel-heading h1, .panel-heading h2, .comparison-panel h2 { margin: 8px 0 0; font-weight: 600; letter-spacing: -.025em; }
.panel-heading h1 { font-size: clamp(20px, 2vw, 31px); }
.panel-heading h2, .comparison-panel h2 { font-size: 17px; }
.panel-note { margin: 0; padding: 14px 18px; color: var(--muted); border-bottom: 1px solid var(--line-soft); font-size: 11px; line-height: 1.55; }
.count-badge, .resource-state, .path-readout { color: var(--muted); font: 600 9px/1 var(--font-data); letter-spacing: .06em; }
.resource-state { padding: 7px 8px; border: 1px solid currentColor; }
.panel-tabs { display: flex; border-bottom: 1px solid var(--line-soft); }
.panel-tabs button { padding: 10px 14px; border: 0; border-bottom: 2px solid transparent; background: none; color: var(--muted); cursor: pointer; font: 600 9px/1 var(--font-data); letter-spacing: .12em; text-transform: uppercase; }
.panel-tabs button:hover { color: var(--text); }
.panel-tabs button[aria-selected="true"] { color: var(--text); border-bottom-color: var(--signal-deep); }
.component-palette { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1px; padding: 1px; background: var(--line-soft); }
.palette-group { grid-column: 1 / -1; margin: 0; padding: 11px 10px 5px; background: var(--surface); color: var(--muted); font: 600 9px/1 var(--font-data); letter-spacing: .08em; }
.palette-group:first-child { padding-top: 8px; }
.palette-item { --icon-line: currentColor; --icon-fill: var(--surface); --icon-accent: var(--surface-raised); display: grid; gap: 6px; justify-items: center; padding: 12px 8px; border: 0; background: var(--surface); color: var(--text); cursor: grab; touch-action: none; user-select: none; -webkit-user-drag: none; }
.palette-item[data-wide] { grid-column: 1 / -1; }
.palette-item > * { pointer-events: none; }
.palette-item:hover { background: var(--surface-raised); color: var(--signal-deep); }
.palette-item.dragging { opacity: .4; }
.palette-glyph { display: grid; place-items: center; width: 100%; height: 40px; }
.palette-glyph svg { display: block; width: 76px; height: 40px; }
.palette-label { font: 600 10px/1 var(--font-ui); }
.palette-kind { color: var(--muted); font: 500 8px/1 var(--font-data); letter-spacing: .1em; }
.palette-ghost { --icon-line: var(--signal-deep); --icon-fill: var(--canvas); --icon-accent: var(--surface-raised); position: fixed; top: 0; left: 0; z-index: 60; display: grid; place-items: center; width: 112px; height: 44px; opacity: .85; pointer-events: none; }
.palette-ghost svg { display: block; width: 108px; height: 40px; }
.topology-scroll.drop-target { outline: 2px dashed var(--signal-deep); outline-offset: -2px; }
.failure-list { display: grid; }
.failure-group h3 { margin: 0; padding: 16px 18px 8px; color: var(--muted); font: 600 9px/1 var(--font-data); letter-spacing: .12em; }
.failure-empty { margin: 0; padding: 4px 18px 14px; color: var(--muted); font: 500 11px/1.4 var(--font-ui); }
.failure-switch { width: 100%; min-height: 52px; padding: 9px 18px; display: grid; grid-template-columns: 20px 1fr auto; align-items: center; gap: 10px; border: 0; border-top: 1px solid var(--line-soft); background: transparent; text-align: left; cursor: pointer; }
.failure-switch:hover { background: var(--surface-raised); }
.failure-switch .switch-glyph { width: 15px; height: 15px; border: 1px solid var(--muted); position: relative; }
.failure-switch.active .switch-glyph { border-color: var(--danger); }
.failure-switch.active .switch-glyph::after { content: ''; position: absolute; inset: 2px; background: var(--danger); }
.failure-switch strong { display: block; font: 600 11px/1.2 var(--font-data); }
.failure-switch small { display: block; color: var(--muted); font-size: 9px; }
/* 판정은 문구로 읽힌다. 색은 보조일 뿐이라 색만으로 구분하지 않는다. */
.failure-forecast { margin-top: 3px; font: 600 9px/1.2 var(--font-data); }
.failure-forecast[data-verdict="severs"] { color: var(--danger); }
.failure-forecast[data-verdict="overloads"] { color: var(--amber); }
.failure-forecast[data-verdict="absorbs"] { color: var(--signal-deep); }
.failure-grade { margin: 0; padding: 2px 18px 12px; color: var(--muted); font: 600 12px/1.4 var(--font-data); letter-spacing: .02em; }
.failure-grade[data-grade="single-point"] { color: var(--danger); }
.failure-grade[data-grade="partial"] { color: var(--amber); }
.failure-switch .switch-state { color: var(--muted); font: 500 9px/1 var(--font-data); }
.failure-switch.active .switch-state { color: var(--danger); }

.topology-panel { min-width: 0; display: grid; grid-template-rows: auto minmax(0, 1fr) auto; background: var(--surface-tint); }
.topology-heading { align-items: center; padding-inline: 22px; }
/* 캔버스 제목은 답이다. 상태에 따라 색이 바뀌고, 그 아래 한 줄이 수치와 성장 여력을 말한다. */
#topology-heading[data-tone="danger"] { color: var(--danger); }
#topology-heading[data-tone="amber"] { color: var(--amber); }
#topology-heading[data-tone="unknown"] { color: var(--unknown); }
.headline-detail { margin: 5px 0 0; color: var(--muted); font: 500 12px/1.3 var(--font-data); }
.topology-live-status { display: grid; justify-items: end; gap: 9px; }
.topology-controls { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; justify-content: flex-end; }
.zoom-control { display: flex; align-items: stretch; border: 1px solid var(--line); }
.zoom-control button { min-width: 30px; padding: 0 9px; border: 0; border-right: 1px solid var(--line); background: var(--surface); color: var(--text); cursor: pointer; font: 600 10px/1 var(--font-data); letter-spacing: .04em; }
.zoom-control button:last-child { border-right: 0; }
.zoom-control button:hover { background: var(--surface-raised); color: var(--signal-deep); }
.zoom-control #zoom-level { min-width: 46px; color: var(--muted); }
.topology-live-status > span { color: var(--cyan); font: 600 9px/1 var(--font-data); letter-spacing: .08em; }
.topology-live-status i { display: inline-block; width: 7px; height: 7px; margin-right: 6px; background: var(--cyan); box-shadow: 0 2px 9px color-mix(in srgb, var(--cyan) 65%, transparent); animation: telemetry-breathe 1.8s cubic-bezier(.16,1,.3,1) infinite alternate; }
.topology-scroll { overflow: auto; overscroll-behavior: contain; cursor: grab; min-width: 0; min-height: 0; }
.topology-scroll.panning { cursor: grabbing; }
.topology-scroll.panning .mesh-node { cursor: grabbing; }
.mobile-pan-cue { display: none; }
.topology-stage { --stage-pad: 300px; position: relative; width: calc(var(--canvas-width, 940px) * var(--zoom, 1) + var(--stage-pad) * 2); height: calc(var(--canvas-height, 580px) * var(--zoom, 1) + var(--stage-pad) * 2); }
.topology-canvas { position: absolute; left: var(--stage-pad); top: var(--stage-pad); width: var(--canvas-width, 940px); height: var(--canvas-height, 580px); background: var(--canvas); transform: scale(var(--zoom, 1)); transform-origin: 0 0; }
.topology-canvas::before { content: ''; position: absolute; inset: 0; opacity: .32; background-image: linear-gradient(var(--line-soft) 1px, transparent 1px), linear-gradient(90deg, var(--line-soft) 1px, transparent 1px); background-size: 30px 30px; background-position: calc(-1 * var(--viewport-x, 0px)) calc(-1 * var(--viewport-y, 0px)); pointer-events: none; }
.link-layer, .diagram-layer, .node-layer { position: absolute; inset: 0; }
.diagram-layer { pointer-events: none; }
.diagram-shape { position: absolute; display: grid; place-items: center; min-width: 24px; min-height: 18px; padding: 6px; border: 1px solid var(--line); background: color-mix(in srgb, var(--surface-raised) 82%, transparent); color: var(--text); font: 500 11px/1.3 var(--font-ui); text-align: center; cursor: move; pointer-events: auto; overflow: hidden; white-space: pre-wrap; }
.diagram-shape[data-kind="ellipse"] { border-radius: 50%; }
.diagram-shape[data-kind="text"] { border-color: transparent; background: transparent; font-size: 13px; }
.diagram-shape[data-kind="note"] { align-items: start; justify-items: start; background: var(--surface); text-align: left; }
.diagram-shape.selected { outline: 2px solid var(--signal-deep); outline-offset: 2px; }
.selection-marquee { position: absolute; z-index: 8; border: 1px dashed var(--signal-deep); background: color-mix(in srgb, var(--signal) 13%, transparent); pointer-events: none; }
.node-layer { pointer-events: none; }
.node-layer .mesh-node { pointer-events: auto; }
/* 그룹 상자는 zone 계층을 그린다. 톤이 영역을, 점선이 경계를 맡는다. */
.topology-group .group-frame { fill: color-mix(in srgb, var(--surface-tint) 55%, transparent); stroke: var(--line-soft); stroke-width: 1; stroke-dasharray: 4 4; vector-effect: non-scaling-stroke; }
.topology-group[data-depth="2"] .group-frame { fill: color-mix(in srgb, var(--surface-raised) 60%, transparent); }
.topology-group .group-label { fill: var(--muted); font: 600 9px/1 var(--font-data); letter-spacing: .1em; }
/* 이름표는 선 위에 뜨지만 배경이 없으면 선이 글자 사이를 지난다. 상자를 깔아 탭처럼 앉힌다.
   깊이마다 바탕을 달리해 어느 층의 이름인지 상자만 보고도 갈린다. */
.group-tag .group-label { fill: var(--muted); font: 600 9px/1 var(--font-data); letter-spacing: .1em; }
.group-tag-frame { fill: var(--surface-tint); stroke: var(--line-soft); stroke-width: 1; vector-effect: non-scaling-stroke; }
.group-tag[data-depth="2"] .group-tag-frame { fill: var(--surface-raised); }

/* 링크 50개가 넘는 설계에서는 모든 선이 같은 굵기면 얽힌 실타래가 된다. 선을 지우지는 않는다 —
   무엇이 무엇에 붙어 있는지가 이 그림의 절반이다. 대신 굵기가 심각도를 말하게 한다. 정상은
   가늘게 물러나고 넘친 링크가 앞으로 나온다. 미확인은 정상보다 진하다 — 모르는 것이 물러나면
   안전으로 읽힌다. 굵기는 vector-effect 로 화면 픽셀에 고정돼 축소해도 사다리가 유지된다. */
.link { stroke: var(--cyan); stroke-width: 1; fill: none; vector-effect: non-scaling-stroke; opacity: .55; }
.link.unknown { stroke: var(--unknown); stroke-width: 1.5; stroke-dasharray: 5 4; opacity: .8; }
.link.warning { stroke: var(--amber); stroke-width: 2.5; opacity: .9; }
.link.overloaded { stroke: var(--danger); stroke-width: 4; opacity: 1; }
.link.invalid { stroke: var(--danger); stroke-width: 2.5; stroke-dasharray: 2 3; opacity: .9; }
.link.disabled { stroke: var(--danger); stroke-width: 2; stroke-dasharray: 7 7; opacity: .55; }
.link.on-severed-path { stroke: var(--danger); stroke-width: 2; stroke-dasharray: 2 6; opacity: .45; }
.link-hit { stroke: transparent; stroke-width: 18; cursor: pointer; pointer-events: stroke; }
.link-label { fill: var(--muted); font: 500 9px var(--font-data); paint-order: stroke; stroke: var(--canvas); stroke-width: 4px; }
.packet-dot { fill: var(--signal-deep); stroke: var(--surface-raised); stroke-width: 1.5; filter: drop-shadow(0 1px 3px color-mix(in srgb, var(--signal-deep) 65%, transparent)); pointer-events: none; }
.packet-dot.warning { fill: var(--amber); }.packet-dot.overloaded { fill: var(--danger); }.packet-dot.disabled { display: none; }
#icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.mesh-node { --node-color: var(--cyan); --symbol-h: 42px; --icon-line: currentColor; --icon-fill: var(--canvas); --icon-accent: var(--surface-raised); position: absolute; display: block; width: 104px; padding: 0; border: 0; background: none; color: var(--text); cursor: pointer; text-align: center; transform: translate(-50%, calc(var(--symbol-h) / -2)); transition: filter 180ms cubic-bezier(.16,1,.3,1), opacity 180ms cubic-bezier(.16,1,.3,1); }
.mesh-node.warning { --node-color: var(--amber); }.mesh-node.overloaded { --node-color: var(--danger); }.mesh-node.unknown { --node-color: var(--unknown); }.mesh-node.invalid { --node-color: var(--danger); }
.mesh-node.disabled { --node-color: var(--danger); color: var(--muted); opacity: .82; }
.mesh-node.disabled .node-glyph { opacity: .28; }
.mesh-node.disabled .node-symbol { position: relative; }
.mesh-node.disabled .node-symbol::before, .mesh-node.disabled .node-symbol::after { content: ''; position: absolute; left: 50%; top: 50%; width: 40px; height: 2px; background: var(--danger); }
.mesh-node.disabled .node-symbol::before { transform: translate(-50%, -50%) rotate(45deg); }
.mesh-node.disabled .node-symbol::after { transform: translate(-50%, -50%) rotate(-45deg); }
.mesh-node:hover .node-name { color: var(--node-color); }
.mesh-node.selected { outline: 2px solid var(--node-color); outline-offset: 2px; }
.mesh-node.multi-selected { outline: 2px solid var(--signal-deep); outline-offset: 3px; }
.mesh-node.connect-source { outline: 3px solid var(--signal); outline-offset: 4px; }
.mesh-node.dragging { cursor: grabbing; filter: saturate(1.2); }
.node-symbol { display: grid; place-items: center; width: 92px; height: var(--symbol-h); margin: 0 auto; }
.node-glyph { display: block; width: 88px; height: 40px; }
.node-rail { display: block; width: 92px; height: 2px; margin: 0 auto 4px; background: var(--node-color); }
.mesh-node.overloaded .node-rail { background-image: repeating-linear-gradient(135deg, transparent 0 3px, color-mix(in srgb, var(--surface-raised) 55%, transparent) 3px 6px); }
.mesh-node.unknown .node-rail, .mesh-node.disabled .node-rail { background: repeating-linear-gradient(90deg, var(--node-color) 0 4px, transparent 4px 8px); }
.node-labels { display: block; width: max-content; max-width: 104px; margin: 0 auto; padding: 2px 4px 3px; overflow: hidden; background: var(--canvas); }
/* 연결 핸들. 노드에 마우스를 올리거나 노드를 고르면 나타나고, 끌면 링크가 된다. */
.node-ports { position: absolute; inset: 0; pointer-events: none; }
.node-ports i { position: absolute; width: 9px; height: 9px; margin: -5px 0 0 -5px; border: 1px solid var(--surface-raised); background: var(--signal-deep); opacity: 0; transition: opacity 120ms ease-out; pointer-events: auto; cursor: crosshair; }
.node-ports i[data-port="top"] { left: 50%; top: 0; }
.node-ports i[data-port="right"] { left: 100%; top: 50%; }
.node-ports i[data-port="bottom"] { left: 50%; top: 100%; }
.node-ports i[data-port="left"] { left: 0; top: 50%; }
.mesh-node:hover .node-ports i, .mesh-node.selected .node-ports i, .mesh-node:focus-visible .node-ports i, .mesh-node.linking .node-ports i { opacity: 1; }
.node-ports i:hover { background: var(--signal); }
.mesh-node.link-target { outline: 2px solid var(--signal-deep); outline-offset: 2px; }
.link-draft { stroke: var(--signal-deep); stroke-width: 2; stroke-dasharray: 5 4; fill: none; vector-effect: non-scaling-stroke; pointer-events: none; }

/* 클래스 표현 후보 — 결정 뒤 고른 것만 남기고 나머지 규칙을 지운다. */
.layout-control { display: grid; gap: 4px; margin-top: 7px; }
.layout-axis { display: flex; align-items: center; flex-wrap: wrap; gap: 3px; }
.layout-axis > span { min-width: 26px; color: var(--muted); font: 600 8px/1 var(--font-data); letter-spacing: .1em; }
.layout-axis button { min-height: 22px; padding: 0 8px; border: 1px solid var(--line-soft); background: var(--surface); color: var(--muted); font: 600 8px/1 var(--font-data); letter-spacing: .06em; cursor: pointer; }
.layout-axis button:hover { border-color: var(--line); color: var(--text); }
.layout-axis button[aria-pressed="true"] { border-color: var(--signal-deep); background: var(--surface-raised); color: var(--signal-deep); }

.node-class-badge { position: absolute; top: 0; right: 0; z-index: 1; padding: 0 4px; border: 1px solid var(--line-soft); background: var(--surface-raised); color: var(--text); font: 700 8px/17px var(--font-data); letter-spacing: .04em; }

/* 제조사 배지는 심볼 좌상단에 얹는다. 로고가 있으면 로고를, 없으면 약칭 텍스트를 쓴다. */
.node-symbol { position: relative; }
.node-vendor, .node-vendor-logo, .node-vendor-mark { position: absolute; top: 0; left: 0; z-index: 1; }
.node-vendor-mark { width: 19px; height: 19px; padding: 2px; border: 1px solid var(--line-soft); background: var(--surface-raised); fill: var(--mark, var(--muted)); }
.node-vendor { max-width: 58px; padding: 0 4px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; border: 1px solid var(--line-soft); background: var(--surface-raised); color: var(--muted); font: 700 8px/17px var(--font-data); letter-spacing: .04em; text-transform: uppercase; }
.node-vendor-logo { width: auto; height: 19px; max-width: 58px; padding: 2px; border: 1px solid var(--line-soft); object-fit: contain; background: var(--surface-raised); }
.node-model { display: block; max-width: 96px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font: 500 8px/1.3 var(--font-data); letter-spacing: .02em; }
/* 자동으로 묶인 백엔드 풀과, 어떤 수요도 지나지 않는 장비를 노드에서 바로 읽게 한다. */
.node-pool { display: block; max-width: 96px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--signal-deep); font: 600 8px/1.3 var(--font-data); letter-spacing: .02em; }
.node-pool[data-warn] { color: var(--amber); }
.node-name { display: block; max-width: 96px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 600 10px/1.1 var(--font-data); letter-spacing: .02em; }
.node-axes { display: grid; gap: 4px; margin: 4px 0; }
.node-axis { --axis-color: var(--cyan); position: relative; display: grid; grid-template-columns: 6px 4ch auto auto; gap: 0 4px; padding-bottom: 3px; align-items: baseline; text-align: left; font: 500 8px/1.2 var(--font-data); }
.node-axis::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--line-soft); }
.node-axis[style*="--util"]::before { content: ''; position: absolute; left: 0; bottom: 0; z-index: 1; width: calc(min(var(--util), 1) * 100%); height: 2px; background: var(--axis-color); }
.node-axis[data-axis-state="overloaded"]::after { background: var(--danger); opacity: .35; }
.node-axis[data-axis-state="warning"] { --axis-color: var(--amber); }
.node-axis[data-axis-state="overloaded"], .node-axis[data-axis-state="invalid"] { --axis-color: var(--danger); }
.node-axis[data-axis-state="unknown"], .node-axis[data-axis-state="disabled"] { --axis-color: var(--unknown); }
.node-axis i { font-style: normal; font-weight: 700; color: var(--axis-color); }
.node-axis b { font-weight: 500; letter-spacing: .06em; color: var(--muted); }
.node-axis[data-binding] b { font-weight: 700; color: var(--text); }
.node-axis em { font-style: normal; text-align: right; font-variant-numeric: tabular-nums; }
.node-axis s { text-decoration: none; font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; color: var(--axis-color); }
.node-meta { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font: 500 8px/1.2 var(--font-data); letter-spacing: .08em; }
.canvas-footer { min-height: 46px; padding: 9px 22px; display: flex; align-items: center; justify-content: space-between; gap: 18px; color: var(--muted); border-top: 1px solid var(--line-soft); font: 500 9px/1 var(--font-data); }
.canvas-footer > div { min-width: 0; }
.learning-panel { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line-soft); color: var(--text); font: 500 10px/1.45 var(--font-ui); }
.learning-panel strong { margin-right: 8px; color: var(--signal-deep); }
.learning-panel button { min-height: 30px; margin: 5px 6px 0 0; border: 1px solid var(--line); background: var(--surface-raised); color: var(--text); cursor: pointer; font: 600 9px/1 var(--font-data); }
.learning-panel output { display: block; margin-top: 5px; color: var(--muted); }
/* display:block 이 [hidden] 을 이긴다. 답을 감추려면 여기서 다시 눌러야 한다. */
.learning-panel output[hidden] { display: none; }

/* 사용 안내. 읽는 문서라 캔버스 어휘를 그대로 쓴다 — 토큰과 규칙을 화면과 같은 모양으로 보인다. */
.evidence-state { display: block; margin-top: 4px; color: var(--text); font-family: var(--font-data); }
.bottleneck-note { margin: 0; color: var(--text); font: 500 11px/1.5 var(--font-ui); }
#calculation-note { flex: none; }

.inspector-content { padding: 18px; }
.empty-inspector { min-height: 200px; display: grid; align-content: center; gap: 9px; color: var(--muted); text-align: center; }.empty-inspector strong { color: var(--text); font-size: 17px; }.empty-inspector span { font-size: 11px; line-height: 1.5; }
.resource-identity { padding-bottom: 18px; border-bottom: 1px solid var(--line-soft); }
.resource-identity strong { display: block; font: 600 24px/1 var(--font-data); letter-spacing: -.02em; }
.resource-identity span { display: block; margin-top: 8px; color: var(--muted); font-size: 11px; }
.binding-callout { margin: 18px 0; padding: 15px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.binding-callout span { color: var(--muted); font: 500 9px/1 var(--font-data); letter-spacing: .1em; }
.binding-callout strong { display: flex; justify-content: space-between; margin-top: 9px; color: var(--signal-deep); font: 600 14px/1 var(--font-data); }
.axis-list { display: grid; gap: 18px; }
.axis-row { --axis-color: var(--cyan); }
.axis-row.warning { --axis-color: var(--amber); }.axis-row.overloaded { --axis-color: var(--danger); }.axis-row.unknown { --axis-color: var(--unknown); }.axis-row.invalid { --axis-color: var(--danger); }
.axis-title, .axis-values { display: flex; justify-content: space-between; gap: 10px; }
.axis-title { margin-bottom: 7px; font: 600 10px/1 var(--font-data); }
.axis-title span:last-child { color: var(--axis-color); }
.axis-meter { position: relative; height: 7px; background: var(--surface-tint); overflow: hidden; }
/* 끌 수 있는 막대. 손잡이와 커서로 조작 가능한 것임을 알린다 — 색만으로 알리지 않는다. */
.axis-meter[data-axis-drag] { height: 11px; overflow: visible; cursor: ew-resize; touch-action: none; }
.axis-meter[data-axis-drag]::before { content: ''; position: absolute; inset: 0; background: repeating-linear-gradient(90deg, var(--line-soft) 0 1px, transparent 1px 9px); opacity: .7; }
.axis-grip { position: absolute; z-index: 2; top: -3px; left: min(var(--axis-width, 0%), 100%); width: 3px; height: 17px; margin-left: -1.5px; background: var(--axis-color); box-shadow: 0 0 0 2px var(--surface); pointer-events: none; }
.axis-meter[data-axis-drag] span { position: relative; z-index: 1; }
.axis-meter[data-axis-drag]:hover .axis-grip, .axis-meter.dragging .axis-grip { width: 5px; margin-left: -2.5px; }
.axis-meter[data-axis-drag]:focus-visible { outline: 2px solid var(--signal-deep); outline-offset: 3px; }
.axis-row[data-axis-editable] .axis-values [data-axis-limit] { color: var(--text); font-weight: 700; }
.axis-meter span { display: block; width: min(var(--axis-width), 100%); height: 100%; background: var(--axis-color); }
.axis-row.overloaded .axis-meter { background-image: repeating-linear-gradient(135deg, color-mix(in srgb, var(--danger) 18%, var(--ground)) 0 4px, color-mix(in srgb, var(--danger) 32%, var(--ground)) 4px 8px); }
.axis-row.invalid .axis-meter { background-image: repeating-linear-gradient(135deg, color-mix(in srgb, var(--danger) 26%, var(--ground)) 0 2px, transparent 2px 5px); }
.axis-values { margin-top: 7px; color: var(--muted); font: 500 9px/1 var(--font-data); }
.behavior-block { margin: 18px 0; padding: 15px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.behavior-code { color: var(--muted); font: 500 9px/1 var(--font-data); letter-spacing: .1em; }
.behavior-choice { display: flex; margin-top: 9px; border: 1px solid var(--line); }
.behavior-choice label { flex: 1; position: relative; }
.behavior-choice input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.behavior-choice span { display: block; padding: 11px 8px; text-align: center; color: var(--muted); font: 600 10px/1 var(--font-data); letter-spacing: .08em; }
.behavior-choice input:checked + span { background: var(--signal); color: var(--action-ink); }
.behavior-choice input:focus-visible + span { outline: 2px solid var(--signal); outline-offset: 2px; }
.behavior-note { margin: 9px 0 0; color: var(--muted); font-size: 11px; line-height: 1.5; }
.behavior-preview { display: grid; gap: 5px; margin-top: 11px; padding: 11px; background: var(--surface-tint); font: 500 10px/1.3 var(--font-data); }
.behavior-preview span { color: var(--muted); font-size: 9px; letter-spacing: .1em; }
.behavior-preview b { font-weight: 700; font-variant-numeric: tabular-nums; }
.behavior-preview s { text-decoration: none; color: var(--signal-deep); font-weight: 700; }
.behavior-preview small { color: var(--muted); font-size: 9px; }
.spec-block { display: grid; gap: 7px; margin: 0 22px 14px; padding: 12px 14px; border: 1px solid var(--line-soft); background: var(--surface-raised); }
.spec-code { color: var(--muted); font: 600 8px/1 var(--font-data); letter-spacing: .12em; }
.spec-block label { display: grid; gap: 4px; color: var(--muted); font: 500 9px/1.2 var(--font-ui); }
.spec-block select { min-height: 32px; padding: 0 8px; border: 1px solid var(--line); background: var(--surface); color: var(--text); font: 500 11px/1 var(--font-ui); }
.spec-note { margin: 0; color: var(--muted); font: 400 10px/1.45 var(--font-ui); }
.limit-field small { display: flex; align-items: center; gap: 6px; margin-top: 3px; color: var(--muted); font: 500 9px/1.2 var(--font-data); }
.limit-field small button { padding: 1px 5px; border: 1px solid var(--line-soft); background: var(--surface); color: var(--muted); font: 600 8px/1.4 var(--font-data); cursor: pointer; }
.limit-field small button:hover { border-color: var(--signal-deep); color: var(--signal-deep); }
.limit-field.corrected input { border-color: var(--amber); }
.limit-field b { color: var(--amber); font-weight: 700; }
.source-note { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line-soft); color: var(--muted); font-size: 10px; line-height: 1.55; }
.source-note strong { color: var(--text); }
.inspector-editor { margin-top: 22px; padding-top: 16px; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; border-top: 1px solid var(--line); }
.inspector-editor h3 { grid-column: 1 / -1; margin: 0 0 4px; font-size: 17px; line-height: 1.2; }
.inspector-editor label { display: grid; gap: 5px; color: var(--muted); font: 600 9px/1 var(--font-data); }
.inspector-editor input { min-width: 0; height: 36px; padding: 0 8px; border: 1px solid var(--line); background: var(--surface-raised); color: var(--text); font: 500 10px/1 var(--font-data); }
.inspector-editor-actions { grid-column: 1 / -1; display: flex; gap: 7px; margin-top: 2px; }
.inspector-editor-actions button { min-height: 36px; padding: 0 10px; border: 1px solid var(--line); background: var(--surface); color: var(--text); cursor: pointer; font: 600 9px/1 var(--font-data); }
.inspector-editor-actions button:first-child { border-color: var(--signal-deep); background: var(--signal); }.inspector-editor-actions button:last-child { color: var(--danger); }
.inspector-editor .editor-error { grid-column: 1 / -1; margin: 0; }

.comparison-panel { padding: 24px 22px 30px; background: var(--surface-tint); }
.comparison-panel > header { display: flex; justify-content: space-between; align-items: end; gap: 24px; margin-bottom: 18px; }
.comparison-panel p { margin: 0; color: var(--muted); font-size: 11px; }
.comparison-grid { display: grid; grid-template-columns: repeat(4, 1fr); border: 1px solid var(--line); }
.comparison-item { min-height: 88px; padding: 15px 18px; border-right: 1px solid var(--line); }
.comparison-item:last-child { border-right: 0; }
.comparison-item span, .comparison-item small { display: block; color: var(--muted); }
.comparison-item span { font-size: 10px; }.comparison-item strong { display: block; margin: 10px 0 7px; font: 600 18px/1 var(--font-data); }.comparison-item small { font: 500 9px/1.3 var(--font-data); }
.comparison-item.negative strong { color: var(--danger); }.comparison-item.positive strong { color: var(--signal-deep); }
/* 오른쪽 버튼 메뉴. 캔버스 위 어디서든 뜨므로 화면 경계에서 접힌다. */
.context-menu { position: fixed; z-index: 40; min-width: 168px; padding: 4px 0; border: 1px solid var(--line); background: var(--surface-raised); box-shadow: 0 10px 30px color-mix(in srgb, var(--panel-deep) 24%, transparent); }
.context-title { margin: 0; padding: 8px 14px 6px; border-bottom: 1px solid var(--line-soft); color: var(--muted); font: 600 9px/1.2 var(--font-data); letter-spacing: .08em; }
.context-menu button { display: block; width: 100%; padding: 9px 14px; border: 0; background: none; color: var(--text); font: 500 12px/1 var(--font-ui); text-align: left; cursor: pointer; }
.context-menu button:hover, .context-menu button:focus-visible { background: var(--surface-tint); outline: none; }
.context-menu button[data-danger] { color: var(--danger); font-weight: 600; }

.toast { position: fixed; right: 18px; bottom: 18px; z-index: 50; min-width: 240px; padding: 13px 15px; background: var(--panel-deep); color: var(--on-deep); font: 600 11px/1.3 var(--font-data); transform: translateY(120px); transition: transform 260ms cubic-bezier(.16,1,.3,1); box-shadow: 0 10px 30px color-mix(in srgb, var(--panel-deep) 24%, transparent); }
.toast { display: flex; align-items: center; gap: 14px; justify-content: space-between; }
.toast button { padding: 6px 10px; border: 1px solid var(--on-deep-line); background: none; color: var(--signal); cursor: pointer; font: 600 9px/1 var(--font-data); letter-spacing: .06em; }
.toast button:hover { border-color: var(--signal); }
.toast.visible { transform: translateY(0); }

@keyframes telemetry-breathe { from { opacity: .45; transform: scale(.82); } to { opacity: 1; transform: scale(1); } }

@media (max-width: 1180px) {
  .app-shell { height: auto; min-height: 100vh; }
  .main-grid { grid-template-columns: 230px minmax(650px, 1fr); }
  .inspector-panel { grid-column: 1 / -1; border-left: 0; border-top: 1px solid var(--line); }
  .inspector-content { display: grid; grid-template-columns: 220px 220px 1fr 280px; gap: 20px; align-items: start; }
  .resource-identity, .binding-callout, .source-note { margin: 0; padding: 0; border: 0; }
  .editor-form { grid-template-columns: repeat(3, minmax(140px, 1fr)); }
  .demand-editor-row { grid-template-columns: repeat(4, minmax(130px, 1fr)); overflow-x: auto; }.demand-row-actions { grid-column: 1 / -1; }
}

@media (max-width: 760px) {
  .topbar { grid-template-columns: 1fr auto; padding: 12px 14px; }
  .run-state { grid-column: 1 / -1; grid-row: 2; justify-content: flex-start; min-width: 0; }
  /* 좁은 화면에서 헤더 동작은 접는다. 안내만 남긴다 — 처음 오는 사람이 가장 필요로 하는 문이다. */
  .top-actions .text-button:not(#guide-button) { display: none; }
  #guide-button { padding-inline: 10px; }
  .brand span { display: none; }
  .control-deck { grid-template-columns: 1fr; gap: 16px; padding: 16px 14px; }
  .editor-deck { padding: 7px 14px; align-items: flex-start; flex-direction: column; }.editor-tools { width: 100%; }.editor-mode { min-height: 24px; }
  .editor-panel > header, .editor-panel-content { padding-inline: 14px; }.editor-form { grid-template-columns: 1fr 1fr; }.editor-form .form-actions { grid-column: 1 / -1; }
  .demand-manager-head { align-items: flex-start; }.demand-editor-row { grid-template-columns: 1fr 1fr; }.demand-row-actions { grid-column: 1 / -1; }
  .scale-control { grid-template-columns: 1fr 64px; }.scale-control > span { grid-column: 1 / -1; }
  .summary-strip { grid-template-columns: 1fr 1fr; }.summary-strip > div:nth-child(2) { border-right: 0; }.summary-strip > div { min-height: 82px; padding: 13px 14px; border-bottom: 1px solid var(--line-soft); }
  .mobile-fault-tray { position: sticky; top: 0; z-index: 20; display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: 8px; padding: 10px 14px; border-bottom: 1px solid var(--panel-line); background: #16332df2; color: var(--on-deep); box-shadow: 0 8px 22px color-mix(in srgb, var(--panel-deep) 24%, transparent); }
  .mobile-fault-tray div { grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
  .mobile-fault-tray div .section-code { color: var(--signal); }.mobile-fault-tray div strong { font-size: 11px; }.mobile-fault-tray button, .mobile-fault-tray a { min-height: 38px; border: 1px solid var(--on-deep-line); background: transparent; padding: 0 11px; color: var(--on-deep); font: 600 10px/36px var(--font-data); text-align: center; text-decoration: none; }
  .mobile-fault-tray button span { color: var(--signal); }.mobile-fault-tray button[aria-pressed="true"] { border-color: var(--danger-soft); }.mobile-fault-tray button[aria-pressed="true"] span { color: var(--danger-soft); }
  .mobile-fault-tray a { color: var(--signal); border-color: var(--signal); }
  .app-shell { height: auto; min-height: 100vh; }
  .main-grid { display: flex; flex-direction: column; min-height: 0; }
  .failure-panel { border-right: 0; order: 2; }.topology-panel { order: 1; }.inspector-panel { order: 3; }
  .failure-list { grid-template-columns: 1fr 1fr; }.failure-group h3 { grid-column: 1 / -1; }.failure-group { display: contents; }
  .topology-heading { min-height: 108px; align-items: flex-start; }.path-readout { margin-top: 4px; }
  .topology-canvas { margin: 0; }.topology-scroll { max-height: 500px; position: relative; }
  .mobile-pan-cue { position: sticky; top: 0; left: 0; z-index: 8; width: 100vw; min-height: 30px; display: flex; align-items: center; justify-content: center; gap: 18px; color: var(--on-deep); background: linear-gradient(90deg, var(--panel-deep) 0%, var(--panel-mid) 18%, var(--panel-mid) 82%, var(--panel-deep) 100%); border-bottom: 1px solid var(--panel-line); font: 600 9px/1 var(--font-data); letter-spacing: .08em; }
  .inspector-content { display: block; }.binding-callout { margin: 18px 0; padding: 15px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }.source-note { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line-soft); }
  .comparison-panel { padding: 22px 14px; }.comparison-panel > header { align-items: flex-start; flex-direction: column; }.comparison-grid { grid-template-columns: 1fr 1fr; }.comparison-item:nth-child(2) { border-right: 0; }.comparison-item { border-bottom: 1px solid var(--line); }
  .canvas-footer { padding-inline: 14px; }.canvas-footer span:last-child { display: none; }
  .verification-columns { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
  .packet-dot { display: none; }
}

/* 방향마다 한계가 다른 링크에만 뜬다. 축 목록과 같은 리듬을 쓰되 한 단 들여 부속임을 보인다. */
.direction-list { display: grid; gap: 6px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 8px; }
.link-direction { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; }
.link-direction strong { min-width: 88px; font-size: 11px; letter-spacing: 0.04em; }
.link-direction strong small { display: block; font-size: 9px; font-weight: 400; color: var(--muted); letter-spacing: 0; }
.link-direction span { font-size: 11px; font-variant-numeric: tabular-nums; color: var(--muted); }
.link-direction span b { color: var(--text); font-weight: 600; }
.link-direction span[data-status="warning"] { color: var(--amber); }
.link-direction span[data-status="overloaded"] { color: var(--danger); }

/* 설계가 스물을 넘으면 한 줄 목록으로는 고를 수 없다. 카드는 그대로 두고 제목만 사이에 끼운다. */
.template-section { display: grid; gap: 8px; margin-bottom: 16px; }
/* display 를 선언하면 [hidden] 의 기본 display:none 을 이긴다. 검색으로 비워진 섹션이 남는다. */
.template-section[hidden] { display: none; }
.template-section h3 { margin: 0; font-size: 10px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }

/* 축이 전부 0인 이유를 그 자리에서 말하고 고칠 길을 낸다. 근거 절벽 배너와 같은 결이다. */
.idle-note { display: grid; gap: 8px; padding: 11px 12px; border: 1px solid var(--amber); background: color-mix(in srgb, var(--amber) 8%, transparent); }
.idle-note p { margin: 0; font-size: 11px; line-height: 1.5; color: var(--text); }
.idle-note button { justify-self: start; padding: 5px 10px; border: 1px solid var(--line); background: var(--surface-raised); color: var(--text); font: 600 11px/1 var(--font-data); cursor: pointer; }
.idle-note button:hover { border-color: var(--cyan); color: var(--cyan); }
