/* ============================================================
   refine.css — 디자인 개편 레이어 (2026-08)
   하동복합 LNG 직배관 사업 대시보드 · POSCO INTERNATIONAL
   ------------------------------------------------------------
   ▶ 목적
     기존 양식(사이드바 Explorer + 탭 에디터 + 카드 그리드)은 그대로 두고,
     ① 공간 리듬을 하나로 묶고 ② 흩어진 표를 구조·도표로 바꾸며
     ③ 같은 값을 두 번 그리던 "차트 + 표" 중복을 한 컴포넌트로 합친다.

   ▶ 로드 순서 — style.css → dashboard.css → refine.css → type.css
     type.css 가 여전히 글꼴·글자크기의 유일한 소스이므로 이 파일에는
     font-size / font-family 를 두지 않는다. (tests/typography.test.js 가 검증)

   ▶ 색 띠 금지 규칙도 그대로 지킨다 — 등급·상태는 배지와 그룹 구조로만.
   ============================================================ */

:root {
  /* 간격 스케일 — 여백을 눈대중으로 찍지 않기 위한 6단계 */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 22px;
  --sp-6: 30px;

  /* 카드 안쪽 여백 */
  --pad-card: 15px 17px;
}

/* ============================================================
   1. 페이지 리듬 — 패널 · 그리드 · 섹션
   ------------------------------------------------------------
   화면이 넓어질수록 카드 사이 간격은 넓히고 카드 안쪽은 조인다.
   "공간감"은 여백의 총량이 아니라 여백의 위계에서 나온다.
   ============================================================ */
.panel,
.panel[data-tab="overview"],
.panel[data-tab="schedule"],
.panel[data-tab="process"],
.panel[data-tab="monthly"] {
  padding: 20px 30px 60px;
  max-width: 1860px;
  margin: 0 auto;
}

/* 패널 제목 — 스크롤해도 남는 고정 헤더.
   패널 좌우 여백(30px)까지 배경이 덮이도록 음수 마진으로 흘려보낸다. */
.panel-head {
  position: sticky;
  top: 0;
  z-index: 6;
  margin: -20px -30px var(--sp-4);
  padding: 15px 30px 12px;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  min-height: 0;
}
/* 표의 sticky thead 가 고정 헤더 위로 올라오지 않도록 */
table th { z-index: 1; }

.grid { gap: var(--sp-4); }

.card {
  padding: var(--pad-card);
  border-radius: 12px;
  box-shadow: none;
}
.card:hover { box-shadow: none; border-color: var(--border-strong); }
.card > h3 {
  margin-bottom: var(--sp-3);
  padding-bottom: 9px;
  border-bottom: 1px solid var(--border-soft);
}
/* 카드 안 마지막 요소의 군더더기 여백 제거 — 카드 높이가 들쭉날쭉해지는 원인 */
.card > *:last-child { margin-bottom: 0; }

/* 섹션 구분 — 위쪽으로 크게 띄우고 아래는 붙인다.
   덩어리와 덩어리 사이가 카드 사이보다 넓어야 층이 읽힌다. */
.sec-bar { margin: var(--sp-5) 0 -6px; }

/* ============================================================
   2. 표 — 밀도를 올리고 장식을 걷어낸다
   ------------------------------------------------------------
   기존: 헤더에 그라디언트 + 대문자 변환 + 12/16px 패딩.
   한글은 대문자 변환이 무의미하고, 넉넉한 패딩은 행이 몇 줄만 되어도
   카드를 세로로 길게 늘여 한 화면에 들어오지 않게 만든다.
   ============================================================ */
table th {
  background: var(--surface-3);
  color: var(--text-muted);
  padding: 8px 12px;
  text-transform: none;
  letter-spacing: 0.01em;
  border-bottom: 1px solid var(--border-strong);
}
table td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--border-soft);
}
table tr:hover td { background: var(--primary-tint); }
tr.row-total td { background: var(--surface-2); }
tr.row-pick  td { background: var(--primary-tint); }

/* ============================================================
   3. 스펙 그리드 (.sg) — 세로로 긴 key-value 표의 대체물
   ------------------------------------------------------------
   9행짜리 kv 표는 카드 하나를 통째로 먹으면서 오른쪽 절반이 빈다.
   라벨을 값 위로 올리고 2~4열로 접으면 같은 내용이 1/3 높이에 들어간다.
   ============================================================ */
.sg {
  display: grid;
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.sg--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.sg--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.sg--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.sg-i {
  background: var(--surface);
  padding: 9px 12px;
  display: flex; flex-direction: column; gap: 2px;
  min-width: 0;
}
.sg-i--wide { grid-column: 1 / -1; }
.sg-i--key  { background: var(--primary-tint); }
.sg-i--fill { background: var(--surface); }
.sg-l { color: var(--text-muted); }
.sg-v { color: var(--text-strong); word-break: keep-all; }
@media (max-width: 1240px) {
  .sg--3, .sg--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ============================================================
   4. 지표 밴드 (.sb) — 카드 머리에 얹는 한 줄 요약
   ============================================================ */
.sb {
  display: flex; flex-wrap: wrap;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-3);
  margin-bottom: var(--sp-3);
}
.sb-i {
  flex: 1 1 0;
  padding: 9px 13px;
  border-left: 1px solid var(--border);
  min-width: 0;
}
.sb-i:first-child { border-left: 0; }
.sb-l { color: var(--text-muted); display: block; }
/* 값이 길면 칸을 넘지 말고 접히게 한다 (금성BV 부지면적처럼 두 값을 겹쳐 쓴 경우).
   한글은 keep-all 로 어절 단위로만 접는다. */
.sb-v { color: var(--text-strong); display: block; margin-top: 1px; word-break: keep-all; }
.sb-u { color: var(--text-muted); margin-left: 2px; }

/* ============================================================
   5. 구성 막대 (.stk) — 100% 누적 띠 + 범례
   ------------------------------------------------------------
   조성비·구성비처럼 "합이 100" 인 값은 표보다 띠가 빠르다.
   ============================================================ */
.stk-wrap { margin: 2px 0 0; }
.stk {
  display: flex; height: 26px;
  border-radius: 6px; overflow: hidden;
  border: 1px solid var(--border-strong);
}
.stk-s {
  display: flex; align-items: center; justify-content: center;
  min-width: 0; position: relative;
  /* 라벨(nowrap)이 조각보다 길면 옆 조각 위로 넘쳐 두 라벨이 겹친다.
     반폭 카드처럼 띠가 좁아지는 곳에서 실제로 일어나므로 조각 안에 가둔다.
     — 넘칠 만큼 좁은 조각은 애초에 opt.min 으로 라벨을 빼는 것이 우선. */
  overflow: hidden;
  transition: filter .15s;
}
.stk-s + .stk-s { box-shadow: inset 1px 0 0 rgba(255,255,255,.85); }
.stk-s:hover { filter: brightness(1.08); }
.stk-l { color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.28); white-space: nowrap; }
.stk-l--dark { color: var(--text-strong); text-shadow: none; }
.stk-lg { display: flex; flex-wrap: wrap; gap: 5px 15px; margin-top: 9px; }
.stk-lg-i { display: inline-flex; align-items: baseline; gap: 6px; color: var(--text-muted); }
.stk-dot { width: 9px; height: 9px; border-radius: 2px; flex: none; transform: translateY(1px); }
.stk-lg-v { color: var(--text-strong); }

/* ============================================================
   6. 순위 막대 (.rb) — "차트 + 같은 값의 표" 중복을 대체
   ------------------------------------------------------------
   기존 사업비·시공계획·EPC 탭은 ECharts 막대 하나와, 같은 숫자를 그대로
   반복하는 표 하나를 나란히 두어 카드 두 장을 썼다.
   막대를 표 안으로 넣으면 카드 한 장에서 순위와 정확한 값을 동시에 읽는다.
   ============================================================ */
.rb { display: flex; flex-direction: column; }
.rb-row {
  display: grid;
  grid-template-columns: var(--rb-lab, 150px) minmax(0, 1fr) var(--rb-val, 104px);
  align-items: center; gap: 12px;
  padding: 7px 0;
  border-bottom: 1px solid var(--border-soft);
}
.rb-row:last-child { border-bottom: 0; }
.rb-row--pick { background: var(--primary-tint); }
.rb-l { color: var(--text-strong); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rb-l i { color: var(--text-muted); font-style: normal; margin-left: 5px; }
/* 보조 설명(물량 · 공법)이 길면 라벨 아래 줄로 내린다 — 잘라 버리면 정보가 사라진다 */
.rb-row--lab2 .rb-l { white-space: normal; word-break: keep-all; line-height: 1.3; }
.rb-row--lab2 .rb-l i { display: block; margin: 1px 0 0; }
.rb-track { height: 14px; background: var(--surface-2); border-radius: 3px; overflow: hidden; position: relative; }
.rb-track > i { display: block; height: 100%; border-radius: 3px; min-width: 2px; }
.rb-mark { position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--danger); opacity: .8; }
.rb-v { color: var(--text-strong); text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.rb-v i { color: var(--text-muted); font-style: normal; margin-left: 5px; }
.rb-foot { display: flex; justify-content: space-between; gap: 12px; color: var(--text-muted); margin-top: 8px; padding-top: 7px; border-top: 1px dashed var(--border); }
@media (max-width: 1240px) { .rb-row { grid-template-columns: 116px minmax(0,1fr) 88px; } }

/* 표 안 막대 셀 (.bc) — 표를 그대로 두고 크기 비교만 얹는다 */
.bc { display: grid; grid-template-columns: minmax(40px, 1fr) auto; align-items: center; gap: 8px; }
.bc-t { height: 10px; background: var(--surface-2); border-radius: 3px; overflow: hidden; position: relative; }
.bc-t > i { display: block; height: 100%; border-radius: 3px; min-width: 2px; }
.bc-m { position: absolute; top: -2px; bottom: -2px; width: 2px; background: var(--danger); opacity: .85; }
.bc-v { color: var(--text-strong); white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ============================================================
   7. 칩 목록 (.cl) — 목록형 산문을 눌러 담는다
   ------------------------------------------------------------
   과업범위·향후계획처럼 "짧은 문장 8개"는 박스 8개보다 칩 8개가 낫다.
   ============================================================ */
.cl { display: flex; flex-wrap: wrap; gap: 6px; }
.cl-i {
  display: inline-flex; align-items: baseline; gap: 6px;
  background: var(--surface-3);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px 12px;
  color: var(--text);
  max-width: 100%;
}
.cl-i > b { color: var(--primary-dark); flex: none; }

/* 번호 붙은 목록 (.nl) — 순서가 있는 절차 */
.nl { display: grid; gap: 6px; }
.nl--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.nl--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.nl-i {
  display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: 9px;
  align-items: baseline;
  padding: 6px 10px;
  background: var(--surface-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.nl-n {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 5px;
  background: var(--primary-soft); color: var(--primary-dark);
}
.nl-t { color: var(--text); }
@media (max-width: 1240px) { .nl--3 { grid-template-columns: repeat(2, minmax(0,1fr)); } }

/* ============================================================
   8. 콜아웃 (.co) — 전폭 배너를 줄인 각주형 안내
   ============================================================ */
.co {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 9px;
  align-items: start;
  padding: 9px 13px;
  border-radius: var(--radius-sm);
  background: var(--primary-tint);
  border: 1px solid var(--primary-soft);
  color: var(--text);
}
.co-k { color: var(--primary-dark); white-space: nowrap; }
.co--warn { background: var(--warning-soft); border-color: var(--warning-border); }
.co--warn .co-k { color: #8a5a12; }
.co--ok { background: var(--success-soft); border-color: var(--success-border); }
.co--ok .co-k { color: #256b3d; }
.co--plain { background: var(--surface-3); border-color: var(--border); }
.co--plain .co-k { color: var(--text-muted); }

/* 기존 전폭 배너도 같은 밀도로 낮춘다 */
.info-banner { padding: 9px 13px; border-radius: var(--radius-sm); }

/* ============================================================
   9. 시추주상도 (.blg) — 지반조사 표의 시각화
   ------------------------------------------------------------
   "0.0~17.0 m 매립" 같은 문자열은 깊이 비교가 안 된다.
   같은 축척의 기둥으로 그리면 어느 공이 얕고 깊은지 한눈에 보인다.
   ============================================================ */
.blg { display: grid; gap: 16px; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.blg-i { min-width: 0; }
.blg-h { display: flex; align-items: baseline; gap: 7px; margin-bottom: 6px; }
.blg-id { color: var(--text-strong); }
.blg-loc { color: var(--text-muted); }
.blg-body { display: grid; grid-template-columns: 36px minmax(0, 1fr); gap: 6px; }
.blg-ax { position: relative; }
.blg-tick { position: absolute; right: 0; transform: translateY(-50%); color: var(--text-muted); white-space: nowrap; }
.blg-col {
  position: relative;
  border: 1px solid var(--border-strong);
  border-radius: 4px;
  overflow: hidden;
  background: var(--surface-2);
}
.blg-lay { position: absolute; left: 0; right: 0; display: flex; align-items: center; padding: 0 7px; overflow: hidden; }
.blg-lay + .blg-lay { box-shadow: inset 0 1px 0 rgba(255,255,255,.65); }
.blg-lay span { color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.32); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.blg-lay--light span { color: var(--text-strong); text-shadow: none; }
.blg-m { display: flex; flex-wrap: wrap; gap: 3px 10px; margin-top: 7px; color: var(--text-muted); }
.blg-m b { color: var(--text-strong); }
@media (max-width: 1240px) { .blg { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* 리스크 등록부 — 등급 그룹 안에서 2열로 흘린다 */
.rkg-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.rkg-list .rk { margin: 0; padding: 11px 13px; background: var(--surface-3); }
.rkg-list .rk-t { min-width: 0; }
@media (max-width: 1240px) { .rkg-list { grid-template-columns: minmax(0, 1fr); } }

/* 접어 둔 상세 (.fx-more) — 요약을 먼저 보여 주고 원표는 필요할 때만 편다 */
.fx-more > summary {
  cursor: pointer; list-style: none;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface-3);
  color: var(--text-muted); user-select: none;
}
.fx-more > summary::-webkit-details-marker { display: none; }
.fx-more > summary::before { content: "▸"; color: var(--primary); }
.fx-more[open] > summary::before { content: "▾"; }
.fx-more > summary:hover { border-color: var(--border-strong); color: var(--text); }
.fx-more[open] > summary { margin-bottom: 10px; }
/* 접힌 채로도 "안에 무엇이 몇 건 있는지"는 보이게 한다 — 접기가 은폐가 되지 않도록 */
.fx-meta { font-style: normal; color: var(--text-muted); opacity: .8; margin-left: 2px; }
.fx-meta::before { content: "· "; }

/* ============================================================
   10. 특수구간 카드 — 세로 목록 → 2열 + 공기 막대
   ============================================================ */
.spg { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.sp2 {
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 11px 13px; background: var(--surface-3);
  display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 10px;
}
.sp2--high { border-color: var(--danger-border); background: #fdf7f7; }
.sp2-n {
  width: 26px; height: 26px; border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--primary-soft); color: var(--primary-dark);
}
.sp2--high .sp2-n { background: var(--danger-soft); color: var(--danger); }
.sp2-h { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.sp2-t { color: var(--text-strong); }
.sp2-len { color: var(--text-muted); }
.sp2-note { color: var(--text-muted); margin: 3px 0 8px; }
.sp2-bar { display: grid; grid-template-columns: minmax(0,1fr) auto; gap: 9px; align-items: center; }
.sp2-track { height: 8px; background: var(--surface-2); border-radius: 999px; overflow: hidden; }
.sp2-track > i { display: block; height: 100%; border-radius: 999px; }
.sp2-dur { color: var(--text-strong); white-space: nowrap; }
@media (max-width: 1240px) { .spg { grid-template-columns: minmax(0, 1fr); } }

/* Baseline 카드 — 반폭 카드 안에서는 세로로 쌓는다 */
.bl-grid--1 { grid-template-columns: minmax(0, 1fr); }
.bl-grid--1 .bl-g { grid-template-columns: repeat(3, minmax(0, 1fr)); }

/* 추진 단계 · 조직도 — 반폭 카드 밀도.
   조직도는 auto-fit 이면 7개가 5+2 로 접혀 마지막 줄이 늘어난다 → 4열 고정(4+3). */
.ph-card { padding: 10px 12px; margin-bottom: 8px; }
.org { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.org-c { padding: 9px 8px; }

/* ============================================================
   11. 파일 탐색기 — 한 줄 목록 → 2열 그리드
   ============================================================ */
.fx-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 18px; }
@media (max-width: 1240px) { .fx-list { grid-template-columns: minmax(0, 1fr); } }

/* ============================================================
   12. 목록형 컴포넌트 여백 축소
   ============================================================ */
.scope-grid { gap: 6px; }
.org { gap: 8px; }
.proc { gap: 6px; }

/* ============================================================
   13. Value Engineering — 밀도 개편
   기존 28장 카드가 7,500px(8.6화면)였다. 문단으로 길던 판정·규정판단·
   게이트를 요약 행으로 접고, 계산 전개는 .fx-more 로 내린다.
   ============================================================ */

/* 판정 밴드 — 판정 · 성립조건 · KPI 를 한 카드에 */
.ve-top { border-left: 3px solid var(--warning); }
.ve-top.ve-verdict--ok { border-left-color: var(--success); }
.ve-top.ve-verdict--bad { border-left-color: var(--danger); }
.ve-vdr { display: flex; align-items: baseline; gap: 11px; flex-wrap: wrap; }
.ve-vdr .ve-vd-l { flex: none; padding: 3px 11px; border-radius: 20px;
  background: var(--warning-soft); color: #8a5a12; }
.ve-top.ve-verdict--ok .ve-vd-l { background: var(--success-soft); color: #23663a; }
.ve-vdr .ve-vd-v { color: var(--text-strong); letter-spacing: -.02em; }
.ve-vdr .ve-vd-t { color: var(--text-muted); }

.ve-conds { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px; margin: 11px 0 13px; }
.ve-cond { display: flex; gap: 9px; align-items: baseline;
  padding: 9px 12px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--surface-3); }
.ve-cond-k { flex: none; padding: 1px 8px; border-radius: 4px;
  background: var(--primary-soft); color: var(--primary-dark); white-space: nowrap; }
.ve-cond-t { color: var(--text); word-break: keep-all; }
@media (max-width: 1240px) { .ve-conds { grid-template-columns: minmax(0, 1fr); } }

/* 최우선 확인 — 충돌하는 두 수치를 값 대비 막대로 */
.ve-rf-cmp { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px; margin: 11px 0 10px; }
.ve-rf-c { padding: 10px 13px; border: 1px solid var(--border);
  border-radius: var(--radius); background: var(--surface); min-width: 0; }
.ve-rf-cv { color: var(--text-strong); letter-spacing: -.02em; line-height: 1.15; }
.ve-rf-ci { color: var(--text); margin-top: 2px; }
.ve-rf-cb { height: 8px; margin: 8px 0 6px; border-radius: 999px;
  background: var(--surface-2); overflow: hidden; }
.ve-rf-cb > i { display: block; height: 100%; border-radius: 999px; min-width: 3px; }
.ve-rf-cs { color: var(--text-muted); word-break: keep-all; }

/* 성립 조건 진행 — 막힌 관문만 추려 올린다 */
.ve-crit { display: flex; flex-direction: column; gap: 6px; margin: 13px 0 0; }
.ve-crit-i { display: flex; align-items: baseline; gap: 8px; min-width: 0;
  padding: 7px 10px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--surface-3); }
.ve-crit-i b { color: var(--text-strong); min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.ve-crit-i i { font-style: normal; color: var(--text-muted); margin-left: auto;
  white-space: nowrap; }

/* 규정 판단 — 3열 문단 카드 → 판정 행 + 접은 근거 */
.ve-rl { display: flex; flex-direction: column; gap: 10px; }
.ve-rl-i { padding: 11px 13px; border: 1px solid var(--border);
  border-radius: var(--radius); background: var(--surface-3); }
.ve-rl-i.ve-rule--ok { border-color: var(--success-border); background: #f4faf5; }
.ve-rl-i.ve-rule--warn { border-color: var(--warning-border); background: #fdfaf4; }
.ve-rl-h { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.ve-rl-h b { color: var(--text-strong); word-break: keep-all; }
.ve-rl-h .ve-rv { margin-left: auto; white-space: nowrap; }
.ve-rl-i .ve-code { margin-top: 4px; }
.ve-rl-i .ve-quote { margin: 8px 0 9px; }

/* 게이트 — 3열 카드 → 2열 요약 행 */
.ve-gt { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.ve-gt-i { display: flex; gap: 10px; align-items: flex-start; min-width: 0;
  padding: 9px 12px; border: 1px solid var(--border);
  border-radius: var(--radius); background: var(--surface-3); }
.ve-gt-i--done { border-color: var(--success-border); background: #f4faf5; }
.ve-gt-i--ing { border-color: var(--warning-border); background: #fdfaf4; }
.ve-gt-n { flex: none; min-width: 26px; text-align: center; padding: 2px 6px;
  border-radius: 5px; background: var(--surface-2); color: var(--primary-dark); }
.ve-gt-b { min-width: 0; }
.ve-gt-h { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; }
.ve-gt-h b { color: var(--text-strong); word-break: keep-all; }
.ve-gt-x { flex: none; padding: 1px 7px; border-radius: 4px;
  background: var(--danger-soft); color: #9c3a3a; white-space: nowrap; }
.ve-gt-c { color: var(--text-muted); margin-top: 3px; word-break: keep-all; }
@media (max-width: 1240px) { .ve-gt { grid-template-columns: minmax(0, 1fr); } }

/* 접기 묶음 — 접힌 상태에서 한 줄씩 나란히 쌓인다 */
.ve-folds { display: flex; flex-direction: column; gap: 8px; margin-top: 13px; }
.ve-folds > .fx-more { padding-top: 8px; border-top: 1px dashed var(--border); }
.ve-folds > .fx-more:first-child { padding-top: 0; border-top: 0; }
/* 두 식 전개는 펼쳤을 때만 2열 */
.ve-fbs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
@media (max-width: 1240px) { .ve-fbs { grid-template-columns: minmax(0, 1fr); } }
/* 계산 상세를 접기 안에 넣으면 폭이 좁아지므로 3열 → 2열 */
.fx-more .ve-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* ============================================================
   15. 계획 대비 실적 막대 (.pl) — 진도율 표의 대체물
   ------------------------------------------------------------
   "막대 하나 + 옆에 계획/실적 두 칸짜리 표" 를 한 줄로 합쳤다.
   옅은 띠가 계획, 진한 띠가 실적, 눈금이 계획 지점 — 실적이 눈금을
   못 넘긴 만큼이 지연이다. 색은 상태를 보조할 뿐, 오른쪽 %p 숫자가
   같은 사실을 글자로도 말한다 (색에만 의존하지 않기).
   ============================================================ */
.pl { display: flex; flex-direction: column; gap: 7px; }
.pl-lg {
  display: flex; gap: 14px; align-items: center;
  margin-bottom: 2px; color: var(--text-muted);
}
.pl-lg span { display: inline-flex; align-items: center; gap: 5px; }
.pl-lg-s { width: 14px; height: 8px; border-radius: 2px; }
/* 「실적」은 상태에 따라 색이 바뀌므로 범례도 세 칸을 나란히 보여준다 —
   범례 색과 막대 색이 어긋나면 범례가 거짓말을 하게 된다. */
.pl-lg-act { gap: 4px !important; }
.pl-lg-act .pl-lg-s { width: 11px; margin-left: 0; }
.pl-lg-act .pl-lg-s + .pl-lg-s { margin-left: -2px; }
.pl-lg-act b { margin-left: 2px; color: var(--text-soft); }   /* 굵기는 type.css */
.pl-lg-m { width: 2px; height: 12px; background: var(--text-strong); opacity: 0.55; }
.pl-lg-est { margin-left: auto; gap: 6px !important; color: var(--text-muted); }

.pl-row {
  display: grid;
  grid-template-columns: var(--pl-lab, 148px) minmax(0, 1fr) 78px 96px;
  align-items: center;
  gap: 10px;
}
.pl-l { color: var(--text); min-width: 0; }
.pl-l i { display: block; color: var(--text-muted); font-style: normal; }

.pl-track {
  position: relative;
  height: 16px;
  border-radius: 4px;
  background: var(--surface-2);
  overflow: hidden;
}
.pl-track > i { position: absolute; top: 0; bottom: 0; left: 0; border-radius: 4px; }
.pl-plan { background: var(--primary-soft); }
.pl-act--ok   { background: var(--success); }
.pl-act--warn { background: var(--warning); }
.pl-act--late { background: var(--danger); }
/* 계획 지점 눈금 — 트랙 위 어디까지가 "제때" 인지 */
.pl-mark {
  width: 2px; left: 0; background: var(--text-strong);
  border-radius: 0 !important; opacity: 0.55;
}

.pl-v { text-align: right; color: var(--text-strong); font-variant-numeric: tabular-nums; }
.pl-v em { font-style: normal; color: var(--text-muted); margin-left: 1px; }
.pl-gap { display: block; font-style: normal; font-variant-numeric: tabular-nums; }
.pl-gap--ok   { color: var(--success-dark); }
.pl-gap--warn { color: var(--warning-dark); }
.pl-gap--late { color: var(--danger-dark); }
.pl-s { display: flex; gap: 4px; align-items: center; justify-content: flex-end; flex-wrap: wrap; }
.pl-foot { margin-top: 10px; color: var(--text-muted); }

@media (max-width: 1100px) {
  .pl-row { grid-template-columns: 112px minmax(0, 1fr) 66px; }
  .pl-s { display: none; }
}

/* ============================================================
   16. 카드 세트 (.cs) — 성격이 같은 과제 2~4건을 나란히
   ------------------------------------------------------------
   카드 안 순서는 언제나 「제목 → 효과 → 지표 → 각주」로 고정한다.
   등급·상태는 좌측 색 띠가 아니라 머리의 배지로만 말한다.
   ============================================================ */
.cs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--sp-3);
}
.cs-i {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 13px;
  background: #fff;
  display: flex; flex-direction: column; gap: 6px;
}
.cs-i--warn { background: var(--warning-soft); border-color: var(--warning-border); }
.cs-i--ok   { background: var(--success-soft); border-color: var(--success-border); }
.cs-h { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.cs-t { color: var(--text-strong); word-break: keep-all; }
.cs-e { color: var(--text); word-break: keep-all; }
.cs-m {
  color: var(--text-strong);
  padding: 4px 8px;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.72);
  border: 1px solid var(--border-soft);
  align-self: flex-start;
}
.cs-i:not([class*="--warn"]):not([class*="--ok"]) .cs-m { background: var(--surface-3); }
.cs-n { color: var(--text-muted); word-break: keep-all; margin-top: auto; }

/* ============================================================
   18. 패널 안 가로 탭 (.stx) — 세로 스크롤을 가로 전환으로
   ------------------------------------------------------------
   탭 하나가 화면 여러 장을 담을 때, 아래로 잇는 대신 옆으로 나눈다.
   막대는 카드가 아니라 패널 폭 전체를 쓰고, 활성 칸만 아래 밑줄로 말한다
   (색 띠가 아니라 굵기·밑줄·배경으로 — 색 단독 의존 금지 규칙 유지).
   ============================================================ */
.stx { margin-top: 2px; }
.stx-bar {
  display: flex;
  align-items: stretch;
  gap: 2px;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--sp-4);
}
.stx-t {
  appearance: none;
  border: 1px solid transparent;
  border-bottom: none;
  background: transparent;
  color: var(--text-muted);
  padding: 8px 15px 9px;
  border-radius: 8px 8px 0 0;
  cursor: pointer;
  display: flex;
  align-items: baseline;
  gap: 7px;
  margin-bottom: -1px;
  white-space: nowrap;
  transition: background .12s, color .12s;
}
.stx-t:hover { background: var(--primary-tint); color: var(--text); }
.stx-t.active {
  background: var(--surface);
  border-color: var(--border);
  color: var(--text-strong);
  box-shadow: inset 0 2px 0 var(--primary);
}
.stx-l { display: block; }
.stx-m { color: var(--text-soft); font-style: normal; }
.stx-t.active .stx-m { color: var(--primary-dark); }
.stx-note { margin-left: auto; align-self: center; color: var(--text-soft); padding: 0 4px 6px; }
/* 칸 전환 — 숨긴 칸은 레이아웃에서 완전히 빠져야 높이가 남지 않는다 */
.stx-p { display: none; }
.stx-p.active { display: block; }
/* 카드 안에 든 sub-tab(요약 카드의 「이번 달 / 다음 달」 류)은 여백을 조인다 */
.card .stx-bar { margin-bottom: var(--sp-3); }
.card .stx-t { padding: 5px 11px 6px; }

/* ============================================================
   19. 도해 (.fig) — 지도 · 횡단계획도 · 현장사진
   ------------------------------------------------------------
   착수회의 자료의 그림을 캡션·출처와 한 덩어리로 묶는다. 이미지는
   원본 비율을 유지한 채 카드 폭에 맞추고, 누르면 원본이 새 탭에서 열린다.
   ============================================================ */
.fig {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--sp-3);
}
.fig--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.fig--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.fig-i {
  margin: 0;
  border: 1px solid var(--border);
  border-radius: 9px;
  overflow: hidden;
  background: var(--surface-3, #f7f9fc);
  display: flex;
  flex-direction: column;
}
.fig-a { display: block; line-height: 0; background: #0e1726; }
.fig-a img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 420px;
  object-fit: contain;
  transition: opacity .12s;
}
.fig-i--tall .fig-a img { max-height: 560px; }
.fig-a:hover img { opacity: .9; }
.fig-c {
  padding: 9px 11px 10px;
  background: var(--surface);
  border-top: 1px solid var(--border-soft);
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.fig-c b { color: var(--text-strong); }
.fig-c span { color: var(--text); word-break: keep-all; }
.fig-s { color: var(--text-soft); font-style: normal; margin-top: 1px; }

@media (max-width: 1200px) {
  .fig--2, .fig--3 { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================
   20. 종합현황 — 한 화면 배치
   ------------------------------------------------------------
   상태 스트립 1줄 + 카드 3열 × 2행. 카드 높이를 뷰포트에서 계산해
   두 행이 항상 한 화면에 들어오게 하고, 넘치는 목록은 카드 안에서만
   스크롤한다. (원본 「광양 제2 LNG터미널 종합현황」 화면과 같은 규칙)
   ============================================================ */
.panel[data-tab="overview"] { padding-bottom: 24px; }

/* ── 상태 스트립 ── */
.ovs {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  padding: 11px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  flex-wrap: wrap;
}
.ovs-i { display: flex; align-items: baseline; gap: 8px; }
.ovs-l { color: var(--text-muted); }
.ovs-v { color: var(--text-strong); }
.ovs-s { color: var(--text-muted); }
.ovs-i--main { gap: 10px; }
.ovs-big { color: var(--primary-dark); letter-spacing: -0.02em; line-height: 1; }
.ovs-u { color: var(--text-muted); margin-left: 2px; }
.ovs-s--ok   { color: var(--success-dark); }
.ovs-s--warn { color: var(--warning-dark); }
.ovs-s--late { color: var(--danger-dark); }
.ovs-sep { width: 1px; align-self: stretch; background: var(--border); }
.ovs-d {
  font-style: normal;
  color: var(--primary-dark);
  background: var(--primary-tint);
  border: 1px solid var(--primary-soft);
  border-radius: 5px;
  padding: 1px 6px;
}
.ovs-d--past { color: var(--text-muted); background: var(--surface-3, #f2f5f9); border-color: var(--border); }
.ovs-d--now  { color: var(--warning-dark); background: var(--warning-soft); border-color: var(--warning-border); }
.ovs-tail { margin-left: auto; display: flex; gap: 6px; align-items: center; }

/* 인허가 · 리스크 3칸 */
.ovg { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-2); }
.ovg-i {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 10px 9px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--surface-3, #f7f9fc);
}
.ovg-l { color: var(--text-muted); }
.ovg-v { color: var(--text-strong); line-height: 1.05; letter-spacing: -0.02em; }
.ovg-v i { font-style: normal; color: var(--text-muted); margin-left: 3px; }
.ovg-v--red    { color: var(--danger-dark); }
.ovg-v--orange { color: var(--warning-dark); }
.ovg-s { color: var(--text-muted); }

/* ============================================================
   21. 노선안 비교 (.ropt) — 기본안 ↔ 대안을 같은 축척으로
   ------------------------------------------------------------
   두 안의 총연장을 같은 눈금 위에 놓아야 "250 m 차이"가 눈에 보인다.
   막대 안은 관리소를 경계로 두 구간(터미널~BV / BV~발전소)으로 나눈다.
   ============================================================ */
.ropt { display: flex; flex-direction: column; gap: var(--sp-3); margin-top: var(--sp-3); }
.ropt-i {
  border: 1px solid var(--border);
  border-radius: 9px;
  padding: 9px 11px 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ropt-i--pick { border-color: var(--primary-soft); background: var(--primary-tint); }
.ropt-h { display: flex; align-items: baseline; gap: 7px; }
.ropt-h b { color: var(--text-strong); }
.ropt-t { margin-left: auto; color: var(--text-strong); font-variant-numeric: tabular-nums; }
.ropt-tr { width: 100%; }
.ropt-bar { display: flex; height: 22px; border-radius: 5px; overflow: hidden; }
.ropt-bar i {
  font-style: normal;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  white-space: nowrap;
}
.ropt-n { display: flex; gap: 10px; align-items: baseline; }
.ropt-n span { color: var(--text-muted); }
.ropt-n b { margin-left: auto; color: var(--text-strong); white-space: nowrap; }

/* 특수구간 카드 1열 배치 (반폭 카드 안에 들어갈 때) */
.spg--1 { grid-template-columns: minmax(0, 1fr) !important; }

/* ============================================================
   22. 종합현황 — 카드 6장 · 스크롤 없음 · 행 높이 동일
   ------------------------------------------------------------
   카드마다 높이를 같은 값으로 고정하고(가로 행 간격 동일),
   그 안에서도 스크롤하지 않는다. 넘칠 내용은 잘라 버리는 게 아니라
   한 줄 행으로 압축하거나 카드 안 sub-tab 으로 나눈다.
   ============================================================ */
.ov-c {
  /* 두 행 + 스트립이 항상 한 화면에 들어오도록 뷰포트에서 역산한다.
     316px = 패널 상하 여백 + 패널 머리 + 스트립 + 그리드 간격 3칸 */
  height: clamp(300px, calc((100vh - 296px) / 2), 404px);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
/* 종합현황만 글자를 줄이던 것을 되돌렸으므로(전 탭 글꼴 통일),
   한 화면에 담는 몫은 여백이 진다 — 제목 아래 간격을 한 단계 좁힌다 */
.ov-c > h3 { flex: 0 0 auto; margin-bottom: 8px; }
/* 카드 본문(제목 뒤 형제들)은 남은 높이를 나눠 갖고, 스스로 넘치지 않는다 */
.ov-c > *:not(h3) { min-height: 0; }
.ov-c .stx { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }
.ov-c .stx-body { min-height: 0; }

/* ── 게이지 + 요약 3칸 ──────────────────────────────────
   게이지는 높이를 고정하지 않고 **카드가 남긴 높이를 전부 쓴다**.
   118px 로 못 박아 두었더니 화면이 커져 카드가 404px 까지 늘어나도
   반원만 그대로여서 카드 아래가 비었다 (게이지 반지름은 컨테이너의
   짧은 변으로 정해지므로, 높이를 안 주면 반원이 안 커진다).
   app.js 의 progressGauge 가 실제 높이를 읽어 띠 두께·가운데 숫자를
   같이 키우므로, 여기서는 자리만 내주면 된다. */
.ovgz { display: grid; grid-template-columns: minmax(0, 1fr) 104px; align-items: center; gap: 10px; }
.ov-c .ovgz { flex: 1 1 auto; align-items: stretch; min-height: 132px; margin: 2px 0 0; }
.ov-c .ovgz-k { align-self: center; }
.ov-gauge { height: 118px; margin: -4px 0 -6px; }
.ov-c .ov-gauge { height: 100%; min-height: 132px; margin: 0; }
.ovgz-k { display: flex; flex-direction: column; gap: 5px; }
.ovgz-k > div {
  display: flex; align-items: baseline; justify-content: space-between; gap: 6px;
  padding: 4px 8px; border-radius: 6px;
  background: var(--surface-3); border: 1px solid var(--border);
}
.ovgz-k span { color: var(--text-muted); display: inline-flex; align-items: center; }
/* 링의 두 색과 짝을 맞추는 표식. 색값은 app.js 의 progressGauge TONE 과
   같은 값이다 — 한쪽만 고치면 링과 범례가 다른 색이 된다. */
.ovgz-sw { width: 9px; height: 9px; border-radius: 3px; margin-right: 5px; flex: 0 0 auto; }
.ovgz--ok   .ovgz-sw--act  { background: var(--success); }
.ovgz--warn .ovgz-sw--act  { background: var(--warning); }
.ovgz--late .ovgz-sw--act  { background: var(--danger); }
.ovgz--ok   .ovgz-sw--plan { background: #a8d8bb; }
.ovgz--warn .ovgz-sw--plan { background: #f0d9b0; }
.ovgz--late .ovgz-sw--plan { background: #f0c2bb; }
.ovgz-k b { color: var(--text-strong); font-variant-numeric: tabular-nums; }
.ovgz-k--ok   { background: var(--success-soft) !important; border-color: var(--success-border) !important; }
.ovgz-k--ok b { color: var(--success-dark); }
.ovgz-k--warn { background: var(--warning-soft) !important; border-color: var(--warning-border) !important; }
.ovgz-k--warn b { color: var(--warning-dark); }
.ovgz-k--late { background: var(--danger-soft) !important; border-color: var(--danger-border) !important; }
.ovgz-k--late b { color: var(--danger-dark); }

/* ── 단계별 계획대비 (압축판) ── */
.ovpl { display: flex; flex-direction: column; margin-top: 8px; flex: 0 0 auto; }
.ovpl-r {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 84px 62px;
  align-items: center; gap: 9px;
  padding: 3px 0;
  border-top: 1px solid var(--border-soft);
}
.ovpl-r:first-child { border-top: 0; }
.ovpl-l { color: var(--text-strong); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ovpl-t { position: relative; height: 11px; background: var(--surface-2, #eef1f6); border-radius: 3px; overflow: hidden; }
.ovpl-t > i { position: absolute; top: 0; left: 0; height: 100%; border-radius: 3px; }
.ovpl-plan { background: #ccd6e6; }
.ovpl-act--ok   { background: var(--success); }
.ovpl-act--warn { background: var(--warning); }
.ovpl-act--late { background: var(--danger); }
.ovpl-mk { top: -2px !important; height: 15px !important; width: 2px; background: var(--text-strong); opacity: .55; border-radius: 0 !important; }
.ovpl-v { text-align: right; color: var(--text-strong); font-variant-numeric: tabular-nums; white-space: nowrap; }
.ovpl-v em { font-style: normal; color: var(--text-muted); margin: 0 1px 0 1px; }
.ovpl-g { font-style: normal; margin-left: 3px; }
.ovpl-g--ok   { color: var(--success-dark); }
.ovpl-g--warn { color: var(--warning-dark); }
.ovpl-g--late { color: var(--danger-dark); }
.ovpl-g::after { content: "%p"; }

/* ── 상태 비율 한 줄 (띠 + 같은 줄 범례) ── */
.ovrt { margin-top: 11px; }
.ovrt-h { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; flex-wrap: wrap; }
.ovrt-h > span:first-child { color: var(--text-muted); }
.ovrt-lg { margin-left: auto; display: flex; gap: 9px; color: var(--text-muted); }
.ovrt-lg i { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 3px; }
.ovrt-lg b { color: var(--text-strong); }
.ovrt-b { display: flex; height: 20px; border-radius: 4px; overflow: hidden; background: var(--surface-2, #eef1f6); }
.ovrt-b > span {
  display: flex; align-items: center; justify-content: center;
  color: #fff; overflow: hidden; white-space: nowrap;
}

/* ── 마일스톤 한 줄 행 ── */
.ovm { display: flex; flex-direction: column; gap: 2px; }
.ovm-i {
  display: grid;
  grid-template-columns: 50px auto minmax(0, 1fr) auto;
  align-items: center; gap: 7px;
  padding: 5px 7px;
  border-radius: 6px;
  border: 1px solid transparent;
}
.ovm-i:nth-child(odd) { background: var(--surface-3); }
.ovm-i--hot { background: var(--warning-soft); border-color: var(--warning-border); }
.ovm-d { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.ovm-disc {
  color: var(--primary-dark); background: var(--primary-tint);
  border-radius: 4px; padding: 1px 5px; white-space: nowrap;
}
.ovm-t { color: var(--text-strong); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── 공정 갭 — 0 을 가운데 축으로 둔 편차 막대 ── */
.ovgap {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  border: 1px solid var(--border); border-radius: 9px; padding: 8px 12px 9px;
}
.ovgap--ok   { background: var(--success-soft); border-color: var(--success-border); }
.ovgap--warn { background: var(--warning-soft); border-color: var(--warning-border); }
.ovgap--late { background: var(--danger-soft);  border-color: var(--danger-border); }
.ovgap-l { display: flex; flex-direction: column; gap: 1px; }
.ovgap-l b { color: var(--text-strong); }
.ovgap-l span { color: var(--text-muted); }
.ovgap-v { line-height: 1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ovgap--ok   .ovgap-v { color: var(--success-dark); }
.ovgap--warn .ovgap-v { color: var(--warning-dark); }
.ovgap--late .ovgap-v { color: var(--danger-dark); }
.ovgap-u { margin-left: 2px; color: var(--text-muted); }

.ovgb { display: flex; flex-direction: column; margin-top: 10px; }
.ovgb-r {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 96px 54px;
  align-items: center; gap: 9px;
  padding: 5px 0;
  border-top: 1px solid var(--border-soft);
}
.ovgb-r:first-child { border-top: 0; }
.ovgb-r--worst .ovgb-l { color: var(--danger-dark); }
.ovgb-l { color: var(--text-strong); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ovgb-t { position: relative; height: 13px; background: var(--surface-2, #eef1f6); border-radius: 3px; }
.ovgb-ax { position: absolute; left: 50%; top: -2px; bottom: -2px; width: 1px; background: var(--text-soft); }
.ovgb-b { position: absolute; top: 2px; bottom: 2px; border-radius: 2px; }
.ovgb-b--ok   { background: var(--success); }
.ovgb-b--warn { background: var(--warning); }
.ovgb-b--late { background: var(--danger); }
.ovgb-v { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ovgb-v--ok   { color: var(--success-dark); }
.ovgb-v--warn { color: var(--warning-dark); }
.ovgb-v--late { color: var(--danger-dark); }
.ovgb-f { margin-top: 8px; color: var(--text-muted); }

/* ── 노선 카드 ── */
.ovr { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: var(--sp-3); }
.ovr-map {
  position: relative; display: block; line-height: 0;
  border: 1px solid var(--border); border-radius: 8px; overflow: hidden; background: #0e1726;
}
.ovr-map img { display: block; width: 100%; height: 132px; object-fit: contain; }
.ovr-map-x {
  position: absolute; right: 6px; bottom: 6px; line-height: 1;
  color: #fff; background: rgba(14, 23, 38, .68);
  border-radius: 4px; padding: 3px 6px; opacity: 0; transition: opacity .12s;
}
.ovr-map:hover .ovr-map-x { opacity: 1; }
.ovr-k { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; align-content: start; }
.ovr-k > div {
  border: 1px solid var(--border); border-radius: 7px;
  padding: 5px 8px 6px; background: var(--surface-3);
  display: flex; flex-direction: column; gap: 0;
  min-width: 0;
}
.ovr-k span, .ovr-k i { color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ovr-k i { font-style: normal; color: var(--text-soft); }
.ovr-k b { color: var(--text-strong); line-height: 1.15; white-space: nowrap; }
/* 카드 안에서는 노선 프로파일을 얕게 — 핀 라벨은 좁은 폭에서 겹쳐 읽히지
   않으므로 접는다 (노선 탭이 전폭으로 다시 그린다) */
.ovr-strip { margin-top: 10px; }
.ovr-strip .rs-wrap { padding: 0 2px; }
.ovr-strip .rs-pins { display: none; }
.ovr-strip .rs-track { height: 19px; }
.ovr-strip .rs-lg-note { display: none; }

/* 좁은 화면에서는 한 화면 규칙을 풀고 자연스럽게 흐르게 한다 */
@media (max-width: 1500px) {
  .panel[data-tab="overview"] .grid > .ov-c { grid-column: span 6; }
  .ov-c { height: auto; overflow: visible; display: block; }
  /* 카드가 flex 를 놓으면 height:100% 의 기준이 사라져 게이지가 0 이 된다
     → 이 폭에서는 다시 고정 높이로 (기존보다 넉넉하게) 되돌린다 */
  .ov-c .ov-gauge { height: 172px; }
}
@media (max-width: 1000px) {
  .panel[data-tab="overview"] .grid > .ov-c { grid-column: span 12; }
}

/* ============================================================
   23. VE — 3열 구성
   ------------------------------------------------------------
   판정 → 근거 → 실행이 각각 한 줄(3칸)에서 닫히도록.
   ============================================================ */
/* 규정 판단 카드 3장 — 등급은 좌측 색 띠가 아니라 판정 배지로만 말한다 */
.ve-rlc > h3 .card-sub {
  border: 1px solid var(--border-strong);
  border-radius: 999px; padding: 1px 9px;
  color: var(--text-strong); background: var(--surface-3);
}
.ve-rlc.ve-rule--ok   > h3 .card-sub { background: var(--success-soft); border-color: var(--success-border); color: var(--success-dark); }
.ve-rlc.ve-rule--warn > h3 .card-sub { background: var(--warning-soft); border-color: var(--warning-border); color: var(--warning-dark); }
.ve-rlc.ve-rule--info > h3 .card-sub { background: var(--primary-tint); border-color: var(--primary-soft); color: var(--primary-dark); }
.ve-rlc .ve-quote { margin: 9px 0 0; }

/* Tie-in 유량 제한 — 3열 표를 항목 카드로 (반폭에서 표는 접힌다) */
.ve-fn { display: flex; flex-direction: column; gap: 8px; }
.ve-fn-i { border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; background: var(--surface-3); }
/* 항목명과 값이 한 줄에 나란히 서면(값이 길 때) 항목명이 0폭으로 눌려
   세로로 한 글자씩 쌓인다 — 값이 긴 항목이 있으므로 위아래로 쌓는다 */
.ve-fn-h { display: flex; flex-direction: column; gap: 2px; }
.ve-fn-h b { color: var(--text-strong); }
.ve-fn-v { color: var(--primary-dark); word-break: keep-all; }
.ve-fn-n { color: var(--text-muted); margin-top: 3px; word-break: keep-all; }

/* 미수령 자료 — 4열 표를 번호 목록으로 */
.ve-gap { display: flex; flex-direction: column; gap: 7px; }
.ve-gap-i { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 9px; align-items: start; }
.ve-gap-n {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; border-radius: 5px;
  background: var(--surface-3); border: 1px solid var(--border); color: var(--text-muted);
}
.ve-gap-i b { color: var(--text-strong); display: block; word-break: keep-all; }
.ve-gap-s { color: var(--text-muted); display: block; margin-top: 1px; }

/* 정량 검증 3칸 — 접기 목록이 카드마다 같은 리듬을 갖도록 */
.ve-folds { display: flex; flex-direction: column; gap: 8px; }

/* ============================================================
   24. 마감 다듬기 (Polish)
   ------------------------------------------------------------
   구조는 그대로 두고, 「어디까지가 한 덩어리인가」가 눈에 더 빨리
   들어오도록 경계·간격·상태 표시만 다듬는다.
   색을 새로 들이지 않고 이미 있는 토큰만 쓴다.
   ============================================================ */

/* ── 카드 ── 경계는 얇게, 반응은 분명하게 ─────────────────── */
.card {
  border: 1px solid var(--border);
  transition: border-color .12s, box-shadow .12s;
}
.card:hover {
  border-color: var(--border-strong);
  box-shadow: 0 1px 3px rgba(15, 30, 61, .05);
}
/* 카드 제목 줄 — 제목과 부제를 양 끝으로 밀어 카드마다 같은 리듬을 만든다 */
.card > h3 {
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.card > h3 .card-sub {
  margin-left: auto;
  text-align: right;
  color: var(--text-muted);
}

/* ── 섹션 구분 ── 앞머리에 짧은 세로 규칙을 세워 층을 보이게 ── */
.sec-bar {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding-left: 11px;
  position: relative;
}
.sec-bar::before {
  content: "";
  position: absolute;
  left: 0; top: 2px; bottom: 2px;
  width: 3px;
  border-radius: 2px;
  background: var(--primary);
  opacity: .55;
}
.sec-bar__m { margin-left: auto; color: var(--text-muted); }

/* ── 패널 안 가로 탭 ── 탭 줄 자체를 하나의 트랙으로 ──────── */
.stx-bar {
  gap: 4px;
  padding: 4px 4px 0;
  background: linear-gradient(to bottom, var(--surface-3) 0%, var(--surface-3) calc(100% - 1px), var(--border) calc(100% - 1px));
  border-radius: 10px 10px 0 0;
  border-bottom: 0;
}
.stx-t { border-radius: 8px 8px 0 0; }
.stx-t.active { box-shadow: inset 0 2px 0 var(--primary), 0 -1px 2px rgba(15, 30, 61, .04); }
.stx-body { padding-top: 2px; }

/* ── 지표 밴드 ── 칸 사이 경계를 옅게 넣어 값이 서로 붙지 않게 ── */
.sb-i + .sb-i { border-left: 1px solid var(--border-soft); }

/* ── 상태 배지 ── 높이를 하나로 맞춘다 (줄바꿈 시 들쭉날쭉 방지) ── */
.tag {
  display: inline-flex;
  align-items: center;
  line-height: 1.4;
  white-space: nowrap;
}

/* ── 접기(details) ── 열림 상태가 한눈에 보이게 ─────────────── */
.fx-more > summary {
  border-radius: 7px;
  transition: background .12s;
}
.fx-more > summary:hover { background: var(--primary-tint); }
.fx-more[open] > summary { color: var(--text-strong); }

/* ── 도해 ── 지도·사진 위에 옅은 안쪽 테두리 (밝은 사진 경계 확보) ── */
.fig-a { position: relative; }
.fig-a::after {
  content: "";
  position: absolute; inset: 0;
  box-shadow: inset 0 0 0 1px rgba(15, 30, 61, .10);
  pointer-events: none;
}

/* ── 사이드바 ── 활성 항목을 왼쪽 규칙으로도 말한다 ─────────── */
.menu-item { position: relative; }
.menu-item.active::before {
  content: "";
  position: absolute;
  left: 0; top: 4px; bottom: 4px;
  width: 3px;
  border-radius: 0 2px 2px 0;
  background: var(--primary);
}

/* ── 표 ── 머리행을 살짝 눌러 본문과 층을 만든다 ────────────── */
table thead th {
  background: var(--surface-3);
  border-bottom: 1px solid var(--border-strong);
}
table tbody tr:hover { background: var(--primary-tint); }
.row-pick, .row-total { background: var(--primary-tint); }
.row-total td { border-top: 1px solid var(--border-strong); }

/* ============================================================
   25. 종합현황 특이사항 — 등급 3분할 고정 (탭 없음)
   ------------------------------------------------------------
   sub-tab 으로 나눴더니 등급마다 건수가 달라(4·3·1) 칸을 바꿀 때마다
   내용 높이가 출렁였다. 한 줄 행으로 줄이면 셋 다 한 화면에 들어오므로
   탭을 없애고 세 덩어리를 고정한다.
   ============================================================ */
/* ── 특이사항 — 등급 3분할 (재설계 '26.09.02) ─────────────────
   여덟 건을 한 줄씩 늘어놓던 판은 등급 구분이 묻히고 어느 것도 눈에
   안 들어왔다. 등급별 상위 2·2·1건만 싣는 대신
     · 등급 블록을 옅은 바탕 + 색 레일로 묶어 세 덩어리로 먼저 읽히게 하고
     · 분야 칩의 폭을 고정해 제목이 한 열에 정렬되게 하고
     · 긴급 건에는 "왜 긴급한가" 한 줄을 붙였다.
   ------------------------------------------------------------ */
.ovf { display: flex; flex-direction: column; gap: 6px; }
.ovf-g {
  border-left: 3px solid var(--border-strong);
  border-radius: 0 7px 7px 0;
  padding: 5px 9px 6px;
  background: var(--surface-3);
}
.ovf-g--high { border-left-color: var(--danger);  background: var(--danger-soft); }
.ovf-g--mid  { border-left-color: var(--warning); background: var(--warning-soft); }
.ovf-g--low  { border-left-color: var(--success); background: var(--success-soft); }
.ovf-h { display: flex; align-items: center; gap: 7px; margin-bottom: 3px; }
.ovf-c { color: var(--text-soft); margin-left: auto; white-space: nowrap; }
.ovf-k { color: var(--text-strong); }
.ovf-i {
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr);
  align-items: baseline;
  gap: 8px;
  padding: 2px 0;
  line-height: 1.4;
}
.ovf-i + .ovf-i { border-top: 1px solid rgba(31, 42, 61, .07); }
.ovf-a {
  color: var(--primary-dark);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0 4px;
  text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 제목 + 이유를 한 줄에. 이유는 basis 0 으로 두어, 자리가 모자라면
   제목이 아니라 이유가 먼저 줄어든다. */
.ovf-b { min-width: 0; display: flex; align-items: baseline; gap: 6px; }
.ovf-t { flex: 0 1 auto; color: var(--text-strong); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ovf-n {
  flex: 1 1 0; min-width: 0; font-style: normal; color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ovf-n::before { content: "· "; }
.ovf-e { color: var(--text-soft); padding: 2px 0; }


/* ============================================================
   26. 개요 — 한 페이지 구성용
   ============================================================ */
/* 목적 · 근거 콜아웃 2장을 나란히 (전폭 배너 두 줄이면 화면을 먹는다) */
.bf-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: var(--sp-3); margin-top: 10px; }
.bf-2 > * { margin: 0; }

/* 추진 단계 — 문단 카드 3장을 한 줄 행 + 접기로 */
.phl { display: flex; flex-direction: column; gap: 8px; }
.phl-i { border: 1px solid var(--border); border-radius: 8px; padding: 9px 11px; background: var(--surface-3); }
.phl-h { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; }
.phl-n { color: var(--text-strong); }
.phl-p { margin-left: auto; color: var(--text-muted); white-space: nowrap; }
.phl-v { color: var(--primary-dark); margin-top: 2px; }
.phl-s { color: var(--text-muted); line-height: var(--lh-base); word-break: keep-all; }
.phl-i .fx-more { margin-top: 5px; }

/* 배관경 검토 — 2안 대비 카드 */
.pcm { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-2); }
.pcm-i { border: 1px solid var(--border); border-radius: 8px; padding: 9px 10px; background: var(--surface-3); }
.pcm-i--pick { border-color: var(--primary-soft); background: var(--primary-tint); }
.pcm-h { display: flex; align-items: center; gap: 7px; margin-bottom: 7px; }
.pcm-h b { color: var(--text-strong); }
.pcm-i .sg { background: transparent; }
.pcm-i .sg-i { background: rgba(255, 255, 255, .7); }

/* ============================================================
   27. 공급관리소 — TYPE 대조표
   ============================================================ */
.stc { display: block; word-break: keep-all; }
.stc--win {
  background: var(--success-soft);
  border: 1px solid var(--success-border);
  border-radius: 5px;
  padding: 3px 7px;
  color: var(--success-dark);
}

/* ============================================================
   28. VE 게이트 — 상태 3열
   ============================================================ */
.ve-gsum { padding-top: 12px; padding-bottom: 12px; }
.ve-gc .ve-gt { display: flex; flex-direction: column; gap: 7px; }
.ve-gc .ve-gt-i {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 9px;
  align-items: start;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 10px;
  background: var(--surface-3);
}
.ve-gc .ve-gt-i--done { background: var(--success-soft); border-color: var(--success-border); }
.ve-gc .ve-gt-i--ing  { background: var(--warning-soft); border-color: var(--warning-border); }
.ve-gc .ve-gt-i--wait { background: var(--surface-3); border-color: var(--border); }
.ve-gc .ve-gt-n {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 24px; height: 22px; border-radius: 6px;
  background: #fff; border: 1px solid var(--border-strong); color: var(--text-strong);
}
.ve-gc .ve-gt-h { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.ve-gc .ve-gt-h b { color: var(--text-strong); word-break: keep-all; }
.ve-gc .ve-gate-o { margin-left: auto; color: var(--text-muted); white-space: nowrap; }
.ve-gc .ve-gt-c { color: var(--text-muted); margin-top: 3px; word-break: keep-all; }
.ve-gc .ve-gt-x {
  background: var(--danger-soft); border: 1px solid var(--danger-border);
  color: var(--danger-dark); border-radius: 4px; padding: 0 5px;
}

/* ============================================================
   23. 구획 바로가기 (.jn) — sub-tab 을 걷어낸 자리
   ------------------------------------------------------------
   탭처럼 생겼지만 탭이 아니다. 누르지 않아도 아래에 전부 이어져 있고,
   누르면 그 구획으로 스크롤한다. 그래서 「선택된 칸」이 아니라
   「지금 보고 있는 구획(.here)」만 표시한다 — 상태가 아니라 위치다.
   ============================================================ */
.jn {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  padding: 7px 10px;
  background: var(--surface-3);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.jn-l {
  color: var(--text-soft);
  padding: 0 6px 0 2px;
  border-right: 1px solid var(--border);
  margin-right: 4px;
  align-self: stretch;
  display: flex;
  align-items: center;
}
.jn-i {
  appearance: none;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text-muted);
  padding: 5px 11px 6px;
  border-radius: 7px;
  cursor: pointer;
  display: flex;
  align-items: baseline;
  gap: 7px;
  text-align: left;
}
.jn-i:hover { background: var(--surface); border-color: var(--border); color: var(--text-strong); }
.jn-i.here {
  background: var(--surface);
  border-color: var(--primary-border, var(--border));
  color: var(--text-strong);
  box-shadow: inset 2px 0 0 var(--primary);
}
.jn-m { color: var(--text-soft); }
.jn-i.here .jn-m { color: var(--primary-dark); }
.jn-note { margin-left: auto; color: var(--text-soft); padding-right: 2px; }
/* 앵커로 내려갈 때 구획 머리가 패널 머리에 가리지 않게 */
.sec-bar[id] { scroll-margin-top: 76px; }

@media (max-width: 1100px) {
  .jn-note { display: none; }
}

/* ============================================================
   17. 인쇄
   ============================================================ */
@media print {
  .sidebar, .tabs, .statusbar, .titlebar .controls { display: none !important; }
  .panel-head { position: static; }
  .card { break-inside: avoid; }
  /* 화면에서 접어 둔 상세는 인쇄물에서는 모두 펼친다 — 종이에는 "펼치기"가 없다.
     ::details-content 가 표준 경로이고, 구형 엔진을 위해 자식 표시도 함께 되돌린다. */
  .fx-more > summary { display: none; }
  .fx-more::details-content { content-visibility: visible; block-size: auto; }
  .fx-more > *:not(summary) { display: revert !important; }
}

/* ============================================================
   30. 개요·기준 — 구조화 · 시각화 ('26.09.02)
   ------------------------------------------------------------
   줄글과 표로만 있던 네 자리를 도표로 바꿨다.
     ① 추진 일정   문단 카드 3장 → 같은 시간 축 위의 막대 (.ptl)
     ② 배관경 검토 숫자 대비표   → 압력 프로파일 + 요구압 선 (.prp)
     ③ 두께 산정   계산/적용 표  → 여유분 이중 막대 (.mgb)
     ④ 설비 기준   3줄 줄글 표   → 기준 대비 충족도 미터 (.lmt)
   원문(표·문장)은 지우지 않고 fold 로 접어 두었다.
   ============================================================ */

/* ── ① 사업 추진 타임라인 ─────────────────────────────── */
.ptl { display: flex; flex-direction: column; gap: 8px; }
.ptl-r {
  display: grid;
  grid-template-columns: 210px minmax(0, 1fr) 96px;
  align-items: center; gap: 12px;
}
.ptl-n { display: flex; flex-direction: column; min-width: 0; }
.ptl-n b { color: var(--text-strong); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ptl-n i { font-style: normal; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ptl-t {
  position: relative; height: 30px;
  background: var(--surface-3);
  border: 1px solid var(--border-soft);
  border-radius: 6px;
}
/* 연 눈금 — 4~5년 축이라 월 눈금은 너무 잘다 */
.ptl-y { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--border); }
.ptl-yl { position: absolute; top: 100%; margin-top: 3px; transform: translateX(-50%); color: var(--text-soft); }
.ptl-now { position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--danger); opacity: .8; z-index: 3; }
.ptl-nowl {
  position: absolute; top: 100%; margin-top: 2px; transform: translateX(-50%);
  font-style: normal; color: var(--danger-dark); white-space: nowrap;
}
.ptl-b {
  position: absolute; top: 4px; bottom: 4px;
  border-radius: 5px; overflow: hidden;
  display: flex; align-items: center;
  min-width: 6px;
}
.ptl-b--done { background: #cfe6d8; border: 1px solid #9ecfb4; }
.ptl-b--ing  { background: #f4e3c4; border: 1px solid #e0bd7e; }
.ptl-b--todo { background: #dfe5ee; border: 1px solid #c3ccda; }
/* 진척 채움 — 막대 안쪽을 왼쪽부터 진하게 */
.ptl-f { position: absolute; left: 0; top: 0; bottom: 0; background: rgba(39, 125, 68, .38); }
.ptl-b--ing .ptl-f { background: rgba(169, 111, 31, .38); }
.ptl-bl {
  position: relative; z-index: 1; padding: 0 8px;
  color: var(--text-strong); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.ptl-s { display: flex; align-items: center; gap: 6px; justify-content: flex-end; }
.ptl-p { font-style: normal; color: var(--text-muted); font-variant-numeric: tabular-nums; }
/* 축 행 — 눈금선과 연도 글자만 */
.ptl-r--axis { margin-top: 4px; }
.ptl-r--axis .ptl-t { height: 20px; background: transparent; border: 0; border-top: 1px solid var(--border); border-radius: 0; }
.ptl-r--axis .ptl-y { top: 0; bottom: auto; height: 4px; }

/* 관문 표식 행 — 막대 위. 삼각형이 아래(막대)를 가리킨다 */
.ptl-r--pins { margin-bottom: 2px; }
.ptl-r--pins .ptl-t { height: 34px; background: transparent; border: 0; }
.ptl-pin {
  position: absolute; bottom: 0; transform: translateX(-50%);
  display: flex; flex-direction: column-reverse; align-items: center; gap: 1px;
}
.ptl-pin::after {
  content: ""; width: 0; height: 0;
  border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 6px solid var(--primary);
}
.ptl-pin b { color: var(--primary-dark); white-space: nowrap; }
/* 한 달 차이로 겹치는 표식은 한 단 올려 엇갈리게 */
.ptl-pin--alt { bottom: 15px; }
.ptl-pin--alt::after { border-top-color: var(--primary-soft, #9db8e0); }
/* 오른쪽 끝 표식은 글자를 안쪽으로 눕힌다 */
.ptl-pin--end b { transform: translateX(-38%); }

/* ── ② 압력 프로파일 ──────────────────────────────────── */
.prp { display: flex; flex-direction: column; gap: 12px; }
.prp-r { border: 1px solid var(--border); border-radius: 9px; padding: 9px 11px 10px; }
.prp-r--pick { border-color: var(--primary-soft); background: var(--primary-tint); }
.prp-h { display: flex; align-items: baseline; gap: 8px; margin-bottom: 7px; }
.prp-h b { color: var(--text-strong); }
.prp-m { margin-left: auto; font-variant-numeric: tabular-nums; }
.prp-m--ok { color: var(--success-dark); }
.prp-m--no { color: var(--danger-dark); }
.prp-t {
  position: relative; height: 24px;
  background: var(--surface-2, #eef1f6);
  border-radius: 5px; overflow: hidden;
}
.prp-a { position: absolute; left: 0; top: 0; bottom: 0; background: var(--primary, #3f6fc4); }
/* 손실분 — 사선 줄무늬로 "잃은 몫"임을 색 없이도 구분 */
.prp-l {
  position: absolute; top: 0; bottom: 0;
  background: repeating-linear-gradient(135deg, #d9a8a0 0 5px, #e8c4bd 5px 10px);
}
.prp-need { position: absolute; top: -2px; bottom: -2px; width: 2px; background: #1f2a3d; z-index: 2; }
.prp-av {
  position: absolute; left: 9px; top: 50%; transform: translateY(-50%);
  color: #fff; z-index: 1; font-variant-numeric: tabular-nums;
}
.prp-k { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 6px; color: var(--text-muted); }
.prp-sw { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 4px; }
.prp-sw--a { background: var(--primary, #3f6fc4); }
.prp-sw--l { background: repeating-linear-gradient(135deg, #d9a8a0 0 3px, #e8c4bd 3px 6px); }
.prp-f { color: var(--text-muted); display: flex; align-items: center; gap: 6px; }
.prp-nk { display: inline-block; width: 2px; height: 12px; background: #1f2a3d; flex: 0 0 auto; }

/* ── ③ 계산 → 적용 (여유) 이중 막대 ───────────────────── */
.mgb { display: flex; flex-direction: column; }
.mgb-r {
  display: grid;
  grid-template-columns: 128px minmax(0, 1fr) 106px;
  align-items: center; gap: 10px;
  padding: 5px 0;
  border-top: 1px solid var(--border-soft);
}
.mgb-r:first-child { border-top: 0; }
.mgb-l { color: var(--text-strong); display: flex; align-items: baseline; gap: 5px; min-width: 0; }
.mgb-l i { font-style: normal; color: var(--text-muted); }
.mgb-t { position: relative; height: 14px; background: var(--surface-2, #eef1f6); border-radius: 4px; overflow: hidden; }
.mgb-b { position: absolute; left: 0; top: 0; bottom: 0; background: var(--primary, #3f6fc4); }
.mgb-m { position: absolute; top: 0; bottom: 0; background: #b9cdec; }
.mgb-v { text-align: right; color: var(--text-strong); font-variant-numeric: tabular-nums; white-space: nowrap; }
.mgb-v em { font-style: normal; color: var(--text-muted); }
.mgb-g { font-style: normal; color: var(--primary-dark); margin-left: 5px; }
.mgb-f { display: flex; gap: 14px; margin-top: 8px; color: var(--text-muted); }
.mgb-sw { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 4px; }
.mgb-sw--b { background: var(--primary, #3f6fc4); }
.mgb-sw--m { background: #b9cdec; }

/* ── ④ 기준 충족도 미터 ───────────────────────────────── */
.lmt { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: var(--sp-3); }
.lmt-i { border: 1px solid var(--border); border-radius: 9px; padding: 10px 12px 11px; }
.lmt-i--ok   { background: var(--success-soft); border-color: var(--success-border); }
.lmt-i--warn { background: var(--warning-soft); border-color: var(--warning-border); }
.lmt-i--late { background: var(--danger-soft);  border-color: var(--danger-border); }
.lmt-h { display: flex; align-items: baseline; gap: 8px; margin-bottom: 6px; }
.lmt-h b { color: var(--text-strong); }
.lmt-r { margin-left: auto; font-variant-numeric: tabular-nums; }
.lmt-i--ok   .lmt-r { color: var(--success-dark); }
.lmt-i--warn .lmt-r { color: var(--warning-dark); }
.lmt-i--late .lmt-r { color: var(--danger-dark); }
.lmt-t { position: relative; height: 12px; background: #fff; border: 1px solid var(--border); border-radius: 4px; overflow: hidden; }
.lmt-t > i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 3px 0 0 3px; }
.lmt-i--ok   .lmt-t > i { background: var(--success); }
.lmt-i--warn .lmt-t > i { background: var(--warning); }
.lmt-i--late .lmt-t > i { background: var(--danger); }
.lmt-k { display: flex; justify-content: space-between; gap: 10px; margin-top: 5px; color: var(--text-strong); }
.lmt-k span:last-child { color: var(--text-muted); }
.lmt-n { margin-top: 5px; color: var(--text-muted); line-height: var(--lh-base); }
