/* 일성산업 내진 버팀대 자동 마킹 웹 UI — 캔버스 중심 셸(F-69). PC 전용, 페이지 스크롤 0.
   브랜드 색(ilsungpipe.com): Primary(azure) #00A0E8 · hover #148AC7.
   판정 색: OK #16A34A · WARNING #D97706 · NG #DC2626 · 배경 #F8FAFC · 보더 #E2E8F0.
   아이콘은 인라인 SVG(이모지 금지). */

:root {
  --primary: #00a0e8;
  --primary-dark: #148ac7;
  --primary-tint: #e6f6fd;
  --primary-tint-strong: #d7f0fb;
  --primary-ring: rgba(0, 160, 232, 0.14);
  --ok: #16a34a;
  --warning: #d97706;
  --ng: #dc2626;
  --sel: #f59e0b;
  /* 방향 색(F-55) — 횡=파랑/종=보라. 버팀대 틱·영향구역 공용(단일 출처). */
  --dir-lat: #2563eb;
  --dir-long: #a855f7;
  --bg: #f8fafc;
  --surface: #ffffff;
  --border: #e2e8f0;
  --text: #1e293b;
  --text-muted: #64748b;
  --radius: 12px;
  --shadow: 0 1px 3px rgba(15, 23, 42, 0.06), 0 1px 2px rgba(15, 23, 42, 0.04);
  --panel-w: 448px;
  --topbar-h: 56px;
  /* 레이어 강조(F-XXX) — 강조 대상 외 원본 배경을 무채색+흐림으로 낮춰 강조 색이 묻히지
     않게 한다(사용자: "강조가 잘 보이지도 않아"). 오버레이 비대상 배관(.lc-layer.dim)과 톤 통일. */
  --bg-dim-opacity: 0.25;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* hidden 속성은 display 지정 클래스보다 우선해야 함. */
[hidden] { display: none !important; }

.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

body {
  font-family: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
/* 앱 셸 — 전체 뷰포트 flex column, 페이지 스크롤 없음(각 영역 내부 스크롤). */
body.app-shell { height: 100vh; overflow: hidden; display: flex; flex-direction: column; min-width: 1100px; }

svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* ── 상단바(고정) ── */
.topbar {
  flex: 0 0 auto; height: var(--topbar-h);
  display: flex; align-items: center; gap: 18px;
  padding: 0 20px; background: var(--surface); border-bottom: 1px solid var(--border);
}
.brand { display: flex; flex-direction: column; line-height: 1.2; flex: 0 0 auto; }
.brand-title { font-size: 16px; font-weight: 800; letter-spacing: -0.01em; }
.brand-sub { font-size: 11px; color: var(--text-muted); }
/* 위상 배지(F-72, stepper 대체) — 현재 위상만 소형으로. 1차=azure tint / 2차=ok tint. */
.phase-pill { flex: 0 0 auto; padding: 4px 11px; border-radius: 999px; font-size: 12px; font-weight: 700; letter-spacing: -0.01em; background: var(--primary-tint); color: var(--primary-dark); white-space: nowrap; }
.phase-pill.placed { background: #f0fdf4; color: #15803d; }
.topbar-spacer { flex: 1; }
.topbar-file { font-size: 13px; color: var(--text-muted); max-width: 340px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar-file #result-name { font-weight: 600; color: var(--text); }
.result-time { margin-left: 8px; }
.topbar-btn { padding: 8px 14px; font-size: 13px; }

/* ── 설정 모달(전역, 분석 무관) — 상단바 [설정] 버튼으로 연다. ── */
.modal-overlay {
  position: fixed; inset: 0; z-index: 50; display: flex; align-items: center; justify-content: center;
  background: rgba(15, 23, 42, 0.4);
}
.modal-panel {
  /* 사이드 탭 도입(2026-09-01)으로 flex 세로 구성 — 스크롤은 패널이 아니라 .modal-body 가
     담당해, 왼쪽 탭·헤더가 본문 스크롤과 무관하게 항상 보인다. 폭도 사이드바 몫만큼 확장. */
  width: min(640px, calc(100% - 40px)); max-height: calc(100vh - 80px);
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface); border-radius: var(--radius, 12px); box-shadow: 0 20px 50px rgba(0, 0, 0, 0.25);
}
.modal-head {
  position: sticky; top: 0; display: flex; align-items: center; justify-content: space-between;
  padding: 16px 18px; border-bottom: 1px solid var(--border); background: var(--surface);
}
.modal-title { font-size: 15px; font-weight: 800; margin: 0; color: var(--text); }
.modal-close {
  width: 30px; height: 30px; padding: 6px; display: inline-flex; align-items: center; justify-content: center;
  border: none; background: transparent; color: var(--text-muted); cursor: pointer; border-radius: 8px;
}
.modal-close:hover { background: var(--bg); color: var(--ng); }
.modal-body { padding: 18px; overflow-y: auto; flex: 1; min-width: 0; }

/* ── 본문 2분할 ── */
.app-main { flex: 1; display: flex; min-height: 0; }

/* ── 캔버스(메인) ── */
.canvas-wrap { flex: 1; position: relative; background: #fbfcfe; overflow: hidden; min-width: 0; }
/* 업로드/진행 — 캔버스 자리 중앙 정렬. */
.scr-upload { position: absolute; inset: 0; display: flex; align-items: flex-start; justify-content: center; overflow-y: auto; padding: 7vh 24px 40px; }
.upload-inner { width: 100%; max-width: 560px; }
.screen-title { font-size: 24px; font-weight: 700; letter-spacing: -0.02em; }
.screen-desc { color: var(--text-muted); margin: 6px 0 24px; font-size: 15px; }
/* 도면 지도 — 캔버스 전체를 채운다(컨테이너만 이전, 엔진 무변경). */
.review-canvas-wrap { position: absolute; inset: 0; }
/* floating 오버레이 토글(좌상) — 캔버스 위. */
.canvas-toolbar { position: absolute; top: 12px; left: 12px; z-index: 5; display: flex; flex-direction: column; gap: 8px; max-width: 74%; }
.canvas-toolbar .lc-view-toggles { margin-bottom: 0; padding: 6px 10px; border-radius: 10px; background: rgba(255,255,255,0.92); box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
/* ── 우측 검수 패널 ── */
.panel { flex: 0 0 var(--panel-w); width: var(--panel-w); background: var(--surface); border-left: 1px solid var(--border); display: flex; flex-direction: column; min-height: 0; }
/* 패널 리사이저(F-72) — 캔버스↔패널 사이 드래그 핸들. hover 시 azure 선. */
.panel-resizer { flex: 0 0 6px; cursor: col-resize; position: relative; z-index: 6; background: transparent; }
.panel-resizer::before { content: ""; position: absolute; inset: 0 2px; border-radius: 2px; background: transparent; transition: background .12s; }
.panel-resizer:hover::before { background: var(--primary); }
body.resizing { cursor: col-resize; user-select: none; }
body.resizing .layer-canvas { pointer-events: none; }
.panel-top { flex: 0 0 auto; padding: 14px 14px 0; display: flex; flex-direction: column; gap: 12px; }
/* 탭 스트립 — 탭을 좁게 눌러담지 않고 각자 읽기 편한 폭 유지 + 넘치면 가로 슬라이드(스크롤). */
/* 탭 슬라이더 래퍼 — 스트립 스크롤 + 좌우 셰브론 오버레이의 위치 기준(경계선을 여기로 이관). */
.review-tabs-wrap { position: relative; flex: 0 0 auto; border-bottom: 1px solid var(--border); }
/* 탭 스트립 — 한 줄 가로 슬라이드. 네이티브 스크롤바 숨김(스와이프/드래그/셰브론으로 이동). */
.review-tabs { display: flex; gap: 2px; padding: 12px 8px 0; overflow-x: auto; overflow-y: hidden; scroll-behavior: smooth; -webkit-overflow-scrolling: touch; touch-action: pan-x; scrollbar-width: none; -ms-overflow-style: none; }
.review-tabs::-webkit-scrollbar { display: none; }
.review-tabs.dragging { scroll-behavior: auto; cursor: grabbing; }
/* 좌우 슬라이드 셰브론 — 넘칠 때만(can-left/can-right) 노출. 페이드 엣지로 '더 있음'을 암시. */
.tab-nav { position: absolute; top: 0; bottom: 1px; width: 34px; display: none; align-items: center; border: none; padding: 0; cursor: pointer; z-index: 3; color: var(--text-muted); }
.tab-nav:hover { color: var(--text); }
.tab-nav svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.tab-nav-left { left: 0; justify-content: flex-start; padding-left: 3px; background: linear-gradient(to right, var(--surface) 60%, transparent); }
.tab-nav-right { right: 0; justify-content: flex-end; padding-right: 3px; background: linear-gradient(to left, var(--surface) 60%, transparent); }
.review-tabs-wrap.can-left .tab-nav-left { display: flex; }
.review-tabs-wrap.can-right .tab-nav-right { display: flex; }
.review-tab { flex: 0 0 auto; display: flex; align-items: center; justify-content: center; gap: 5px; padding: 9px 14px; background: none; border: none; border-bottom: 2px solid transparent; margin-bottom: -1px; cursor: pointer; font-size: 13px; font-weight: 600; color: var(--text-muted); white-space: nowrap; }
.review-tab:hover { color: var(--text); }
.review-tab.active { color: var(--primary); border-bottom-color: var(--primary); }
.tab-badge { font-size: 10.5px; font-weight: 700; color: var(--text-muted); background: var(--bg); border-radius: 8px; padding: 1px 5px; line-height: 1.5; }
.review-tab.active .tab-badge { color: var(--primary); background: var(--primary-tint); }
.tab-badge.badge-ng { color: #fff; background: var(--ng); }
/* 활성 탭이어도 NG 배지는 빨강 유지(명시도로 active tint 를 이김) — 결함 표면화는 계약 불변식. */
.review-tab.active .tab-badge.badge-ng { color: #fff; background: var(--ng); }
/* M7(diff-review) — 지정 동일성 검증 실패(unverified/missing 등) 건수. NG(빨강)보다 약한 신호. */
.tab-badge.badge-warn { color: #fff; background: var(--warning); }
.review-tab.active .tab-badge.badge-warn { color: #fff; background: var(--warning); }
/* 검수 단계 게이트 — 잠긴 탭(레이어 확정 전 배관 탭). */
.review-tab.locked { opacity: .45; cursor: not-allowed; }
.review-tab.locked:hover { color: var(--text-muted); }
.review-body { flex: 1; overflow-y: auto; padding: 14px; min-height: 0; display: flex; flex-direction: column; }
/* ── 요약 탭(F-73) — 분석 결과 개요(panel-top 슬림통계에서 이관, 첫 탭·기본 착지) ── */
.summary-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.sum-card { background: var(--bg); border: 1px solid var(--border); border-radius: 10px; padding: 12px; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.sum-card-n { font-size: 24px; font-weight: 800; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.sum-card-l { font-size: 11px; color: var(--text-muted); }
/* 「인식 배관」 카드의 제외 병기(L-3) — 라벨보다 한 단계 약하게. 값이 0 이면 hidden. */
.sum-card-sub { font-size: 11px; font-weight: 600; color: var(--text-muted); opacity: 0.85; }
.summary-verdict { display: flex; gap: 8px; margin-top: 10px; }
.sv-seg { flex: 1; border-radius: 10px; padding: 10px 12px; display: flex; flex-direction: column; gap: 1px; border: 1px solid; }
.sv-n { font-size: 20px; font-weight: 800; font-variant-numeric: tabular-nums; }
.sv-l { font-size: 12px; font-weight: 600; }
.summary-info { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; margin: 14px 2px 0; font-size: 13px; }
.summary-info dt { color: var(--text-muted); font-weight: 600; }
.summary-info dd { margin: 0; color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
.summary-hint { font-size: 12px; color: var(--text-muted); margin: 16px 2px 0; line-height: 1.6; }
/* 요약 탭 상세 개요(F-75) — 데이터 파생 분포 막대 + 규정 기준. */
.summary-detail { display: flex; flex-direction: column; gap: 14px; margin: 16px 2px 0; }
.sd-block { min-width: 0; }
.sd-title { font-size: 12px; font-weight: 700; color: var(--text); margin: 0 0 7px; display: flex; align-items: baseline; gap: 6px; }
.sd-sub { font-size: 10px; font-weight: 500; color: var(--text-muted); }
.sd-bars { display: flex; flex-direction: column; gap: 5px; }
.sd-bar { display: flex; align-items: center; gap: 8px; }
.sd-bar-label { flex: 0 0 92px; font-size: 11px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sd-bar-track { flex: 1 1 auto; height: 8px; background: var(--border); border-radius: 999px; overflow: hidden; }
.sd-bar-fill { display: block; height: 100%; background: var(--primary); border-radius: 999px; }
.sd-bar-n { flex: 0 0 auto; min-width: 28px; text-align: right; font-size: 11px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.seg-ok { background: #f0fdf4; border-color: #bbf7d0; color: var(--ok); }
.seg-warning { background: #fffbeb; border-color: #fde68a; color: var(--warning); }
.seg-ng { background: #fef2f2; border-color: #fecaca; color: var(--ng); }
.panel-foot { flex: 0 0 auto; padding: 14px; border-top: 1px solid var(--border); background: var(--surface); }

/* ── 드롭존 ── */
.dropzone {
  border: 2px dashed var(--border); border-radius: var(--radius); background: var(--surface);
  padding: 48px 24px; text-align: center; cursor: pointer; transition: border-color 0.15s, background 0.15s;
}
.dropzone:hover, .dropzone:focus-visible { border-color: var(--primary); background: var(--primary-tint); outline: none; }
.dropzone.dragover { border-color: var(--primary); background: var(--primary-tint-strong); }
.dz-icon { width: 44px; height: 44px; color: var(--primary); margin: 0 auto 14px; }
.dz-primary { font-size: 15px; font-weight: 500; }
.dz-link { color: var(--primary); font-weight: 600; }
.dz-hint { font-size: 13px; color: var(--text-muted); margin-top: 6px; }

/* ── 선택된 파일 ── */
.selected-file { display: flex; align-items: center; gap: 12px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 16px; margin-top: 16px; }
.sf-icon { width: 26px; height: 26px; color: var(--primary); flex-shrink: 0; }
.sf-meta { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.sf-name { font-weight: 600; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sf-size { font-size: 12px; color: var(--text-muted); }
/* 업로드 진행 — 원격 접속에서 대형 도면 전송(수십 초) 동안의 침묵을 없앤다. */
.sf-upload { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.sf-upload-track { flex: 1; height: 4px; background: var(--bg); border-radius: 2px; overflow: hidden; }
.sf-upload-bar { width: 0; height: 100%; background: var(--primary); border-radius: 2px; transition: width .15s linear; }
.sf-upload-pct { font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; min-width: 34px; text-align: right; }
.sf-clear { width: 30px; height: 30px; padding: 6px; border: none; background: transparent; color: var(--text-muted); cursor: pointer; border-radius: 8px; }
.sf-clear:hover { background: var(--bg); color: var(--ng); }

/* ── 버튼 ── */
.btn-primary, .btn-secondary, .btn-ghost {
  font-family: inherit; font-size: 15px; font-weight: 600; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border-radius: 10px; transition: background 0.15s, border-color 0.15s, opacity 0.15s;
}
.btn-primary { width: 100%; margin-top: 24px; padding: 15px; border: none; background: var(--primary); color: #fff; }
.btn-primary:hover:not(:disabled) { background: var(--primary-dark); }
.btn-primary:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-secondary { padding: 12px 18px; border: 1px solid var(--border); background: var(--surface); color: var(--text); }
.btn-secondary:hover { border-color: var(--primary); color: var(--primary); }
.btn-ghost { padding: 9px 14px; border: 1px dashed var(--border); background: transparent; color: var(--primary); font-size: 13px; margin-top: 12px; }
.btn-ghost:hover { border-color: var(--primary); background: var(--primary-tint); }
.btn-primary svg, .btn-secondary svg, .btn-ghost svg { width: 18px; height: 18px; flex-shrink: 0; }

/* ── 진행 ── */
.progress-area { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 22px; margin-top: 24px; }
.progress-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 10px; }
.progress-msg { font-size: 14px; font-weight: 500; }
.progress-pct { font-size: 14px; font-weight: 700; color: var(--primary); font-variant-numeric: tabular-nums; }
.progress-track { height: 8px; background: var(--border); border-radius: 4px; overflow: hidden; }
.progress-bar { height: 100%; width: 0; background: var(--primary); border-radius: 4px; transition: width 2s linear; }
.step-list { list-style: none; display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 18px; }
.step-item { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--text-muted); }
.step-dot { width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--border); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.step-dot svg { width: 11px; height: 11px; color: #fff; opacity: 0; }
.step-item.active { color: var(--text); font-weight: 600; }
.step-item.active .step-dot { border-color: var(--primary); }
.step-item.done .step-dot { background: var(--ok); border-color: var(--ok); }
.step-item.done .step-dot svg { opacity: 1; }
.step-item.done { color: var(--text); }

/* ── 요약(패널 상단) ── */
.preview-img { max-width: 100%; border-radius: 6px; }

/* ── 선택 상세 카드 ── */
.sel-card { border: 1px solid var(--primary-tint-strong); background: var(--primary-tint); border-radius: 12px; padding: 14px; }
/* 빈 상태는 카드 자체를 숨김(F-72) — 상시 placeholder 제거, 선택 시에만 노출. */
.sel-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; }
.sel-title { font-weight: 800; font-size: 15px; }
.sel-kind { font-size: 11px; color: var(--text-muted); flex: 0 0 auto; }
.sel-close { display: inline-flex; padding: 3px; border: none; background: none; color: var(--text-muted); cursor: pointer; border-radius: 6px; }
.sel-close:hover { background: rgba(255,255,255,0.7); color: var(--text); }
.sel-close svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2; }
.sel-rows { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; font-size: 13px; margin-top: 4px; }
.sel-rows dt { color: var(--text-muted); font-weight: 600; white-space: nowrap; }
.sel-rows dd { margin: 0; color: var(--text); }
/* 제외 사유(점선 배관) — 엔진 문구 그대로. 값이 길어 줄바꿈 허용. */
.sel-rows dd.sel-excl-reason { color: #b42318; font-weight: 600; line-height: 1.45; }
/* 버팀대 선택 카드의 판정 칩은 공유 fillBraceRows 가 .lc-bd-verdict 를 재사용한다. */

/* ── 아코디언 ── */
/* 탭 패널 — 활성 탭 섹션만 표시(review-body 안, 이 영역만 스크롤). */
.tabpanel { flex: 1 1 auto; display: flex; flex-direction: column; gap: 8px; }
.tabpanel[hidden] { display: none; }
.acc-body { display: flex; flex-direction: column; gap: 8px; }
.acc-note { font-size: 12px; color: var(--text-muted); line-height: 1.6; }
/* 안내문 컴팩트화(탭 UI — 세로 공간 절약, 정보는 유지) */

/* 관경 미지정 고지 — 버팀대가 «안 붙은» 배관이 있다는 뜻이라 경고보다 한 단계 강하게. */
.size-unknown-notice { font-size: 12px; color: #7f1d1d; background: #fef2f2; border: 1px solid #fca5a5;
  border-left: 4px solid #dc2626; border-radius: 8px; padding: 10px 12px; margin: 0 0 12px; line-height: 1.6; }
.size-unknown-notice b { font-weight: 700; }
/* 레이어 이름 규칙(전역 설정) — 설정 모달 안(분석 무관, 상단바 [설정] 버튼으로 접근). */
.layer-rules-section { margin: 0; }
.layer-rules-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.layer-rules-title { font-size: 13px; font-weight: 700; margin: 0; color: var(--text); }
.layer-rules-state { margin-left: auto; font-size: 11px; color: var(--text-muted); }
.layer-rules-desc { font-size: 11.5px; color: var(--text-muted); line-height: 1.55; margin: 0 0 12px; }
.layer-rules-axis { margin-bottom: 12px; }
.layer-rules-axis-head { font-size: 12px; font-weight: 600; color: var(--text); margin: 0 0 2px; }
.layer-rules-axis-help { font-size: 11px; color: var(--text-muted); line-height: 1.5; margin: 0 0 6px; }
.layer-rules-input { width: 100%; box-sizing: border-box; min-height: 58px; resize: vertical;
  font: inherit; font-size: 12px; line-height: 1.6; padding: 7px 9px; color: var(--text);
  background: var(--bg); border: 1px solid var(--border); border-radius: 6px; }
.layer-rules-input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-ring); }
.layer-rules-actions { display: flex; gap: 8px; align-items: center; margin-top: 4px; }
.layer-rules-msg { font-size: 11.5px; line-height: 1.5; margin: 8px 0 0; }
.layer-rules-msg.is-ok { color: var(--ok); }
.layer-rules-msg.is-err { color: var(--ng); }
/* 스프링클러 헤드 기준(전역 설정) — 설정 모달 안, 레이어 규칙 아래. 머리글·설명·액션·메시지는
   .layer-rules-* 를 그대로 재사용하고 여기서는 «표 그리드»만 정의한다(관행 유지). */
.head-sizes-section { margin: 18px 0 0; padding-top: 16px; border-top: 1px solid var(--border); }
/* 열 수가 구경 개수에 따라 달라지므로 grid-template-columns 는 JS 가 인라인으로 넣는다. */
.head-sizes-table { display: grid; gap: 4px 6px; align-items: center; margin: 0 0 12px;
  overflow-x: auto; }
.head-sizes-cell { min-width: 0; }
.head-sizes-colhead { font-size: 11px; font-weight: 600; color: var(--text-muted); text-align: center;
  padding-bottom: 2px; white-space: nowrap; }
.head-sizes-colhead.is-name { text-align: left; }
.head-sizes-name { font-size: 12px; color: var(--text); white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }
/* 숫자·이름 입력 — 네이티브 type=number 미사용(inputMode=numeric + text). */
.head-sizes-input { width: 100%; box-sizing: border-box; font: inherit; font-size: 12px;
  padding: 5px 7px; color: var(--text); background: var(--bg); border: 1px solid var(--border);
  border-radius: 6px; text-align: center; }
.head-sizes-input.is-name { text-align: left; }
.head-sizes-input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-ring); }
/* 값이 비었거나 정수가 아닐 때의 «안내» 표시 — 판정이 아니다(저장 가부는 서버가 정한다). */
.head-sizes-input.is-bad { border-color: var(--ng); }
.head-sizes-del { display: inline-flex; align-items: center; justify-content: center; width: 24px;
  height: 24px; padding: 0; border: 1px solid var(--border); border-radius: 6px; background: var(--bg);
  color: var(--text-muted); cursor: pointer; }
.head-sizes-del:hover { color: var(--ng); border-color: var(--ng); }
.head-sizes-del svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; }
/* canonical 행(상향/하향·상하향)은 삭제 버튼이 없다 — 자리만 비워 열 정렬을 유지한다. */
.head-sizes-del-spacer { width: 24px; height: 24px; }
/* F-108 — 미분류 레이어 미리보기(2026-08-31 부터 #layer-list 에 통합). 미분류 행은 클릭이
   미리보기 토글이라는 걸 커서·hover 로 알린다(분류 행의 강조 클릭과는 별개 시각 신호). */
#layer-list .layer-item.preview-on { background: var(--primary-tint-strong); box-shadow: inset 3px 0 0 #a3e635; }

/* ── 위상 게이팅(body.phase-detect / phase-placed) ── */
/* 버팀대·하중 의존 위젯은 1차(검출) 단계에서 숨김. */
/* 1차엔 요약 탭의 버팀대 카드·판정 분포 숨김(2차 전용, F-73). 직경 미식별은 0일 때 JS 로 숨김. */
body.phase-detect .summary-cards .card-braces,
body.phase-detect .summary-verdict { display: none; }
body.phase-detect .summary-cards { grid-template-columns: repeat(2, 1fr); }
/* footer 액션 — 1차=2차 진입 버튼 · 2차=다운로드. */
body.phase-detect .download-row,
body.phase-detect .marking-png-link,
body.phase-detect #pdf-missing { display: none; }
body.phase-placed #place-btn,
body.phase-placed .place-hint { display: none; }
/* 패널별 재분석 버튼은 2차(placed)에서만(1차엔 단일 #place-btn 이 진입 담당). */
body.phase-detect .panel-reanalyze { display: none; }
/* 레이어 확정(검수 단계 게이트)은 1차(detect)에서만 — 2차는 「변경 적용 · 재분석」이 담당. */
body.phase-placed .panel-confirm,
body.phase-placed .layer-gate-note { display: none; }
#place-btn:disabled { opacity: .5; cursor: not-allowed; }
.place-hint.gate-locked { color: #b42318; font-weight: 600; }

#place-btn { margin-top: 0; margin-bottom: 6px; }
.place-hint { color: var(--text-muted); font-size: 12px; margin: 0; }
.download-row { display: flex; gap: 10px; }
.download-row .btn-primary, .download-row .btn-secondary { width: auto; flex: 1; margin-top: 0; padding: 12px; text-decoration: none; font-size: 14px; }
.marking-png-link { display: inline-block; margin-top: 10px; color: var(--primary); font-size: 13px; font-weight: 600; text-decoration: none; }
.marking-png-link:hover { text-decoration: underline; }

/* ── 평면도 검수(아코디언 내부) ── */
.floor-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 10px; }
.floor-tab { padding: 6px 12px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); color: var(--text-muted); font-size: 12px; font-weight: 600; cursor: pointer; transition: all .12s; }
.floor-tab:hover { border-color: var(--primary); color: var(--primary); }
.floor-tab.active { background: var(--primary); border-color: var(--primary); color: #fff; }
.floor-list-wrap { max-height: 260px; overflow-y: auto; border: 1px solid var(--border); border-radius: 10px; }
.floor-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.floor-table thead th { position: sticky; top: 0; background: var(--bg); color: var(--text-muted); font-weight: 600; text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--border); }
.floor-table tbody td { padding: 7px 10px; border-bottom: 1px solid var(--border); color: var(--text); }
.floor-table tbody tr:last-child td { border-bottom: none; }

/* ── 평면도별 이름·지하/지상 지정(override) ── */
.floor-override { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }
.floor-override-title { font-size: 14px; font-weight: 700; color: var(--text); }
.floor-override-desc { color: var(--text-muted); font-size: 12px; margin: 6px 0 12px; line-height: 1.5; }
.floor-override-rows { display: flex; flex-direction: column; gap: 10px; margin-bottom: 14px; }
.floor-ov-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.floor-ov-detected { flex: 0 0 auto; min-width: 40px; max-width: 96px; font-weight: 600; font-size: 13px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.floor-ov-arrow { flex: 0 0 auto; color: var(--text-muted); }
.floor-dropdown { position: relative; min-width: 140px; }
.floor-name-input { min-width: 72px; flex: 1 1 80px; padding: 8px 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); color: var(--text); font-size: 13px; font-weight: 600; }
.floor-name-input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-ring); }
.floor-ug-dd { min-width: 78px; flex: 0 0 auto; }
.floor-ug-dd .floor-dd-btn { padding: 8px 10px; }
.floor-dd-btn { display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; text-align: left; padding: 8px 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); color: var(--text); font-size: 13px; font-weight: 600; cursor: pointer; }
.floor-dd-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.floor-dd-caret { display: inline-flex; flex-shrink: 0; color: var(--text-muted); }
.floor-dd-caret svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.floor-dd-btn[aria-expanded="true"] .floor-dd-caret { transform: rotate(180deg); }
.floor-dd-btn:hover { border-color: var(--primary); }
.floor-dd-btn[aria-expanded="true"] { border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-ring); }
.floor-dd-list { position: absolute; z-index: 20; top: calc(100% + 4px); left: 0; right: 0; max-height: 220px; overflow-y: auto; margin: 0; padding: 4px; list-style: none; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; box-shadow: var(--shadow); }
.floor-dd-opt { padding: 8px 12px; border-radius: 7px; font-size: 13px; cursor: pointer; }
.floor-dd-opt:hover { background: var(--bg); }
.floor-dd-opt.selected { color: var(--primary); font-weight: 700; }
#reanalyze-btn { width: 100%; margin-top: 0; padding: 11px; }
#reanalyze-btn:disabled { opacity: .5; cursor: not-allowed; }
.panel-reanalyze { margin-top: 4px; padding: 11px; font-size: 14px; }

/* ── 메시지 ── */
.inline-error { padding: 10px 14px; border-radius: 10px; background: #fef2f2; border: 1px solid #fecaca; color: var(--ng); font-size: 13px; font-weight: 500; }
.inline-note { margin-top: 10px; font-size: 12px; color: var(--text-muted); }

/* ── 레이어 검수(아코디언 내부) ── */
/* 도면 지도 프레임 — 캔버스 전체를 채운다(F-69 메인 이전). */
.layer-overlay-frame { position: absolute; inset: 0; overflow: hidden; background: var(--bg); }
/* 캔버스 오버레이 컨트롤 — 전체보기 버튼(우상단)·판정 범례(좌하단). */
.lc-fit-btn { position: absolute; top: 10px; right: 10px; z-index: 2; padding: 6px 12px; border: 1px solid var(--border); border-radius: 8px; background: rgba(255,255,255,0.92); color: var(--text); font-size: 12px; font-weight: 600; cursor: pointer; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
.lc-fit-btn:hover { border-color: var(--primary); color: var(--primary); }
.lc-legend { position: absolute; left: 10px; bottom: 10px; z-index: 2; display: flex; flex-wrap: wrap; gap: 10px; padding: 6px 10px; border-radius: 8px; background: rgba(255,255,255,0.92); box-shadow: 0 1px 3px rgba(0,0,0,0.08); font-size: 11px; color: var(--text-muted); }
.lc-lg { display: inline-flex; align-items: center; gap: 5px; }
.lc-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--ok); box-sizing: border-box; }
.lc-dot.warn { background: var(--warning); }
.lc-dot.ng { background: var(--ng); }
.lc-dot.unlabeled { background: #fca5a5; box-shadow: 0 0 0 1.5px var(--ng); }

/* ── 레이어 도면 지도(SVG 캔버스) — 캔버스 전체 채움 ── */
/* ★z-index 1 필수 — 뒤의 .lc-gl 은 positioned(absolute)라, 이게 static 이면 DOM 순서와 무관하게
   canvas 가 **위**에 칠해진다(CSS 페인팅 순서: positioned/z-auto 가 in-flow 콘텐츠보다 나중).
   그러면 배관·버팀대·라벨·영향구역 오버레이가 전부 canvas 에 가려 안 보인다. 같은 프레임의
   .lc-fit-btn(z-index 2)보다는 아래여야 하므로 1. 층: canvas(0) → 이 SVG(1) → 컨트롤(2). */
.layer-canvas { display: block; position: relative; z-index: 1; width: 100%; height: 100%; background: #fff; cursor: grab; touch-action: none; }
/* F-91 배경 GPU 면 — SVG 안엔 canvas 를 못 두므로 SVG **뒤**에 같은 크기로 깐다(포인터는 위
   SVG 가 받아야 하므로 pointer-events 없음). SVG 는 흰 배경이라 GL 활성 시 .gl-bg 로 투명하게
   비켜준다(안 그러면 canvas 가 가려진다). 흰 바탕은 canvas 가 clearColor 로 직접 칠한다.
   ★"뒤"는 DOM 순서가 아니라 위 .layer-canvas 의 z-index 가 만든다 — 그거 없으면 뒤집힌다. */
.lc-gl { position: absolute; inset: 0; display: block; width: 100%; height: 100%; pointer-events: none; }
/* GL 활성 시 SVG 안의 굽기 배경 <image> 를 숨긴다(안 그러면 canvas 를 덮는다). ★인라인
   style.display 로 숨기면 안 된다 — applyViewLayers 가 같은 인라인 속성으로 배경 표시
   토글(viewLayers.bg)을 제어하므로, GL 이 껐다 켜며 인라인을 되돌리면 **꺼둔 배경이
   되살아난다**. 클래스로만 관여해 토글의 인라인과 겹치지 않게 한다. */
.layer-canvas.gl-bg { background: transparent; }
.layer-canvas.gl-bg image { display: none; }
.layer-canvas.panning { cursor: grabbing; }
/* F-107: WebGL 배경 준비 진행 표시(굽기 <image> placeholder 대체). 캔버스 중앙 pill.
   z-index 2 = fit 버튼과 동층(SVG 위). pointer-events 없음 — 팬/줌·클릭은 아래 SVG 가 받는다. */
/* 준비 중에는 **뒤를 흐리게** 덮는다(CAD 뷰어 관행) — 미완성 배경 위에 오버레이만 떠 있는
   화면은 "이게 최종인가"로 읽힌다. 흐림이 그 상태를 명시적으로 '아직'으로 만든다.
   ★pointer-events 는 없다 — 팬/줌은 그대로 받는다(덮개는 시각적 표시일 뿐 조작 차단이 아님). */
.lc-bg-loading {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  background: rgba(248, 250, 252, 0.55);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
}
.lc-bg-loading-card {
  min-width: 340px; max-width: min(520px, 80%);
  padding: 18px 20px 16px; border-radius: var(--radius, 12px);
  background: var(--surface, #fff); border: 1px solid var(--border, #e2e8f0);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.12);
}
.lc-bg-loading-title { font-size: 14px; font-weight: 600; color: var(--text, #1e293b); }
.lc-bg-loading-file {
  margin-top: 2px; font-size: 12px; color: var(--text-muted, #64748b);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.lc-bg-loading-track {
  position: relative; overflow: hidden;
  margin: 14px 0 10px; height: 4px; border-radius: 2px; background: var(--bg, #f1f5f9);
}
/* 기본 = 불확정(좌우로 훑는 띠). 채워지는 막대가 아니라 퍼센트를 암시하지 않는다. */
.lc-bg-loading-bar {
  position: absolute; top: 0; left: -35%; width: 35%; height: 100%;
  border-radius: 2px; background: var(--primary, #00a0e8);
  animation: lcBgSweep 1.4s ease-in-out infinite;
}
/* 확정 = 실제 바이트 진행률이 있는 구간(다운로드). 왼쪽에 고정하고 폭만 키운다. */
.lc-bg-loading-track.is-determinate .lc-bg-loading-bar {
  animation: none; left: 0; transition: width .12s linear;
}
.lc-bg-loading-foot {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  font-size: 12px; color: var(--text-muted, #64748b);
}
.lc-bg-loading-elapsed { font-variant-numeric: tabular-nums; flex: none; }
@keyframes lcBgSweep { 0% { left: -35%; } 100% { left: 100%; } }
@media (prefers-reduced-motion: reduce) {
  .lc-bg-loading-bar { animation: none; left: 0; width: 100%; opacity: 0.35; }
}
.lc-seg { stroke: currentColor; stroke-width: 1.6px; vector-effect: non-scaling-stroke; stroke-linecap: round; }
.lc-seg.excluded { stroke-dasharray: 4 3; opacity: 0.3; }
.lc-bridge { stroke: currentColor; stroke-width: 1.6px; vector-effect: non-scaling-stroke; stroke-linecap: round; }
.lc-hit { stroke: transparent; stroke-width: 10px; vector-effect: non-scaling-stroke; cursor: pointer; }
/* 무채색+흐림 — 강조색이 회색 배경 위에서도 도드라지게(흐림만으로는 원색이 남아 강조가 묻힘). */
.lc-layer.dim { opacity: 0.08; filter: grayscale(1); }
.lc-layer.focus .lc-seg, .lc-layer.focus .lc-bridge { stroke-width: 2.6px; }
/* 레이어 강조 시 원본 도면 배경 — 오버레이(.lc-layer.dim)는 이미 흐려지지만 배경은 원래
   농도로 남아 강조색을 묻는다(사용자: "강조가 잘 보이지도 않아"). 배경 요소(정적 <image>·
   동적 .lc-sharp-bg 타일·GL 배경 canvas)는 팬/줌·재렌더마다 개별적으로 재생성되므로, 그
   요소 자신이 아니라 «안정적인 부모»(#layer-canvas svg 자체 · #lc-gl canvas 자체)에 클래스를
   얹고 후손 셀렉터로 내려적용한다 — 요소가 재생성돼도 부모 클래스가 살아 있으면 새로
   생긴 요소에도 그대로 걸린다(applyLayerCanvasHighlight 가 렌더 직후마다 재적용).
   값은 --bg-dim-opacity 토큰(위 :root) 단일 출처. */
.layer-canvas.bg-dim image,
.layer-canvas.bg-dim .lc-sharp-bg {
  filter: grayscale(1);
  opacity: var(--bg-dim-opacity);
}
#lc-gl.bg-dim { filter: grayscale(1); opacity: var(--bg-dim-opacity); }
/* 배관 run 선택 오버레이(F-74) — 최상위 글로우+크리스프 선 + pulse 링. 클릭 통과·월드앵커.
   버팀대 selHalo(점)의 런(선) 버전 — 팬/줌 자동 추종, non-scaling 으로 어느 줌에서도 가시. */
.lc-run-sel { pointer-events: none; }
.lc-run-glow { stroke: var(--sel); stroke-width: 9px; stroke-opacity: 0.3; vector-effect: non-scaling-stroke; stroke-linecap: round; }
.lc-run-crisp { stroke: var(--sel); stroke-width: 4.5px; vector-effect: non-scaling-stroke; stroke-linecap: round; }
.lc-run-ring { fill: none; stroke: var(--sel); stroke-width: 2.5px; vector-effect: non-scaling-stroke; transform-box: fill-box; transform-origin: center; animation: runPing 0.7s ease-out 3 forwards; }
@keyframes runPing { 0% { transform: scale(0.4); stroke-opacity: 0.9; } 100% { transform: scale(1.7); stroke-opacity: 0; } }
/* 배관 분리(Option C) — 절단점 마커(월드앵커) + 분리 모드 커서. */
.lc-split-cut { fill: #dc2626; stroke: #fff; stroke-width: 1.5px; vector-effect: non-scaling-stroke; pointer-events: none; }
#layer-canvas.split-mode { cursor: crosshair; }
/* 구간 오버레이(F-85) — 선택 런을 구간별 구분색 폴리라인 + 번호 배지로 표시(구간 1/2 위치·분할
   미리보기). 라인=world 좌표(팬/줌 추종)·non-scaling(화면 굵기 일정), 배지 폰트=vb 상대(줌 훅
   재렌더로 화면크기 일정). pointer-events:none(클릭 통과 — 분리 모드 절단 클릭 방해 금지). */
.lc-run-sections { pointer-events: none; }
.lc-sec-line { stroke: var(--sec); stroke-width: 5px; stroke-opacity: 0.85; vector-effect: non-scaling-stroke; stroke-linecap: round; }
.lc-sec-line.emph { stroke-width: 8px; stroke-opacity: 1; }
.lc-sec-leader { stroke: var(--sec); stroke-width: 1.5px; stroke-opacity: 0.7; vector-effect: non-scaling-stroke; }
.lc-sec-leader.emph { stroke-width: 2.5px; stroke-opacity: 1; }
.lc-sec-badge-bg { fill: var(--sec); stroke: #fff; stroke-width: 2px; vector-effect: non-scaling-stroke; }
.lc-sec-badge-bg.emph { stroke-width: 3px; }
.lc-sec-badge { fill: #fff; font-weight: 800; pointer-events: none; paint-order: stroke; stroke: rgba(0,0,0,0.25); stroke-width: 0.5px; }
/* 구간 팔레트 — ⚠선택 런 강조색(--sel #f59e0b)과 같은 값을 쓰면 안 된다. 굵기도
   4.5px 대 5px 라 화면에서 «구간 2» 인지 «선택 런» 인지 구분이 불가능해진다(실제 오인
   신고: 구간에 안 든 본선이 구간 2 로 읽혔다). c1 은 그래서 자홍으로 뺐다. */
.lc-sec-line.c0, .lc-sec-leader.c0, .lc-sec-badge-bg.c0 { --sec: #2563eb; }
.lc-sec-line.c1, .lc-sec-leader.c1, .lc-sec-badge-bg.c1 { --sec: #db2777; }
.lc-sec-line.c2, .lc-sec-leader.c2, .lc-sec-badge-bg.c2 { --sec: #10b981; }
.lc-sec-line.c3, .lc-sec-leader.c3, .lc-sec-badge-bg.c3 { --sec: #8b5cf6; }
/* «나머지» — 어느 구간에도 안 든 부분. 지정 구간과 구분되도록 무채색 + 파선.
   rem-base = 파선 «틈»을 메우는 불투명 바탕. 없으면 틈으로 선택 런 강조색(앰버)이 비쳐
   회색이 아니라 «회색+주황 얼룩»으로 읽힌다(구간 색 c1 을 주황에서 뺀 것과 같은 이유). */
.lc-sec-line.rem, .lc-sec-leader.rem, .lc-sec-badge-bg.rem { --sec: #64748b; }
.lc-sec-line.rem { stroke-dasharray: 10 6; stroke-opacity: 1; --sec: #334155; }
.lc-sec-line.rem-base { stroke: #cbd5e1; stroke-opacity: 1; }
.lc-brace { fill: var(--ok); stroke: #fff; stroke-width: 1px; vector-effect: non-scaling-stroke; pointer-events: none; }
.lc-brace.warn { fill: var(--warning); }
.lc-brace.ng { fill: var(--ng); }
.lc-brace.unknown { fill: var(--text-muted); }
.lc-brace.unlabeled { fill: #fca5a5; stroke: var(--ng); }
.lc-brace-hover { fill: none; stroke: var(--text); stroke-width: 1.5px; stroke-opacity: 0.55; vector-effect: non-scaling-stroke; pointer-events: none; }
.lc-brace-sel { fill: none; stroke: var(--primary); stroke-width: 2.4px; vector-effect: non-scaling-stroke; pointer-events: none; }
/* 버팀대 마커 사각형(F-80c WYSIWYG) — DXF MARK 블록 footprint 크기·회전. 옅은 판정 fill +
   판정색 테두리(줌 무관 얇은 선). groove 는 .lc-brace 원(위) 유지. */
.lc-marker { fill: var(--ok); fill-opacity: 0.22; stroke: var(--ok); stroke-width: 1.5px; vector-effect: non-scaling-stroke; pointer-events: none; }
.lc-marker.warn { fill: var(--warning); stroke: var(--warning); }
.lc-marker.ng { fill: var(--ng); stroke: var(--ng); }
.lc-marker.unknown { fill: var(--text-muted); stroke: var(--text-muted); }
.lc-marker.unlabeled { fill: #fca5a5; stroke: var(--ng); }
/* 가지(스프링클러) 버팀대 마름모 안의 십자 — 판정색 테두리와 같은 색·fill 없음. */
.lc-marker-cross { fill: none; stroke: var(--ok); stroke-width: 1.2px; vector-effect: non-scaling-stroke; pointer-events: none; }
.lc-marker-cross.warn { stroke: var(--warning); }
.lc-marker-cross.ng { stroke: var(--ng); }
.lc-marker-cross.unknown { stroke: var(--text-muted); }
.lc-marker-cross.unlabeled { stroke: var(--ng); }
.lc-zones { pointer-events: none; }
.lc-zone-path { stroke-width: 1.2px; vector-effect: non-scaling-stroke; }
.lc-zones.lat .lc-zone-path { fill: rgba(37,99,235,0.12); stroke: rgba(37,99,235,0.7); }
.lc-zones.long .lc-zone-path { fill: rgba(168,85,247,0.12); stroke: rgba(168,85,247,0.7); }
/* fourway 분기점 박스 — 중립색(슬레이트). DXF 가 color 7(중립)로 그리는 것과 맞춘다:
   횡(파랑)·종(보라) 어느 쪽으로도 읽히면 안 되는 «두 역할 동시» 지점이기 때문. */
.lc-zones.fourway .lc-zone-path { fill: rgba(100,116,139,0.12); stroke: rgba(100,116,139,0.7); }
.lc-zone-legend { position: absolute; left: 10px; bottom: 44px; z-index: 2; display: flex; flex-wrap: wrap; gap: 10px; padding: 6px 10px; border-radius: 8px; background: rgba(255,255,255,0.92); box-shadow: 0 1px 3px rgba(0,0,0,0.08); font-size: 11px; color: var(--text-muted); }
.lc-zlg { display: inline-flex; align-items: center; gap: 5px; }
.lc-zsw { width: 12px; height: 9px; border-radius: 2px; box-sizing: border-box; }
.lc-zsw.lat { background: rgba(37,99,235,0.18); border: 1.5px solid rgba(37,99,235,0.75); }
.lc-zsw.long { background: rgba(168,85,247,0.18); border: 1.5px solid rgba(168,85,247,0.75); }
/* 가지(스프링클러) 버팀대 심볼 칩 — 캔버스 마커(.lc-marker/.lc-marker-cross)와 같은 모양. */
.lc-zsym { width: 12px; height: 12px; }
.lc-zsym polygon { fill: rgba(22,163,74,0.22); stroke: var(--ok); stroke-width: 1.2; }
.lc-zsym path { fill: none; stroke: var(--ok); stroke-width: 1.2; }
/* 뷰 레이어 토글 strip — canvas-toolbar 안에서 floating. */
.lc-view-toggles { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.lc-vt-label { font-size: 12px; font-weight: 600; color: var(--text-muted); margin-right: 2px; }
.lc-vt { padding: 5px 12px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); color: var(--text-muted); font-size: 12px; font-weight: 600; cursor: pointer; }
.lc-vt:hover { border-color: var(--primary); color: var(--primary); }
.lc-vt.on { background: var(--primary); color: #fff; border-color: var(--primary); }
.lc-dir { padding: 5px 12px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); color: var(--text-muted); font-size: 12px; font-weight: 600; cursor: pointer; }
.lc-dir:hover:not(:disabled) { border-color: var(--primary); color: var(--primary); }
.lc-dir.on { background: var(--primary); color: #fff; border-color: var(--primary); }
.lc-dir:disabled, .lc-dir.disabled { opacity: 0.4; cursor: not-allowed; }
.lc-layout { padding: 5px 12px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); color: var(--text-muted); font-size: 12px; font-weight: 600; cursor: pointer; }
.lc-layout:hover { border-color: var(--primary); color: var(--primary); }
.lc-layout.on { background: var(--primary); color: #fff; border-color: var(--primary); }
.lc-split-label { fill: var(--text); stroke: #fff; paint-order: stroke; font-weight: 700; text-anchor: start; dominant-baseline: text-after-edge; pointer-events: none; }
/* 버팀대 식별번호 라벨(F-79·F-80c) — 방향색 채움. 흰 배경은 아래 .lc-blabel-box(태그)가 제공.
   회전 그룹 안(0,0)에 중앙정렬. 히트는 geometric labelHitTest(pointer-events:none). */
.lc-blabel { font-weight: 700; pointer-events: none; }
.lc-blabel.lateral { fill: var(--dir-lat); }
.lc-blabel.longitudinal { fill: var(--dir-long); }
.lc-blabel.none { fill: var(--text); }
/* 라벨 테두리 박스(F-80c) — DXF TAG10 과 동일(흰 배경 WIPEOUT + 방향색 테두리). 크기·회전은
   backend b.label_box(world)를 appendCanvasBraces 가 그대로 렌더. */
.lc-blabel-box { fill: rgba(255,255,255,0.9); stroke-width: 1px; vector-effect: non-scaling-stroke; pointer-events: none; }
.lc-blabel-box.lateral { stroke: var(--dir-lat); }
.lc-blabel-box.longitudinal { stroke: var(--dir-long); }
.lc-blabel-box.none { stroke: var(--text-muted); }
.layer-canvas.label-dragging { cursor: grabbing; }
/* 라벨 이동 미적용 → 재분석 pill(우하). 기존 편집 모델 동일 = 편집 적재·재분석이 적용·DXF 재생성. */
.lc-label-pill { position: absolute; right: 10px; bottom: 10px; z-index: 3; padding: 7px 13px; border: 1px solid var(--primary); border-radius: 999px; background: var(--primary); color: #fff; font-size: 12px; font-weight: 700; cursor: pointer; box-shadow: 0 2px 6px rgba(0,0,0,0.16); }
.lc-label-pill:hover { filter: brightness(1.06); }
.lc-floors { pointer-events: none; }
.lc-floor-rect { fill: none; stroke: #f59e0b; stroke-width: 1.4px; stroke-dasharray: 8 5; vector-effect: non-scaling-stroke; }
.lc-floor-label { fill: #b45309; stroke: #fff; paint-order: stroke; font-weight: 700; text-anchor: middle; dominant-baseline: middle; }
.lc-layer.layer-excluded .lc-seg, .lc-layer.layer-excluded .lc-bridge { opacity: 0.3; stroke-dasharray: 4 3; }
/* 인라인 선택 툴바(①) — 도면 위 배관 클릭 시 상단 중앙 노출. */
.lc-sel-bar { position: absolute; top: 10px; left: 50%; transform: translateX(-50%); z-index: 3; display: flex; align-items: center; gap: 8px; padding: 6px 8px 6px 12px; border: 1px solid var(--border); border-radius: 10px; background: rgba(255,255,255,0.96); box-shadow: 0 2px 8px rgba(0,0,0,0.12); font-size: 12px; }
.lc-sel-chip { width: 12px; height: 12px; border-radius: 3px; box-sizing: border-box; flex: none; }
.lc-sel-name { font-weight: 600; color: var(--text); max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lc-sel-btn { padding: 4px 12px; border: 1px solid var(--primary); border-radius: 7px; background: var(--primary); color: #fff; font-size: 12px; font-weight: 600; cursor: pointer; }
.lc-sel-btn.is-excluded { background: #fff; color: var(--primary); }
/* 버팀대 상세 hover 프리뷰(F-56) — 클릭 상세는 우측 선택 카드로. */
.lc-brace-detail { position: absolute; z-index: 4; min-width: 180px; max-width: 264px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; background: rgba(255,255,255,0.98); box-shadow: 0 4px 14px rgba(0,0,0,0.16); font-size: 12px; color: var(--text); pointer-events: none; }
.lc-brace-detail.pinned { pointer-events: auto; }
.lc-bd-close { position: absolute; top: 6px; right: 6px; width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; border: none; border-radius: 6px; background: transparent; color: var(--text-muted); cursor: pointer; }
.lc-bd-close:hover { background: var(--border); color: var(--text); }
.lc-bd-close svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; }
.lc-bd-title { font-weight: 700; font-size: 13px; color: var(--text); margin-bottom: 8px; padding-right: 20px; }
.lc-bd-rows { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; margin: 0; }
.lc-bd-rows dt { color: var(--text-muted); font-weight: 600; white-space: nowrap; }
.lc-bd-rows dd { margin: 0; color: var(--text); text-align: right; word-break: keep-all; }
.lc-bd-verdict { display: inline-block; padding: 1px 8px; border-radius: 999px; font-weight: 700; font-size: 11px; color: #fff; }
.lc-bd-verdict.ok { background: var(--ok); }
.lc-bd-verdict.warn { background: var(--warning); }
.lc-bd-verdict.ng { background: var(--ng); }
.lc-bd-verdict.unknown { background: var(--text-muted); }
.lc-sel-x { display: inline-flex; padding: 4px; border: none; background: none; color: var(--text-muted); cursor: pointer; border-radius: 6px; }
.lc-sel-x:hover { background: var(--bg); color: var(--text); }
.lc-sel-x svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2; }
/* 레이어 색범례(②) — 우측 접이식 패널. */
.lc-layer-legend { position: absolute; top: 46px; right: 10px; z-index: 2; width: 190px; border: 1px solid var(--border); border-radius: 8px; background: rgba(255,255,255,0.94); box-shadow: 0 1px 3px rgba(0,0,0,0.08); overflow: hidden; }
.lc-ll-head { display: flex; align-items: center; justify-content: space-between; width: 100%; padding: 6px 10px; border: none; background: none; cursor: pointer; font-size: 12px; font-weight: 600; color: var(--text); }
.lc-ll-caret svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; transition: transform 0.15s; display: block; }
.lc-ll-head[aria-expanded="false"] .lc-ll-caret svg { transform: rotate(-90deg); }
.lc-ll-body { max-height: 180px; overflow-y: auto; display: flex; flex-direction: column; padding: 0 4px 4px; }
.lc-ll-body.collapsed { display: none; }
/* 선 종류 범례(실선/점선) — 색 목록과 함께 접힌다. */
.lc-ll-note { padding: 5px 10px 7px; font-size: 10.5px; line-height: 1.4; color: var(--text-muted); border-top: 1px solid var(--border); }
.lc-ll-body.collapsed + .lc-ll-note { display: none; }
.lc-ll-item { display: flex; align-items: center; gap: 7px; width: 100%; padding: 4px 6px; border: none; background: none; cursor: pointer; border-radius: 6px; text-align: left; }
.lc-ll-item:hover { background: var(--bg); }
.lc-ll-item.active { background: var(--primary-tint, #e6f4fc); }
.lc-ll-chip { width: 12px; height: 9px; border-radius: 2px; box-sizing: border-box; flex: none; }
.lc-ll-name { font-size: 11px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── 레이어 목록 ── */
.layer-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.layer-item { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); cursor: pointer; transition: border-color .12s, box-shadow .12s, background .12s; flex-wrap: wrap; }
.layer-item:hover { border-color: var(--primary); }
.layer-item.highlight { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary-ring); background: var(--primary-tint); }
.layer-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 140px; }
.layer-name { font-weight: 600; font-size: 13px; color: var(--text); word-break: break-all; }
.layer-meta { font-size: 11px; color: var(--text-muted); }
/* ⛔레이어 행에는 상태별 표식(흐림·취소선·의심 붉은 박스)을 두지 않는다(2026-09-02 사용자
   지시) — 모든 행이 같은 카드고, 켜짐/꺼짐은 스위치(.layer-toggle/.layer-head-toggle) 색으로만
   읽는다. 배관 목록(.pipe-size-row.excluded)은 별개 축이라 종전 관례를 유지한다. */
/* 레이어 행 요소 지정 스위치 — 「배관 요소」(.layer-toggle)·「스프링클러 요소」
   (.layer-head-toggle)가 **같은 생김새**여야 한다(2026-09-02 사용자 지시). 클래스를 합치지는
   않는다 — `#layer-list .layer-toggle` 는 배관 포함 토글 «수집» 선택자라 헤드 스위치가 끼면
   포함/제외로 오독된다(app.js createLayerHeadToggle 주석 참조). 룩만 선택자 병기로 공유. */
.layer-toggle, .layer-head-toggle { display: inline-flex; align-items: center; gap: 8px; flex-shrink: 0; padding: 5px 8px 5px 12px; border: 1px solid var(--border); border-radius: 999px; background: var(--bg); color: var(--text-muted); font-size: 12px; font-weight: 600; cursor: pointer; transition: all .15s; }
.layer-toggle.on, .layer-head-toggle.on { background: var(--primary-tint); border-color: var(--primary); color: var(--primary); }
.layer-toggle-text { line-height: 1; white-space: nowrap; }
.layer-knob { width: 16px; height: 16px; border-radius: 50%; background: var(--text-muted); transition: background .15s; }
.layer-toggle.on .layer-knob, .layer-head-toggle.on .layer-knob { background: var(--primary); }
.layer-toggle:focus-visible, .layer-head-toggle:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
/* 요소 지정 스위치 2개는 «세로 스택»이다(2026-09-02 사용자 결정) — 가로로 늘어놓으면 행
   오른쪽 절반을 덮어 «행 중앙» 클릭이 스위치 위에 떨어진다(행 클릭=도면 강조 계약이 죽고,
   누르려던 적도 없는 포함 스위치가 켜진다. elementFromPoint 로 실측). */
.layer-controls { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex-shrink: 0; cursor: default; }
#layer-reanalyze-btn:disabled { opacity: .5; cursor: not-allowed; }
.layer-bulk-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.layer-bulk-row .btn-ghost { margin-top: 0; }
.layer-name-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.layer-chip { width: 12px; height: 12px; border-radius: 3px; flex-shrink: 0; border: 1px solid rgba(0,0,0,.12); }

/* ── 버팀대 목록(F-71) — 버팀대·하중 탭. 판정 나쁜 순 + 필터 칩 + 행 클릭=도면 강조. ── */
.brace-filter { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.brace-chip { padding: 5px 11px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); color: var(--text-muted); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; font-variant-numeric: tabular-nums; }
.brace-chip:hover { border-color: var(--primary); color: var(--primary); }
.brace-chip.active { background: var(--primary); border-color: var(--primary); color: #fff; }
.brace-chip.chip-ng.active { background: var(--ng); border-color: var(--ng); }
.brace-chip.chip-warn.active { background: var(--warning); border-color: var(--warning); }
.brace-list { display: flex; flex-direction: column; gap: 6px; }
.brace-list-empty { font-size: 12px; color: var(--text-muted); text-align: center; padding: 16px 0; }
.brace-row { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; padding: 9px 11px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); cursor: pointer; font: inherit; transition: border-color .12s, box-shadow .12s, background .12s; }
.brace-row:hover { border-color: var(--primary); }
.brace-row.selected { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary-ring); background: var(--primary-tint); }
.brace-row-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--ok); box-sizing: border-box; }
.brace-row-dot.warn { background: var(--warning); }
.brace-row-dot.ng { background: var(--ng); }
.brace-row-dot.unknown { background: var(--text-muted); }
.brace-row-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.brace-row-label { font-size: 13px; font-weight: 700; color: var(--text); }
.brace-row-meta { font-size: 11px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.brace-row-verdict { flex: none; } /* .lc-bd-verdict 재사용(판정 pill 색·라벨) */

/* 검수 단계 게이트 — 레이어 확정 버튼 + 상태 안내(레이어 탭 하단). */
.panel-confirm { width: 100%; margin-top: 4px; padding: 11px; font-size: 14px; }
.layer-gate-note { margin: 6px 0 0; font-size: 12px; color: var(--text-muted); line-height: 1.5; }
.layer-gate-note.gate-locked { color: #b42318; font-weight: 600; }
/* ── 배관 관경 컨트롤(F-68 이식) — 선택 카드 + 배관·관경 목록 공용 ── */
.pipe-size-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
/* 숨김 행 고지(결번 착시 해소) — 표시/전체/숨김 건수 + 「모두 보기」. */
.pipe-size-hidden { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; padding: 8px 12px; border: 1px dashed var(--border); border-radius: 10px; background: var(--bg); }
.pipe-size-hidden .pshn-text { flex: 1 1 auto; font-size: 12px; color: var(--text-muted); }
.pipe-size-hidden .pshn-btn { flex: 0 0 auto; margin-top: 0; padding: 6px 12px; }
.pipe-size-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 10px 12px; border: 1px solid var(--border); border-radius: 10px; background: var(--surface); cursor: pointer; }
.pipe-size-row:hover { border-color: var(--primary); }
.pipe-size-row.highlight { border-color: var(--sel); box-shadow: 0 0 0 2px rgba(245,158,11,.18); }
/* 제외 토글(F-XXX) — 배관 행은 흐리게 + 취소선(레이어 행과 달리 표식을 유지한다). */
.pipe-size-row.excluded .psr-label { text-decoration: line-through; color: var(--text-muted); }
.pipe-size-row.excluded .psr-meta { opacity: 0.5; }
.pipe-size-row .psr-label { font-weight: 600; font-size: 13px; color: var(--text); flex: 0 0 auto; }
.pipe-size-row .psr-meta { font-size: 11px; color: var(--text-muted); flex: 1 1 auto; }
/* 도면값 채택이 배치 조건을 건드릴 수 있는 행의 고지 — 채택은 하되 «조용히» 하지 않는다.
   행 전체 폭을 차지해 컨트롤 아래 줄로 내려간다(입력 위치 고정 규칙과 동일). */
/* 비소화 계통 의심(advisory, F-nonfire) — 급수·배수 배관이 레이어명 "소방"으로 소화배관
   오검출된 걸 지목만 하는 배지. 판정색 --warning 재사용(새 색 추가 금지). */
.pipe-size-row .psr-nonfire-badge { flex: 0 0 auto; font-size: 10.5px; font-weight: 700; color: #fff; background: var(--warning); border-radius: 8px; padding: 1px 6px; line-height: 1.6; }
.pipe-size-row .psr-spacing-badge { flex: 0 0 auto; font-size: 10.5px; font-weight: 700; color: #fff; background: var(--ng); border-radius: 8px; padding: 1px 6px; line-height: 1.6; }
/* 조건부(H1) — 확정(ng, 빨강)과 시각적으로 분리되어야 한다. 가지배관 여부가 미확인이라는
   뜻이므로 warning(주황) 계열 + 점선 테두리로 「경고 미만·확인 필요」임을 구분한다. */
.pipe-size-row .psr-spacing-check-badge { flex: 0 0 auto; font-size: 10.5px; font-weight: 700; color: var(--warning); background: #fff; border: 1px dashed var(--warning); border-radius: 8px; padding: 0px 5px; line-height: 1.6; }
/* 제13조①8 면제(High2, 2026-08-28 4차 리뷰) — 위반도 경고도 아닌 «판정 제외» 상태라
   ng/warning 톤과 분리한다(중립 회색). */
.pipe-size-row .psr-spacing-exempt-badge { flex: 0 0 auto; font-size: 10.5px; font-weight: 700; color: var(--text-muted); background: #fff; border: 1px dashed var(--border); border-radius: 8px; padding: 0px 5px; line-height: 1.6; }
/* run 제외 구간(≤1.2m 물리런) — 관경 «입력 필요» 게이트 밖(표시 전용). */
.pipe-size-row .psr-size-exempt-badge { flex: 0 0 auto; font-size: 10.5px; font-weight: 700; color: var(--text-muted); background: #fff; border: 1px dashed var(--border); border-radius: 8px; padding: 0px 5px; line-height: 1.6; }
/* 설정 모달 사이드 탭(2026-09-01, 상단 스트립 → 왼쪽 세로 — 사용자 요청) */
.settings-layout { display: flex; flex: 1; min-height: 0; }
.settings-tabs {
  flex: 0 0 148px; display: flex; flex-direction: column; gap: 2px;
  padding: 12px 8px; border-right: 1px solid var(--border); background: var(--bg);
}
.settings-tab {
  display: flex; align-items: center; width: 100%; padding: 9px 12px;
  border: none; border-left: 2px solid transparent; border-radius: 8px;
  background: none; cursor: pointer; text-align: left;
  font-size: 13px; font-weight: 600; color: var(--text-muted); white-space: nowrap;
}
.settings-tab:hover { color: var(--text); background: var(--surface); }
.settings-tab.active { color: var(--primary); background: var(--primary-tint); border-left-color: var(--primary); border-radius: 0 8px 8px 0; }

/* 스프링클러 헤드 기준 적용 범위(전역/현재 도면) — 알약형 세그먼트. */
.head-sizes-scope { display: flex; gap: 6px; margin-bottom: 10px; }
.scope-btn { padding: 6px 12px; border: 1px solid var(--border); border-radius: 999px; background: none; font-size: 12px; font-weight: 600; color: var(--text-muted); cursor: pointer; }
.scope-btn:hover:not(:disabled) { color: var(--text); border-color: var(--text-muted); }
.scope-btn.active { color: var(--primary); border-color: var(--primary); background: var(--primary-tint); }
.scope-btn:disabled { opacity: .45; cursor: not-allowed; }

/* «스프링클러 요소» 스위치 고유 규칙 — 공통 룩(형태·knob·on 색)은 위 .layer-toggle 병기
   선언이 단일 출처다. 여기엔 hover 만 남긴다. */
.layer-head-toggle:hover { color: var(--text); border-color: var(--text-muted); }
/* ⑥ — 잠금 사유 문구가 클릭 가능한 상태(관경 미인식 점프) */
.place-hint.gate-jump { cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }

/* 관경 미인식 — 입력 필요(2차 분석 게이트 대상). 경고 톤 채움 배지 + 입력칸 강조 테두리. */
.pipe-size-row .psr-size-required-badge { flex: 0 0 auto; font-size: 10.5px; font-weight: 700; color: #fff; background: var(--warning); border-radius: 8px; padding: 1px 6px; line-height: 1.6; }
.pipe-size-row.size-required .pipe-size-input { border-color: var(--warning); }
/* 런 그룹 뷰(S2, 표시 전용) — 헤더 button + 접히는 상자. 정상 배관의 «묶어 보기»다. */
.pipe-run-group-bar { display: flex; justify-content: flex-end; margin: 0 0 8px; }
.pipe-run-group-bar .prg-btn { padding: 6px 12px; margin-top: 0; }
.pipe-run-head { width: 100%; margin-top: 4px; padding: 8px 12px; border: 1px solid var(--border);
  border-radius: 10px; background: var(--surface-muted, #f7f8fa); color: var(--text);
  font-size: 12px; font-weight: 700; text-align: left; cursor: pointer; }
.pipe-run-head:hover { border-color: var(--primary); }
.pipe-run-head[aria-expanded="true"] { border-color: var(--primary); }
/* 그룹 안 행은 살짝 들여써 «이 런에 속한 조각»이 눈으로 읽히게. */
.pipe-run-group { display: flex; flex-direction: column; gap: 8px; margin: 8px 0 8px 12px; }
.pipe-size-row .psr-adopt-risk { flex: 1 0 100%; font-size: 11px; color: var(--text-muted); }
.pipe-size-row .psr-adopt-risk.ng { color: var(--ng); }
/* 지정 동일성 검증 실패(ADR-0008) — 도면 재인식으로 라벨이 다른 배관을 가리키게 돼
   지정(관경·제외·분리·구간 등)이 적용되지 않은 행. 행 배지 + 요약 배너 공용 톤. */
.pipe-size-row .psr-identity-flag { flex: 1 0 100%; font-size: 11px; color: #b42318; font-weight: 600; }
/* H-B(diff-review 3차) — 관경 지정 미적용의 «방향»(버팀대 소멸 위험) 고지. 실패 배지(빨강)와
   구분되게 주황 계열을 쓴다 — 실패가 아니라 그 실패의 결과 방향을 알리는 것이라 톤이 다르다. */
.pipe-size-row .psr-size-revert-warn { flex: 1 0 100%; font-size: 11px; color: #b54708; font-weight: 600; }
.identity-notice { font-size: 12px; color: #b42318; background: #fef3f2; border: 1px solid #fecdca; border-radius: 8px; padding: 10px 12px; margin: 0 0 14px; }
.identity-notice-head { font-weight: 700; margin: 0 0 4px; line-height: 1.5; }
/* H-A(diff-review 3차) — reason 별 실제 사유 문장. head(총량)와 breakdown(필드별 건수) 사이. */
.identity-notice-reasons { color: #9f2f22; margin: 0 0 4px; font-size: 11px; }
.identity-notice-breakdown { color: #9f2f22; margin: 0 0 8px; font-size: 11px; }
/* H-B(diff-review 3차) — 위 psr-size-revert-warn 과 동일 취지·동일 톤(주황), 요약 배너 쪽. */
.identity-notice-size-warn { color: #b54708; font-weight: 600; margin: 0 0 8px; font-size: 11px; }
.identity-notice-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.identity-notice-chip { font: inherit; font-size: 11px; padding: 3px 10px; border: 1px solid #fecdca; border-radius: 999px; background: #fff; color: #b42318; cursor: pointer; font-weight: 600; }
.identity-notice-chip:hover { background: #fef3f2; border-color: #f97066; }
.identity-notice-chip-disabled { cursor: default; opacity: 0.55; }
.identity-notice-chip-disabled:hover { background: #fff; border-color: #fecdca; }
.identity-notice-tip { font-size: 11px; color: #9f2f22; margin: 0; }
/* M8 — 자동 채택분 고지는 실패가 아니라 정보성이라 위 실패 계열(빨강)과 다른 톤을 쓴다. */
.identity-notice-auto { font-size: 11px; color: #7a7a7a; margin: 0; }
/* M-3(diff-review 3차) — 적용됐지만(rebound) 제외 배관이라 반영되지 않은 지정. 실패가
   아니므로 빨강 대신 중립 톤이되, 조용히 사라지지 않게 별도 문단으로 항상 보인다. */
.identity-notice-ineffective-head { font-weight: 700; margin: 10px 0 2px; color: #475467; font-size: 12px; }
.identity-notice-ineffective-list { font-size: 11px; color: #667085; margin: 0; }
.pipe-size-ctrl { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* 배관 목록 행(F-73) — 컨트롤을 항상 자체 줄 full-width로 내려 입력 위치 고정.
   (배지 유무로 ctrl이 1줄 우측/2줄 좌측 오가던 깨짐 방지. sel-card 안 컨트롤은 직계 아님=미영향.) */
.pipe-size-row > .pipe-size-ctrl { flex-basis: 100%; margin-top: 6px; }
/* 배관 단위 주/가지 역할 지정(A-0012 대체) — pipe-size-ctrl 과 동일 관례(자체 줄 full-width). */
.pipe-role-ctrl { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pipe-size-row > .pipe-role-ctrl { flex-basis: 100%; margin-top: 6px; }
.pipe-role-detected { font-size: 11px; color: var(--text-muted); flex: 0 0 auto; }
.pipe-role-dd { min-width: 96px; }
.pipe-role-dd .floor-dd-btn { padding: 6px 10px; font-size: 12px; }
.size-input { width: 62px; padding: 6px 8px; border: 1px solid var(--border); border-radius: 8px; text-align: right; font: inherit; font-size: 13px; }
.size-input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-ring); }
.pipe-size-unit { font-size: 12px; color: var(--text-muted); }
.pipe-size-detected { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; padding: 3px 8px; border-radius: 999px; background: var(--surface); border: 1px solid var(--primary-tint-strong); flex-wrap: wrap; }
.pipe-size-detected.warn { background: #fffbeb; border-color: #fcd34d; }
.pipe-size-detected.danger { background: #fef2f2; border-color: #fca5a5; }
.pipe-size-detected.adopted { background: #f0fdf4; border-color: #bbf7d0; } /* 도면값 채택됨(F-73 #4) */
.pipe-size-applied { font-size: 10px; font-weight: 700; color: #15803d; padding: 1px 6px; }
.pipe-size-detected b { font-weight: 800; }
.conf { font-size: 10px; font-weight: 700; padding: 1px 6px; border-radius: 999px; background: #dcfce7; color: #15803d; }
.conf.conf-mid { background: #fef9c3; color: #a16207; }
.conf.conf-low { background: #f1f5f9; color: var(--text-muted); }
.pipe-size-use { font-size: 11px; padding: 2px 9px; border: 1px solid var(--primary); color: var(--primary); background: #fff; border-radius: 999px; cursor: pointer; }
.pipe-size-use:hover { background: var(--primary-tint); }
.pipe-size-note { font-size: 11px; color: #b45309; flex-basis: 100%; margin-top: 2px; }
.pipe-size-note.danger { color: #b91c1c; font-weight: 600; }
/* 배관 분리 → 구간별 관경(Option C) — 선택 카드 내. */
.pipe-split { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--border); display: flex; flex-direction: column; gap: 8px; }
.pipe-split-title { font-size: 12px; font-weight: 700; color: var(--text); }
.pipe-split-help { font-size: 11px; color: var(--text-muted); line-height: 1.5; margin: -2px 0 2px; }
.pipe-split-start { align-self: flex-start; font-size: 12px; padding: 5px 12px; border: 1px solid var(--primary); color: var(--primary); background: #fff; border-radius: 8px; cursor: pointer; font-weight: 600; }
.pipe-split-start:hover { background: var(--primary-tint); }
.pipe-split-hint { font-size: 12px; color: #b45309; background: #fffbeb; border: 1px solid #fcd34d; border-radius: 8px; padding: 7px 10px; line-height: 1.4; }
/* 확정 거부 사유(겹침·단절) — 힌트 안에서 한 단계 강한 톤. */
.pipe-split-warn { margin-top: 6px; padding-top: 6px; border-top: 1px solid #fcd34d; color: #b91c1c; font-weight: 600; }
.pipe-split-actions { display: flex; gap: 8px; }
.pipe-split-apply { flex: 1 1 auto; font-size: 12px; padding: 6px 10px; border: none; background: var(--primary); color: #fff; border-radius: 8px; cursor: pointer; font-weight: 700; }
.pipe-split-apply:disabled { background: var(--border); color: var(--text-muted); cursor: default; }
.pipe-split-cancel { flex: 0 0 auto; font-size: 12px; padding: 6px 12px; border: 1px solid var(--border); background: #fff; color: var(--text-muted); border-radius: 8px; cursor: pointer; }
.pipe-split-undo { flex: 0 0 auto; font-size: 12px; padding: 6px 12px; border: 1px solid var(--border); color: var(--text); background: #fff; border-radius: 8px; cursor: pointer; }
.pipe-split-undo:hover { border-color: var(--primary); color: var(--primary); }
.pipe-split-sec { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pipe-split-sec-label { font-size: 12px; color: var(--text-muted); min-width: 72px; }
.pipe-split-sec-input { width: 72px; }

/* F-89 진행 중 표시 — 점이 "." → ".." → "..." 로 순환.
   ★애니메이션 자체는 살아있음을 증명하지 못한다(서버가 죽어도 계속 돈다). 살아있음의
   근거는 **막대**다 — 서버 하트비트의 실경과초로만 움직이므로 서버가 멈추면 같이 멈춘다.
   점은 "작업 중"을 읽히게 하는 보조 신호. */
.progress-dots::after {
  content: "";
  animation: progress-dots 1.2s steps(1, end) infinite;
}
@keyframes progress-dots {
  0%   { content: "."; }
  33%  { content: ".."; }
  66%  { content: "..."; }
  100% { content: "."; }
}
@media (prefers-reduced-motion: reduce) {
  .progress-dots::after { animation: none; content: "..."; }
}
