/* 대흥정밀 생산/금형 EMR — 스타일 */

/* ===== 폰트: 나눔스퀘어 self-host (사내망·오프라인에서도 각 PC 설치 없이 동작) =====
   R=400(본문 기본) · B=700(강조: 제목·값·지표·표데이터) · EB=800(여유분) */
@font-face { font-family:'NanumSquare'; font-weight:400; font-style:normal; font-display:swap; src:url('/fonts/NanumSquareR.woff2') format('woff2'); }
@font-face { font-family:'NanumSquare'; font-weight:700; font-style:normal; font-display:swap; src:url('/fonts/NanumSquareB.woff2') format('woff2'); }
@font-face { font-family:'NanumSquare'; font-weight:800; font-style:normal; font-display:swap; src:url('/fonts/NanumSquareEB.woff2') format('woff2'); }

/* ★색·크기 토큰은 /css/tokens.css(세 앱 공통, index.html에서 style.css보다 먼저 로드) — 여기서는 정의하지 않는다. 09-10 디자인 1단계 */
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
/* 뷰 전환 시 세로 스크롤바 생겼다/사라졌다로 화면이 흔들리는 것 방지 */
html { scrollbar-gutter: stable; }
body {
  /* 나눔스퀘어(self-host) 우선 → 미로드 시 맑은고딕 대체. 한글·숫자·영문 모두 나눔스퀘어로 통일 */
  font-family: "NanumSquare", "Malgun Gothic", "맑은 고딕", system-ui, sans-serif;
  background: var(--bg); color: var(--ink); font-size: 14px; line-height: 1.45;
  /* ★ 전역 기본 굵기 = 400(Regular). 강조는 개별 요소에서만 700(제목·값·지표·표데이터). */
  font-weight: 400;
}
#app { min-height: 100vh; }

/* ===== 상단 네비 ===== */
.topnav {
  display: flex; align-items: center; gap: 24px;
  background: var(--panel); border-bottom: 1px solid var(--line);
  padding: 0 20px; height: 56px; position: sticky; top: 0; z-index: 50;
  box-shadow: var(--shadow);
}
.brand { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 15px; white-space: nowrap; }
.brand .logo { font-size: 20px; }
.navlinks { display: flex; gap: 4px; flex-wrap: wrap; overflow-x: auto; }
.navlink {
  display: inline-flex; align-items: center; gap: 6px; text-decoration: none;
  color: var(--muted); padding: 8px 14px; border-radius: 8px; font-weight: 400; white-space: nowrap;
}
.navlink:hover { background: var(--chip); color: var(--ink); }
.navlink.active { background: var(--brand); color: #fff; }
.badge {
  background: var(--danger); color: #fff; border-radius: 999px; font-size: 11.5px;
  min-width: 18px; height: 18px; padding: 0 5px; display: inline-flex; align-items: center; justify-content: center;
}
.badge.hidden { display: none; }

/* ===== 레이아웃 =====
   섹션 간 간격은 12px로 통일한다. */
.content { padding: 14px 18px; margin: 0 auto; } /* ★폭 상한 없음(08-11 사장님) — 넓은 모니터에선 끝까지 늘어난다. 3000·3100 공통 규칙 */
/* align-items: flex-start = 섹터 전환 시 h1 세로 위치 균일(07-22 rev02 S4) — datechip·버튼 등 우측 요소가
   h1보다 커도 h1을 아래로 밀지 않는다(구 center는 품질 datechip 때문에 h1이 2px 내려가 섹터마다 어긋났다). */
/* min-height 37 = 표준 버튼 높이(08-11 사장님 "화면 이동 시 좌표 일정") — 헤더에 버튼·날짜칩이 있는 화면과
   없는 화면의 제목줄 높이가 같아져, 뷰·섹터를 오가도 서브탭·표 시작 Y좌표가 흔들리지 않는다. */
.page-head { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 12px; flex-wrap: wrap; gap: 10px; min-height: 37px; }
.page-head h1 { font-size: 18px; margin: 0; }
.page-head .sub { color: var(--muted); font-size: 12px; }

.panel { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: 12px 14px; margin-bottom: 12px; }
.panel h2 { font-size: 14px; margin: 0 0 8px; }
.grid-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; margin-bottom: 12px; }
.panel .grid-cards { margin-bottom: 0; }

/* ===== 대시보드 상단: 부서 카드 4구획(07-27 대개편 — 구 .stat 요약 카드+.qbtn 이동 버튼 폐지) =====
   헤더(부서명) 클릭 = 작업면 이동 / 행 클릭 = 그 부서 화면의 팝업·필터 딥링크.
   행 = 라벨 좌·값 우(수검 현황 1줄화 문법). 색 위계 = 품질 스트립과 동일(빨강=조치·앰버=확정/검증·잉크 볼드=참고).
   0건 = 회색·클릭 없음 · 조회 실패 = '—'+재시도. */
.dept-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 12px; }
@media (max-width: 1280px) { .dept-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 700px) { .dept-grid { grid-template-columns: 1fr; } }
.dcard { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow); padding: 10px 14px 11px; }
.dcard-head { display: flex; align-items: center; gap: 8px; text-decoration: none; color: var(--ink);
  padding-bottom: 8px; border-bottom: 1px solid var(--line); margin-bottom: 5px; }
.dcard-head .t { font-size: 14px; font-weight: 800; }
/* '열기 →' = 무채색 외곽선 칩(08-11 사장님 — 색 없이 테두리만). radius 8 = 칩 전역 규칙(§4-D) */
.dcard-head .go { margin-left: auto; font-size: 12px; color: var(--muted); font-weight: 400; white-space: nowrap;
  border: 1px solid var(--line); border-radius: 8px; height: 20px; padding: 0 9px; display: inline-flex; align-items: center; }
.dcard-head:hover .t { color: var(--brand-dark); }
.dcard-head:hover .go { color: var(--brand-dark); border-color: var(--brand-dark); }
.drow { display: flex; align-items: baseline; gap: 8px; padding: 5px 6px; margin: 0 -6px; border-radius: 6px; }
/* 가독성 상향(07-27 사장님) — 라벨 12.5→13.5 · 값 13.5→15(강조값 표준 크기 §2) */
.drow .k { font-size: 13.5px; color: var(--ink); }
.drow .v { margin-left: auto; font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }
.drow.red .v { color: var(--danger); }
.drow.amber .v { color: var(--warn-ink); } /* warn 텍스트 대비 기준(§1) */
.drow.gray .k, .drow.gray .v { color: var(--muted); }
.drow.gray .v { font-weight: 400; }
.drow.clickable { cursor: pointer; }
.drow.clickable:hover { background: var(--hover); }
.drow.clickable:hover .k { color: var(--brand-dark); text-decoration: underline; }

/* 가동 현황 칩 */
.run-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.run-chip {
  display: inline-flex; align-items: center; gap: 8px; background: var(--brand-bg); border: 1px solid var(--brand-line);
  border-radius: 8px; padding: 6px 10px; font-size: 12.5px;
}
.run-chip b { color: var(--brand-dark); font-weight: 800; }
.run-chip span { color: var(--ink-2); }
.run-chip.fixing { background: var(--danger-bg); border-color: var(--danger-line); }
.run-chip .mini-tag { background: var(--danger); color: #fff; border-radius: 5px; padding: 1px 6px; font-size: 11.5px; font-weight: 700; }

/* 패널 헤더(악센트 바) */
.panel-head { display: flex; align-items: center; gap: 10px; margin: 0 0 10px; padding-bottom: 8px; border-bottom: 1px solid var(--line); }
.panel-head h2 { margin: 0; font-size: 14px; position: relative; padding-left: 10px; }
.panel-head h2::before { content: ''; position: absolute; left: 0; top: 1px; bottom: 1px; width: 3px; border-radius: 2px; background: var(--brand); }
.panel-head .hint { margin-left: auto; }
/* 매트릭스 헤더 우측 컨트롤(보기·과부족·월) — 툴바 행을 없애고 헤더로 내림(07-22 rev02 S4).
   .meta와 .ph-controls 둘 다 margin-left:auto → 남는 폭을 둘로 나눠 meta가 가운데, 컨트롤이 우측에 온다. */
.panel-head .ph-controls, .filterbar .ph-controls { margin-left: auto; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* 그룹(보기/과부족/기준월) 사이는 라벨 앞 여백으로 구분 — 옮기기 전(헤더) 수준의 리듬(07-24 rev09 S2) */
.ph-controls > .lbl { margin-left: 12px; }
.ph-controls > .lbl:first-child { margin-left: 0; }
.panel-head .ph-controls .lbl, .filterbar .ph-controls .lbl { font-size: 12px; color: var(--muted); }
/* meta는 제목 바로 오른쪽에(가운데 붕 뜨는 느낌 방지, rev02 point3). 컨트롤만 우측 끝. */
.panel-head.ph-3 .meta { margin-left: 12px; margin-right: 0; }
/* 기준월 입력·컨트롤을 컴팩트하게 — 기본 40px 입력이 헤더를 붕 띄우던 것 교정(rev02 point1). */
.panel-head .ph-controls input[type="month"], .filterbar .ph-controls input[type="month"] { height: 26px; padding: 0 6px; font-size: 12px; box-sizing: border-box; }
.panel-head .ph-controls .seg .btn, .filterbar .ph-controls .seg .btn { height: 22px; }
.panel-head .meta { margin-left: auto; margin-right: 6px; font-weight: 400; font-size: 12.5px; color: var(--ink); } /* 우측 끝에서 살짝 안쪽으로(07-21 — 월 필터와 세로로 겹쳐 보이던 것) */
/* 패널 헤더 안 버튼은 제목 줄 높이(20px)를 넘지 않게 — 뷰 간 표 시작 위치 통일(흔들림 금지).
   07-17: 하단 2px 보정 폐지 — 전 요소 순수 flex 센터링 통일(기준=서브탭 렌더). */
.panel-head .btn, .panel-head .btn.sm { height: 20px; padding: 0 10px; font-size: 12px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px; white-space: nowrap; flex-shrink: 0; }

/* 패널 헤더의 건수 칩(.cnt) — 헤더 버튼(20px)과 같은 높이·폰트로 맞춘다.
   기본 칩은 23px/12.5px라 그대로 두면 버튼보다 커져 줄이 어긋난다(품질 .gauge-sec-head .cnt와 같은 규칙). */
.panel-head .chip.cnt { height: 20px; min-width: 0; padding: 0 9px; font-size: 12px; font-weight: 800; }
.panel-head .chip.cnt b { margin-left: 4px; } /* 라벨-건수 간격(08-12 사장님 "등록제품 85종" 띄어쓰기) — 텍스트 공백은 collapse */
/* 헤더 안 보조 라벨 — .sub는 .page-head 안에서만 정의돼 있어 패널 헤더에선 14px로 튀었다(폰트 스케일 §2 위반). */
.panel-head .sub { font-size: 12.5px; color: var(--muted); }

/* 제목 영문 병기 */
.h1-en { font-size: 15px; font-weight: 700; color: var(--muted); margin-left: 8px; letter-spacing: .3px; }
/* padding 세로값을 h1 라인박스 안에 들어오게(3px) — 이보다 크면 page-head가 커져 datechip 있는 뷰(생산 오늘)만
   nav가 아래로 밀려 탭 전환 시 흔들린다(07-22 rev02, 후처리 스캔과 같은 패턴). */
.datechip { background: var(--chip); color: var(--brand-dark); border: 1px solid var(--brand-line); border-radius: 999px; padding: 3px 12px; font-weight: 700; font-size: 12.5px; }

/* 정렬 그룹: 같은 제품 이어지는 행은 상단 경계 없이 이어 보이게(색 없음) */
tbody tr.grp td { border-top: none; }
tbody tr:not(.grp) td { border-top: 1px solid var(--line-soft); }
td.strong { font-weight: 700; }

/* 2단 배치 */
.cols2 { display: grid; grid-template-columns: 1.15fr 1fr; gap: 12px; align-items: start; margin-bottom: 12px; }
.cols2.cols2-even { grid-template-columns: 1fr 1fr; } /* 같은 성격의 두 표(PO 기록·출하 기록)는 균등 폭 */
.cols2 .panel { margin-bottom: 0; }
@media (max-width: 1100px) { .cols2 { grid-template-columns: 1fr; } }
/* ===== ★08-11 대시보드 개편(사장님 목업 확정): KPI 5 타일 + [PO 현황 | 수리의뢰 원인 Pareto] ===== */
/* ★KPI 줄 = 화면 상단 고정(08-11 사장님 — 스크롤해도 젤 위 BOX는 항상 보이게): 네비 바(56px) 바로 아래 sticky.
   배경 = 페이지 배경으로 채워 타일 사이 틈으로 뒤 내용이 비치지 않게. z 40 = 네비(50) 아래·본문 위. */
.kpi-row { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; margin-bottom: 12px;
  position: sticky; top: 56px; z-index: 40; background: var(--bg); padding: 6px 0; margin-top: -6px; }
@media (max-width: 1100px) { .kpi-row { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 700px) { .kpi-row { grid-template-columns: 1fr 1fr; } }
.kpi { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow);
  padding: 9px 14px 10px; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* 라벨·부가줄은 말줄임 — 좁은 화면에서 글자가 겹치거나 칸을 밀지 않게(사장님 2) */
.kpi .k { font-size: 12.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kpi .v { font-size: 31px; font-weight: 800; line-height: 1.1; letter-spacing: -.5px; } /* §2 대시보드 지표 규격 */
.kpi .v small { font-size: 12.5px; font-weight: 400; color: var(--muted); letter-spacing: 0; margin-left: 2px; }
.kpi .sub { font-size: 11.5px; color: var(--dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kpi.red .v { color: var(--danger); }
.kpi.amber .v { color: var(--warn-ink); } /* warn 텍스트 대비 기준(§1) — drow.amber와 동일 */
.kpi.gray .v { color: var(--muted); }
.kpi.clickable { cursor: pointer; }
.kpi.clickable:hover { background: var(--hover); }

/* PO 현황 | Pareto — 딱 반반·높이 동일(stretch). 차트 0선 ↔ '계' 윗선 정렬: 표를 패널 바닥에 붙이고
   차트가 '계' 행 실측 위치에 0선을 그린다(home.js drawPoChart). dept-grid 2×2 경계(1280)에서 1단 스택. */
.cols2.home-charts { grid-template-columns: 1fr 1fr; align-items: stretch; }
.cols2.home-charts > .panel { min-width: 0; display: flex; flex-direction: column; }
.cols2.home-charts .table-wrap { margin-top: auto; }
@media (max-width: 1280px) { .cols2.home-charts { grid-template-columns: 1fr; } }
/* flex-basis 0 필수 — auto면 그려 넣은 svg 높이가 패널 자연 높이를 다시 키워 그릴 때마다 자라는 되먹임이 생긴다.
   overflow visible = svg가 +12px(주차/TTL 2줄 간격 몫) 패널 하단 패딩으로 삐져나가 그리는 것 허용(basis 0이라 되먹임 없음) */
.po-chart .chart-box { flex: 1 1 0; min-height: 170px; overflow: visible; }
.chart-legend { display: flex; gap: 14px; font-size: 12px; color: var(--muted); margin: 0 0 2px; }
.chart-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 5px; vertical-align: -1px; }
table.pareto .pbar { display: inline-block; height: 9px; border-radius: 2px; background: var(--danger); margin-right: 8px; vertical-align: 1px; }
table.pareto tr.tot td { border-top: 2px solid var(--line-2); }
/* 행높이 30px 고정(매트릭스 표준 §4-D) — 폰트 로드로 행높이가 흔들리면 차트 0선-'계' 선 정렬이 깨진다(결정적 기하) */
table.pareto th, table.pareto td { height: 30px; }

/* ★홈 하단(08-11 사장님): 좌우 경계 = 부서 카드 경계 — 생산 이력 폭 = 생산+품질 카드 합, 수리·개발 = 재고출하+금형 합.
   min-width 0 = 우측 표(nowrap 셀)의 최소폭이 좌측 생산 이력을 찌그러뜨리던 과도기 형상 제거(표는 내부 스크롤).
   dept-grid가 2×2로 접히는 1280에서 하단도 같이 1단 스택 — 카드 위 아래 폭이 항상 일치. */
.cols2.home-hist { grid-template-columns: 1fr 1fr; }
.cols2.home-hist > * { min-width: 0; }
@media (max-width: 1280px) { .cols2.home-hist { grid-template-columns: 1fr; } }

/* ★홈 이력 3표 고정폭(08-11 사장님 px 지정) — fixed + 말줄임. min-width = 고정열 합 + 잔여열 최소:
   창이 좁아져 잔여열(가동률/내용/비고)이 밀려날 것 같으면 열을 찌그러뜨리지 않고 표 내부 가로 스크롤(.table-wrap). */
table.hp-table, table.hr-table, table.hd-table { table-layout: fixed; width: 100%; }
table.hp-table th, table.hp-table td, table.hr-table th, table.hr-table td,
table.hd-table th, table.hd-table td { overflow: hidden; text-overflow: ellipsis; }
/* 상태(75px) 셀은 좌우 패딩 축소 — 4자 칩('접수대기' ≈64px)이 기본 패딩(8+8)에선 잘려 말줄임 점이 떴다.
   칩 규격은 그대로, 셀 여백만 8→4로 줄여 온전히 수납(칩은 가운데 정렬이라 시각 차이 없음). */
table.hp-table td:nth-child(1), table.hr-table td:nth-child(1), table.hd-table td:nth-child(1) {
  padding-left: 4px; padding-right: 4px; }
/* 생산 이력: 상태75 · 품명150 · 고객사70(가운데) · 금형80 · 설비/주야/담당자 60 · 생산/불량/마감 70 · 가동률=잔여 */
table.hp-table { min-width: 840px; }
table.hp-table th:nth-child(1), table.hp-table td:nth-child(1) { width: 75px; }
table.hp-table th:nth-child(2), table.hp-table td:nth-child(2) { width: 150px; }
table.hp-table th:nth-child(3), table.hp-table td:nth-child(3) { width: 70px; text-align: center; }
table.hp-table th:nth-child(4), table.hp-table td:nth-child(4) { width: 80px; }
table.hp-table th:nth-child(5), table.hp-table td:nth-child(5),
table.hp-table th:nth-child(6), table.hp-table td:nth-child(6),
table.hp-table th:nth-child(7), table.hp-table td:nth-child(7) { width: 60px; }
table.hp-table th:nth-child(8), table.hp-table td:nth-child(8),
table.hp-table th:nth-child(9), table.hp-table td:nth-child(9),
table.hp-table th:nth-child(10), table.hp-table td:nth-child(10) { width: 70px; }
/* 수리 이력: 상태75 · 품명150 · 금형80 · 내용=잔여(말줄임, title 전문) · 담당자60 · 일자90 */
table.hr-table { min-width: 760px; }
table.hr-table th:nth-child(1), table.hr-table td:nth-child(1) { width: 96px; } /* 09-09: 상태 칩 '조치대기' + 할 일 점까지 잘림 없이 */
table.hr-table th:nth-child(2), table.hr-table td:nth-child(2) { width: 150px; }
table.hr-table th:nth-child(3), table.hr-table td:nth-child(3) { width: 80px; }
table.hr-table th:nth-child(5), table.hr-table td:nth-child(5) { width: 60px; }
table.hr-table th:nth-child(6), table.hr-table td:nth-child(6) { width: 90px; }
/* 개발 이력: 상태75 · 품명150 · 금형80 · Trial 80 · 최근 검사 120 · 고객납기 140 · SPL 건수 70 · 비고=잔여 */
table.hd-table { min-width: 875px; }
table.hd-table th:nth-child(1), table.hd-table td:nth-child(1) { width: 75px; }
table.hd-table th:nth-child(2), table.hd-table td:nth-child(2) { width: 150px; }
table.hd-table th:nth-child(3), table.hd-table td:nth-child(3) { width: 80px; }
table.hd-table th:nth-child(4), table.hd-table td:nth-child(4) { width: 80px; }
table.hd-table th:nth-child(5), table.hd-table td:nth-child(5) { width: 120px; }
table.hd-table th:nth-child(6), table.hd-table td:nth-child(6) { width: 140px; }
table.hd-table th:nth-child(7), table.hd-table td:nth-child(7) { width: 70px; }

/* ===== 버튼 ===== */
.xi { vertical-align: -2px; }
.btn {
  border: 1px solid var(--brand); background: var(--brand); color: #fff; cursor: pointer;
  border-radius: 8px; font-weight: 400; font-size: 12.5px; white-space: nowrap;
  /* 07-17 수직 여백 균형: line box가 3px 아래로 치우치던 것을 flex 센터링으로 교정(높이는 기존 37 유지).
     line-height 1.45 — 폰트 메트릭 비대칭 상쇄(칩과 동일 원리) */
  display: inline-flex; align-items: center; justify-content: center;
  line-height: 1.45; padding: 0 14px; height: 37px; box-sizing: border-box; vertical-align: middle;
}
.btn:hover { background: var(--brand-dark); }
.btn.ghost { background: #fff; color: var(--ink); border-color: var(--line); }
.btn.ghost:hover { background: var(--chip); }
/* 삭제 = 빨강이되 '아웃라인'. 솔리드 빨강은 "조치 필요"(수리의뢰·수검NG 칩) 전용으로 남긴다 —
   표에 삭제 버튼이 수십~수백 개 늘어서면 솔리드는 화면이 통째로 빨개져 정작 조치 신호가 죽는다. */
.btn.danger { background: #fff; border-color: var(--danger); color: var(--danger); }
.btn.danger:hover { background: var(--danger); border-color: var(--danger); color: #fff; }
/* 솔리드 빨강 = 다른 팀에 접수되는 행위의 최상급 구분(07-28 사장님 — 검사 입력 [금형 수리의뢰]) — 남용 금지 */
.btn.danger.solid { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn.danger.solid:hover { background: var(--danger-ink); border-color: var(--danger-ink); color: #fff; }
/* ★[취소] = 솔리드 빨강 + 흰 글자, 전 화면 통일(09-09 사장님 — 구 ghost/아웃라인 혼재 폐지).
   솔리드 빨강 "남용 금지"의 예외: 취소는 화면당 1개라 조치 신호를 죽이지 않는다. 라벨이 '취소'인 버튼에만. */
.btn.cancel { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn.cancel:hover { background: var(--danger-ink); border-color: var(--danger-ink); color: #fff; }
/* ★파일이 있어야 열리는 버튼(도면 열람 등)에 등록된 파일이 없으면 회색(09-09 사장님 — "올린 게 없구나"를 색으로).
   누르면 그대로 열려 등록할 수 있다(disabled 아님). inspect.js drawingBtn()이 도면 수를 조회해 토글. */
.btn.no-file, .btn.ghost.no-file { background: var(--gray-bg-2); border-color: var(--gray-bg-2); color: var(--muted); }
.btn.no-file:hover, .btn.ghost.no-file:hover { background: var(--line-2); border-color: var(--line-2); }
/* ★대기 버튼 = 빨강 틴트(흐름 바 .chip.wait와 같은 톤, 09-09 사장님) — 수검 현황 [수검대기] 등 "기다리는 일"의 클릭 버튼. 솔리드 파랑은 주 행동·헤더 전용 */
.btn.wait { background: var(--danger-bg-2); border-color: var(--danger-line); color: var(--danger); font-weight: 700; }
.btn.wait:hover { background: var(--danger-bg-2); border-color: var(--danger-line); color: var(--danger); }
.btn.sm { padding: 0 10px; height: 30px; font-size: 12px; }
/* 아이콘 전용 버튼(◀ ▶ 등 기호만) — 글자 라벨 없이 최소 정사각 폭(07-21 월 이동 버튼). */
.btn.sm.icon { padding: 0; width: 30px; min-width: 30px; }
/* 07-16 칩 표준화: 표 안 sm 버튼 = 26px 고정(셀 높이 안정). 버튼과 병기되는 칩(.btn-h)은 버튼과 같은 높이·정렬 */
td .btn.sm { height: 26px; padding-top: 0; padding-bottom: 0; line-height: 24px; }
.chip.btn-h { display: inline-flex; align-items: center; justify-content: center; height: 26px; padding-top: 0; padding-bottom: 0; min-width: 66px; vertical-align: middle; font-size: 12px; } /* 폰트도 sm 버튼(12px)과 통일 */
.btn:disabled { opacity: .5; cursor: not-allowed; }

.row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.row.end { justify-content: flex-end; }
.row.gap { gap: 12px; }
.spacer { flex: 1; }
.muted { color: var(--muted); }
.chip { background: var(--chip); color: var(--brand-dark); border-radius: 8px; font-size: 12.5px; font-weight: 400;
  display: inline-flex; align-items: center; justify-content: center; line-height: 1.45;
  height: 23px; padding: 0 10px; box-sizing: border-box; vertical-align: middle;
  white-space: nowrap; flex: 0 0 auto; }
  /* 칩 radius 8 전역(pill 금지). 07-17: 상하 패딩 비대칭 보정(2/3px) 폐지 → flex 센터링+고정 높이 23으로 수직 균형 통일.
     ★line-height는 1이 아니라 1.45 유지 — 나눔스퀘어 ascent/descent 비대칭이 line-height:1에서 그대로 드러나 텍스트가 위로 치우침(실측 2.8/6.3 → 1.45에서 대칭)
     ★nowrap+flex:none 전역(08-03) — 칩은 짧은 라벨이라 절대 줄이 꺾이면 안 된다. 긴 텍스트 옆 flex 행에서
     칩이 눌려 글자가 세로로 쌓이던 것(수리의뢰 배너 실측 — 07-27 .mold-head 스코프 수정의 일반화). */
.chip.gray { background: var(--gray-bg); color: var(--muted); }
.chip.ok { background: var(--ok-bg); color: var(--ok); }
.chip.warn { background: var(--warn-bg-2); color: var(--warn-ink); }
.chip.wait { background: var(--danger-bg-2); color: var(--danger); }
.chip.brand { background: var(--brand); color: #fff; } /* 강조 관리구분(중점관리/CPK/CHK) — 솔리드 파랑 */
/* 외주 입고 팝업 — 입력 요소 컴팩트(행 높이 축소, #7). 업체·공정은 외주출고 기록에서 자동 채움. */
.rc-form { row-gap: 8px; }
/* 07-31 감사: 13px는 표준 스케일 9종(DESIGN §2) 밖 — 팝업 본문 규격 13.5로 통일 */
.rc-form .rc-in, .rc-form select.rc-in, .rc-form input.rc-in { height: 30px; padding: 3px 8px; font-size: 13.5px; box-sizing: border-box; }
.rc-form .lbl { font-size: 12.5px; color: var(--muted); }
.chip.bold { font-weight: 700; } /* '관리' 칩 — 비관리보다 강조 */
/* 표 안 칩 고정폭 (DESIGN 4-D): 그룹 내 최장 텍스트 기준 통일 — 표준 = 한글 4자(66px)·가운데 정렬.
   칩 텍스트는 최대 4자로 한정(품질의뢰/생산의뢰/수리검토/접수대기 등, 띄어쓰기 없음) */
table .chip { min-width: 66px; padding-left: 4px; padding-right: 4px; text-align: center; box-sizing: border-box; }

/* ===== 표 ===== (DHPV MES 색 구성: 파란 헤더 + 흰 글자)
   스크롤 기준점: 표 내부에서 스크롤(헤더·고정컬럼은 고정) */
.table-wrap { overflow: auto; max-height: calc(100vh - 250px); border-bottom: 1px solid var(--line); } /* 표가 넘쳐 스크롤돼도 표 맨 밑 라인 유지 */
/* ★07-27 팝업 안 표 = 뷰포트 캡(사장님 — 스크롤 시 헤더 실종 일반화 수정): 래퍼가 팝업 내부보다 크면
   래퍼 대신 팝업이 스크롤돼 thead sticky가 무력화된다. 팝업 안에서는 항상 표 내부 스크롤이 되도록 캡.
   rowsN·spec-wrap 등 고정 캡은 아래에서 min(고정값, 뷰포트)로 각자 재정의(뒤 규칙이 이 규칙을 이긴다). */
.modal-box .table-wrap { max-height: calc(100vh - 340px); }
.table-wrap tbody tr:last-child td { border-bottom: none; } /* 마지막 행 밑줄은 래퍼 테두리가 대신(이중선 방지) */
table { border-collapse: collapse; width: 100%; font-size: 12.5px; }
th, td { padding: 5px 8px; border-bottom: 1px solid var(--line-2); border-right: 1px solid var(--line-soft); text-align: left; white-space: nowrap; } /* 행 구분선 = 짙은 회색 1px(매트릭스와 통일, 제품 구분 가독성) */
th { background: var(--brand); color: #fff; font-weight: 700; position: sticky; top: 0; z-index: 2; border-bottom: none; border-right: 1px solid var(--brand-dark); text-align: center; }
/* ★표 헤더는 무조건 가운데(07-24 사장님 확정 — 07-22 pj-table "금형·num 헤더 가운데" 지시의 전역 승격).
   데이터 정렬(좌/우)은 td 규칙이 담당한다. 개별 표의 "th:nth-child, td:nth-child { text-align:left }" 같은
   묶음 규칙이 th까지 물들던 누수가 반복돼(품명·LOT 헤더가 왼쪽으로) 전역 보증으로 못 박는다 — 예외 없음(!important). */
thead th { text-align: center !important; }
/* 표 안 데이터는 전부 볼드 (통일) */
tbody td { font-weight: 700; }
/* 표 좌우 끝에는 세로선 없음 */
th:last-child, td:last-child { border-right: none; }
tbody tr:hover { background: var(--hover); }
/* PO 없는 양산 제품: 연회색 처리 */
tbody tr.nopo td { color: var(--dim); }
tbody tr.nopo td.strong { color: var(--dim); font-weight: 700; }
td.num { text-align: right; font-variant-numeric: tabular-nums; }
th.num { font-variant-numeric: tabular-nums; } /* 헤더는 가운데 정렬 유지 */
tr.clickable { cursor: pointer; }
.pos { color: var(--ok); font-weight: 700; }
.neg { color: var(--danger); font-weight: 700; }
.need { color: var(--ink); font-weight: 700; } /* 잔여PO — 굵기로만 강조(색 제거, 가독성) */
/* 표 공통 기준 (DESIGN 4-D):
   일자 컬럼 표준폭 = 숫자 12자(110px) · 구분 칩 다열 간격 · 가동률 조건부 서식
   범주값 셀(칩·날짜·시각·구분 등)은 가운데 정렬 = td.ctr (텍스트 왼쪽·숫자 오른쪽은 유지) */
th.col-date, td.col-date { width: 110px; min-width: 110px; white-space: nowrap; text-align: center; } /* min-width: 컬럼 많은 표에서도 압축 금지 */

/* 금형 목록(EMR) 컬럼 폭 — 07-27 사장님 px 지정. 헤더 정렬은 표준(가운데) 유지 */
/* ★07-31 감사: min-width가 없어 1280px 이하 화면에서 잔여 열(비고)이 68px까지 눌렸다 —
   "차수 정정(2026-07-31)" 같은 실제 값이 네 글자만 보인다(실측 68 < 653).
   고정열 합 1,040 + 비고 최소 200 = 1,240 → 좁으면 표 내부 가로 스크롤(DESIGN §5 체크리스트). */
.mold-list { table-layout: fixed; width: 100%; } /* 칼럼 폭·min-width = molds.js MCOLS(colgroup, 09-07 tablekit — 구 nth-child 폭 규칙 폐지) */
.mold-list th, .mold-list td { overflow: hidden; text-overflow: ellipsis; }
.mold-list td.clip-s { max-width: none; } /* 비고 = 잔여 흡수(clip-s 220 캡 해제) */
td.chips .chip + .chip { margin-left: 6px; }
td.chips { text-align: center; }
td.ctr { text-align: center; }
.rate-low { color: var(--danger) !important; } /* 가동률 85% 미만 */
td.rate-na { color: var(--muted); }            /* 마감인데 산출불가(SPM·시간 미입력) */
/* 긴 텍스트 컬럼 말줄임 — 표가 옆으로 늘어나지 않게. 전체 내용은 툴팁(title)·상세 팝업에서 */
td.clip-l { max-width: 380px; overflow: hidden; text-overflow: ellipsis; }
td.clip-s { max-width: 220px; overflow: hidden; text-overflow: ellipsis; }
/* LOT 역추적·출하 상세 팝업의 여러 표(rev03) — 자동 폭. 다른 칼럼은 내용폭(nowrap)으로 고정되고,
   긴 텍스트 칼럼(.ev-note = 문제점·내용·비고·경로)이 남는 폭을 흡수해 가장 넓어진다. 비어도 폭을 유지. */
.ltrace { table-layout: auto; }
.ltrace td.ev-note { width: 100%; min-width: 160px; }
/* ★사장님 지정 고정 폭(rev03) — table-layout:fixed, 폭은 thead th에서 결정. 폭 미지정 칼럼이 남는 폭을 흡수(여럿이면 균등 분할).
   좁게 지정한 칼럼은 넘치면 …로 말줄임(전체값은 title 툴팁). 긴 텍스트 칼럼(.ev-note)은 줄바꿈. */
.lt-post, .lt-ev, .lt-round, .lt-prod, .lt-ship, .lt-cong { table-layout: fixed; }
.lt-post th, .lt-post td, .lt-ev th, .lt-ev td, .lt-round th, .lt-round td,
.lt-prod th, .lt-prod td, .lt-ship th, .lt-ship td, .lt-cong th, .lt-cong td { overflow: hidden; text-overflow: ellipsis; }
/* ★09-12 5차 사장님 재지정: 주야·외관·불량수 50 · 담당자·SPM·Cavity·검사자 70 · 수리구분·결과 80(2차 — 70은 잘림) · 생산·불량·마감 80 · 가동률 90(2차 — "90.7%" 잘림).
   가장 넓은 표 = 생산 건 790(100+100+50+70+70+70+80×3+90) → 드로어 폭도 그만큼(v5.css .lot-trace 850 = 790 + 패딩 36 + 테두리 1 + 스크롤바 여유 17(scrollbar-gutter)). */
/* 후처리·수검: 일자100 구분100 업체100 공정80 수량80 검사자70 결과90 · 비고=나머지
   ★09-19 사장님: 결과 70은 '수검OK'(71)·'특별관리'(78) 칩이 …로 잘렸다 → 90. 늘린 20은 비고(나머지 흡수)에서 온다. */
.lt-post thead th:nth-child(1) { width: 100px; } .lt-post thead th:nth-child(2) { width: 100px; }
.lt-post thead th:nth-child(3) { width: 100px; } .lt-post thead th:nth-child(4) { width: 80px; }
.lt-post thead th:nth-child(5) { width: 80px; }  .lt-post thead th:nth-child(6) { width: 70px; }
.lt-post thead th:nth-child(7) { width: 90px; }
/* 생산 세부: 시각100 유형100 불량수50 · 내용=나머지 */
.lt-ev thead th:nth-child(1) { width: 100px; } .lt-ev thead th:nth-child(2) { width: 100px; } .lt-ev thead th:nth-child(3) { width: 50px; }
/* 순회검사: 검사시각100 구분100 외관50 수리구분80 결과80 검사자70 · 문제점=나머지 */
.lt-round thead th:nth-child(1) { width: 100px; } .lt-round thead th:nth-child(2) { width: 100px; }
.lt-round thead th:nth-child(3) { width: 50px; }  .lt-round thead th:nth-child(4) { width: 80px; }
.lt-round thead th:nth-child(5) { width: 80px; }  .lt-round thead th:nth-child(6) { width: 70px; }
/* 생산 건: 생산일100 설비100 주야50 담당자70 SPM70 Cavity70 · 생산/불량/마감 80 · 가동률 90 고정(구 4등분 폐지) */
.lt-prod thead th:nth-child(1) { width: 100px; } .lt-prod thead th:nth-child(2) { width: 100px; }
.lt-prod thead th:nth-child(3) { width: 50px; }  .lt-prod thead th:nth-child(4) { width: 70px; }
.lt-prod thead th:nth-child(5) { width: 70px; }  .lt-prod thead th:nth-child(6) { width: 70px; }
.lt-prod thead th:nth-child(7) { width: 80px; }  .lt-prod thead th:nth-child(8) { width: 80px; }
.lt-prod thead th:nth-child(9) { width: 80px; }  .lt-prod thead th:nth-child(10) { width: 90px; }
/* 출하 사용 내역: 출하일100 도착고객사100 사용수량100 Box100 · 경로=나머지 */
.lt-ship thead th:nth-child(1) { width: 100px; } .lt-ship thead th:nth-child(2) { width: 100px; }
.lt-ship thead th:nth-child(3) { width: 100px; } .lt-ship thead th:nth-child(4) { width: 100px; }
/* 출하 상세 구성 LOT(팝업 xl): LOT번호310(현재+10%) 생산일100 주야50 열50 사용수량100 Box100 상태100 · 비고=나머지 */
.lt-cong thead th:nth-child(1) { width: 310px; } .lt-cong thead th:nth-child(2) { width: 100px; }
.lt-cong thead th:nth-child(3) { width: 50px; }  .lt-cong thead th:nth-child(4) { width: 50px; }
.lt-cong thead th:nth-child(5) { width: 100px; } .lt-cong thead th:nth-child(6) { width: 100px; }
.lt-cong thead th:nth-child(7) { width: 100px; }
/* 측정완료·마감된 이력 행 = 회색 (마감상태=회색 원칙) */
tbody tr.row-closed td { background: var(--done-row); }
tbody tr.row-closed:hover td { background: var(--done-row); }

/* ===== 폼 ===== */
.form-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
/* 수리 등록 폼: 4열 — 수리일·담당자가 한 줄에 각 1/4 폭(합쳐서 기존 절반 폭), .col2=절반 폭 */
.form-grid.rep-form { grid-template-columns: repeat(4, 1fr); }
.rep-form .field.col2 { grid-column: span 2; }
/* 첫 줄 높이 통일 38 (4-G): date input의 내재 높이가 select보다 커서 어긋나는 것 교정. 수리완료 버튼도 동일 높이 */
.rep-form input, .rep-form select, .rep-form .field > .btn { height: 38px; box-sizing: border-box; }
/* 조치 부품 체크 목록: 부위·부품명 라벨이 가로로 흐르며 줄바꿈 */
.rp-checks { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 10px; }
.rp-check { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 8px; padding: 4px 9px; background: #fff; }
.rp-check:hover { background: var(--chip); }
.field { display: flex; flex-direction: column; gap: 4px; }
.field.full { grid-column: 1 / -1; }
.field .lbl { font-size: 12px; color: var(--muted); font-weight: 400; }
/* 신규 생산 등록: 필드별 고정폭 + wrap으로 줄 수 압축(목록이 위로) */
.reg-grid { display: flex; flex-wrap: wrap; gap: 12px 14px; align-items: flex-start; }
.reg-grid .field { flex: 0 0 auto; }
.reg-grid input, .reg-grid select { width: 100%; }
/* 미입력 강조(공통): 담당자가 직접 입력해야 하는 칸이 비어있으면 앰버 표시 (등록 패널·상세 SPM) */
input.f-empty, select.f-empty { background: var(--warn-bg); border-color: var(--warn); }
/* [도면] 버튼 미첨부 표시(08-04) — 입력 미입력(f-empty)과 같은 축: "여기에 채울 것이 있다"를 앰버로 */
.btn.f-empty { background: var(--warn-bg); border-color: var(--warn); color: var(--warn-ink); }
.btn.f-empty:hover { background: var(--warn-bg); }
/* ★rev09 S4: 지금 생산이 어려운 금형(수리중·운휴·단종)이 선택된 칸 — 빨강 틴트로 즉시 인지(f-empty 앰버=미입력과 구분) */
select.f-warn, input.f-warn { background: var(--danger-bg); border-color: var(--danger); color: var(--danger); font-weight: 700; }
input, select, textarea {
  font: inherit; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; background: #fff; color: var(--ink);
}
/* ★버튼 폰트 상속(07-24 사장님 재확인) — 폼 요소는 body 폰트를 상속하지 않아 전 버튼이 Arial로 렌더되고 있었다.
   family만 상속(크기·굵기는 .btn 규격이 담당) → 전 버튼 나눔스퀘어 통일. */
button { font-family: inherit; }
/* 탭 줄 안의 버튼(예: [+ 생산 건 등록]) = 서브탭 pill(32px)과 같은 줄 — 표준 37px이면 줄이 어긋난다(07-24 사장님) */
.subtabs .btn { height: 32px; }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--brand-line-2); border-color: var(--brand); }
textarea { min-height: 70px; resize: vertical; }
.toolbar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 12px; }
.search-input { min-width: 240px; }

/* ===== 모달 ===== */
/* ★모달 = 배경을 막지 않는다(09-09 사장님 — "팝업 아래도 입력이 되어야 하고, X·ESC 전엔 저절로 안 꺼져야").
   구버전은 오버레이가 화면을 회색으로 덮고 클릭을 삼켰다. 이제 오버레이는 자리잡기(가운데 정렬)만 담당:
   투명 + pointer-events:none(뒤 화면에 클릭·휠이 그대로 간다), 팝업 상자만 pointer-events:auto.
   닫힘 = X·ESC·저장/취소 버튼뿐(바깥 클릭 닫기는 원래 없었다). 뒤가 어두워지지 않으니 상자 경계는 테두리+짙은 그림자로. */
.modal-overlay { position: fixed; inset: 0; background: transparent; pointer-events: none; display: flex; align-items: flex-start; justify-content: center; padding: 40px 16px; z-index: 100; overflow-y: auto; }
.modal-box { pointer-events: auto; background: #fff; border: 1px solid var(--line); border-radius: 12px; width: 1120px; max-width: 100%; box-shadow: 0 16px 48px rgba(0,0,0,.32);
  max-height: calc(100vh - 80px); overflow-y: auto; } /* 소형 폼 팝업 2배(560→1120).
  ★팝업은 항상 화면 안(07-25 사장님 — 긴 팝업이 오버레이를 스크롤시켜 모서리가 잘리고 위치가 팝업마다 달라 보이던 것):
  넘치는 내용은 팝업 내부 스크롤, 제목줄은 sticky로 고정. 80 = 오버레이 상하 패딩(40×2) — 시작 위치 전 팝업 동일 */
.modal-box.sm { width: 560px; } /* 확인 대화상자 등 — 기존 기본 크기 유지 */
.modal-box.smf { width: 840px; } /* 필드 적은 마스터 폼(작업자·관리구분 등) — 기본(1120)보다 조금 작게 */
.modal-box.wide { width: 900px; }
.modal-box.xl { width: 84vw; max-width: 1320px; }
.modal-box.xl.ship-modal { width: 92vw; max-width: 1452px; } /* 출하 몰아서 입력 = xl +10%(07-23 사장님 — PO 컬럼 공간 확보). 제품 하나 출하 입력은 rev05로 xl 복귀(일자별 상세와 동일 폭) */
.modal-box.lg { width: 67vw; max-width: 1060px; } /* 생산건 상세(xl)의 80% — 금형 수리의뢰 등 */
.modal-box.lgx { width: 77vw; max-width: 1220px; } /* lg + 15% — 품질검사 입력(비고 1줄 확보) */
.modal-box.md { width: min(880px, 92vw); max-width: 92vw; }
.modal-box.mdl { width: 90vw; max-width: 1584px; } /* 소형 폼 2배(792→1584) — 수검(OQC) 팝업 */
.modal-box.xxl { width: 90vw; max-width: 1440px; } /* xl보다 넓게 — 수검 목록 팝업(내부PASS 버튼 열 확보) */
/* 성적서(PDF) 업로드 드롭존 — 수검 팝업 */
.cert-drop { margin-top: 6px; padding: 14px 12px; border: 1.5px dashed var(--line-2); border-radius: 8px; text-align: center; color: var(--muted); font-size: 12.5px; cursor: pointer; background: var(--bg-soft); }
.cert-drop:hover { border-color: var(--brand); color: var(--brand); }
.cert-drop.over { border-color: var(--brand); background: var(--brand-bg); color: var(--brand); }
.drawing-view.over { outline: 2px dashed var(--brand); outline-offset: -4px; background: var(--brand-bg); }
.modal-box.w90 { width: 76vw; max-width: 1190px; } /* 생산 이력 상세(xl)의 90% — 순회 품질 검사 이력 */
.modal-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 18px; border-bottom: 1px solid var(--line); cursor: move; user-select: none;
  position: sticky; top: 0; background: #fff; z-index: 5; } /* 제목줄 드래그로 팝업 이동 · 내부 스크롤 시 제목·X 항상 보임(07-25) */
.modal-head h3 { margin: 0; font-size: 15px; }
/* ★팝업 상단 고정 틀(.pin-top, 07-29 사용자 — 긴 팝업을 스크롤해도 품명·구분 탭·기록 헤더가 계속 보이게):
   modal-head(sticky·z5) 바로 아래 붙는 2층 sticky. top은 JS가 제목줄 실측 높이로 지정(제목 길이 대응).
   좌우 마이너스 마진 = modal-body 패딩(18)을 덮어 스크롤 내용이 옆 틈으로 비치지 않게(.modal-actions와 같은 문법). */
/* top = 제목줄 실측 높이(ui.js modal()이 --pin-top으로 내려준다). 51px은 폴백 — 고정값은 제목줄(56)과 어긋나
   공통 정보가 제목줄 밑으로 파고들었다(08-01 실측: 91 vs 96). 제목이 2줄이 되면 더 벌어진다. */
.pin-top { position: sticky; top: var(--pin-top, 51px); z-index: 4; background: #fff; margin: 0 -18px; padding: 0 18px 6px; border-bottom: 1px solid var(--line); }
/* ★틀 내부 구분선 정리(07-29 사용자 지적 — 기록 헤더 밑선과 틀 밑선이 2중으로 그려지고 아래 내용이 선에 밀착):
   틀의 마지막 구분선은 .pin-top border-bottom 하나만 담당.
   · 기록 헤더(panel-head)의 자체 밑선·여백 제거 · 정보줄(.detail-head) 아래 마진 제거(탭바 마진이 간격 담당)
   · 정보줄이 틀의 마지막 내용(검사 상세 pinD)이면 자체 밑선도 제거 */
.pin-top .panel-head { border-bottom: 0; padding-bottom: 0; margin-bottom: 0; }
.pin-top .detail-head { margin-bottom: 0; }
.pin-top > .detail-head:last-child { border-bottom: 0; padding-bottom: 4px; }
.modal-head .x { border: none; background: none; font-size: 18px; cursor: pointer; color: var(--muted); }
/* container-type: 모달 내부 폼(.pr-row 등)이 뷰포트가 아니라 '모달 폭' 기준으로 반응형 전환되게 한다 */
.modal-body { padding: 18px; container-type: inline-size; }
/* ★팝업 하단 액션 바(07-25 사장님 — "저장·취소류 버튼은 스크롤과 무관하게 항상 보이게, 전 섹터"):
   내부 스크롤 도입(같은 날)으로 긴 팝업에서 하단 버튼이 안 보이던 것 — 버튼 행을 sticky bottom으로 고정.
   위치는 기존 관습(우하단) 유지 — 제목줄로 올리는 안은 버튼 3~4개 팝업(검사 입력)·긴 제목(LOT 병기)과 겹쳐 배제.
   기존 행에 클래스만 추가하는 방식 — 각 행의 inline 정렬(spacer·flex-end)은 그대로 동작. */
/* ★스크롤 끝에서 버튼이 18px 떠 보이던 오류(07-27 사장님): sticky는 스크롤 끝에 도달하면 본래 위치로
   돌아가는데, 바가 .modal-body(padding 18px) 안이라 본래 위치가 패딩 위였다 → 음수 마진으로 패딩 상쇄(끝까지 밀착) */
.modal-actions { position: sticky; bottom: 0; z-index: 4; background: #fff; border-top: 1px solid var(--line); padding: 10px 0 14px; margin-bottom: -18px; }
/* ★확인창 문구는 줄바꿈을 그대로 살린다 — \n을 넣어도 공백으로 뭉개져 한 문단이 되던 문제(07-20) */
.confirm-msg { margin: 0 0 16px; white-space: pre-line; line-height: 1.6; }
/* 구조형 확인창: 상황(what) → 대상 정보(info) → 질문(ask) → 보조 설명(note).
   한 문단으로 이어 붙이면 무엇이 상황이고 무엇이 질문인지 구분이 안 돼 작업자가 읽지 않고 넘긴다. */
.confirm-box { margin: 0 0 16px; }
.cf-what { margin: 0 0 10px; font-weight: 700; font-size: 13.5px; line-height: 1.5; }
.cf-info { background: var(--bg-soft); border: 1px solid var(--line); border-radius: 8px;
  padding: 9px 12px; margin: 0 0 12px; display: grid; grid-template-columns: max-content 1fr; gap: 4px 14px;
  /* ★정보 행이 많아도 질문(.cf-ask)·버튼이 화면 밖으로 밀리지 않게 정보 박스가 먼저 스크롤한다(08-01 사용자).
     짧은 확인창은 이 값에 닿지 않아 보이는 변화가 없다 — 긴 목록(정리 대상 20건 등)에서만 내부 스크롤. */
  max-height: min(300px, calc(100vh - 330px)); overflow-y: auto; }
.cf-kv { display: contents; }   /* 라벨 열·값 열이 세로로 맞아떨어지게(각 항목이 한 줄) */
.cf-info .k { color: var(--muted); font-size: 12px; }
.cf-info .v { font-weight: 700; font-size: 12.5px; }
.cf-info .v.miss { color: var(--danger); }   /* '(미입력)' = 누락 인지(07-23) */
.cf-info .v.warn { color: var(--warn-ink); }         /* PO 초과분 등 주의 값 — 앰버 구분(07-23) */
.cf-info .v.neg { color: var(--danger); }    /* NG 특성 값 = 빨강(07-29 사용자) */
.cf-info .v.node { display: block; }         /* 표 등 구조 값 — 셀 전폭 사용(07-29) */
/* 확인창 미니 표(치수 특이사항) — 격자 셀, NG 값 빨강.
   폭(07-29 사용자): 항목·기준은 다른 측정 표 기준(170·150)에 맞추고, 단일 측정(.one)은 측정값 90 고정 +
   끝 스페이서가 잔여 흡수(측정값이 남는 폭을 다 먹지 않게). Avg/Max/Min(다수 측정)은 70 균일·측정값=잔여. */
.cf-dims { width: 100%; border-collapse: collapse; background: #fff; margin: 2px 0; table-layout: fixed; }
.cf-dims th, .cf-dims td { border: 1px solid var(--line); padding: 2px 8px; height: 24px; font-size: 12px; font-weight: 400; text-align: center; overflow: hidden; }
.cf-dims th { background: var(--bg-soft); color: var(--muted); font-weight: 700; }
.cf-dims td.ng { color: var(--danger); font-weight: 700; }
.cf-dims th:nth-child(1), .cf-dims td:nth-child(1) { width: 170px; } /* 항목 */
.cf-dims th:nth-child(2), .cf-dims td:nth-child(2) { width: 150px; } /* 기준 */
.cf-dims.one th:nth-child(3), .cf-dims.one td:nth-child(3) { width: 90px; } /* 측정값(단일) — 스페이서 = 잔여 */
.cf-dims.one th:nth-child(4), .cf-dims.one td:nth-child(4) { border-left: 0; background: transparent; } /* 스페이서(빈 열) */
.cf-dims:not(.one) th:nth-child(n+4), .cf-dims:not(.one) td:nth-child(n+4) { width: 70px; } /* Avg/Max/Min — 측정값 = 잔여 */

/* 문제점 구조화 표(.prob-table, 07-29 사용자) — 구분(치수/외관)·항목·기준공차·NG 측정값(빨강)·비고 */
/* 09-08 사장님: NG 측정값 = 치수 측정 표 구조(항목 행 × SPL 칼럼) — .dim-table 규칙을 함께 받는다(행 26·수치 우측). 구 nth-child 폭 규칙 폐지 */
.prob-table { width: 100%; }
.prob-table :is(th, td).pt-end { border-right: 1px solid var(--line-2); } /* 09-24(ppt): 아래 치수 측정 표의 고정 구간 끝 세로선과 같게 */
.prob-table td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prob-table:has(> colgroup) :is(th, td) { width: auto !important; min-width: 0 !important; } /* 09-24(ppt): 폭 = colgroup만(아래 치수 표 .dim-table.ch와 같은 규칙) — 옛 nth-child 폭은 colgroup 없는 구 화면용 */
.prob-table th:nth-child(1), .prob-table td:nth-child(1) { width: 64px; }   /* 구분 */
.prob-table th:nth-child(2), .prob-table td:nth-child(2) { min-width: 200px; white-space: nowrap; }  /* 항목 + NG n/m 칩 */
.prob-table th:nth-child(3), .prob-table td:nth-child(3) { width: 80px; text-align: center; }  /* 관리구분 */
.prob-table th.note-col, .prob-table td.ev-note { width: 200px; min-width: 200px; }  /* 비고(항목 비고·외관 특이사항) — 마지막 열 */
.prob-table td { height: 26px; padding: 1px 8px; }
.prob-table td.pv-ng, .prob-table .pv-ng { color: var(--danger); font-weight: 700; }
.prob-table td.ev-note { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cf-ask { margin: 0 0 6px; line-height: 1.55; }
.cf-note { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.5; }
/* ★빈 상태 강조판(07-24 rev08 S3) — "오늘 등록 없음"처럼 다음 행동을 유도해야 하는 빈 상태(뮤트 한 줄은 안 읽힘) */
.empty-warn { padding: 14px 16px; background: var(--warn-bg); border: 1px solid var(--warn-line); border-radius: 8px;
  color: var(--warn-ink); font-size: 13.5px; font-weight: 700; text-align: center; }
/* 빨간 변형(rev09 후속) — 금형 수리중 등으로 "지금은 할 수 없다"를 말해야 할 때(앰버=안내, 빨강=차단) */
.empty-neg { padding: 14px 16px; background: var(--danger-bg); border: 1px solid var(--danger-line); border-radius: 8px;
  color: var(--danger); font-size: 13.5px; font-weight: 700; text-align: center; }

/* ★확인창 경고 강조(07-24 rev06 S5) — "안 하고 넘어가면 문제가 생길 수 있다"만 빨강 부각(남용 금지) */
.cf-warn { margin: 0 0 6px; padding: 6px 10px; background: var(--danger-bg); border: 1px solid var(--danger-line); border-radius: 6px;
  color: var(--danger); font-size: 12.5px; font-weight: 700; line-height: 1.5; }

/* ===== 토스트 ===== */
.toast { position: fixed; top: 50%; left: 50%; transform: translate(-50%, calc(-50% + 16px)); font-size: 18px; font-weight: 700; line-height: 1.5; max-width: calc(100vw - 48px); width: max-content; white-space: normal; word-break: keep-all; text-align: center; background: var(--ink); color: #fff; padding: 22px 36px; border-radius: 12px; opacity: 0; transition: all .25s; z-index: 200; box-shadow: var(--shadow); }
.toast.show { opacity: 1; transform: translate(-50%, -50%); }
.toast.err { background: var(--danger); }

/* ===== EMR 차트 ===== */
.chart-head { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 8px 20px; }
.chart-head .kv .k { color: var(--muted); font-size: 12px; }
.chart-head .kv .v { font-weight: 700; }
/* 금형 기본정보 한 줄 배치: 항목별 예상 텍스트 길이 반영 —
   금형번호 84 · 고객사 70 · 제품군 100 · 품명(유동) · 차수 70 · 후처리(칩2) 128 · 상태(칩2 — 양산+수리중/검증대기) 128 · 직전가동일 94 · 비고(유동)
   ★07-27: 상태 칸 70→128 — 07-24에 수리중/검증대기 칩이 추가됐는데 칸은 칩 1개 폭 그대로라 두 번째 칩이 글자 단위 세로 줄바꿈됐다. */
.mold-head { grid-template-columns: 84px 70px 100px minmax(150px, 1.2fr) 70px 128px 128px 94px minmax(130px, 1fr); gap: 8px 16px; }
.mold-head .kv .chip { white-space: nowrap; } /* 칸이 눌려도 칩 글자는 절대 세로로 꺾이지 않게 */
.mold-head .kv .v.clip-v { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* 비고 길면 …+툴팁 */
/* 좁은 모달은 자동 줄바꿈 — 뷰포트가 아니라 모달 폭(container) 기준: w90 팝업은 76vw라 뷰포트 쿼리로는 못 잡음.
   전환폭 = 그리드 최소폭(고정열 954 + gap 128 = 1082) 이상 */
@container (max-width: 1090px) { .mold-head { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); } }
.thumbs { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.thumb { width: 72px; height: 72px; object-fit: cover; border-radius: 8px; border: 1px solid var(--line); cursor: pointer; }

/* ===== 서브탭 ===== */
/* 07-17: 서브탭 줄 상하 여백 — 활성 pill이 위 헤더·아래 패널(필터바 등)에 닿아 침범해 보이던 것 해소 */
.subtabs { display: flex; gap: 4px; margin: 2px 0 12px; align-items: center; }
.toolbar .subtabs { margin: 0; } /* 재고·PO처럼 툴바 안에 있을 땐 툴바가 간격을 담당 */
/* 07-18: 섹터 최상위 서브탭(.sec) = 밑줄 행 — 그 아래 뷰 탭(pill 행)과 위계 구분(칩 두 줄이 붙어 보이던 문제) */
.subtabs.sec { border-bottom: 1px solid var(--line); padding-bottom: 10px; margin-bottom: 14px; width: 100%; }
.subtab { padding: 7px 16px; border-radius: 8px; text-decoration: none; color: var(--muted); font-weight: 400; font-size: 12.5px;
  display: inline-flex; align-items: center; } /* 라벨+뱃지 수직 정렬 */
.subtab:hover { background: var(--chip); color: var(--ink); }
.subtab.on { background: var(--brand); color: #fff; }
/* ★뷰 탭(툴바 안 PO 관리·생산 계획)은 섹터 탭(재고·PO)과 같은 진한 파랑이라 위계가 안 보였다 →
   뷰 탭 선택은 옅은 파랑으로 구분(07-21 사장님 지시). 섹터 탭 = 진한 파랑(상위) / 뷰 탭 = 옅은 파랑(하위). */
.toolbar .subtabs .subtab.on { background: var(--brand-bg-3); color: var(--brand); font-weight: 700; }
/* ★2단 하위 탭(LOT 원장·후처리·출하이력 등, .sec 아닌 .subtabs) = 옅은 파랑 — 1단 카테고리(진한 파랑)와 위계 구분(rev02 point4) */
.subtabs:not(.sec) .subtab.on { background: var(--brand-bg-3); color: var(--brand); font-weight: 700; }
.subtab.action { cursor: pointer; }
/* 재고·PO 2단 행에서 입력 권한이 없을 때(열람 전용) — 행 높이를 액션 탭과 맞춰 카테고리 전환 흔들림 방지(07-22 rev02 S1) */
.subtabs .subtab-note { padding: 7px 4px; color: var(--muted); font-size: 12.5px; }

/* ===== 일자별 매트릭스 ===== (표 규격은 '현황요약' 기준: 12.5px / 5px 8px)
   스크롤 기준점: 매트릭스 내부 스크롤(헤더 상단·좌측 컬럼 고정) */
/* 외곽 테두리·라운드 없음 — 현황요약 표와 동일한 직각/무외곽 규격 */
.matrix-wrap { overflow: auto; max-height: calc(100vh - 250px); max-width: 100%; border-bottom: 1px solid var(--line); } /* 표 맨 밑 라인 유지(.table-wrap과 동일 규칙) */
.matrix-wrap tbody tr:last-child td { border-bottom: none; }
table.matrix { border-collapse: separate; border-spacing: 0; font-size: 12.5px; white-space: nowrap; background: #fff; }
.matrix th, .matrix td { padding: 5px 8px; border-bottom: 1px solid var(--line-2); border-right: 1px solid var(--line-soft); text-align: center; } /* 행 구분선 = 짙은 회색 1px(제품 구분 가독성), 세로선은 옅게 유지 */
.matrix thead th { background: var(--brand); color: #fff; position: sticky; top: 0; z-index: 2; border-right: 1px solid var(--brand-dark); }
/* ★일자 컬럼 폭 고정(07-20 사장님 확정) — 컬럼 폭이 균일해야 눈에 들어온다. 넘치면 가로 스크롤로 감당.
   ★일자별·주별을 같은 값으로 둔다 — 보기를 바꿔도 격자가 흔들리지 않게(DESIGN 4-B "뷰 전환 픽셀 통일"). */
.matrix { width: auto; }  /* 100%면 컬럼 수가 적은 주별에서 남는 폭이 분배돼 폭이 들쭉날쭉해진다 */
 /* 일자별 = 한 칸 최대 3자리(실측 최대 500) → 좁게 잡아 한 화면에 더 많이 */
.matrix .dc, .matrix th.dh { min-width: 52px; width: 52px; max-width: 52px; }
/* 주별 = PO 최대 4자리(1,000) + 잔량 8자(-1,018.7) → 그에 맞춰 넓게. 보기 안에서는 전부 균일 */
.matrix.wk .dc, .matrix.wk th.dh { min-width: 74px; width: 74px; max-width: 74px; }
/* 일자별 상세 모달 = 값이 천개(반올림)라 최대 5자(백만개=1,000) → 더 좁혀(46px) 한 화면에 날짜를 더 많이.
   좌우 패딩도 줄여 5자가 안 잘리게 함(메인 표는 낱개 4자리라 52px 유지 — .daily에만 적용). */
.matrix.daily .dc, .matrix.daily th.dh { min-width: 46px; width: 46px; max-width: 46px; padding-left: 5px; padding-right: 5px; }
/* 매트릭스 안 칩은 컴팩트 — 칩이 들어간 컬럼 때문에 행 높이가 딴 표보다 커지면 한 화면 정보량이 준다
   (07-20: 생산 계획 44px → 납품 관리와 같은 30px로 맞춤) */
.matrix td .chip { height: 18px; padding: 0 8px; min-width: 0; font-size: 12px; line-height: 1.2; }
/* 팝업 안 기록·이력 표(.rec-table) = 본문 표(30px)와 같은 밀도.
   버튼·칩이 들어가면 행이 37~44px로 부풀어 같은 창인데 표마다 리듬이 달라 보였다(07-20). */
.rec-table td .btn.sm { height: 20px; line-height: 18px; padding: 0 10px; font-size: 11.5px; }
.rec-table td .chip { height: 18px; padding: 0 8px; min-width: 0; font-size: 12px; line-height: 1.2; }
/* ★두 패널(PO 기록·출하 기록) 컬럼 폭 통일 + 삭제 컬럼 좁힘·가운데(07-21 사장님 지시).
   table-layout:fixed → 같은 규칙을 쓰는 두 표의 일자·수량·삭제 폭이 정확히 일치한다. */
.rec-table { width: 100%; table-layout: fixed; }
.rec-table th:nth-child(2), .rec-table td:nth-child(2) { width: 104px; }
.rec-table th:nth-child(3), .rec-table td:nth-child(3) { width: 60px; text-align: center; }
.rec-table td.ctr, .rec-table th.ctr { text-align: center; }
/* 일자별 상세 기록 패널(.rec-log 3열) 전용 — 조치 열에 [수정][삭제] 두 버튼(출하 기록, 07-23 rev04). 두 패널 폭 정렬 유지. */
.rec-table.rec-log th:nth-child(3), .rec-table.rec-log td:nth-child(3) { width: 110px; }
.rec-table .rec-lock { color: var(--muted); font-size: 11.5px; } /* 출하완료 PO = 삭제 잠금(뮤트 텍스트 — 22차 '재가동됨' 문법) */
/* 출하로 채워진 PO 기록 행 = 회색(종결) — 틴트 행엔 구분선 색도 정의(DESIGN §4-K) */
.rec-table tr.po-shipped td { background: var(--done-row); color: var(--muted); border-bottom-color: var(--line-2); }
.rec-table tr.po-shipped td.num.strong { color: var(--muted); }
/* 07-31 감사: 11px는 가독 하한(11.5px) 미만 — 장년층 UX 규칙(DESIGN §1) 위반이라 11.5로 올림 */
.rec-table .chip.rec-st { height: 18px; padding: 0 7px; min-width: 0; font-size: 11.5px; line-height: 1.2; margin-left: 6px; vertical-align: middle; }
/* 생산 판단 팝업(showProdRegister) — 헤더 강조 + 두 표(오늘·지난) 같은 류 칼럼 폭·정렬 통일(07-21 S8) */
/* ★07-24 rev06 S7: 큰 박스·20px 숫자 폐지(사장님 예시) — 라벨 뮤트 + 숫자만 살짝 bold, 배경 없음 */
.pj-head { display: flex; align-items: center; gap: 20px; padding: 2px 2px 8px; margin-bottom: 4px; }
.pj-head .pj-meta { font-size: 12.5px; font-weight: 700; color: var(--muted); }
.pj-head .pj-stats { display: flex; gap: 22px; margin-left: auto; }
.pj-head .pj-stat { display: flex; align-items: baseline; gap: 6px; }
.pj-head .pj-stat .k { font-size: 12.5px; color: var(--muted); }
.pj-head .pj-stat .v { font-size: 13.5px; font-weight: 700; }
.pj-head .pj-stat .v.neg { color: var(--danger); }
/* ★.pj-stat은 .pj-head 안에서만 정의돼 있다 — 다른 곳에 쓸 땐 그 스코프 규칙을 같이 정의할 것(07-20 14차 함정).
   제품 팝업 'DHPV 검사현황' 지표 줄이 같은 문법을 쓴다(07-31). */
.dhpv-stats { display: flex; gap: 22px; flex-wrap: wrap; padding: 2px 2px 6px; }
.dhpv-stats .pj-stat { display: flex; align-items: baseline; gap: 6px; }
.dhpv-stats .pj-stat .k { font-size: 12.5px; color: var(--muted); }
.dhpv-stats .pj-stat .v { font-size: 13.5px; font-weight: 700; }
/* DHPV 연계 표 — 모델명이 식별자라 말줄임 금지, 나머지는 값 길이 기준 고정폭.
   ★min-width = 고정열 합(1,138) + '대흥 제품'이 가져갈 최소폭(250). 열을 더하면 이 값을 다시 계산할 것
   (§4-O — 고정폭 표에서 min-width가 고정열 합에 가까우면 잔여 열이 눌려 글자가 겹친다). */
/* 마스터 = 기반 정보 6열(실적은 품질 페이지). 비고가 잔여 폭을 흡수한다. */
.dhpv-table { table-layout: fixed; min-width: 1080px; }
.dhpv-table th:nth-child(1), .dhpv-table td:nth-child(1) { width: 110px; }  /* 상태 */
.dhpv-table th:nth-child(2), .dhpv-table td:nth-child(2) { width: 240px; }  /* DHPV 모델 — 식별자라 넓게 */
.dhpv-table th:nth-child(3), .dhpv-table td:nth-child(3) { width: 130px; }  /* 차수·열 — "A (1차) · 2열" */
.dhpv-table th:nth-child(4), .dhpv-table td:nth-child(4) { width: 260px; }  /* 본사 제품 */
.dhpv-table th:nth-child(5), .dhpv-table td:nth-child(5) { width: 130px; }  /* 본사 금형 */
/* 품질 > DHPV 실적 — 수치 열은 값 길이 기준, 모델·제품이 넓다 */
.dhpvq-table { table-layout: fixed; min-width: 1500px; }
.dhpvq-table th:nth-child(1), .dhpvq-table td:nth-child(1) { width: 240px; }
.dhpvq-table th:nth-child(2), .dhpvq-table td:nth-child(2) { width: 240px; }
.dhpvq-table th:nth-child(3), .dhpvq-table td:nth-child(3) { width: 80px; }
.dhpvq-table th:nth-child(4), .dhpvq-table td:nth-child(4) { width: 120px; }
.dhpvq-table th:nth-child(5), .dhpvq-table td:nth-child(5) { width: 64px; }
.dhpvq-table th:nth-child(6), .dhpvq-table td:nth-child(6) { width: 110px; }
.dhpvq-table th:nth-child(7), .dhpvq-table td:nth-child(7) { width: 90px; }
.dhpvq-table th:nth-child(8), .dhpvq-table td:nth-child(8) { width: 90px; }
.dhpvq-table th:nth-child(9), .dhpvq-table td:nth-child(9) { width: 90px; }
.dhpvq-table th:nth-child(10), .dhpvq-table td:nth-child(10) { width: 76px; }
.dhpvq-table th:nth-child(11), .dhpvq-table td:nth-child(11) { width: 100px; }
.dhpvq-table th:nth-child(12), .dhpvq-table td:nth-child(12) { width: 190px; }
/* ── DHPV 연계 수정 팝업(07-31 재작업) — 기존 팝업 문법 그대로 조립한다.
   구 버전은 `.de-head`·`.de-tag`·구획 파란 세로 바 같은 **새 클래스를 만들어 붙여** 낯선 화면이 됐다.
   지금은 중분류 `.fsec` · 성격 태그 `.dept-lbl` · 읽기 정보 `.chart-head .kv` · 입력 `.form-grid`를 재사용하고,
   여기서는 **폭만** 정의한다(제품·금형 수정 팝업의 pf-* 규격과 같은 방식). */
/* 읽기 정보 4칸 — 고정폭을 잡으면 최소폭 합(830)이 lg 팝업 본문(765)을 넘어 가로 스크롤이 난다(§4-O 실측).
   기본 .chart-head의 auto-fit을 그대로 쓰되 최소만 160으로 올린다(라벨이 두 줄로 꺾이지 않는 하한). */
.chart-head.dhpv-info { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
/* 저장 결과 = 한 줄 전폭 — 4칸 그리드에 끼우면 값(제품+금형+칩)이 한 칸에 갇혀 3줄로 접힌다 */
.chart-head.dhpv-result { grid-template-columns: 1fr; }
/* 입력 한 줄 5칸 = 제품·금형 수정 '기본 정보'(고객사·제품군·품명·강종·상태)와 같은 리듬. 비고는 .field.full */
.form-grid.dhpv-form { grid-template-columns: 1fr 1fr 1.7fr 1.1fr 0.9fr; }
.form-grid.dhpv-form .field, .form-grid.dhpv-form .field input,
.form-grid.dhpv-form .field select, .form-grid.dhpv-form .field .ssel { min-width: 0; }
.form-grid.dhpv-form .field .ssel, .form-grid.dhpv-form .field .ssel .ssel-in { width: 100%; }
@media (max-width: 1000px) { .form-grid.dhpv-form { grid-template-columns: 1fr 1fr; } }
/* 표준 코드 목록 — 코드가 식별자라 넓게, 나머지는 값 길이 기준 */
.stdcode-table { table-layout: fixed; min-width: 880px; }
.stdcode-table th:nth-child(1), .stdcode-table td:nth-child(1) { width: 250px; }
.stdcode-table th:nth-child(3), .stdcode-table td:nth-child(3) { width: 80px; }
.stdcode-table th:nth-child(4), .stdcode-table td:nth-child(4) { width: 120px; }
.stdcode-table th:nth-child(5), .stdcode-table td:nth-child(5) { width: 50px; }
.stdcode-table th:nth-child(6), .stdcode-table td:nth-child(6) { width: 80px; }
/* 제품 팝업 안의 연계 표 — 연결 정보 4열만(실적은 품질 화면 담당, 07-31) */
.dhpv-mini { table-layout: fixed; min-width: 520px; }
.dhpv-mini th:nth-child(2), .dhpv-mini td:nth-child(2) { width: 70px; }
.dhpv-mini th:nth-child(3), .dhpv-mini td:nth-child(3) { width: 50px; }
.dhpv-mini th:nth-child(4), .dhpv-mini td:nth-child(4) { width: 130px; }
.pj-table { width: 100%; table-layout: fixed; }
.pj-table th, .pj-table td { text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pj-table th.l, .pj-table td.l { text-align: left; }
.pj-table td.num { text-align: right; } /* 본문 숫자는 우측 — 헤더 th.num은 기본(가운데) 유지(2026-07-22 사장님 지시: 금형·num 헤더 가운데) */
.modal-box.w90.pj-modal { width: 84vw; max-width: 1309px; } /* 생산 판단 팝업 전용 = w90(76vw/1190) +10% */
.pj-table td .chip { height: 18px; padding: 0 8px; min-width: 0; font-size: 12px; line-height: 1.2; }
.pj-table tbody tr.clk { cursor: pointer; }
.pj-table tbody tr.clk:hover { background: var(--hover); }
/* ★전 프로젝트 페이지 테이블 행 높이를 매트릭스(현황요약, 30px) 기준으로 통일(07-22 rev02 point5).
   칩 23px·버튼 26px가 행을 34~37px로 부풀리던 것을 컴팩트(칩 18·버튼 22)로 낮춰 셀 패딩(5·8) 안에 들어오게 한다.
   범위 = .table-wrap 내 모든 표(매트릭스는 .matrix-wrap이라 제외, 팝업 .rec-table/.pj-table은 자체 규칙 유지). */
.table-wrap td .chip { height: 18px; padding: 0 8px; min-width: 0; font-size: 12px; line-height: 18px; }
.table-wrap td .btn.sm, .table-wrap td .btn.ghost.sm { height: 20px; padding: 0 10px; font-size: 11.5px; line-height: 1; }
/* 마감대기 점(08-11 절충 — 구 [+마감대기 n] 칩 대체): 현재고 숫자 옆 파란 점 + 칩형 커스텀 툴팁.
   네이티브 title 대신 ::after — 위쪽 표시·표 표준 폰트(12.5)·칩 radius 8(사장님 "정사각형 말고 칩형태·위로"). */
.matrix .udot-wrap { position: relative; }
/* ★점 신호 전역화(08-12) — 파랑 = 정보(마감대기), 빨강 = 채울 일(누락 정보, 마스터 품명) */
.udot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--brand); margin-left: 5px; vertical-align: 1px; flex: 0 0 auto; }
.udot.red { background: var(--danger); }
/* ★hover 팝업 공용(08-12, ui.js hoverPop) — 마감대기 점 칩형 툴팁의 다중 줄 일반화. body 포털(z 300 — 모달 위).
   ★폭 = 텍스트에 맞춤(08-12 3차 사장님 "가로폭을 TEXT에 맞춰" — '있습니 다' 같은 어절 중간 줄바꿈이 전문성을 해친다):
   width:max-content = 내용이 짧으면 박스도 좁게, 캡(ui.js hoverPop width)은 상한만.
   word-break:keep-all = 한글을 어절(띄어쓰기) 단위로만 꺾는다. 캡을 넘는 긴 문장만 어절 경계에서 줄바꿈. */
.hover-pop { position: fixed; z-index: 300; background: #fff; border: 1px solid var(--line); border-radius: 8px;
  box-shadow: var(--shadow); padding: 10px 14px; font-size: 12.5px; color: var(--ink); pointer-events: none;
  line-height: 1.6; width: max-content; word-break: keep-all; overflow-wrap: break-word; }
.hover-pop b { font-weight: 700; }
/* 도움 팝업 구조(08-12 3차 사장님 "글머리 기호로 구분") — 소제목 + 불릿. 문단(.hp-p)은 pre-line */
.hover-pop .hp-body { text-align: left; font-weight: 400; }
.hover-pop .hp-p { white-space: pre-line; margin: 0 0 6px; }
.hover-pop .hp-p:last-child { margin-bottom: 0; }
.hover-pop .hp-sec { margin: 0 0 8px; }
.hover-pop .hp-sec:last-child { margin-bottom: 0; }
.hover-pop .hp-h { font-weight: 700; color: var(--brand-dark); margin: 0 0 3px; }
.hover-pop ul.hp-list { margin: 0; padding-left: 16px; }
.hover-pop ul.hp-list li { margin: 2px 0; }
/* ★도움 칩 '?'(08-12, ui.js helpChip) — 제목 옆 고정 규격(§4-O: 패널 제목줄 안은 20px 계열).
   08-12 2차 사장님 "눈에 잘 안 띈다" → 파랑 틴트 + hover 반전(활성 탭과 같은 어휘 — 장식이 아니라 눌리는 것의 신호) */
.chip.help { min-width: 0; width: 21px; height: 20px; padding: 0; justify-content: center; cursor: help;
  color: var(--brand); background: var(--brand-bg-3); border: none; font-weight: 800; font-size: 13px; flex: 0 0 auto; }
.chip.help:hover { background: var(--brand); color: #fff; }
/* 기본 납품처 복수 칩(08-12 2차) — 첫 칩 = 1순위(파랑), 이후 회색. × = 제거 */
.shipc { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-height: 38px; }
.shipc select { height: 28px; width: 110px; }
.shipc-x { cursor: pointer; font-weight: 700; margin-left: 6px; }
.matrix .udot-wrap:hover::after { content: attr(data-tip); position: absolute; left: 50%; bottom: calc(100% + 7px);
  transform: translateX(-50%); background: #fff; border: 1px solid var(--line); border-radius: 8px;
  box-shadow: var(--shadow); padding: 3px 11px; font-size: 12.5px; font-weight: 700; color: var(--ink);
  white-space: nowrap; z-index: 30; pointer-events: none; }
.matrix td.sticky:hover { z-index: 5; } /* 툴팁이 sticky 헤더(z2)에 가리지 않게 — 호버 중에만 승격 */
.matrix .dc { color: var(--dim); }
.matrix .dc.has { color: var(--ink); font-weight: 700; }
.matrix .dc.po { color: var(--ink); font-weight: 700; } /* 날짜별 PO 수량 = 검정·굵게(잔여PO와 동일 강조, 색 제거) */
.matrix .dc.neg { color: var(--danger); font-weight: 700; }
/* 재고 부족 시점 PO: 현재고 기준 대응 불가 → 빨간 배경 강조 */
.matrix td.dc.short { background: var(--danger-bg-2); color: var(--danger); font-weight: 700; } /* 부족 PO도 동일 굵기(700) */
/* 일반 표에서 재고 부족 셀(현재고 < 당월 PO) */
td.short-cell { background: var(--danger-bg-2); color: var(--danger); font-weight: 800; text-align: right; }
/* 오늘: 헤더 진한 주황+흰글자, 본문 옅은 노랑 */
.matrix td.today { background: var(--warn-bg); }
.matrix thead th.today { background: var(--amber); color: #fff; }
/* 주별 보기 — 지난 주는 흐리게(지나간 것과 앞으로 할 것의 경계가 한눈에) */
.matrix thead th.past { color: var(--dim); background: var(--bg-soft); }
.matrix td.dc.past { color: var(--dim); }
/* 주별 셀 2번째 줄 = 그 주까지 소화하고 남는 재고(±). 부족이 누적되는 흐름을 그대로 보여준다. */
.matrix td .bal { display: block; font-size: 11.5px; color: var(--brand); line-height: 1.15; margin-top: 1px; font-weight: 400; }
.matrix td .bal.neg { color: var(--danger); font-weight: 700; }
/* 세그먼트 토글(일자별/주별) — 붙은 버튼 2개 */
/* 상단 부서(역할) 선택 — 오른쪽 끝. 잠금이 아니라 기본값 제어라 눈에 띄되 조용하게. */
.rolebox { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.rolebox .lbl { color: rgba(255, 255, 255, .72); font-size: 12px; }
.rolesel { height: 28px; font-size: 12.5px; padding: 0 8px; border-radius: 8px;
  background: rgba(255, 255, 255, .14); color: #fff; border: 1px solid rgba(255, 255, 255, .28); }
.rolesel option { color: var(--ink); background: #fff; }
.seg { display: inline-flex; gap: 0; }
.seg .btn { border-radius: 0; margin: 0; }
.seg .btn:first-child { border-radius: 8px 0 0 8px; }
.seg .btn:last-child { border-radius: 0 8px 8px 0; margin-left: -1px; }
/* 일요일·공휴일: 헤더만 빨강+흰글자로 구분(본문 셀 배경 강조 없음 — 헤더로만 인식) */
.matrix thead th.sun, .matrix thead th.hol { background: var(--danger); color: #fff; }
/* 고객사 열 = 가운데 정렬, 날짜 셀 = 오른쪽 정렬(현재고·잔여PO 등 숫자열과 동일) */
.matrix td.cat { text-align: center; }
.matrix td.dc { text-align: right; }
.matrix tr.stock td { background: var(--bg-soft); color: var(--ink-2); font-weight: 700; }
/* 과부족 = 재고 바로 아래 짝행 — 재고와 같은 톤으로 묶되 위 경계선을 지워 한 덩어리로 읽히게(음수는 .dc.neg 빨강) */
.matrix tr.shortage td { background: var(--bg-soft); }
.matrix tr.stock td { border-bottom-color: var(--gray-bg); }
/* ★일자별 상세: PO납기 행에 옅은 파랑 틴트(07-21 사장님 지시) — 흰색(생산·출하)·회색(재고)과 구분.
   PO 숫자가 파란 강조라 파란 계열로 묶어 "이 줄이 납기"임을 색으로 인지. */
.matrix.daily tr.po-due-row td { background: var(--brand-bg-2); }
.matrix.daily tr.po-due-row td.dc.po { background: var(--brand-bg-2); } /* 값 있는 PO 셀도 같은 틴트 유지 */
/* PO 값 셀 클릭 = 그 일자로 출하 입력 — 클릭 가능함을 커서·밑줄·호버로(07-21 S4) */
.matrix.daily tr.po-due-row td.dc.po-ship { cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.matrix.daily tr.po-due-row td.dc.po-ship:hover { background: var(--brand-line); }
.matrix.daily tr.po-due-row td.dc.po-add { cursor: cell; }
.matrix.daily tr.po-due-row td.dc.po-add:hover { background: var(--brand-line); }
/* ★과부족 행 아래 구분선(07-21 사장님 지시 — 표 맨 아래 경계가 없어 행이 허공에 뜬 듯 보였다) */
.matrix.daily tr.shortage td { border-bottom: 1px solid var(--line-2); }
.matrix .rowlab { color: var(--muted); font-weight: 400; }
.matrix .mini { color: var(--muted); font-weight: 400; font-size: 11.5px; }
.matrix tr.clickable:hover td { background: var(--hover); }
.matrix tr.nopo td { color: var(--dim); }
/* 매트릭스도 좌우 끝 세로선 없음 + 데이터 볼드 (현황요약 규격) */
.matrix th:last-child, .matrix td:last-child { border-right: none; }
.matrix tbody td { font-weight: 700; }

/* 범용 고정 컬럼 (left/width는 인라인으로 지정) */
.matrix .sticky { position: sticky; background: #fff; text-align: left; z-index: 1; border-right: 1px solid var(--line); }
/* ★고정 컬럼 사이 세로 구분선을 가로선과 같은 농도로(07-21 사장님 지시 — 품명↔현재고 사이가 안 보였다).
   thead(파란 배경)는 제외하고 tbody 셀만 진하게 — 흰 배경 위 컬럼 경계가 또렷해진다. */
.matrix tbody td.sticky { border-right-color: var(--line-2); }
.matrix .sticky.num { text-align: right; }
.matrix .sticky.ctr { text-align: center; }  /* 칩이 들어가는 고정 컬럼(재고 소진 등)은 가운데 */
.matrix thead .sticky { background: var(--brand); color: #fff; z-index: 3; text-align: center; }
.matrix .cat { color: var(--ink); font-weight: 700; } /* 고객사 = 제품(품명)열과 동일 폰트(볼드·본문색) */
.matrix .strong { font-weight: 700; }

/* 팝업/구분 고정 컬럼 */
.matrix .c-gubun { position: sticky; left: 0; width: 52px; min-width: 52px; background: #fff; z-index: 1; border-right: 1px solid var(--line); }
.matrix thead .c-gubun { background: var(--brand); color: #fff; z-index: 3; }

/* ===== 요약 카드(현황판 상단) ===== */
.sum-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; margin-bottom: 12px; }
.panel.sum { margin: 0; padding: 10px 12px; }
.sum-t { font-weight: 700; font-size: 12.5px; margin-bottom: 6px; padding-left: 8px; border-left: 3px solid var(--brand); }
.panel.sum table { font-size: 12px; }
.panel.sum td { padding: 3px 6px; }
.sum-total td { border-top: 2px solid var(--line); color: var(--brand-dark); }
.bars { display: flex; flex-direction: column; gap: 5px; }
.bar-row { display: grid; grid-template-columns: 40px 1fr 46px; align-items: center; gap: 8px; font-size: 12px; }
.bar-lbl { color: var(--muted); }
.bar-track { background: var(--line-soft); border-radius: 4px; height: 12px; overflow: hidden; }
.bar-fill { display: block; height: 100%; background: var(--brand); border-radius: 4px; }
.bar-val { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }

/* ===== 필터 바 ===== */
/* 첨부 있음 상태 버튼(07-19) — 불량 사진·도식 등: 파랑 틴트 = "내용물 있음" 정보 표시(조치 필요 아님 — 빨강 금지) */
.btn.has-att { background: var(--brand-bg-2); border-color: var(--brand); color: var(--brand-dark); font-weight: 700; }
/* 옅은 파랑 틴트 버튼(07-24 사장님) — 2단 서브탭 활성 칩(#dbe8fb)과 동일 문법. 보조 진입 버튼용(솔리드 파랑=주 행동과 구분) */
.btn.tint { background: var(--brand-bg-3); border-color: transparent; color: var(--brand); font-weight: 700; }
.btn.tint:hover { background: var(--brand-line); }
/* 앰버 틴트 버튼 — 조건부 처분(한도출하=특별관리 전환) 전용, 07-30. 특별관리 칩(.warn) 색 축과 정렬 */
.btn.amber { background: var(--warn-bg); border-color: transparent; color: var(--warn-ink); font-weight: 700; }
.btn.amber:hover { background: var(--warn-bg-2); }

/* ===== 검색형 셀렉트(.ssel — ui.js searchSelect, 07-19 전역 필터 UX) =====
   입력칸 = select와 동일 외형 + 오른쪽 ▾(CSS 삼각형). 패널 = body 포털(fixed, z-index 300 — 모달 100·플로팅 140 위). */
.ssel { position: relative; display: inline-flex; }
.ssel-native { display: none; } /* 원본 select는 데이터 원천으로만 */
.ssel-in { width: 140px; padding-right: 24px; cursor: pointer; }
.ssel::after { content: ''; position: absolute; right: 10px; top: 50%; margin-top: -2px; border: 4px solid transparent; border-top-color: var(--muted); pointer-events: none; }
.filterbar .ssel-in { padding: 6px 24px 6px 8px; font-size: 12.5px; }
.ssel-pop { position: fixed; z-index: 300; background: #fff; border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 8px 28px rgba(0,0,0,.18); max-height: 300px; overflow-y: auto; padding: 4px; }
.ssel-opt { padding: 6px 10px; border-radius: 6px; cursor: pointer; font-size: 12.5px; white-space: nowrap; }
.ssel-opt:hover, .ssel-opt.act { background: var(--hover); }
.ssel-opt.on { background: var(--brand-bg-2); font-weight: 700; }
.ssel-opt.ssel-all { color: var(--muted); border-bottom: 1px solid var(--line); border-radius: 6px 6px 0 0; margin-bottom: 2px; }
.ssel-empty { padding: 6px 10px; font-size: 12px; color: var(--muted); }
.ssel-prod .ssel-in { width: 220px; } /* 품명 칸(productPicker)은 넓게 */
/* 폼 그리드(생산 다건 .pr-row / PO·출하 다건 .me-row) 안에서는 셀 폭을 그리드가 결정 — wrapper·입력칸 100% */
.pr-row .ssel, .me-row .ssel { min-width: 0; width: 100%; }
.pr-row .ssel .ssel-in, .me-row .ssel .ssel-in { width: 100%; }

/* margin-bottom 8 통일(08-11 — 구 12: 생산·재고는 인라인 8을 쓰고 있어 화면마다 표 간격이 달랐다) */
.filterbar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; margin-bottom: 8px; box-shadow: var(--shadow); }
.filterbar .fb-lbl { font-size: 12px; color: var(--muted); font-weight: 400; }
.filterbar select, .filterbar input { padding: 6px 8px; font-size: 12.5px; }
.filterbar .fb-count { margin-left: auto; font-size: 12px; color: var(--muted); font-weight: 400; }
/* 필터바 건수 — 전역 `.meta`(14px 잉크)를 그대로 받아 패널헤더 meta(12.5)보다 커 보이던 것 정렬(07-31 §2).
   조회 결과 수는 보조 정보라 뮤트. 오른쪽 끝 정렬은 fb-count와 동일 규칙. */
.filterbar .meta { margin-left: auto; font-size: 12.5px; color: var(--muted); font-weight: 400; }

/* ===== 요약 breakdown (고객사>제품군>후처리) ===== */
.breakdown { font-size: 12.5px; }
.breakdown th, .breakdown td { padding: 4px 10px; }
.breakdown td.bd-cust { font-weight: 800; background: var(--chip); vertical-align: top; }
.breakdown td.bd-grp { font-weight: 700; color: var(--ink-2); vertical-align: top; }
.breakdown tr.bd-sub td { border-top: 1px solid var(--line); font-weight: 800; color: var(--brand-dark); background: var(--bg-soft); }
.breakdown tr.bd-total td { border-top: 2px solid var(--brand); font-weight: 800; }

/* ===== 팝업 빠른 입력 ===== */
.quick-entry { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 14px; }
/* 출하 합계 강조 박스(07-21) — 담은 LOT·출하수량·BOX를 한눈에. 출하 입력의 결과가 밀려 보이지 않게. */
.ship-total { display: flex; gap: 28px; align-items: baseline; justify-content: flex-end;
  background: var(--brand-bg); border: 1px solid var(--brand-line); border-radius: 8px; padding: 10px 16px; }
.ship-total .st-item { display: flex; gap: 8px; align-items: baseline; }
.ship-total .st-lbl { font-size: 12.5px; color: var(--muted); font-weight: 700; }
.ship-total .st-val { font-size: 15px; font-weight: 700; color: var(--ink); }
.ship-total .st-val.big { font-size: 20px; color: var(--brand); }
/* 출하 팝업 상단 BOX 포장단위 정보(07-22 rev02 S2 — 하단 힌트에서 헤더로 이동) */
/* BOX 포장단위 = 왼쪽 납품처 입력칸(높이 34px) 정도로 키움(07-23 사장님) — 읽는 정보라 테두리로 박스처럼 보이되 편집칸과 구분(연한 배경). */
.box-unit-info { display: inline-flex; align-items: center; gap: 6px; margin-left: 4px; padding: 0 12px; height: 38px; box-sizing: border-box; background: var(--bg-soft); border: 1px solid var(--line); border-radius: 6px; }
.box-unit-info:empty { display: none; }
.box-unit-info .bu-k { font-size: 13.5px; color: var(--muted); font-weight: 700; }
.box-unit-info .bu-v { font-size: 15px; font-weight: 700; color: var(--ink); }
.box-unit-info .bu-v.muted { color: var(--muted); }   /* '이 일자 PO 없음' 등 — 값 없음은 뮤트(07-23) */
.qe-box { background: var(--bg-soft); border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; }
.qe-box b { font-size: 12.5px; display: block; margin-bottom: 6px; }
.qe-box input[type=number] { width: 90px; }
.mini { font-size: 11.5px; color: var(--muted); }
@media (max-width: 720px) { .quick-entry { grid-template-columns: 1fr; } }

.rate-preview { background: var(--brand-bg); border: 1px solid var(--brand-line); border-radius: 8px; padding: 8px 12px; font-weight: 800; color: var(--brand-dark); text-align: center; }

/* 수리의뢰 배너 (생산 건 상세 상단) — 품질/생산 누가 냈든 여기 표시 */
.req-banner { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
/* 배너 텍스트 = 세부이력 표 내용(td)과 동일(13.5 · 볼드). 출처 구분은 칩·배경톤으로 */
/* ★flex 행 압착 가드(08-03 사용자 캡처 — 문제현상이 길어지면 메타가 두 줄로 꺾이고 이름이 세로로 쌓였다):
   고정 내용(칩·메타·이름·주석·버튼) = flex:none + nowrap / 가변 텍스트(문제현상) = flex:1 + min-width:0.
   좁으면 flex-wrap으로 문제현상이 다음 줄 전폭으로 내려간다(글자 압착 대신 줄 이동). */
.req-line { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; background: var(--danger-bg-2); border: 1px solid var(--danger-line); border-radius: 8px; padding: 8px 12px; font-size: 13.5px; }
.req-line > .chip:first-child { margin-right: 20px; }  /* 출처 칩 ↔ 접수대기 간격 3배(gap10 + 20 = 30) — 첫 칩만(재발 칩 제외) */
.req-line .req-meta { color: var(--danger); font-weight: 700; flex: 0 0 auto; white-space: nowrap; }
.req-line .req-name { color: var(--ink); font-weight: 700; flex: 0 0 auto; white-space: nowrap; } /* 이름은 빨간색 금지 */
.req-line .sub { flex: 0 0 auto; white-space: nowrap; } /* '지난 의뢰' 주석 */
.req-line .btn { flex: 0 0 auto; }
/* 문제현상 = 잔여 폭 전부·내부 줄바꿈. pre-line = [재발 …] 줄이 한 줄씩 읽힌다(재발 이력 = 목록이지 문단이 아니다) */
.req-line .req-sym { color: var(--ink); font-weight: 700; flex: 1 1 260px; min-width: 0; white-space: pre-line; }
/* 품질 의뢰: 같은 빨강 계열이되 더 짙게 구분 — 배경 톤·좌측바 짙은red */
.req-line.qual { background: var(--danger-bg-2); border-color: var(--danger-line); }
/* 수리 검증 대기 배너(생산 건 상세) — 경고성 앰버 톤(의뢰 빨강과 구분: 조치할 일이지 문제 상황은 아님) */
.req-line.verify { background: var(--warn-bg); border-color: var(--warn-line); }
.req-line.verify .req-meta { color: var(--warn-ink); }
/* 출처 칩: 둘 다 도형(pill)이되 구분 — 생산=테두리형(흰 배경·빨강 테두리), 품질=솔리드 레드 */
.chip.trial { background: #fff; border: 1px solid var(--brand); color: var(--brand); } /* Trial(개발 시타) — 테두리형 파랑 */
/* 출처 칩(범주값) — 07-17: 파랑은 OK/양품 연상이라 품질=보라 틴트로 교체. 스캔 규칙 = "색 있으면 품질, 무채색이면 생산".
   보라는 상태색(빨강=조치필요/앰버=조건부/초록=통과/빨강틴트=대기)과 어느 것과도 안 겹치는 유일한 범주 전용 색. */
.chip.rq-prod { background: var(--gray-bg); border: 1px solid var(--line); color: var(--ink-2); }        /* 생산의뢰 — 중립 회색, 텍스트 대비 강화 */
.chip.rq-qual { background: #f3ecfb; border: 1px solid #e0d0f3; color: #6d28a8; }            /* 품질의뢰 — 보라 틴트 */
/* "이 문제로 수리의뢰?" 팝업의 직전 이력 표시 박스 */
.prev-ev { margin-top: 10px; background: var(--bg-soft); border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; font-size: 13.5px; font-weight: 700; white-space: pre-wrap; }
/* 재발 기록 대상 선택(08-03 C-11) — 여러 미완결 의뢰 중 클릭으로 지정. 활성 = 파란 외곽선(EMR 현황 칩 문법) */
.prev-ev.pickable { cursor: pointer; }
.prev-ev.pickable:hover { background: var(--hover); }
.prev-ev.pickable.sel { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand) inset; }

/* ★즉시 저장 마이크로 피드백(08-03 — ui.js savedFlash): 저장 성공 순간 칸 초록 + '저장됨 ✓' 1.5초.
   라벨 = absolute + 흰 배경(겹치는 이웃 요소를 잠깐 덮되 레이아웃은 불변 — §4-B), pointer-events 없음. */
input.saved-flash, select.saved-flash { border-color: var(--ok) !important; box-shadow: 0 0 0 2px rgba(26, 157, 90, .18) !important; }
.saved-tag { position: absolute; transform: translateY(-50%); z-index: 5; font-size: 11.5px; font-weight: 700;
  color: var(--ok); background: #fff; padding: 1px 5px; border-radius: 4px; border: 1px solid var(--ok-line);
  white-space: nowrap; pointer-events: none; animation: savedTagFade 1.5s forwards; }
@keyframes savedTagFade { 0% { opacity: 0; } 12% { opacity: 1; } 75% { opacity: 1; } 100% { opacity: 0; } }
/* 금형 지난 수리이력 박스 (수리의뢰 창) */
.mold-hist { margin-top: 12px; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.mold-hist .mh-title { background: var(--bg); padding: 6px 10px; font-size: 12.5px; color: var(--muted); border-bottom: 1px solid var(--line); }
.mold-hist .mh-empty { padding: 10px; font-size: 12.5px; color: var(--muted); }
.mold-hist .mh-list { max-height: 150px; overflow-y: auto; }
.mold-hist .mh-row { display: flex; gap: 10px; padding: 6px 10px; border-bottom: 1px solid var(--line-soft); font-size: 12.5px; }
.mold-hist .mh-row:last-child { border-bottom: none; }
.mold-hist .mh-date { flex: 0 0 auto; color: var(--muted); font-variant-numeric: tabular-nums; }
.mold-hist .mh-sym { flex: 1 1 auto; }
.mold-hist .mh-eng { flex: 0 0 auto; color: var(--muted); }

/* 생산 건 상세 — 헤더(상태 우측, 폰트 키움) */
.detail-head { display: flex; flex-wrap: wrap; gap: 6px 40px; align-items: center; margin-bottom: 12px; padding-bottom: 10px; border-bottom: 1px solid var(--line); } /* 항목 간 간격 40(2배) — flex gap이라 제품명이 길어도 유지 */
/* 헤더 정보 항목: 키·값 폰트 크기 통일(16px)로 균일성·가독성 확보 */
.dkv { display: flex; gap: 7px; align-items: baseline; font-size: 15px; }
.dkv .k { color: var(--muted); font-size: 15px; }
.dkv .v { font-weight: 700; }
/* 헤더 SPM 인라인 입력: 시타 후 확정값을 상세에서 바로 입력/수정(즉시 저장) */
.dkv-spm { width: 76px; height: 30px; padding: 4px 8px; font-size: 15px; font-weight: 700; }
/* 상태 dkv: 다른 항목과 같은 간격·표준 칩 크기 (오른쪽 밀착·확대 금지 — 간격 균일) */
.dkv-status { gap: 8px; }

/* 마감 가로 바 — 입력·지표 셀 동일 스타일, 전체폭 균등, 버튼 오른쪽.
   좁은 폭에선 셀이 0으로 눌려 시간 텍스트가 잘리므로 최소폭(110)에서 줄바꿈(flex-wrap) */
.close-bar { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; }
.cb-cell { flex: 1 1 110px; min-width: 110px; display: flex; flex-direction: column; gap: 5px; }
.cb-cell .lbl { font-size: 13.5px; color: var(--muted); font-weight: 400; } /* 셀 라벨 13.5 · Regular */
.cb-cell input { width: 100%; height: 38px; font-size: 15px; padding: 10px; } /* 입력칸 15 · 여백 10 균일 */
/* ★수기 입력칸(.cb-in) = 생산수량·불량수량 둘뿐 — 나머지는 자동값이다(07-20).
   "어디에 내가 값을 넣어야 하나"가 한눈에 보이게 라벨을 파랑·볼드로, 칸은 파란 테두리로. */
.cb-cell.cb-in .lbl { color: var(--brand-dark); font-weight: 700; }
.cb-cell.cb-in input { border-color: var(--brand); background: #fff; }
.cb-cell.cb-in input:focus { box-shadow: 0 0 0 3px rgba(31, 111, 235, .12); }
/* 마감 바 행동 버튼 묶음 — 줄이 바뀌어도 오른쪽 끝 유지(구: 버튼이 왼쪽으로 흩어졌다) */
.cb-actions { margin-left: auto; display: flex; gap: 10px; align-items: flex-end; flex: 0 0 auto; }
/* 유형이 금형 문제일 때 뜨는 예고 문구 — "저장하면 수리의뢰를 물어봅니다"(앰버 = 조건부 안내)
   .plain = 정지성(비금형) 유형의 안내 — 조건부가 아니라 단순 설명이라 뮤트 회색 */
.ev-req-hint { margin-top: 10px; font-size: 12.5px; color: var(--warn-ink); }
.ev-req-hint.plain { color: var(--muted); }
/* 유형별 논리 검사 차단(08-01) — "지금 상태에서는 이 유형으로 기록할 수 없다".
   앰버=확인 후 진행 / 빨강=차단 (.empty-warn ↔ .empty-neg와 같은 짝, §1 빨강 농도 규칙) */
.ev-req-hint.neg { color: var(--danger); font-weight: 700; }
/* 내용 필수(문제성 유형) 강조 — 미입력 상태를 색으로 인지시키는 f-empty와 같은 사상 */
.ev-add-grid textarea.f-req { border-color: var(--brand); }
.num-in { text-align: right; font-variant-numeric: tabular-nums; }
.mval { height: 38px; border: 1px solid var(--brand-line); border-radius: 8px; background: var(--brand-bg); display: flex; align-items: center; justify-content: center; font-size: 15px; font-weight: 800; color: var(--brand-dark); } /* 지표값 15 */
.cb-btn { flex: 0 0 auto; align-self: flex-end; height: 38px; padding: 0 24px; font-size: 15px; } /* 버튼류 폰트 15 통일 */
/* 마감 상태: 배경 회색 (확실한 구분) */
.panel.closed .mval { background: var(--done-row); border-color: var(--line-2); }

/* ===== 상세 팝업 공통 기준 (다른 패널 수정 시에도 이 기준 적용)
   폰트: 패널제목 14 · 표/칩/라벨/입력 본문 13.5(마감 입력은 15) · 지표값 15
   여백: TRBL 균일(패널/박스 14 · 입력·표셀 8~10, 좌우값에 상하 맞춤)
   모서리: 버튼·유형칩 radius 8 통일 · 버튼 높이 38(표 안 버튼 제외) ===== */
.ev-panel, .close-panel { padding: 14px; }                     /* 패널 안쪽여백 TRBL 14 */

/* 세부 이력 패널: 표·유형칩·meta */
.ev-panel .panel-head .meta { font-size: 14px; }               /* meta(건수) 14 */
.ev-table th, .ev-table td { font-size: 13.5px; padding: 5px 8px; } /* 표 헤더·본문 13.5 · 상하5/좌우8 */
.ev-table .chip { font-size: 12.5px; padding: 2px 5px; border-radius: 8px; } /* 유형칩: 폰트 12.5 · 상하2(표준 칩 높이와 동일) · radius 8 */
/* 팝업 이력 표 행 높이 통일 (기준 = 품질검사 이력: 칩 포함 32px) — 세부이력·수리이력·검사이력·가동이력 동일 */
.ev-table td, .rep-table td, .qi-table td, .run-table td { height: 32px; }
/* 금형 차트 이력 표 기본 행수: 수리 7행 · 검사/가동 4행 — 넘치면 내부 스크롤 (thead 28.5 + 행 32×n)
   (.hist-sec .table-wrap 240px 기본보다 우선하도록 특이도 유지) */
.table-wrap.rows7, .hist-sec .table-wrap.rows7 { max-height: min(254px, calc(100vh - 340px)); }
.table-wrap.rows4, .hist-sec .table-wrap.rows4 { max-height: min(158px, calc(100vh - 340px)); }
/* 금형 가동 이력 (.run-table, fixed): 생산일 폭 = 검사일(106) 통일, 남는 폭은 품명(auto)으로.
   min-width: 좁은 화면에서 품명이 0으로 눌리지 않게 — 부족하면 표 내부 가로 스크롤 */
/* 07-27 사장님 px: 생산일100·품명180·차수60·설비60·주야60·담당자80·생산~가동률 80 균일·이력50.
   전 컬럼 고정이 되므로 끝 스페이서 열(12)이 잔여 흡수 — 넓은 화면 비례 확대 방지(07-18 8차 규칙) */
.run-table { table-layout: fixed; width: 100%; min-width: 1080px; } /* 고정열 합 1040 + 스페이서 최소 40 — 좁으면 표 내부 가로 스크롤 */
.run-table th:nth-child(1), .run-table td:nth-child(1) { width: 100px; }  /* 생산일 = 검사일 폭 */
.run-table th:nth-child(2), .run-table td:nth-child(2) { width: 310px; }  /* 품명 = 시각+결과+외관+수리구분 합(07-30 사장님) */
.run-table th:nth-child(3), .run-table td:nth-child(3) { width: 60px; }   /* 차수 */
.run-table th:nth-child(4), .run-table td:nth-child(4) { width: 60px; }   /* 설비 */
.run-table th:nth-child(5), .run-table td:nth-child(5) { width: 60px; }   /* 주야 */
.run-table th:nth-child(6), .run-table td:nth-child(6) { width: 80px; }   /* 담당자 */
.run-table th:nth-child(7), .run-table td:nth-child(7) { width: 80px; }   /* 생산 */
.run-table th:nth-child(8), .run-table td:nth-child(8) { width: 80px; }   /* 불량 */
.run-table th:nth-child(9), .run-table td:nth-child(9) { width: 80px; }   /* 마감 */
.run-table th:nth-child(10), .run-table td:nth-child(10) { width: 80px; } /* 가동률 */
.run-table th:nth-child(11), .run-table td:nth-child(11) { width: 50px; } /* 이력 */
.run-table td:nth-child(2) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* 품명 180 고정 — 긴 품명은 …(잘림 방지) */
/* 세부이력 컬럼 폭: 유형 축소 · 불량수 축소 · 내용 최대 · 삭제 우측 */
.ev-table { table-layout: fixed; width: 100%; }
/* 07-20 재구성: 삭제(맨 왼쪽) | 시각 | 유형 | 불량수 | 내용(잔여 흡수) | 조치(수리의뢰)
   ★조치 열은 버튼이 잘리지 않는 고정폭(90) — 내용이 잔여를 먹으므로 버튼 열을 침범하지 않는다. */
.ev-table th:nth-child(1), .ev-table td:nth-child(1) { width: 58px; text-align: center; }   /* 삭제 */
.ev-table th:nth-child(2), .ev-table td:nth-child(2) { width: 62px; text-align: center; }   /* 시각 — 범주값 가운데 */
.ev-table th:nth-child(3), .ev-table td:nth-child(3) { width: 96px; text-align: center; }   /* 유형 칩 — 가운데 */
.ev-table th:nth-child(4), .ev-table td:nth-child(4) { width: 58px; }   /* 불량수 */
.ev-table th:nth-child(6), .ev-table td:nth-child(6) { width: 90px; }   /* 조치(수리의뢰) */
/* 삭제 = 기록 정정이라 평상시엔 조치 버튼보다 약하게(뮤트). 단 hover는 .btn.danger와 같은 문법 —
   ★ui.js el()이 '삭제'가 든 버튼을 전역에서 .danger로 바꾸므로 hover에 빨간 배경이 깔린다.
   여기서 글자색까지 빨강으로 두면 빨강 위 빨강이 되어 글자가 사라진다(07-20 실제 발생). 반드시 흰색. */
.ev-table .ev-del { color: var(--muted); border-color: var(--line); }
.ev-table .ev-del:hover { background: var(--danger); border-color: var(--danger); color: #fff; }
/* 표 안 수리의뢰 버튼: 삭제와 같은 규격, 빨강 톤으로만 구분 */
.btn.ghost.req-btn, .btn.ghost.alt-danger { color: var(--danger); border-color: var(--danger-line); }
.btn.ghost.req-btn:hover, .btn.ghost.alt-danger:hover { background: var(--danger-bg-2); }
.ev-note { white-space: pre-wrap; word-break: break-word; }
/* 표 안의 보조 텍스트(조치 열 '재가동됨' · 내용 앞 '정지 N분') = 뮤트 12.5.
   ★`.sub`는 `.page-head`/`.panel-head` 안에서만 정의돼 있어 표에서는 본문색 13.5로 튄다(07-20 14차와 같은 함정).
   새 위치에 `.sub`를 쓸 땐 그 스코프에 규칙이 있는지 먼저 확인할 것. */
.ev-table .sub, .ev-view .sub, .mst .sub { color: var(--muted); font-size: 12.5px; }
/* ★패널 본문의 설명 줄(07-31 사장님 "주석 폰트가 불일치") — `.sub`는 `.page-head`/`.panel-head` 안에서만
   정의돼 있어 패널 직계 자식으로 쓰면 본문색 13.5로 튀었다(§4-O 스코프 함정, 07-20 14차와 같은 계열).
   마스터 5탭·품질 DHPV 실적 등 6곳이 여기 해당 — 한 줄로 전부 정렬된다. */
/* 팝업 본문의 설명 줄도 같은 규격 — `.sub`가 스코프별로 정의돼 있어 모달 안에서는 본문색 14로 튀었다(07-31).
   §4-O 함정 7번째 사례. 이 한 줄로 전 팝업의 안내 문구가 정렬된다. */
.panel > .sub, .panel > .hist-sec > .sub, .modal-body .sub { font-size: 12.5px; color: var(--muted); line-height: 1.6; }
/* 형식 예시(`제품명_차수_#열`) — 배경 칩만 주고 **서체·크기는 본문 그대로**.
   ★프로젝트는 나눔스퀘어 단일 서체다(§2). code 태그를 그냥 두면 브라우저 기본 monospace가 나와
   한 줄 안에서 서체·크기가 갈린다(07-31 사장님 지적). 구분은 서체가 아니라 칩 배경+굵기로 준다. */
.sub code, .panel > .sub code, .modal-body .sub code {
  font-family: inherit; font-size: inherit; font-weight: 700;
  background: var(--chip); color: var(--brand-dark); padding: 1px 6px; border-radius: 4px;
}
.panel > .sub b { color: var(--ink); }

.ev-add { margin-top: 12px; background: var(--bg-soft); padding: 14px; } /* 박스 안쪽여백 TRBL 14 */
/* 제목줄 = 제목 + 오른쪽 끝 빠른 기록 버튼. 간격은 컨테이너 gap이 담당(고정 margin 금지 — §4-O) */
.ev-add-title { font-size: 14px; font-weight: 700; margin-bottom: 10px; display: flex; align-items: center; gap: 10px; } /* 패널제목 14 */
/* 빠른 기록(재가동·소재교체) = 입력 박스의 [+ 이력 추가]와 성격이 같은 '기록' 행위라 같은 박스에 둔다.
   단 제목줄로 올려 입력 그리드 안 버튼은 [+ 이력 추가] 하나뿐이라는 규칙(15차)은 유지.
   버튼 규격은 공통 .btn.sm(높이 30·12px) 그대로 — 제목 14px 줄에 얹어도 중심선이 맞는다(실측 4요소 동일). */
.ev-quick { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.ev-quick .sub { font-size: 12.5px; color: var(--muted); font-weight: 400; }
.ev-quick .btn { font-weight: 700; }
/* 이력추가 하단 버튼줄: 높이 38 통일(입력칸과 일치), 폰트 15, radius 8, 텍스트 세로중앙 */
.ev-add .row .btn { height: 38px; font-size: 15px; display: inline-flex; align-items: center; justify-content: center; }
/* 시각 · 유형 · 내용(유형 바로 오른쪽에서 시작, 잔여 전폭) — 상단 라인 정렬, 내용은 기본 1줄(입력 시 자동 확장)
   불량수 컬럼은 '불량발생'일 때만(.has-extra) 펼침 → 그 외엔 내용칸이 왼쪽으로 당겨지고 넓어짐 */
/* 마지막 열 = [+ 이력 추가] 버튼(07-20): 별도 버튼 줄을 없애고 내용칸 오른쪽 같은 줄에 둔다 —
   "적는다 → 바로 오른쪽에서 넣는다"로 손과 눈이 한 줄에서 끝난다(박스 높이도 한 줄 줄어든다). */
/* 07-20 2단 분류: 시각 | 구분(대분류) | 세부 유형 | [불량수] | 내용(잔여) | 버튼 */
.ev-add-grid { display: grid; grid-template-columns: 150px 130px 150px 1fr max-content; gap: 12px; align-items: start; }
.ev-add-grid.has-extra { grid-template-columns: 150px 130px 150px 110px 1fr max-content; }
/* 버튼은 행 바닥에 맞춘다(align-self:end) — 고정 margin으로 내리면 라벨 높이가 1px만 달라져도 어긋난다.
   내용칸이 여러 줄로 늘어나도(autoGrow) 항상 입력칸 아래끝과 같은 선에 선다. */
.ev-add-grid .ev-add-btn { height: 38px; font-size: 15px; align-self: end; display: inline-flex; align-items: center; justify-content: center; white-space: nowrap; }
.ev-extra { display: none; }                                   /* 불량수 숨김(기본) */
.ev-add-grid.has-extra .ev-extra { display: block; }           /* 불량발생 시 노출 */
.ev-add-grid .field { gap: 5px; }                              /* 라벨↔입력 간격 통일 */
.ev-add-grid .lbl { font-size: 13.5px; }                       /* 셀 라벨 13.5 */
.ev-add-grid input, .ev-add-grid select, .ev-add-grid textarea { height: 38px; font-size: 13.5px; padding: 10px; } /* 박스 높이 38 · 본문 13.5 · 여백 10 균일 */
.ev-note-field textarea { min-height: 0; resize: none; overflow-y: hidden; line-height: 16px; } /* 1줄이 여백10+높이38 안에 딱 맞게(줄바꿈 시 autoGrow) */
@media (max-width: 900px) { .ev-add-grid { grid-template-columns: 1fr 1fr; } }

/* 열람 팝업 섹션(생산 이력 상세 등) — 섹션 간격 12px 통일(DESIGN 기준) + 표는 섹션 내부 스크롤 */
/* ===== 검사 기준(프리셋) 팝업 ===== */
/* 팝업 공통 규격(DESIGN 4-G): 칩 radius 8·폰트 12.5·여백 상하6/좌우5. 패널 제목줄 버튼은 sm(29·5/10·12) */
.modal-box .panel-head .btn { height: auto; padding: 5px 10px; font-size: 12px; line-height: inherit; border-radius: 8px; }
/* 모달 안 필터 바(제목 + 버튼 + 셀렉트 + 검색): 좁아지면 한 줄이 밖으로 넘치므로 줄바꿈 허용.
   spacer(flex:1)가 line1을 채워 제목만 위, 필터 컨트롤은 아래 줄로 자연히 내려간다. 검색창은 폭 상한. */
.modal-box .panel-head { flex-wrap: wrap; row-gap: 8px; }
.modal-box .panel-head input, .modal-box .panel-head select { max-width: 100%; min-width: 0; }
.spec-table { table-layout: fixed; width: 100%; min-width: 1664px; } /* 고정컬럼 1524 + 측정항목(auto ≥140) — 부족하면 표 내부 가로 스크롤(잘림 금지) */
.table-wrap.spec-wrap { max-height: min(510px, calc(100vh - 340px)); }
/* 검사 기준 창(09-18 사장님): 측정 특이사항은 아래 고정, 측정항목 표만 스크롤.
   .spec-pane까지 이어지는 조상 전부를 flex 열로 세워 높이를 내려보낸다(:has로 이 창에만 적용). */
.modal-box .modal-body:has(.spec-pane),
.modal-box .modal-body :has(.spec-pane) { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; overflow: hidden; }
.modal-box .spec-pane { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }
.modal-box .spec-pane > .panel-head, .modal-box .spec-pane > .hist-sec { flex: 0 0 auto; }
.modal-box .spec-pane > div:not(.panel-head):not(.hist-sec) { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.modal-box .spec-pane .table-wrap.spec-wrap { flex: 1 1 auto; min-height: 140px; }
.modal-box .spec-pane > .hist-sec { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--line); } /* .table-wrap 병기 = 팝업 일반 캡(.modal-box .table-wrap)과 특이도 동급(뒤 규칙 우선) */
.spec-table .chip { font-size: 12.5px; padding: 2px 5px; border-radius: 8px; } /* 유형칩 상하2/좌우5 (4-G 표준 칩 높이) */
.spec-table td { height: 26px; padding-top: 0; padding-bottom: 0; overflow: hidden; text-overflow: ellipsis; } /* 행 26px(치수 측정 표 규격 — 07-30 사장님 "한 화면에 많이"). 잘리면 …로, 전체 텍스트는 툴팁(title) */
/* ★08-05 3차 정정 = nth-child 지도 폐지 → 칼럼 클래스(검사 입력 표 .std-col 문법과 통일).
   07-28 '순서' 신설·08-05 '검사축' 신설 때마다 nth가 밀려 폭·웜 틴트가 옆 칼럼(-공차)을 오염시켰다 —
   열이 늘어도 안 밀리는 클래스 폭 지도로 전환(§4-O 함정 목록의 nth-child 폭 지도 항목). 항목명 = 잔여 폭 전부(auto). */
.spec-table th:nth-child(1), .spec-table td:nth-child(1) { width: 76px; }   /* 순서(좌1 고정 — 마스터=↑↓ / 차트=순번 열람) */
.spec-table td:nth-child(1) { white-space: nowrap; } /* ↑↓ 세로 꺾임 방지(07-30 — 화살표 한 줄) */
.spec-table td:nth-child(1) .row { flex-wrap: nowrap; } /* 폭이 애매해도 두 버튼이 절대 두 줄로 안 꺾이게 */
/* 표 안 버튼(↑↓·삭제) 소형화 = 행 26px 유지(07-30 사장님 "치수측정 표 높이만큼") */
.spec-table td .btn.sm { height: 22px; min-width: 22px; padding: 0 5px; font-size: 12px; }
.spec-table th.grp-col, .spec-table td.grp-col { width: 164px; }   /* 측정구분 — 가장 긴 "정면_평면도 3D", "배면_내측 3D"+[측정] 칩이 안 잘리는 폭(09-24 실측) */
.spec-table th.axis-col, .spec-table td.axis-col { width: 72px; }  /* 검사축(08-05) — 수검/순회/별도 2자 + 여백 */
.spec-table th.std-col, .spec-table td.std-col { width: 78px; }    /* 기준값 — 8자 */
.spec-table th.tol-col, .spec-table td.tol-col { width: 78px; }    /* ±공차 */
.spec-table th.in-col, .spec-table td.in-col { width: 150px; }     /* 내부 관리 — rev02 S3: 92px에선 "1.50 +0.0…"으로 잘렸다. 검사 입력 표 기준 칼럼(150)과 동일 폭 */
.spec-table th.kind-col, .spec-table td.kind-col { width: 92px; }  /* 구분 — 칩 66 + 여백 확보 */
.spec-table th.mg-col, .spec-table td.mg-col { width: 120px; }
.spec-table th.fj-col, .spec-table td.fj-col { width: 150px; }      /* 관리구분 — 칩 66 + 여백 */
.spec-table th.certno-col, .spec-table td.certno-col { width: 88px; text-align: center; }
.spec-table th.certtxt-col, .spec-table td.certtxt-col { width: 104px; }  /* 성적서 기재 표기(09-18) — 비우면 왼쪽 그룹·항목명 그대로 */ /* 성적서 No(08-06) — 자유 텍스트, 잘리면 …+툴팁 */
.spec-table th.date-col, .spec-table td.date-col { width: 106px; } /* 저장일 2026-07-05 */
.spec-table th.del-col, .spec-table td.del-col { width: 64px; }    /* 삭제 */
.spec-table th.note-col, .spec-table td.note-col { width: 210px; } /* 비고(붙여넣기 미리보기 전용 열, 08-05) — 잘리면 …+툴팁 */
/* 범주값 가운데 정렬 (DESIGN 4-D): 검사축 · 구분·관리구분 칩 · 저장일 · 삭제 버튼 (정렬은 td에만 — 헤더는 공통 가운데) */
.spec-table td.axis-col, .spec-table td.kind-col, .spec-table td.mg-col,
.spec-table td.date-col, .spec-table td.del-col { text-align: center; }
/* 도면 열람 팝업 (금형당 1장, A4/A3 가로) — 이미지 또는 PDF(브라우저 내장 뷰어) */
/* ===== 플로팅 창 (도면 열람 등) — 배경을 막지 않아 뒤 팝업과 동시 작업 가능. 제목줄 드래그·모서리 리사이즈 ===== */
.float-win { position: fixed; z-index: 140; background: #fff; border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 16px 48px rgba(0,0,0,.3); display: flex; flex-direction: column;
  resize: both; overflow: hidden; min-width: 420px; min-height: 300px; max-width: 98vw; max-height: 96vh; }
.float-win .fw-head { display: flex; align-items: center; justify-content: space-between;
  padding: 10px 14px; border-bottom: 1px solid var(--line); cursor: move; user-select: none; flex: 0 0 auto; }
.float-win .fw-head h3 { margin: 0; font-size: 15px; }
.float-win .fw-head .x { border: none; background: none; font-size: 18px; cursor: pointer; color: var(--muted); }
.float-win .fw-body { flex: 1; overflow: auto; padding: 12px 14px; display: flex; flex-direction: column; }
/* 크기 조절 손잡이(09-18) — CSS resize:both는 본문이 모서리를 덮어 잡히지 않았다 */
.float-win .fw-grip { position: absolute; right: 0; bottom: 0; width: 18px; height: 18px; cursor: nwse-resize; z-index: 3;
  background: linear-gradient(135deg, transparent 0 46%, var(--line-2) 46% 58%, transparent 58% 70%, var(--line-2) 70% 82%, transparent 82%); }
body.fw-resizing { user-select: none; cursor: nwse-resize; }
/* 도면 창·금형(차수)·도면 관리 줄의 입력·드롭다운 = 26px 표준(09-18 사장님 — 구 34~38px로 칩·버튼보다 두꺼웠다) */
.float-win .drawing-view select, .float-win .drawing-view input,
.pfm-row select, .pfm-row input { height: 26px; box-sizing: border-box; font-size: 12px; padding: 0 6px; }
.pfm-row input.num-in { padding: 0 8px; }

/* 도면 뷰: 플로팅 창 크기에 맞춰 꽉 차게 (아래 잘림 없음 — 창을 늘리면 도면도 늘어남) */
.drawing-view { flex: 1; display: flex; flex-direction: column; min-height: 0; }
/* 도면 스크롤 래퍼(08-03) — 맞춤(.fit)=창에 맞춰 전체 / 자유 배율(.free)=휠 줌(커서 고정)·스크롤·드래그 이동.
   테두리·배경은 래퍼가 담당(구 .drawing-view img 직속 규칙 대체) */
.drawing-view .drawing-wrap { flex: 1; min-height: 0; overflow: auto; background: var(--bg-soft); border: 1px solid var(--line); border-radius: 8px; }
.drawing-view .drawing-wrap img { display: block; }
.drawing-view .drawing-wrap.fit img { width: 100%; height: 100%; object-fit: contain; }
.drawing-view .drawing-wrap.free img { max-width: none; height: auto; margin: 0 auto; user-select: none; -webkit-user-drag: none; }
/* (구 iframe.drawing-pdf 규칙 삭제 — 08-03: PDF도 pdf.js 변환 후 .drawing-wrap 공용. iframe은 PDF 플러그인 없는 브라우저에서 빈 화면) */

/* ===== 품질검사 입력 ===== */
/* ★고정폭 규격(07-25 사장님 — .oqc-meas 문법 통일): 창 크기·샘플 수와 무관하게 데이터 칸 폭 동일.
   비고 = 유일한 가변 열(잔여 흡수). min-width는 JS가 캐비티×샘플 수로 계산(550+70n). */
.insp-table { table-layout: fixed; width: 100%; }
.insp-table th:nth-child(1), .insp-table td:nth-child(1) { width: 160px; }  /* 항목(=.oqc-meas) */
.insp-table th:nth-child(2), .insp-table td:nth-child(2) { width: 90px; }   /* 관리구분 — 칩 66+여백 */
.insp-table .std-col { width: 150px; } /* 기준 (+/-공차) — 클래스 폭(07-28: 숨김 토글로 칼럼이 밀려도 측정 칸 규격 유지) */
.insp-table th:nth-child(n+3):not(:last-child):not(.in-col):not(.std-col), .insp-table td:nth-child(n+3):not(:last-child):not(.in-col):not(.std-col) { width: 70px; } /* 측정 칸 균일(=.oqc-meas) */
.insp-table .in-col { width: 150px; } /* 내부 관리치수(07-28) — 기준 칼럼과 동일 폭·좌정렬·색(조건부 색은 측정값만, 사용자 확정) */
/* ★내부 관리 칼럼 공통 틴트(rev02 S3 — "기준 치수와 내부 관리치수가 헷갈려 엉뚱한 공차를 고쳤다"):
   내부 축 = 옅은 웜 배경(주황 관리 신호 .warn-in의 옅은 짝). 검사기준 목록·검사 입력·수검·검사 상세 4곳 공통.
   틴트가 아주 옅어 기본 격자선 대비는 유지(§4-K — 별도 구분선 재정의 불필요 실측). */
.insp-table td.in-col, .oqc-meas td.in-col, .dim-table td.dimin-col, .spec-table td.in-col { background: var(--in-tint); }
/* 검사 기준 폼 2구획(rev02 S3) — 고객 기준(도면 공차)과 내부 관리치수를 박스로 분리. 내부 = 같은 웜 틴트 짝 */
.spec-sec { margin-top: 12px; border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px 12px; }
.spec-sec-t { font-size: 12.5px; font-weight: 700; color: var(--brand-dark); }
.spec-sec.spec-sec-in { background: var(--in-tint); border-color: var(--warn-line); }
.spec-sec.spec-sec-in .spec-sec-t { color: var(--warn-ink); }
.spec-sec.spec-sec-in input { background: #fff; } /* 입력칸은 흰 배경 유지 — 틴트 위에서도 칸 경계가 읽히게 */
.insp-table td.note-td { padding: 0; } /* 비고 = 잔여 열, 엑셀 셀 입력 */
.insp-table .meas-td { padding: 3px 6px; }
/* 검사 입력 표: 행 높이 = 직전 검사(qi-table, 32px) 수준으로 컴팩트 */
.insp-table td { padding: 1px 8px; height: 26px; } /* 07-28 사용자: 측정 표 4종 행 26px — 한 화면 정보량 우선 */
.insp-table input.meas, .insp-table select.meas { width: 96px; height: 26px; padding: 2px 8px; }

/* 외관 검사 표(.app-table, 07-28 사용자 — 치수 측정과 일관): 판정100·NG수90·수리구분190·특이사항=잔여, 엑셀 셀 문법·행 26px */
.app-table { table-layout: fixed; width: 100%; }
.app-table th:nth-child(1), .app-table td:nth-child(1) { width: 100px; }
.app-table th:nth-child(2), .app-table td:nth-child(2) { width: 90px; }
.app-table th:nth-child(3), .app-table td:nth-child(3) { width: 190px; }
.app-table td { padding: 0; height: 26px; }
.app-table input.meas, .app-table select.meas, .spec-table input.meas, .spec-table select.meas { width: 100%; height: 26px; border: 0; border-radius: 0; background: transparent; padding: 0 8px; font: inherit; font-size: 12.5px; font-weight: 700; text-align: center; }
.app-table input.meas:focus, .app-table select.meas:focus, .spec-table input.meas:focus, .spec-table select.meas:focus { outline: 2px solid var(--brand); outline-offset: -2px; background: #fff; }
.app-table .meas.ng { background: var(--danger-bg); color: var(--danger); font-weight: 700; }
.app-table select.meas.f-empty, .app-table input.meas.f-empty { background: var(--warn-bg); } /* 미입력 앰버(08-06 사장님) — .meas 투명 배경보다 우선 */
/* 특이사항 = 메모(비고류 문법 — 볼드 제외·좌정렬). ★input.meas 규칙(0,2,1)이 .app-note(0,2,0)를 이겨
   가운데 정렬로 보이던 결함(07-29 사용자 캡처) — 특이도 승격(§4-O 스코프·특이도 함정 계열) */
.app-table input.meas.app-note { text-align: left; font-weight: 400; }
.app-table input.meas::-webkit-outer-spin-button, .app-table input.meas::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.tol-part { font-weight: 400; } /* 기준(+/-공차): 기준값=볼드(표 기본), 공차=Regular로 구분 */
/* 측정 샘플수 선택 (검사 입력 팝업 제목줄) — 제품 2~3개 반복 측정 시 열 확장 */
.smp-pick { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--muted); }
.smp-pick select { height: 29px; padding: 4px 8px; font-size: 12.5px; }

/* 검사 상세 치수표 (.dim-table): 치수 데이터는 밀도 우선 — 행 높이 컴팩트 + 고정 폭.
   측정값·판정은 기준 폭 수준으로 줄이고, 남는 폭은 항목명(auto)이 흡수 */
/* (구 .dim-table nth-child 폭 정의는 아래 07-27 확정 블록이 대체 — 07-28 내부 관리 칼럼 추가로 여기 구 규칙은 삭제.
   같은 표에 두 벌의 nth-child 폭을 두면 칼럼이 하나만 밀려도 조용히 어긋난다) */
.dim-table td { padding: 1px 8px; height: 26px; } /* 행 26px(07-28 — 측정 표 4종 통일) */
.dim-table .meas { width: 80px; height: 24px; padding: 2px 6px; font-size: 12.5px; }
.dim-table .note-in { width: 100%; height: 24px; padding: 2px 6px; font-size: 12.5px; }
.dim-table .chip { min-width: 44px; padding-top: 1px; padding-bottom: 1px; }       /* 판정 OK/NG 2자 그룹 */
.dim-table td:nth-child(3) .chip { min-width: 66px; } /* 관리구분은 4자 그룹 표준(66) 유지 */
.dim-table .btn { padding: 2px 8px; font-size: 11.5px; }

/* 수검 측정 표 (.oqc-meas, 07-25 사장님): 엑셀 성적서 인상 — 격자 셀(세로선)·칩 없음·측정 입력 = 투명 셀 입력.
   전 컬럼 고정폭 + 끝 스페이서 열(잔여 흡수) — 샘플 수를 바꿔도 칸이 비례 확대로 겹치지 않는다.
   min-width는 JS가 샘플 수로 계산(500+64n) — 넘치면 .table-wrap 가로 스크롤(텍스트 잘림 금지). */
.oqc-meas { table-layout: fixed; width: 100%; }
.oqc-meas th:nth-child(1), .oqc-meas td:nth-child(1) { width: 80px; }   /* 그룹 */
.oqc-meas th:nth-child(2), .oqc-meas td:nth-child(2) { width: 250px; }  /* 항목 — 250(08-11 사장님, 구 160). min-width 계산(lots.js)과 한 몸 */
.oqc-meas th:nth-child(3), .oqc-meas td:nth-child(3) { width: 70px; }   /* 관리구분(텍스트 — 칩 폐지, 07-25 사장님 px) */
/* ★4번째 이후 칼럼 폭 = 클래스(07-29) — 기준 칼럼 숨김 토글로 칼럼이 빠져도 측정 칸 규격이 밀리지 않는다(.insp-table .std-col과 동일 원칙) */
.oqc-meas .std-col { width: 70px; }  /* 기준 */
.oqc-meas .tol-col { width: 60px; }  /* +공차 / -공차 */
.oqc-meas .m-col { width: 70px; }    /* 측정 칸 균일 */
.oqc-meas .in-col { width: 130px; } /* 내부 관리치수(07-28) */
.oqc-meas td { padding: 0 6px; height: 26px; border-right: 1px solid var(--line); } /* 세로선 = 엑셀 격자 · 행 26px(07-28) */
.oqc-meas td:last-child { border-right: 0; } /* 마지막(비고) 열 */
.oqc-meas td.meas-td, .oqc-meas td.note-td { padding: 0; }
.oqc-meas input.meas, .oqc-meas select.meas { width: 100%; height: 26px; border: 0; border-radius: 0; background: transparent; padding: 0 6px; font: inherit; font-size: 12.5px; font-weight: 700; text-align: center; }
.oqc-meas input.meas:focus, .oqc-meas select.meas:focus { outline: 2px solid var(--brand); outline-offset: -2px; background: #fff; }
.oqc-meas input.meas.ng, .oqc-meas select.meas.ng { background: var(--danger-bg); color: var(--danger); }
.oqc-meas input.meas::-webkit-outer-spin-button, .oqc-meas input.meas::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
/* 항목별 비고(07-29 — 순회 .insp-table .item-note와 동일 엑셀 셀 문법) */
.oqc-meas .item-note { width: 100%; height: 26px; border: 0; border-radius: 0; background: transparent; padding: 0 8px; font: inherit; font-size: 12.5px; }
.oqc-meas .item-note:focus { outline: 2px solid var(--brand); outline-offset: -2px; background: #fff; }

/* 검사 입력 표 항목별 비고 입력칸 */
/* 항목별 비고 = 엑셀 셀 입력(07-25 사장님 — 측정값과 동일 문법: 테두리·라운드 없음·투명, 포커스만 파란 외곽선) */
.insp-table .item-note { width: 100%; height: 26px; border: 0; border-radius: 0; background: transparent; padding: 0 8px; font: inherit; font-size: 12.5px; }
.insp-table .item-note:focus { outline: 2px solid var(--brand); outline-offset: -2px; background: #fff; }

/* ── 검사 입력 구분 탭(07-29 사용자): 팝업 하나에서 수시/초물/중물/종물 열람·입력 전환 ── */
.itab-bar { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin: 10px 0; }
.itab-lbl { font-size: 12.5px; font-weight: 700; color: var(--muted); margin-right: 2px; }
.itab { height: 26px; padding: 0 12px; border: 1px solid var(--line); border-radius: 8px; background: #fff;
  font-family: inherit; font-size: 12.5px; font-weight: 700; color: var(--muted); cursor: pointer;
  display: inline-flex; align-items: center; gap: 4px; line-height: 1.45; }
.itab:hover { background: var(--hover); }
.itab.done { color: var(--brand); border-color: var(--brand-line); } /* 저장된 회차 칩 */
.itab.on { background: var(--brand); border-color: var(--brand); color: #fff; }
/* [+ 새 검사] = 기록 칩과 살짝 구분(07-29 사용자 — 점선 테두리, 활성 시엔 일반 활성과 동일 솔리드).
   ★.add가 .on과 같은 특이도라 뒤에 선언된 .add 색이 활성 흰 글자를 덮는다 — .add.on에서 흰색 재명시(§4-O 배경=글자색 함정) */
.itab.add { border-style: dashed; color: var(--brand); }
.itab.add.on { border-style: solid; color: #fff; }

/* 치수 피벗(열람 전용, 07-29) — 검사 입력 표와 같은 배열(항목×SPL 가로), 폭은 전용 규격
   (.insp-table 재사용 금지 — nth-child 폭이 관리구분 칼럼을 전제해 어긋난다) */
.dimv-table { table-layout: fixed; width: 100%; }
.dimv-table th:nth-child(1), .dimv-table td:nth-child(1) { width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }  /* 항목 */
.dimv-table th:nth-child(2), .dimv-table td:nth-child(2) { width: 150px; }  /* 기준 (+/-공차) */
.dimv-table th:nth-child(n+3):not(:last-child):not(.in-col), .dimv-table td:nth-child(n+3):not(:last-child):not(.in-col) { width: 70px; } /* 측정 칸 균일 */
.dimv-table td { padding: 1px 8px; height: 26px; } /* 측정 표 26px 리듬(07-28) */

/* (구 .qual-top 2단 레이아웃 삭제 — 07-18 놓친 순회검사 팝업화로 순회검사 패널이 전폭) */
/* 순회검사 표: 상태 · LOT(예정) · 품명 · 금형 · 설비 · 주야 · 담당자 · 오늘검사 */
/* min-width로 폭 확보 → 화면이 좁아지면 품명이 쪼그라들지 않고 .table-wrap이 가로 스크롤(overflow:auto) */
/* ★품질 표 문법 공통 폭(07-18 통일, DESIGN 4-D): 상태/조치 90 · 기준일 100 · 품명 220 · 금형 110 · 담당 90
   — 어느 팝업을 열어도 품명·금형이 같은 자리·같은 폭(금형 관리 dev/spl 표와 동일 규격) */
.round-table { table-layout: fixed; width: 100%; min-width: 1040px; } /* 고객사 70·금형 80 통일(08-11)로 -40 */
.round-table th:nth-child(1), .round-table td:nth-child(1) { width: 90px; }   /* 상태 */
.round-table th:nth-child(2), .round-table td:nth-child(2) { width: 100px; }  /* LOT(예정 — 기준일 자리) */
.round-table th:nth-child(3), .round-table td:nth-child(3) { width: 70px; }   /* 고객사(전역 70, 08-11) */
.round-table th:nth-child(4), .round-table td:nth-child(4) { width: 110px; }  /* 제품군(공통 규격) */
.round-table th:nth-child(5), .round-table td:nth-child(5) { width: 220px; }  /* 품명(공통 규격) */
.round-table th:nth-child(6), .round-table td:nth-child(6) { width: 80px; }  /* 금형(전역 80, 08-11) */
.round-table th:nth-child(7), .round-table td:nth-child(7) { width: 80px; }   /* 설비 */
.round-table th:nth-child(8), .round-table td:nth-child(8) { width: 50px; }   /* 주야 */
.round-table th:nth-child(9), .round-table td:nth-child(9) { width: 90px; }   /* 담당자 */
.round-table th:nth-child(10), .round-table td:nth-child(10) { width: 60px; } /* 시작(가동 시작시각) */
.round-table th:nth-child(11), .round-table td:nth-child(11) { width: 84px; } /* 오늘 검사 */

/* 할 일 소형 표(.qact-table — 놓친 순회검사·수리 검증): 상태→기준일(LOT/수리일)→고객사→품명→금형→(고유)→담당(끝)+스페이서.
   OQC 수검 목록과 같은 접두 순서(07-18). 끝 스페이서 = 잔여 폭 흡수, 담당 = 뒤에서 2번째(고정 90) */
.qact-table { table-layout: fixed; width: 100%; min-width: 720px; } /* 고객사 70·금형 80 통일(08-11)로 -40 */
.qact-table th:nth-child(1), .qact-table td:nth-child(1) { width: 90px; text-align: center; }   /* 상태 */
.qact-table th:nth-child(2), .qact-table td:nth-child(2) { width: 100px; text-align: center; }  /* LOT/수리일 */
.qact-table th:nth-child(3), .qact-table td:nth-child(3) { width: 70px; text-align: center; }   /* 고객사(전역 70, 08-11) */
.qact-table th:nth-child(4), .qact-table td:nth-child(4) { width: 220px; }                      /* 품명(공통 규격) */
.qact-table th:nth-child(5), .qact-table td:nth-child(5) { width: 80px; text-align: center; }  /* 금형(전역 80, 08-11) */
.qact-table th:nth-last-child(2), .qact-table td:nth-last-child(2) { width: 90px; text-align: center; } /* 담당 */
.qact-table.verify th:nth-child(6), .qact-table.verify td:nth-child(6) { width: 200px; }        /* 이상 유형(수리 검증) */
.qact-table.vhist th:nth-child(6), .qact-table.vhist td:nth-child(6) { width: 110px; text-align: center; } /* 이상 유형(검증 이력) — 검토결과가 잔여 폭 흡수 */

/* 순회검사 상시 표(.ptl-table, 07-28 재구성 — 구 .ihist-table 팝업 대체):
   좌1 = 결과(상태 통합 칩 — 검사없음/OK/한도생산/수리요청/생략) · 좌2 = 검사일(§4-P) · LOT 칼럼 폐지 → 주야.
   문제점 = 잔여 폭 전부(구 문제점+비고 수준으로 확폭, 사용자 확정) — min-width를 키워 비고·검사자는
   기본 화면에서 가로 스크롤 뒤로 밀려도 무방(사용자 확정: 문제점 우선). */
/* ★08-11 재매핑: '생산/불량' 컬럼(감사 D그룹 신설)이 7열로 끼면서 구 nth 규칙이 한 칸씩 밀려
   외관 폭이 생산/불량에 가고 검사자가 잔여가 되는 오배정이 있었다(넘침 스캔으로 발견). 12열 전면 재지정 + 말줄임. */
.ptl-table { table-layout: fixed; width: 100%; min-width: 1500px; } /* 고정열 합 1204 + 문제점(잔여) 최소 ~300. 칼럼 폭 = quality.js PTL_COLS(colgroup, 09-07 tablekit — 구 nth-child 폭 규칙 폐지; 순회 표는 inline min-width가 덮는다) */
.ptl-table th, .ptl-table td { overflow: hidden; text-overflow: ellipsis; }

/* 수리구분 마스터(.rc-table — 대분류 서브헤더 + 그룹 내 ↑↓, 이력 유형과 동형): 순서 90 · 세부 항목 280 */
.mst.rc-table th:nth-child(1), .mst.rc-table td:nth-child(1) { width: 90px; }
.mst.rc-table th:nth-child(2), .mst.rc-table td:nth-child(2) { width: 280px; }
/* 지표 목록 (수리 검증 대기·마감필요 배지) — 클릭 행 */
/* (구 .qneed/.qlist 리스트 규격 삭제 — 07-18 놓친 순회검사 팝업을 표준 표 형식으로 통일, 어디서도 미사용) */

/* 순회검사 미검사(순회대상·0회) 강조 — 맨 위 정렬 + 빨간 왼쪽 띠 + 연한 배경 */
.round-table tr.qrow-need td { background: var(--danger-bg); }
.round-table tr.qrow-need:hover td { background: var(--danger-bg); }
/* 왼쪽 빨간 바는 제거(07-19 사용자 확정) — 배경 틴트 + 미검사 칩으로 충분 */

/* ===== 재고 과부족 행 강조(07-18) — 칩 폐지: 행 배경 틴트 + 빨간 숫자(순회검사 미검사 행 .qrow-need와 동일 문법).
   음수(심각) = 진한 틴트·굵은 빨강 / 부족 = 옅은 틴트. 왼쪽 빨간 바 = "조치 필요" 공통 마커. */
tbody tr.row-short td { background: var(--danger-bg); }
tbody tr.row-neg td { background: var(--danger-bg); }
tbody tr.row-short:hover td, tbody tr.row-neg:hover td { background: var(--danger-bg); }
/* (구 왼쪽 세로 빨간 바 제거 — 07-20 사장님 지시. 배경 틴트만으로 충분하고 바는 지저분했다) */
/* ★배경 틴트가 깔린 행은 구분선도 같이 진해져야 한다(07-20 전수 점검).
   흰 배경 기준으로 고른 회색선(#c4ccd7)을 분홍 틴트 위에 쓰면 대비가 1.49까지 떨어져 행이 붙어 보인다.
   틴트 계열에 맞춘 선 색으로 바꿔 대비 2.1 확보(세로선도 1.02 → 1.4). 새 틴트를 추가하면 여기도 같이 정의할 것. */
tbody tr.row-short td, tbody tr.row-neg td,
.round-table tr.qrow-need td { border-bottom-color: var(--danger-line); border-right-color: var(--danger-line); }
tbody tr.row-closed td, .matrix tr.stock td { border-bottom-color: var(--line-2); border-right-color: var(--line); }
/* 마스터 누락 정보 행(08-04) — 칼럼 폐지: 채울 값이 남은 행 = 앰버 틴트(f-empty 미입력=앰버와 같은 축, 빨강은 조치 필요 전용).
   §4-K: 틴트 행은 구분선도 같이 정의(웜 계열 선 — 가로 진하게/세로 옅게, 분홍 틴트 쌍과 동일 문법) */
tbody tr.row-miss td { background: var(--in-tint); }
tbody tr.row-miss:hover td { background: var(--warn-bg); }
tbody tr.row-miss td { border-bottom-color: var(--warn-line); border-right-color: var(--warn-line); }
tbody tr.row-neg td.neg { font-weight: 800; }
/* 매트릭스(생산 계획·전체 현황판) sticky 셀은 흰 배경 마스크 → 행 틴트를 명시적으로 덮어써야 유지된다 */
.matrix tr.row-short td.sticky { background: var(--danger-bg); }
.matrix tr.row-neg td.sticky { background: var(--danger-bg); }
.matrix tr.row-short:hover td.sticky, .matrix tr.row-neg:hover td.sticky { background: var(--danger-bg); }
.chip.neg { background: var(--danger); color: #fff; }

/* 지표 하위 섹션 헤더 — 제목 + 건수 칩 + 오른쪽 끝 열기 버튼(수검 현황 진입과 동일 패턴) */
.gauge-sec-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.gauge-sec-head .sum-t { margin-bottom: 0; }
.gauge-sec-head .cnt { min-width: 0; padding: 1px 9px; font-weight: 800; }
/* [마감 필요 건 열기] 버튼 높이 = 패널 헤더의 [수검 목록 열기]와 동일(20px) */
.gauge-sec-head .btn, .gauge-sec-head .btn.sm { height: 20px; padding: 0 10px; font-size: 12px; line-height: 1; border-radius: 8px; }

/* 수검 목록 팝업 표 — 고객사·품명·금형 = 공통 규격(80·220·110, 07-18). fixed 레이아웃으로 규격 강제.
   LOT = 접미부만(날짜(D/N)·차수·#열, 한 줄 고정 — 품명은 품명 열이 담당), 끝 스페이서(14열) = 잔여 폭 흡수 */
/* ★§4-P 소급(07-24): 좌1=조치 · 좌2=생산일100 · 주야50 별도 · 금형100·열50 공통 폭 */
/* 수검(IQC/OQC) 검사 이력 팝업(.oqch-table, 07-29 신설) — .ptl-table(순회 이력) 규격 준용, LOT·고객사 칼럼 추가.
   07-30: 좌1 = 조치([NG 처리] — §4-P 좌1=상태/조치류) 신설, 이하 한 칸씩 밀림 */
.oqch-table { table-layout: fixed; width: 100%; min-width: 1715px; } /* 고객사 70·금형 80 통일(08-11)로 -40 */
.oqch-table th:nth-child(1), .oqch-table td:nth-child(1) { width: 90px; }   /* 조치([후속 조치] — 수검NG LOT 최신 기록만) */
.oqch-table th:nth-child(2), .oqch-table td:nth-child(2) { width: 110px; }  /* 결과(회차 병기 칩 "① · 수검NG") */
.oqch-table th:nth-child(3), .oqch-table td:nth-child(3) { width: 100px; }  /* 검사일 */
.oqch-table th:nth-child(4), .oqch-table td:nth-child(4) { width: 60px; }   /* 시각 */
.oqch-table th:nth-child(5), .oqch-table td:nth-child(5) { width: 145px; }  /* LOT(접미부 최대 "20260714(D) #2 · 2차" 실측 131+패딩, 07-30) */
.oqch-table th:nth-child(6), .oqch-table td:nth-child(6) { width: 70px; text-align: center; }   /* 고객사(전역 70, 08-11) */
.oqch-table th:nth-child(7), .oqch-table td:nth-child(7) { width: 220px; }  /* 품명(공통 규격) */
.oqch-table th:nth-child(8), .oqch-table td:nth-child(8) { width: 80px; }  /* 금형(전역 80, 08-11) */
.oqch-table th:nth-child(9), .oqch-table td:nth-child(9) { width: 64px; }   /* 외관 */
.oqch-table th:nth-child(10), .oqch-table td:nth-child(10) { width: 100px; } /* 수리구분(07-30 사장님 px) */
/* 11 문제점 = 잔여 폭 전부 */
.oqch-table th:nth-child(12), .oqch-table td:nth-child(12) { width: 200px; } /* 비고(스크롤 뒤 무방) */
.oqch-table th:nth-child(13), .oqch-table td:nth-child(13) { width: 90px; }  /* 검사자(스크롤 뒤 무방) */

.oqc-table { table-layout: fixed; width: 100%; } /* 칼럼 폭·min-width = quality.js OQ_COLS(colgroup, 09-07 tablekit — 구 nth-child 폭·정렬 규칙 폐지, 정렬은 td.ctr) */
/* 상태 칼럼(좌1, td.oqc-st): 버튼·칩 폭 = [후속 조치] 실측 70px로 전부 통일(07-30 2차 사장님 — 들쭉날쭉하던 폭 정리).
   내부 제품 대기 행은 [내부]+[수검대기] 2버튼 = 144. 구 td:nth-child(1) 훅 → 클래스(칼럼 숨김으로 index가 밀린다, 09-07) */
.oqc-table td.oqc-st .btn.sm, .oqc-table td.oqc-st .chip {
  width: 70px; min-width: 70px; padding-left: 0; padding-right: 0; justify-content: center; box-sizing: border-box;
}
.oqc-table td.col-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* 품명(공통 규격 220) 말줄임 */
.oqc-table td.oqc-st { white-space: nowrap; } /* 상태 칩 + 할 일 점 = 1줄(09-09 6차) */
/* 재수검(재작업 후 재수검 대기) 칩 — 분홍색으로 구분 */
.chip.reinsp { background: #fcdcea; color: #c2185b; }

/* LOT 공정 파이프라인 바 (역추적 팝업) */
.lot-pipe { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; margin: 8px 0 2px; }
.lot-pipe .lp-step { font-size: 12px; font-weight: 700; padding: 3px 11px; border-radius: 8px; background: var(--gray-bg); color: var(--muted); }
.lot-pipe .lp-step.lp-done { background: var(--ok-bg); color: var(--ok); }
.lot-pipe .lp-step.lp-cur { background: var(--brand); color: #fff; }
.lot-pipe .lp-step.lp-ng { background: var(--danger); color: #fff; }
.lot-pipe .lp-arrow { color: var(--muted); font-weight: 700; }
/* 순회 검사 이력 — 기본 20행 표시 + 내부 스크롤 (헤더 36 + 33×20) */
.table-wrap.rows20 { max-height: min(696px, calc(100vh - 340px)); overflow: auto; }
/* 수검 목록 팝업 — 한 번에 18행 (헤더 36 + 33×18) */
.table-wrap.rows18 { max-height: min(630px, calc(100vh - 340px)); overflow: auto; }

/* (구 .ship-warn 미준비 LOT 경고 블록 폐지 — 07-23 rev04: 저장/담기 시점 확인 팝업(confirmNotReady)으로 대체) */

/* ===== 재고·출하 표 폭 규격(07-17) — 날짜 110·고객사 100·제품군 110, 잔여 폭은 품명이 흡수 ===== */
/* ★07-24 사장님 공통 폭: 날짜 100·고객사 80·제품군 100·출하수량/LOT수/BOX수 90·비고 250·조치 120. LOT수 = BOX수 왼쪽. */
.ship-table { table-layout: fixed; width: 100%; } /* 칼럼 폭·min-width = lots.js SHIP_COLS(colgroup, 09-07 tablekit — 구 nth-child 폭 규칙 폐지. 비고 값 = 좌(기본), 헤더 = 전역 가운데) */
.ship-table th, .ship-table td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 출하 입력 팝업 LOT 표(.ship-lot-table) — 행 밀도를 PO 기록 패널(.rec-table 30px) 수준으로(07-21 사장님).
   LOT 번호가 잔여 폭을 흡수(식별자라 말줄임 금지), 나머지 컬럼은 텍스트 최대치 기준 고정. */
.ship-lot-table { table-layout: fixed; width: 100%; }
.ship-lot-table th, .ship-lot-table td { padding: 4px 8px; vertical-align: middle; }
.ship-lot-table td .btn.sm { height: 24px; line-height: 22px; padding: 0 8px; font-size: 11.5px; }
.ship-lot-table td .chip { height: 20px; line-height: 1.2; }
.ship-lot-table th:nth-child(1), .ship-lot-table td:nth-child(1) { text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* LOT 번호 = 잔여 흡수 */
.ship-lot-table th:nth-child(2), .ship-lot-table td:nth-child(2) { width: 100px; }  /* 생산일 */
.ship-lot-table th:nth-child(3), .ship-lot-table td:nth-child(3) { width: 50px; }   /* 주야 */
.ship-lot-table th:nth-child(4), .ship-lot-table td:nth-child(4) { width: 50px; }   /* 열 */
.ship-lot-table th:nth-child(5), .ship-lot-table td:nth-child(5) { width: 80px; }   /* 상태 */
.ship-lot-table th:nth-child(6), .ship-lot-table td:nth-child(6) { width: 84px; }   /* LOT 수량(원래 수량 — 07-23 rev04, LOT 번호 잔여폭에서 흡수) */
.ship-lot-table th:nth-child(7), .ship-lot-table td:nth-child(7) { width: 80px; }   /* 잔량 */
.ship-lot-table th:nth-child(8), .ship-lot-table td:nth-child(8) { width: 160px; }  /* 사용수량(입력+전량) */
.ship-lot-table th:nth-child(9), .ship-lot-table td:nth-child(9) { width: 80px; }   /* Box */
.ship-lot-table th:nth-child(10), .ship-lot-table td:nth-child(10) { width: 200px; } /* 비고 */
.ship-lot-table td:nth-child(10) { text-align: left; }    /* 비고 본문 = 좌(입력칸) */
.ship-lot-table th:nth-child(10) { text-align: center; }  /* 비고 헤더 = 가운데(2026-07-22 사장님) */
.ship-lot-table td:nth-child(8) .row { flex-wrap: nowrap; }  /* 입력+버튼 = 한 줄(줄바꿈 시 행 높이 2배) */
/* 열람 전용 행(담기 불가 — 외주중·수검NG·폐기·출하완료) = 종결 회색 톤. 틴트 행 구분선은 같이 정의(§4-K). */
.ship-lot-table tr.lot-view td { background: var(--done-row); color: var(--muted); border-bottom-color: var(--line-2); }
.ship-lot-table tr.lot-view td.num { color: var(--muted); }
.ship-lot-table .num-in { width: 68px; padding: 5px 8px; }
.ship-note-in { width: 100%; padding: 5px 8px; font-size: 12.5px; }
/* 출하 입력 방식 선택(S11 두 진입) — 큰 2택 카드 */
.ship-entry-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.ship-entry-card { text-align: left; background: var(--bg-soft); border: 1px solid var(--line); border-radius: 10px; padding: 16px; cursor: pointer; transition: border-color .12s, background .12s; }
.ship-entry-card:hover { border-color: var(--brand); background: var(--panel); }
.ship-entry-card .se-title { font-size: 14px; font-weight: 700; margin-bottom: 6px; }
.ship-entry-card .se-desc { font-size: 12.5px; color: var(--muted); line-height: 1.5; }
@media (max-width: 640px) { .ship-entry-grid { grid-template-columns: 1fr; } }
/* 출하 몰아서 입력 — 한 줄 = 제품 picker + 수량·BOX·고객사·비고 + 삭제 */
/* 출하 몰아서 입력(제품별 LOT 선택) 행 — .me-row와 같은 밀도(34px 입력·행간 6px, 07-23 FIFO 폐지 재설계).
   ★07-23 사장님 폭 확정: 고객사100·제품군120·품명(유동)·[LOT 선택]84·LOT수70·LOT수량110·PO100·납품처100·비고(유동)·×40.
   요약 TEXT 폐지 → LOT수·LOT수량은 PO와 같은 자동표시 박스(.bs-po).
   고정열 100+120+84+70+110+100+100+40 = 724 + 최소 품명170+비고120 = 1014 + gap 72 = 1086 → 전환폭 1100(≥최소폭, DESIGN §4) */
.bs-row { display: grid; grid-template-columns: 100px 120px minmax(170px, 1.2fr) 84px 70px 110px 100px 100px minmax(120px, 1fr) 40px;
  gap: 8px; align-items: center; margin-top: 6px; }
.bs-row.bs-head { margin-top: 0; }
.bs-row.bs-head .lbl { font-size: 12px; color: var(--muted); white-space: nowrap; }
.bs-row input, .bs-row select { height: 34px; box-sizing: border-box; min-width: 0; width: 100%; }
.bs-row .ssel, .bs-row .ssel .ssel-in { min-width: 0; width: 100%; }
.bs-row .btn { height: 34px; padding-left: 0; padding-right: 0; width: 100%; }
/* PO 박스 — 자동입력 값이라 입력칸과 살짝 구분(생산등록 .auto-in과 같은 음영 문법, 07-23 사장님 2) */
.bs-row .bs-po { height: 34px; box-sizing: border-box; display: flex; align-items: center; justify-content: center;
  background: var(--bg-soft); border: 1px solid var(--line); border-radius: 8px; font-size: 12.5px; font-weight: 700; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 0 8px; }
.bs-row .bs-po.none { color: var(--muted); font-weight: 400; }
/* 제품은 골랐는데 LOT을 안 담은 행 — 다음 할 일을 색으로(누락은 색으로 인지) */
.bs-pick-req { border-color: var(--brand); color: var(--brand); font-weight: 700; }
/* 납품처 미입력 큐(07-23 사장님) — 제품을 골랐는데 납품처가 비면 테두리로 인지(두 출하 팝업 공용) */
input.bs-miss { border-color: var(--brand); }
/* LOT 선택 팝업 필터행 오른쪽 PO 표시 — "날짜 출하 PO 수량 : N ea"(07-23 사장님 3, 필터바 12.5px 스케일).
   높이 = 필터 셀렉트(29px)와 동일 — 같은 행 요소는 같은 높이(07-23 사장님·§4-O). */
.filterbar .fb-right { margin-left: auto; }
.fb-po { display: inline-flex; align-items: center; height: 29px; box-sizing: border-box;
  font-size: 12.5px; font-weight: 700; color: var(--brand); background: var(--brand-bg-2);
  border: 1px solid var(--brand-line-2); border-radius: 6px; padding: 0 10px; white-space: nowrap; }
.fb-po.none { color: var(--muted); font-weight: 400; background: var(--bg-soft); border-color: var(--line); }
/* ★PO 수량 표시 강조(07-23 rev04 사장님) — 아래 LOT 수량 구성의 목표값이라 일반 정보 박스(BOX 포장단위 등)와
   구분되는 파랑 틴트. 세 위치(출하 입력 헤더 칩·LOT 선택 필터행·몰아서 행 PO 박스) 동일 문법. */
.box-unit-info.po-info { background: var(--brand-bg-2); border-color: var(--brand-line-2); }
.box-unit-info.po-info .bu-v { color: var(--brand); }
.box-unit-info.po-info .bu-v.muted { color: var(--muted); }
.bs-row .bs-po.po-info:not(.none) { background: var(--brand-bg-2); border-color: var(--brand-line-2); color: var(--brand); }
/* 합계 바 맨 왼쪽 항목(BOX 포장단위 등 참고 정보) — 오른쪽 정렬 바에서 혼자 왼쪽 끝(07-23 사장님) */
.ship-total .st-item.st-left { margin-right: auto; }
/* Packing List 허브 상단 바 — 출하일 변경 + [+ 출하 추가] (07-23) */
.pl-hub-bar { display: flex; gap: 10px; align-items: center; margin-bottom: 8px; flex-wrap: wrap; }
/* PL 목록 팝업(08-18) — 새 정의는 폭만(§1-A): 출하일·수치 고정, 고객사 = 남는 폭 흡수 */
.pl-dates { table-layout: fixed; }
.pl-dates th:nth-child(1), .pl-dates td:nth-child(1) { width: 126px; }
.pl-dates th:nth-child(3), .pl-dates td:nth-child(3) { width: 64px; }
.pl-dates th:nth-child(4), .pl-dates td:nth-child(4) { width: 72px; }
.pl-dates th:nth-child(5), .pl-dates td:nth-child(5) { width: 100px; }
@container (max-width: 1100px) {
  .bs-row.bs-head { display: none; }
  .bs-row { grid-template-columns: 1fr 1fr; gap: 8px 10px;
    border: 1px solid var(--line); border-radius: 10px; padding: 10px; margin-top: 10px; }
}
/* 후처리 대기열: LOT번호 고정 폭(구 잔여 흡수 → 품명으로 이양해 LOT번호와 품명이 붙어 보임) */
/* ★07-24 rev09 S1: 마감 필요 팝업 전용(.uc-table) — 시작시간·SPM·Cavity 추가, 품명=잔여(수량 잔여 흡수 폐지) */
.uc-table { table-layout: fixed; width: 100%; min-width: 980px; } /* 고객사 70·금형 80 통일(08-11)로 -30 */
.uc-table th, .uc-table td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.uc-table th:nth-child(1), .uc-table td:nth-child(1) { width: 90px; }   /* 상태 */
.uc-table th:nth-child(2), .uc-table td:nth-child(2) { width: 100px; }  /* 생산일 */
.uc-table th:nth-child(3), .uc-table td:nth-child(3) { width: 50px; }   /* 주야 */
.uc-table th:nth-child(4), .uc-table td:nth-child(4) { width: 70px; }   /* 고객사(전역 70, 08-11) */
.uc-table th:nth-child(5), .uc-table td:nth-child(5) { text-align: left; } /* 품명 = 잔여 */
.uc-table th:nth-child(6), .uc-table td:nth-child(6) { width: 80px; }  /* 금형(전역 80, 08-11) */
.uc-table th:nth-child(7), .uc-table td:nth-child(7) { width: 80px; }   /* 설비 */
.uc-table th:nth-child(8), .uc-table td:nth-child(8) { width: 80px; }   /* 시작시간 */
.uc-table th:nth-child(9), .uc-table td:nth-child(9) { width: 60px; }   /* SPM */
.uc-table th:nth-child(10), .uc-table td:nth-child(10) { width: 60px; } /* Cavity */
.uc-table th:nth-child(11), .uc-table td:nth-child(11) { width: 90px; } /* 생산수량 */
.uc-table th:nth-child(12), .uc-table td:nth-child(12) { width: 80px; } /* 담당자 */

/* ★07-24 rev06 S8: 수리 인계 대기·지난 미마감 팝업(.ho-table) — 출처·담당자가 잔여 폭을 먹지 않게 고정.
   좌1=상태 · 좌2=생산일 · 주야 분리(수검 목록 문법) · 문제현상/생산수량 열만 잔여 흡수 */
.ho-table { table-layout: fixed; width: 100%; min-width: 1040px; } /* 고객사 70·금형 80 통일(08-11)로 -40 */
.ho-table th, .ho-table td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ho-table th:nth-child(1), .ho-table td:nth-child(1) { width: 90px; }   /* 상태 */
.ho-table th:nth-child(2), .ho-table td:nth-child(2) { width: 100px; }  /* 생산일 */
.ho-table th:nth-child(3), .ho-table td:nth-child(3) { width: 50px; }   /* 주야 */
.ho-table th:nth-child(4), .ho-table td:nth-child(4) { width: 70px; }   /* 고객사(전역 70, 08-11) */
.ho-table th:nth-child(5), .ho-table td:nth-child(5) { width: 220px; text-align: left; } /* 품명 */
.ho-table th:nth-child(6), .ho-table td:nth-child(6) { width: 80px; }   /* 금형(전역 80, 08-11) */
.ho-table th:nth-child(7), .ho-table td:nth-child(7) { width: 90px; }   /* 의뢰출처/설비 */
.ho-table th:nth-child(8), .ho-table td:nth-child(8) { text-align: left; } /* 문제 현상/생산수량 = 잔여 */
.ho-table th:nth-child(9), .ho-table td:nth-child(9) { width: 90px; }   /* 담당자 */
.ho-table th.num, .ho-table td.num { text-align: right; }               /* 수치 열(생산수량)은 우측 정렬 우선 */

/* ★07-24 rev06 S6 + A안: LOT 원장(.lot-table) — LOT 번호 칼럼 삭제(전체 번호 = 행 클릭 역추적·툴팁).
   ★공유 칼럼 폭 = 후처리(.queue-table)와 공통 기준(사장님 3): 상태90·생산일96·주야48·고객사84·제품군100·열44·후처리72 */
.lot-table { table-layout: fixed; width: 100%; } /* 칼럼 폭·min-width = lots.js LOT_COLS(colgroup, 09-07 tablekit — 구 nth-child 폭 규칙 폐지. 품명 = 유동·좌, 헤더는 전역 가운데) */
.lot-table th, .lot-table td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ★07-24 rev06 S5 + A안: 조치=맨 왼쪽 · 생산일·주야 다음 · LOT 번호 = 전체 형식(카드·실물 대조 작업면).
   ★공유 칼럼 폭 = LOT 원장(.lot-table) 기준 통일(사장님 3): 생산일96·주야48·고객사84·제품군100·열44·후처리72·수량92·상태90 —
   확보된 폭은 LOT 번호(280)·품명(잔여)이 넉넉히 흡수. */
.queue-table { table-layout: fixed; width: 100%; min-width: 1340px; } /* 조치 90·고객사 70·금형 80 통일 후 LOT 340 확장(08-11) — 고정열 합 1140 + 품명 최소 200 */
.queue-table th, .queue-table td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.queue-table th:nth-child(1), .queue-table td:nth-child(1) { width: 90px; }  /* 조치(외주 출고·입고 처리) — 90(08-11 사장님) */
.queue-table th:nth-child(2), .queue-table td:nth-child(2) { width: 100px; }  /* 생산일 = 날짜 공통 100 */
.queue-table th:nth-child(3), .queue-table td:nth-child(3) { width: 50px; }   /* 주야 = lot-table */
.queue-table th:nth-child(4), .queue-table td:nth-child(4) { width: 340px; text-align: left; } /* LOT 번호(전체 형식) — 340(08-11 사장님): 경과일 칩+최장 LOT(~300)도 잘림 없이. 잔여(품명)가 그만큼 줄어든다 */
.queue-table th:nth-child(5), .queue-table td:nth-child(5) { width: 70px; }   /* 고객사(전역 70, 08-11) */
.queue-table th:nth-child(6), .queue-table td:nth-child(6) { width: 100px; }  /* 제품군 = lot-table */
.queue-table th:nth-child(7), .queue-table td:nth-child(7) { text-align: left; } /* 품명 = 잔여 폭 */
/* 헤더만 가운데(07-24 사장님) — 데이터는 좌(식별자·텍스트), 헤더 라벨은 가운데 */
.queue-table thead th:nth-child(4), .queue-table thead th:nth-child(7) { text-align: center; }
.queue-table th:nth-child(8), .queue-table td:nth-child(8) { width: 80px; }  /* 금형(전역 80, 08-11) */
.queue-table th:nth-child(9), .queue-table td:nth-child(9) { width: 50px; }   /* 열 = lot-table */
.queue-table th:nth-child(10), .queue-table td:nth-child(10) { width: 80px; }  /* 후처리 = lot-table */
.queue-table th:nth-child(11), .queue-table td:nth-child(11) { width: 90px; }  /* 수량 = lot-table */
.queue-table th:nth-child(12), .queue-table td:nth-child(12) { width: 90px; }  /* 상태 = lot-table */

/* 오늘 할 일 스트립(07-25, 구 .qstat 세로 박스·q2col 2단 대체) — 조치 필요 숫자만 컴팩트 카드 1줄.
   색 위계: 빨강 = 오늘 조치(수검 대기·NG·순회 미검사) / 앰버 = 확정·검증(측정완료 필요·수리 검증) / 뮤트 = 백로그(놓친 검사).
   0건 = 회색·클릭 없음(07-24) · 조회 실패 = '—' + 재시도(장애≠0건). 그룹 구분 = .qtd-div 세로선(라벨 소음 방지). */
.qtd-strip { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.qtd { flex: 1 1 0; min-width: 112px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel, #fff); padding: 8px 12px 9px; }
.qtd .n { font-size: 20px; font-weight: 800; line-height: 1.15; color: var(--brand-dark); }
.qtd .l { font-size: 12.5px; font-weight: 700; color: var(--ink); margin-top: 2px; white-space: nowrap; }
.qtd.red .n { color: var(--danger); }
.qtd.amber .n { color: var(--warn-ink); }
.qtd.mute .n { color: var(--muted); }
.qtd.gray .n, .qtd.gray .l { color: var(--muted); }
.qtd.clickable { cursor: pointer; transition: background .12s, border-color .12s; }
.qtd.clickable:hover { background: var(--hover); border-color: var(--brand); }
.qtd-div { width: 1px; flex: none; align-self: stretch; background: var(--line); margin: 2px; }

/* 수검 흐름 바(07-25, 구 수검 현황 세로 5박스 대체) — LOT 상태별 현황을 공정 순서 1줄로.
   칩 색 = LOT 상태 칩 문법(lotStatusChip 계열), 외주 가공중만 회색(물류 소관 상류 참고). 클릭 = 필터된 수검 목록. */
.qpipe { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 2px 0 3px; }
.qpipe .chip { min-width: 0; cursor: pointer; padding: 2px 12px 3px; }
.qpipe .chip b { font-weight: 800; margin-left: 5px; } /* 라벨-건수 간격 — 텍스트 노드 공백은 collapse되므로 margin으로 */
.qpipe .chip:hover { filter: brightness(.95); }
.qp-arr { color: var(--muted); font-weight: 700; }
.qp-lbl { color: var(--muted); font-size: 12.5px; }
/* 칩 바 끝 주석(기준일·미도입 안내 등) — 칩·라벨과 같은 12.5. 12px로 두면 옆 칩보다 작아 읽히지 않는다(07-31 사장님).
   ★일회성 인라인 font-size 금지: 새 주석은 이 클래스를 쓴다(§2 폰트 스케일 9종 수렴). */
.qpipe .note { color: var(--muted); font-size: 12.5px; margin-left: 4px; }

.qsec-head { display: flex; align-items: baseline; gap: 10px; margin: 14px 0 10px; padding-top: 12px; border-top: 2px solid var(--line); }
.qsec-head .t { font-size: 15px; font-weight: 800; }
.qsec-head .d { font-size: 12px; color: var(--muted); }
.page-head + .qsec-head { border-top: none; padding-top: 0; margin-top: 4px; } /* 첫 섹션은 페이지 제목 바로 아래 — 구분선 생략 */
/* 기본 10행 표시 + 내부 스크롤 (thead는 전역 sticky). 행 높이 약 33px × 10 + 헤더 */
.table-wrap.rows10 { max-height: min(366px, calc(100vh - 340px)); overflow: auto; }

/* 측정완료(잠금) 열람 모드 — 값 배경은 다른 표와 같은 흰색, 잠금 표시는 제목 머리(모달 머리·구획 머리)에서 한다(09-21 사장님).
   측정값 입력 테두리만 제거한다(수정하는 곳이 아니므로). */
.insp-closed .dim-table .meas { border: none; background: transparent; appearance: none; pointer-events: none; padding-left: 0; }
.insp-closed .dim-table .meas.ng { background: transparent; color: var(--danger); }
.insp-table .meas.ng { background: var(--danger-bg); border-color: var(--danger); color: var(--danger); font-weight: 700; }
input.ng { background: var(--danger-bg); border-color: var(--danger); color: var(--danger); font-weight: 700; }
.spec-grp td { background: var(--bg); color: var(--muted); font-weight: 700; font-size: 12px; padding: 4px 8px; }
.meta.neg { color: var(--danger); font-weight: 700; }
.row.wrap { flex-wrap: wrap; }

/* 열람 팝업 섹션 리듬 — 근접성: 제목 위 여백(20) > 제목→자기 내용(12)이어야 제목이 아래 내용과 한 덩어리로 읽힘.
   페이지 본문 패널의 섹션 간격 12px 규격과는 별개(팝업 .hist-sec 한정) */
.hist-sec { margin-top: 20px; }
.hist-sec > .panel-head { margin-bottom: 6px; padding-bottom: 6px; }
.hist-sec .table-wrap { max-height: min(240px, calc(100vh - 340px)); }            /* 이력 많으면 섹션 안에서 스크롤(헤더 고정) */
/* 수검 측정 표(07-25 15행 → 08-06 2단 개편으로 확보된 세로만큼 확장. 작은 화면은 구 캡 유지).
   ★수검 팝업의 측정 래퍼는 JS 실측 캡(lots.js fitMeas, 08-11)이 인라인으로 덮는다 — 가로 스크롤바 상시 노출용.
   여기 CSS 캡은 순회 검사 입력 등 .hist-sec의 다른 rows15 표가 그대로 쓴다. */
.hist-sec .table-wrap.rows15 { max-height: min(calc(100vh - 340px), max(531px, calc(100vh - 470px))); }
/* 순회검사 상시 표 = 15행(07-29 사용자) — .rows15는 .hist-sec 스코프라 페이지 패널에선 무효(§4-O 스코프 함정),
   행 29px 실측 기준 전용 캡(29×15+헤더 34) */
.table-wrap.ptl15 { max-height: min(472px, calc(100vh - 340px)); overflow: auto; }
.hist-sec .empty { padding: 12px 0; }                   /* 빈 상태도 같은 리듬(40px → 12px) */

/* 금형 차트(EMR) 이력 표 — 셀별 Max text 기준 고정폭, 텍스트 컬럼(문제점·현상·조치)이 잔여 폭 전부 */
/* 품질 검사 이력 8열 — 07-27 사장님 px: 검사일100·시각60·구분60·외관60·수리구분80·결과80·문제점=잔여80%·비고=잔여20% */
.qi-table { table-layout: fixed; width: 100%; }
.qi-table th:nth-child(1), .qi-table td:nth-child(1) { width: 100px; } /* 검사일 2026-07-05 */
.qi-table th:nth-child(2), .qi-table td:nth-child(2) { width: 60px; }  /* 시각 18:30 */
.qi-table th:nth-child(3), .qi-table td:nth-child(3) { width: 60px; }  /* 구분 초물 */
.qi-table th:nth-child(4), .qi-table td:nth-child(4) { width: 60px; }  /* 외관 30/30 */
.qi-table th:nth-child(5), .qi-table td:nth-child(5) { width: 80px; }  /* 수리구분 외관 */
.qi-table th:nth-child(6), .qi-table td:nth-child(6) { width: 80px; }  /* 결과 수리요청 칩 */
/* 문제점·비고 = 잔여 폭 3:1 (over-constrained % → 잔여만 비율 분배. 비고는 짧은 메모라 문제점에 폭 몰아줌) */
/* 07-20: 문제점 −15%(실측 444→378) → 줄어든 폭은 비고가 전부 흡수(148→215).
   두 열이 남은 폭을 나눠 갖는 구조라 한쪽이 줄면 다른 쪽이 그만큼 늘어난다(비율 75:25 → 63.75:36.25). */
.qi-table th:nth-child(7), .qi-table td:nth-child(7) { width: 70%; }   /* 문제점 — 07-27 사장님: 잔여 70% */
.qi-table th:nth-child(8), .qi-table td:nth-child(8) { width: 30%; }   /* 비고 — 잔여 30% */
/* 07-27 사장님: 행 = 1줄 고정(긴 문구는 …+툴팁, 전문은 행 클릭=검사 상세) — 행 높이가 들쭉날쭉하던 것 */
.qi-table td.ev-note { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 범주값 가운데 정렬: 검사일·시각·구분·외관·수리구분·결과 칩 */
.qi-table td:nth-child(1), .qi-table td:nth-child(2), .qi-table td:nth-child(3),
.qi-table td:nth-child(4), .qi-table td:nth-child(5), .qi-table td:nth-child(6) { text-align: center; }
/* .qi-lite = 축약 변형(Trial 등록: 검사일|구분|외관|결과|문제점|비고 6열) — nth-child 어긋남 분리(21차 교훈) */
.qi-table.qi-lite th:nth-child(2), .qi-table.qi-lite td:nth-child(2) { width: 60px; }   /* 구분 */
.qi-table.qi-lite th:nth-child(4), .qi-table.qi-lite td:nth-child(4) { width: 80px; }   /* 결과 */
.qi-table.qi-lite th:nth-child(5), .qi-table.qi-lite td:nth-child(5) { width: 80%; text-align: left; }  /* 문제점 = 잔여 80% */
.qi-table.qi-lite th:nth-child(6), .qi-table.qi-lite td:nth-child(6) { width: 20%; text-align: left; }  /* 비고 = 잔여 20% */
/* .qi-m = 결과·구분 통합 변형(07-29 사용자 — 결과 칩에 구분 병기 "초물 OK", 구분 칼럼 폐지):
   검사일|시각|결과|외관|수리구분|문제점|비고 7열 — 직전 검사·검사 이력 팝업·EMR·생산 이력 상세 공용 */
.qi-table.qi-m th:nth-child(3), .qi-table.qi-m td:nth-child(3) { width: 110px; } /* 결과(구분 병기 칩 "중물 · 한도생산") */
.qi-table.qi-m td:nth-child(3) { text-align: left; } /* 값 좌정렬(헤더는 전역 가운데, 07-29 사용자) */
.qi-table.qi-m th:nth-child(4), .qi-table.qi-m td:nth-child(4) { width: 60px; }  /* 외관 */
.qi-table.qi-m th:nth-child(5), .qi-table.qi-m td:nth-child(5) { width: 110px; } /* 수리구분(최장 "외관 · 찍힘·눌림" 실측 88+패딩 — 07-30 사장님 "넘침") */
.qi-table.qi-m th:nth-child(6), .qi-table.qi-m td:nth-child(6) { width: 75%; text-align: left; } /* 문제점 = 잔여 75% */
.qi-table.qi-m th:nth-child(7), .qi-table.qi-m td:nth-child(7) { width: 25%; text-align: left; } /* 비고 = 잔여 25%(수리구분 확폭분 흡수, 07-30) */
/* 열람 팝업(생산 이력 상세)의 세부 이력 표 — 입력 표(.ev-table 6열)와 컬럼 구성이 다르므로 전용 규격.
   ★시각·구분·유형·불량수는 아래 두 표(수리·검사)의 앞 컬럼 폭에 맞춰 좁게, 남는 폭은 전부 내용이 흡수(07-20).
   (구: nth-child 규칙이 입력 표와 섞여 시각 231px·내용 231px처럼 엉뚱하게 배분됐다) */
.ev-view th:nth-child(1), .ev-view td:nth-child(1) { width: 106px; text-align: center; }  /* 시각 = 수리일 폭(rev09 S5) */
.ev-view th:nth-child(2), .ev-view td:nth-child(2) { width: 84px; text-align: center; }   /* 구분 = 담당자 폭(rev09 S5) */
.ev-view th:nth-child(3), .ev-view td:nth-child(3) { width: 90px; text-align: center; }   /* 유형 칩(rev09 S5) */
.ev-view th:nth-child(4), .ev-view td:nth-child(4) { width: 67px; }                       /* 불량수 = 외관 폭(rev09 S5) */
.ev-view th:nth-child(5), .ev-view td:nth-child(5) { width: auto; }                       /* 내용 = 잔여 전부 */

/* ★07-24 §4-P: 좌1=검증(상태) 열 신설 + 이상 유형 열 — 검증90|수리일100|담당자84|이상유형90|문제현상(잔여)|조치(잔여)|LOT103|사진91 */
/* EMR 차트 수리이력 7열(LOT 삭제) — 07-27 사장님 px: 검증100·수리일100·담당자80·이상유형100·문제현상/조치=잔여·사진60 */
.rep-table { table-layout: fixed; width: 100%; }
/* 07-30 사장님: 좌1=수리일(검사 이력 검사일과 동일 100) · 검증+담당자 = 시각+결과 합(60+110=170) ·
   이상 유형 = 외관+수리구분 합(60+80=140, 확폭분은 조치가 흡수 — 문제 현상:조치 52:48) */
.rep-table th:nth-child(1), .rep-table td:nth-child(1) { width: 100px; }  /* 수리일(공통 날짜 폭) — 가운데는 td.ctr */
.rep-table th:nth-child(2), .rep-table td:nth-child(2) { width: 90px; }   /* 검증 칩(170 − 담당자 80) */
.rep-table th:nth-child(3), .rep-table td:nth-child(3) { width: 80px; }   /* 담당자 */
.rep-table th:nth-child(4), .rep-table td:nth-child(4) { width: 140px; }  /* 이상 유형 */
.rep-table:not(.rep-lite) th:nth-child(5), .rep-table:not(.rep-lite) td:nth-child(5) { width: 52%; } /* 문제 현상 */
.rep-table:not(.rep-lite) th:nth-child(6), .rep-table:not(.rep-lite) td:nth-child(6) { width: 48%; } /* 조치 */
.rep-table th:nth-child(7), .rep-table td:nth-child(7) { width: 60px; }   /* 사진 수 */
/* .rep-lite = 축약 변형(생산 이력 상세: 수리일|담당자|문제현상|조치|첨부 · Trial 등록: 첨부 없음 4열) —
   같은 클래스에 다른 컬럼 구성을 얹으면 nth-child가 어긋난다(07-20 21차 교훈): 변형은 폭 자체 정의 */
.rep-table.rep-lite th:nth-child(2), .rep-table.rep-lite td:nth-child(2) { width: 80px; }   /* 담당자 */
.rep-table.rep-lite th:nth-child(3), .rep-table.rep-lite td:nth-child(3) { width: auto; }   /* 문제 현상 = 잔여 */
.rep-table.rep-lite th:nth-child(4), .rep-table.rep-lite td:nth-child(4) { width: auto; }   /* 조치 = 잔여 */
.rep-table.rep-lite th:nth-child(5), .rep-table.rep-lite td:nth-child(5) { width: 60px; }   /* 첨부 */

/* ===== 부품 리스트(BOM) — P/N 체계 ===== */
/* 컬럼 폭 = 지정 글자수 기준 고정. 남는 공간은 폭 미지정인 '수리' 컬럼이 흡수. */
.bom-table { table-layout: fixed; width: 100%; }
.bom-table th, .bom-table td { white-space: nowrap; padding: 0 12px; overflow: hidden; text-overflow: ellipsis; }
.bom-table th { padding: 5px 12px; }   /* 헤더 세로 패딩 = 표준 th(5px)와 동일 높이 */
.bom-table td { height: 26px; } /* 행 26px(치수 측정 표 규격 — 07-30 사장님 "한 화면에 많이") */
.bom-table .pn { font-weight: 700; }                                 /* P/N = 식별자 강조 */
.bom-table .chip { font-size: 12.5px; padding: 2px 7px; border-radius: 8px; }
.table-wrap.bom-wrap { max-height: min(574px, calc(100vh - 340px)); }        /* 헤더 + 17행(07-27) — .table-wrap 병기 = 팝업 일반 캡과 특이도 동급(뒤 규칙 우선) */
/* 글자수 기준 폭 = 글자수(ch) + 셀 패딩(24px). (1구분·2Stage/코드·3계열·4명칭·5P/N·6Rev·7수리(잔여)·8삭제) */
/* 07-16 7컬럼(Part·중구분·계열·P/N·Rev·수리·삭제) — 수리(6)만 폭 미지정 = 잔여 폭 전부 흡수 */
.bom-table th:nth-child(1), .bom-table td:nth-child(1) { width: 92px; }   /* Part 칩(고정폭 66) */
.bom-table th:nth-child(2), .bom-table td:nth-child(2) { width: calc(18ch + 24px); text-align: left; }  /* 중구분 18자 좌정렬 */
.bom-table th:nth-child(3), .bom-table td:nth-child(3) { width: 100px; }  /* 계열 칩 (LIFTER 6자) */
.bom-table th:nth-child(4), .bom-table td:nth-child(4) { width: calc(34ch + 24px); text-align: left; }  /* P/N 34자 좌정렬 */
.bom-table th:nth-child(5), .bom-table td:nth-child(5) { width: 70px; }   /* Rev — R00 고정 3자 기준 */
.bom-table th:nth-child(7), .bom-table td:nth-child(7) { width: 56px; }   /* 삭제(버튼 최소폭) */
.bom-table .num.neg, .ph-table .neg, .v.neg { color: var(--danger); font-weight: 700; } /* 수리 3회↑ 경고 */
/* 부품 수리 이력 표 */
/* 수리 이력 의뢰 표(접수대기·처리이력 공통) — 07-16 폭 정비: 범주 컬럼 최소화, 잔여 폭 전부 문제현상 */
/* ★§4-P 소급(07-24): 처리 이력 = 상태|의뢰일|출처|고객사|품명|차수|문제현상(잔여)|의뢰자 ·
   접수 대기(.acc) = 맨 앞에 조치 136 추가(이후 열 +1). 공통 폭: 날짜100·고객사80·품명220·상태90 */
.rq-list { table-layout: fixed; width: 100%; }
.rq-list th, .rq-list td { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 문제현상 = 한 줄 말줄임(전체는 title 툴팁·행 클릭 상세) — 줄바꿈으로 행이 51px까지 커지던 것 통일(rev02 point5) */
/* ★td에 직접 display:flex 금지(07-24 사장님 — 문제현상 헤더 단차의 원인): 셀이 table-cell에서 이탈해
   헤더와 본문의 칼럼 경계·높이가 미세하게 어긋난다. flex는 셀 안 래퍼(.symp-in)가 담당. */
.rq-list td.rq-symptom { white-space: nowrap; }
.rq-list td.rq-symptom .symp-in { display: flex; align-items: center; gap: 6px; min-width: 0; }
.rq-list td.rq-symptom .symp-in > span { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
/* '경과' 열 신설(07-26) — 의뢰일 오른쪽, 미완결 건 방치 신호(3일+ 앰버·7일+ 빨강) */
/* ★07-30 사장님: 조치·상태 한 칼럼 통합 + 경과 칼럼 폐지(경과 칩 = 품명 왼쪽 병기) — acc/일반 동일 8열 */
/* 칼럼 폭 = requests.js RQ_COLS(colgroup, 09-07 tablekit — 구 nth-child 폭 규칙 폐지). 상태 칸 = td.rq-st */
.rq-list td.rq-st { white-space: nowrap; overflow: visible; } /* [수리 처리] + 할 일 점 1줄(09-09 7차) */
.rq-list.acc td.rq-st { white-space: normal; }  /* 90px에선 [접수]+작성중 칩이 한 줄에 안 들어감 — 칩만 아래로 감싼다 */

.ph-table { table-layout: fixed; width: 100%; }
.ph-table td { height: 32px; }
.ph-table th:nth-child(1), .ph-table td:nth-child(1) { width: 106px; }  /* 수리일 = 날짜 폭 통일 */
.ph-table th:nth-child(2), .ph-table td:nth-child(2) { width: 84px; }   /* 구분 칩(66) + 좌우 여백 — 칩 넘침 방지 */
.ph-table th:nth-child(3), .ph-table td:nth-child(3) { width: 96px; }   /* Rev R00→R01 */
.ph-table th:nth-child(6), .ph-table td:nth-child(6) { width: 76px; }   /* 담당자 */

/* BOM Tree — 스테이지 헤더 행 + 들여쓴 부품 행 (32px 리듬) */
.tree-wrap { height: 62vh; overflow: auto; border: 1px solid var(--line); } /* 고정 높이 — Layout/Part별 뷰 전환 시 팝업 크기·위치 불변(DESIGN 4-B) */
.bom-tree { min-width: 980px; }  /* 좁은 화면에서 P/N(flex)이 눌리지 않게 — 부족하면 내부 가로 스크롤(표 규격과 동일 원칙) */
.tree-stage { display: flex; align-items: center; gap: 10px; height: 32px; padding: 0 10px;
  background: var(--bg); font-weight: 700; font-size: 12.5px; border-top: 1px solid var(--line); }
.tree-stage:first-child { border-top: none; }
.tree-stage.dim .t-name { color: var(--muted); font-weight: 400; }
.tree-stage .meta { margin-left: auto; font-size: 12px; color: var(--muted); }
.tree-part { display: flex; align-items: center; gap: 10px; height: 32px; padding: 0 10px 0 26px;
  font-size: 12.5px; border-top: 1px solid var(--gray-bg); }
.tree-part:hover { background: var(--brand-bg); }
.tree-part .t-kind { width: 66px; text-align: center; flex-shrink: 0; }   /* 구분: 공정부품/플레이트/규격품 */
.tree-part .t-fam { width: 62px; text-align: center; flex-shrink: 0; }    /* 계열: PUNCH/STR/DIE */
.tree-part .t-name { font-weight: 700; width: 170px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex-shrink: 0; } /* (구 명칭 — 07-16부터 행에서 미사용, 그룹 헤더만 사용) */
/* P/N = 식별자, 절대 잘리면 안 됨 — 잔여 폭 전부 + 최소폭 보장(부족하면 트리 가로 스크롤) */
.tree-part .t-pn { font-weight: 700; white-space: nowrap; flex: 1; min-width: 220px; overflow: hidden; text-overflow: ellipsis; } /* P/N = 식별자(볼드) — 07-16 명칭 컬럼 폐지 */
.tree-part .t-spec { color: var(--muted); width: 80px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex-shrink: 0; } /* 규격 8자 */
.tree-part .t-rev { width: 44px; text-align: center; flex-shrink: 0; }    /* Rev 3자 */
.tree-part .t-rep { width: 74px; text-align: right; flex-shrink: 0; }
.tree-part .t-rep.neg { color: var(--danger); font-weight: 700; }
.tree-part .t-last { width: 84px; text-align: right; color: var(--muted); flex-shrink: 0; }
.tree-part .chip { font-size: 12.5px; padding: 2px 5px; border-radius: 8px; flex-shrink: 0; }

/* BOM Tree 스트립 도식 — 스트립 레이아웃의 대략 개념만(장식 없음). 피스 클릭 = 스테이지 필터 토글.
   도면 콜아웃식 세로 라벨(아래→위) + 번호. 한 화면에 억지로 안 구겨넣음 — 넘치면 가로 스크롤(말줄임 없음) */
.strip { display: flex; margin-bottom: 10px; border: 1px solid var(--line); border-radius: 6px;
  overflow-x: auto; }
.strip-pc { flex: 0 0 60px; display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  padding: 8px 0 4px; cursor: pointer; border-left: 1px solid var(--line); background: #fff; }
.strip-pc:first-child { border-left: none; }
.strip-pc.all { flex: 0 0 46px; background: var(--bg); } /* [전체] 피스 — 스테이지 필터 해제 */
.strip-pc .pc-nm { writing-mode: vertical-rl; text-orientation: sideways; transform: rotate(180deg);
  white-space: nowrap; height: 104px; display: flex; align-items: center; font-size: 11.5px; color: var(--ink); }
  /* text-orientation: sideways — 한글·숫자도 영문처럼 통째로 눕혀 회전(도면 콜아웃과 동일). 기본값(mixed)은 "1차"가 제각각 섬 */
.strip-pc .pc-no { font-size: 12.5px; font-weight: 700; line-height: 1.2; margin-top: 12px; } /* 세로 라벨과 간격 2배 */
/* 진행 도트 — 스트립을 지나는 제품 흐름 상징: 피스마다 점, 라인은 피스 폭 전체(이웃과 이어져 보임).
   부품 등록 스테이지 = 채운 점 / 없음 = 빈 점 / 선택 = 파란 점 */
.pc-track { position: relative; width: 100%; height: 14px; margin-top: 6px;
  display: flex; align-items: center; justify-content: center; }
.pc-track::before { content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 2px;
  margin-top: -1px; background: var(--line-2); }
.pc-dot { position: relative; width: 9px; height: 9px; border-radius: 50%; background: var(--ink-2); }
.pc-dot.hollow { width: 8px; height: 8px; background: #fff; border: 2px solid var(--line-2); }
.strip-pc.on .pc-dot { background: var(--brand); }
.strip-pc.dim { background: var(--gray-bg); }
.strip-pc.dim .pc-no, .strip-pc.dim .pc-nm { color: var(--muted); font-weight: 400; }
.strip-pc:hover { background: var(--brand-bg); }
.strip-pc.on { background: var(--chip); box-shadow: inset 0 -2px 0 var(--brand); }

/* 수리 등록 팝업 안 "지난 수리이력" 표 */
.rr-table { table-layout: fixed; width: 100%; }
.rr-table td { height: 32px; }
.rr-table th:nth-child(1), .rr-table td:nth-child(1) { width: 100px; }  /* 수리일 — 07-27 공통 날짜 폭 통일 */
.rr-table th:nth-child(2), .rr-table td:nth-child(2) { width: 80px; }   /* 담당자 */
.rr-table th:nth-child(3), .rr-table td:nth-child(3) { width: 100px; }  /* 이상 유형 */
.rr-table th:nth-child(6), .rr-table td:nth-child(6) { width: 60px; }   /* 부품 수 */

/* 유사 수리 참고(수리 등록 팝업) 전용 — 5열: 수리일|제품·금형|부위|문제현상(잔여)|조치(잔여).
   ★.rr-table(6열) 재사용 금지 — 열 수가 달라 폭이 어긋나 글자가 겹쳤다(07-24, rev03 .ev-table 교훈과 동일). */
.sim-table { table-layout: fixed; width: 100%; }
.sim-table td { height: 32px; }
.sim-table th, .sim-table td { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sim-table th:nth-child(1), .sim-table td:nth-child(1) { width: 100px; }  /* 수리일 */
.sim-table th:nth-child(2), .sim-table td:nth-child(2) { width: 220px; }  /* 제품 · 금형(품명 공통 폭) */
.sim-table th:nth-child(3), .sim-table td:nth-child(3) { width: 150px; }  /* 부위(Part · 스테이지) */

/* ===== 수리 등록 팝업 — 목업 구성(07-07) ===== */
.rep2-grid { display: grid; grid-template-columns: 1fr 1.7fr; gap: 14px; align-items: stretch; }
.rep2-left { display: flex; flex-direction: column; gap: 10px; }
.rep2-symp textarea { min-height: 96px; height: 100%; }   /* 문제 현상 3줄 — 왼쪽 입력 2단 높이에 맞춤 */
.grow { flex: 1; min-width: 0; }
/* 하단 메모(2줄)·첨부 — 양쪽 박스 끝단 높이 맞춤 */
.rep2-foot { align-items: stretch; }
.rep2-foot .field textarea { flex: 1; resize: none; }
.rep2-foot .panel { margin-bottom: 0; } /* panel 기본 하단마진 제거 — 메모·첨부 박스 하단 정확히 정렬 */
.rep2-foot .grow { min-width: 220px; }   /* 좁아지면 메모·첨부가 다음 줄로 내려가게(0으로 눌려 겹침 방지) */
/* 네이티브 파일 선택 input은 고유 폭이 커서 모달 밖으로 튀어나감 — 컨테이너에 맞춰 축소 */
input[type="file"] { max-width: 100%; box-sizing: border-box; }
/* 좁은 모달: 수리 등록 2열 구성을 1열로 세움(모바일에서만 — 태블릿은 2열 유지) */
@container (max-width: 470px) {
  .rep2-grid { grid-template-columns: 1fr; }
}
/* 조치 부품 결과 표 — 선택은 BOM Tree에서, 여기는 기록만. 행 32px 리듬 · 최대 6행 후 내부 스크롤(224px)
   min-width: 텍스트 잘림 방지(공통 규칙) — 좁으면 표 내부 가로 스크롤 */
/* 조치 부품 표 — BOM 표와 동일하게 내용 기준 폭(auto), 행 높이 살짝 축소(28px) */
.cp-table { table-layout: auto; width: 100%; }
.cp-table th, .cp-table td { white-space: nowrap; padding: 0 12px; }
.cp-table th { padding: 5px 12px; }   /* 헤더 세로 패딩 = 표준 th와 동일 높이 */
.cp-table td { height: 28px; }
.cp-table .chip { font-size: 12.5px; padding: 2px 7px; border-radius: 8px; }

/* 재고·PO 현황 3개 뷰(현황 요약·생산 계획·전체 현황판) — 컬럼 제목(th)만 가운데 정렬(사용자 확정).
   데이터 셀 정렬은 기존 규칙 유지(숫자 우측 등). th.num(우측) 개별 규칙을 덮기 위해 !important */
.tbl-center th { text-align: center !important; }

/* 신규 생산 등록 — 입력요소 높이 38px 한 기준으로 전부 통일(박스별 미세 차이 금지) */
.reg-grid input, .reg-grid select, .reg-grid .btn { height: 38px; box-sizing: border-box; }

/* 생산 건 목록 — 상태·구분 5자 폭(78px)·가운데, 우측(설비~이력) 열 폭 균일(88px), 남는 폭은 제품이 흡수.
   min-width 1170 = 고정폭 합(1000) + 제품 최소 170px(20자 보장) — 더 좁아지면 표 내부 가로 스크롤 */
/* min-width = 고정 컬럼 합 + 품명 최소폭. 품명 최소폭은 '품명 + 금형수리 의뢰중(생산) 칩'이 한 줄에 들어가는 값(실측 233px). */
/* ★07-24 rev08 S4(사장님 px 지정): 상태 90 · 구분 60 · 품명 잔여 · 금형 100 · 설비 80 · 주야 50 · 담당자 80 · 생산~이력 90.
   구분·금형 = 헤더+내용 전부 가운데. */
.prod-list { table-layout: fixed; width: 100%; } /* 칼럼 폭·min-width = production.js PL_COLS(colgroup, 09-07 tablekit — 구 nth-child 폭·정렬 규칙 폐지, 정렬은 td.ctr) */
.prod-list td.col-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* 초장문 품명 침범 방지(보험) */
.prod-list tr.row-closed td { background: var(--done-row); } /* 마감 건 = 옅은 회색(08-11 사장님 — 남은 일/끝난 일 한눈 구분) */

/* 생산 이력(누적) — 표준 고정폭(08-11 사장님, 구 auto): 상태90(좌1, §4-P)·일자100·구분80·고객사70·제품군100·품명220·금형80·
   설비80·주야50·담당자80·SPM60·Cavity60·생산/불량/마감90·가동률90 + 끝 빈 스페이서 열(잔여 흡수). 합 1430+40. */
.phist-table { table-layout: fixed; width: 100%; } /* 칼럼 폭·min-width = history.js PH_COLS(colgroup, 09-07 tablekit — 구 nth-child 폭 규칙 폐지) */
.phist-table td.col-name { overflow: hidden; text-overflow: ellipsis; } /* 품명 220 말줄임 */
.prod-list .chip { min-width: 0; padding-left: 6px; padding-right: 6px; } /* 5자 컬럼 안에서 칩 고정폭 66 해제 */
/* 품명 뒤 딱지(.req-tag) — 간격이 0이면 칩의 틴트 배경이 품명 글자에 바로 붙어 침범한 것처럼 읽힌다.
   ★여백은 색 클래스(.wait/.rq-*)가 아니라 이 공통 클래스에 건다 — 상태에 따라 색이 바뀌어도 간격은 유지. */
.prod-list td.col-name .chip.req-tag { margin-left: 8px; }
.ptl-table td .chip.req-tag { margin-left: 8px; } /* 순회검사 표 품명 뒤 '수리의뢰중' 딱지(08-04) — 같은 역할 클래스 */

/* 신규 생산 등록(다건) 라인 — 구분·제품·금형·Cavity·설비·담당자·SPM·삭제 + 끝 스페이서(1fr).
   제품 = minmax(150,260): 20자 폭 상한(무한정 늘어남 방지) · 트레일링 1fr가 넓은 화면의 남는 폭 흡수 */
/* 07-18: 품명 캐스케이드(고객사·제품군) 열 추가 — 잔여 폭(1fr spacer) 축소로 흡수 */
/* 설비 144→164(08-04 사장님 — "DP17 HANIL 110T"가 잘렸다: 최장 라벨 select 실측 159px + 여유). 잔여는 1fr 스페이서가 흡수 */
.pr-row { display: grid;
  grid-template-columns: 80px 100px 116px minmax(150px, 240px) 126px 70px 164px 104px 72px 56px 1fr;
  gap: 8px; align-items: center; margin-top: 6px; }
.pr-row.pr-head { margin-top: 0; }
.pr-row.pr-head .lbl { font-size: 12px; color: var(--muted); }
.pr-row input, .pr-row select { height: 34px; box-sizing: border-box; min-width: 0; width: 100%; }
/* 셀 = 라벨+입력. 데스크톱은 display:contents로 입력이 직접 그리드 트랙에 들어가고 셀 라벨은 숨김(상단 헤더가 라벨) */
.pr-row .prc { display: contents; }
.pr-row .prc-lbl { display: none; }
.pr-row .pr-spacer { display: block; }
/* 자동 입력 박스 — 제품 선택 시 자동으로 채워지는 값(금형 차수·Cavity): 입력창이 아니라 표시형으로 보이게.
   드롭다운 화살표 제거·음영 배경. 클릭하면 여전히 차수 변경/Cavity 수정 가능(신규 금형 대비) */
.pr-row .auto-in { background: var(--bg-soft); border-color: var(--line); appearance: none; -webkit-appearance: none;
  text-align: center; color: var(--ink); }
/* ★수리중 금형이 선택된 칸 = 빨강(07-24 사장님: 수리는 빨간색) — .pr-row .auto-in의 색을 이기도록 더 구체적으로 */
.pr-row .auto-in.f-warn, select.f-warn, input.f-warn { background: var(--danger-bg); border-color: var(--danger); color: var(--danger); font-weight: 700; }

/* 좁은 모달(태블릿/모바일 또는 폭 좁은 팝업): 한 줄 그리드가 모달 밖으로 넘치지 않게 라인을 라벨 카드로 재구성.
   ★뷰포트가 아니라 모달 폭 기준(container query) — .xl 모달은 84vw라 화면보다 좁아 뷰포트 기준으론 못 잡는다.
   각 라인 = 테두리 카드, 필드는 2열로 쌓이고 라벨이 다시 보인다(제품·삭제는 한 줄 전체).
   ★전환폭 = 그리드 최소폭(고정열 1038 + gap 80 = 1118, 08-04 설비 164 반영) 이상이어야 함 — 더 낮으면 중간 폭에서 행이 모달 밖으로 넘침 */
@container (max-width: 1120px) {
  .pr-row.pr-head { display: none; }
  .pr-row { grid-template-columns: 1fr 1fr; gap: 8px 10px;
    border: 1px solid var(--line); border-radius: 10px; padding: 10px; margin-top: 10px; }
  .pr-row .prc { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
  .pr-row .prc-lbl { display: block; font-size: 12px; color: var(--muted); }
  .pr-row .prc-prod { grid-column: 1 / -1; }         /* 제품은 한 줄 전체 */
  .pr-row .prc-del { grid-column: 1 / -1; }           /* 삭제 버튼 한 줄 전체 */
  .pr-row .prc-del .prc-lbl { display: none; }
  .pr-row .prc-del .btn { width: 100%; }
  .pr-row .pr-spacer { display: none; }
}

/* PO·출하 다건 입력 행 — 제품(넓게)·날짜·수량·비고·삭제 */
/* 07-18: 품명 캐스케이드(고객사·제품군·품명) 3연 — 열 확장 */
/* 비고 열을 넓혀 특이사항을 길게(07-21 사장님 지시). 최소폭 합 = 108+124+150+136+110+160+56=844 + gap 48 = 892 → 전환폭 900 */
.me-row { display: grid; grid-template-columns: 108px 124px minmax(150px, 1.4fr) 136px 110px minmax(160px, 1.4fr) 56px;
  gap: 8px; align-items: start; margin-top: 6px; }
.me-row.me-head { margin-top: 0; }
.me-row.me-head .lbl { font-size: 12px; color: var(--muted); }
.me-row input, .me-row select { height: 34px; box-sizing: border-box; min-width: 0; width: 100%; }
/* (수량 환산 주석 "5,000ea = 5k" 폐지 — 07-23 rev04 사장님. 수량 입력은 우측 정렬 낱개 입력만) */
/* 안내문 중 조치가 필요한 것(값 누락 등) — 앰버 = 조건부/확인 필요 */
.hint.warn { color: var(--warn-ink); background: var(--warn-bg-2); border-radius: 6px; padding: 6px 10px; font-weight: 700; }
.me-row .mec { display: contents; }
.me-row .mec-lbl { display: none; }
/* 좁은 모달: 다건 입력 행도 라벨 카드로 재구성(제품·삭제 한 줄 전체)
   ★전환폭 = 그리드 최소폭(고정열 844 + gap 48 = 892) 이상이어야 함 — 더 낮으면 중간 폭에서 행이 모달 밖으로 넘침 */
@container (max-width: 900px) {
  .me-row.me-head { display: none; }
  .me-row { grid-template-columns: 1fr 1fr; gap: 8px 10px;
    border: 1px solid var(--line); border-radius: 10px; padding: 10px; margin-top: 10px; }
  .me-row .mec { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
  .me-row .mec-lbl { display: block; font-size: 12px; color: var(--muted); }
  .me-row .mec-prod, .me-row .mec-note, .me-row .mec-del { grid-column: 1 / -1; }
  .me-row .mec-del .mec-lbl { display: none; }
  .me-row .mec-del .btn { width: 100%; }
}

/* ===== 개발·Trial 두 표(.dev-table/.spl-table, 07-18) =====
   고객사·제품군·품명·금형 앞 4열 폭 공유 → 위아래 표가 세로로 정렬돼 보인다. 잔여 폭 흡수 열 = 개발: 고객납기 / SPL: 수신처.
   행 높이 32px 통일(.mst 리듬) — 고객납기 인라인 date 입력이 행을 키우던 것 교정(입력 28px). */
.dev-table, .spl-table { table-layout: fixed; width: 100%; }
/* min-width = 고정열 합 + 잔여 열 최소폭 — 좁으면 .table-wrap 내부 가로 스크롤(잔여 열이 음수로 눌려 입력이 잘리는 것 방지) */
/* ★08-03 부서별 입력 루트 분리(13열 재편): 도면(5) 신설 · Trial 회차·최근 Trial·[+ Trial](6~8) = 금형팀 축 ·
   최근 검사·[검사](9~10) = 품질팀 축(헤더에 .dept-lbl 병기). 열을 추가하면 nth-child 지도와 min-width를
   반드시 같이 고친다(DESIGN §4-O — 한 칸 밀리면 고정폭이 엉뚱한 열에 걸려 조용히 넘친다, 07-31 감사 실측).
   고정열 합 1,292 + 고객납기(date 130 + D-day 칩) 최소 190 = 1,482 → 여유 포함 1,490 */
.dev-table { min-width: 1450px; } /* 고객사 70·금형 80 통일(08-11)로 -40 */
.spl-table { min-width: 1180px; }
.dev-table th:nth-child(1), .dev-table td:nth-child(1), .spl-table th:nth-child(1), .spl-table td:nth-child(1) { width: 70px; }   /* 고객사(전역 70, 08-11) */
.dev-table th:nth-child(2), .dev-table td:nth-child(2), .spl-table th:nth-child(2), .spl-table td:nth-child(2) { width: 110px; } /* 제품군 */
.dev-table th:nth-child(3), .dev-table td:nth-child(3), .spl-table th:nth-child(3), .spl-table td:nth-child(3) { width: 220px; } /* 품명 */
.dev-table th:nth-child(4), .dev-table td:nth-child(4), .spl-table th:nth-child(4), .spl-table td:nth-child(4) { width: 80px; } /* 금형(전역 80, 08-11) */
.dev-table th:nth-child(5), .dev-table td:nth-child(5) { width: 64px; }   /* 도면(버튼 — 검토 도면 열람·업로드, 08-03) */
.dev-table th:nth-child(6), .dev-table td:nth-child(6) { width: 80px; }   /* Trial 회차(num) */
.dev-table th:nth-child(7), .dev-table td:nth-child(7) { width: 100px; }  /* 최근 Trial */
.dev-table th:nth-child(8), .dev-table td:nth-child(8) { width: 96px; }   /* Trial 입력(버튼 — 금형팀) */
.dev-table th:nth-child(9), .dev-table td:nth-child(9) { width: 150px; }  /* 최근 검사(칩+일자) */
.dev-table th:nth-child(10), .dev-table td:nth-child(10) { width: 96px; } /* 검사 입력(버튼 — 품질팀) */
.dev-table th:nth-child(12), .dev-table td:nth-child(12) { width: 90px; } /* 상태 — 11열(고객납기)이 잔여 폭 흡수 */
.dev-table th:nth-child(13), .dev-table td:nth-child(13) { width: 96px; } /* 양산 이관(버튼, 08-03) */
.spl-table th:nth-child(5), .spl-table td:nth-child(5) { width: 100px; }  /* 접수일 */
.spl-table th:nth-child(6), .spl-table td:nth-child(6) { width: 170px; }  /* 납기+D-day */
.spl-table th:nth-child(7), .spl-table td:nth-child(7) { width: 100px; }  /* 수량(num) */
.spl-table th:nth-child(9), .spl-table td:nth-child(9) { width: 90px; }   /* 진행 — 8열(수신처)이 잔여 폭 흡수 */
.spl-table th:nth-child(10), .spl-table td:nth-child(10) { width: 96px; } /* 조치(다음 단계 버튼) */
/* 범주값 가운데 정렬(DESIGN 4-D) — 품명·수신처·고객납기 좌, 수량·회차 우 유지 */
.dev-table td:nth-child(1), .dev-table td:nth-child(2), .dev-table td:nth-child(4),
.dev-table td:nth-child(5), .dev-table td:nth-child(7), .dev-table td:nth-child(8),
.dev-table td:nth-child(9), .dev-table td:nth-child(10), .dev-table td:nth-child(12),
.dev-table td:nth-child(13) { text-align: center; }
.spl-table td:nth-child(1), .spl-table td:nth-child(2), .spl-table td:nth-child(4),
.spl-table td:nth-child(5), .spl-table td:nth-child(6) { text-align: center; }
.dev-table td, .spl-table td { height: 32px; padding-top: 1px; padding-bottom: 1px; }
.dev-table input[type="date"] { height: 28px; padding: 2px 6px; font-size: 12.5px; }

/* 마스터 표 공통(.mst) — ★행 높이 26px = 검사 기준 표(.spec-table)와 같은 규격(09-18 사장님 — 구 29px/32px).
   칩 18px·입력 24px·버튼 22px 전부 26 안에 들어오게(칩·버튼은 .table-wrap 공통 규칙과 같은 값). 행 클릭 = 편집 팝업(행별 버튼 금지, ↑↓만 예외) */
.mst td { height: 26px; padding-top: 0; padding-bottom: 0; }
.mst .chip { font-size: 12px; height: 18px; line-height: 18px; padding: 0 8px; border-radius: 8px; }
.mst select, .mst input { height: 24px; padding: 1px 6px; font-size: 12.5px; box-sizing: border-box; }
.mst .btn.sm { height: 22px; padding: 0 8px; line-height: 20px; }
/* 차수 칩(1차~4차, 2글자 고정) — 표준 66px 대신 2글자 폭으로 좁혀 금형차수 컬럼을 최소화 */
.mst .chip.stg { min-width: 34px; padding-left: 4px; padding-right: 4px; }
/* 금형차수 컬럼 = 칩(1줄) 폭만큼만 차지(width:1% + nowrap) → 남는 폭은 품명(nowrap로 우선 흡수) */
.mst th.col-stage, .mst td.col-stage { width: 1%; white-space: nowrap; }
.mst th.col-name, .mst td.col-name { white-space: nowrap; }

/* 칩 하단 여백 통일 — 상단 2 / 하단 3 (나눔스퀘어 하단 잘림 방지). 스코프별 shorthand가 덮지 않게 마지막에 일괄 적용 */
.ev-table .chip, .spec-table .chip, .bom-table .chip, .tree-part .chip, .cp-table .chip,
.qi-table .chip, .rr-table .chip, .ph-table .chip, .dim-table .chip, table .chip { padding-bottom: 3px; }

/* 치수 측정 입력 행 */
.dim-head, .dim-row { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr 32px; gap: 6px; align-items: center; }
.dim-head { font-size: 11.5px; color: var(--muted); font-weight: 400; margin: 6px 0 4px; padding: 0 2px; }
.dim-row { margin-bottom: 5px; }
.dim-row input { padding: 5px 7px; font-size: 12px; }

.error-box { background: var(--danger-bg-2); color: var(--danger); padding: 14px; border-radius: 8px; }
.empty { text-align: center; color: var(--muted); padding: 40px 0; }
.hint { font-size: 12px; color: var(--muted); }

/* ===== 이미지 첨부(수리의뢰 불량 사진/도식) ===== */
.imgatt-drop { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; border: 1px dashed var(--line); border-radius: 8px; padding: 10px 12px; background: var(--bg-soft); }
.imgatt-drop.over { border-color: var(--brand); background: var(--brand-bg); }
.imgatt-hint { font-size: 12px; color: var(--muted); }
/* 썸네일 = 2열 그리드(2줄이면 최대 4장). 프리뷰에서도 대략 위치가 보이게 크게 + contain(전체 표시) */
.imgatt-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-top: 10px; }
.imgatt-grid:empty { display: none; }
.imgatt-thumb { position: relative; width: 100%; aspect-ratio: 4 / 3; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; background: var(--bg); }
.imgatt-thumb img { width: 100%; height: 100%; object-fit: contain; }
.imgatt-ov { position: absolute; left: 0; right: 0; bottom: 0; display: flex; gap: 4px; padding: 4px; background: rgba(0,0,0,.45); justify-content: center; }
.imgatt-ov .btn { padding: 1px 6px; font-size: 11.5px; }
/* 인라인 표시용 썸네일(의뢰 상세·수리등록) — 클릭해 확대 */
.att-thumbs { display: flex; flex-wrap: wrap; gap: 6px; }
.att-thumbs img, .view-thumb { width: 66px; height: 66px; object-fit: cover; border: 1px solid var(--line); border-radius: 6px; cursor: pointer; }
.att-thumbs img.lg { width: 92px; height: 92px; }
/* 검사 상세 인라인 사진(07-19) — 썸네일이 아니라 내용이 읽히는 크기(약 4:3 가로 400px급). 클릭 = 확대 뷰어 */
.att-thumbs img.xl { width: auto; height: 192px; max-width: 440px; object-fit: contain; background: var(--bg-soft); } /* 240→192(-20%, 07-29 사용자) — 가로 긴 이미지는 비율 유지·높이만 축소 */
.view-thumb.on { outline: 2px solid var(--brand); }
/* 주석 도구 */
.tool-on { background: var(--brand) !important; color: #fff !important; border-color: var(--brand) !important; }
.color-sw { width: 22px; height: 22px; border-radius: 6px; border: 1px solid var(--line); cursor: pointer; padding: 0; }
.color-sw.on { outline: 2px solid var(--ink); outline-offset: 1px; }
/* 주석 텍스트 인라인 입력칸 — 캔버스 위 클릭 지점에 뜸 */
.annot-text-in { position: absolute; margin: 0; padding: 0 2px; border: 1px dashed rgba(0,0,0,.45); background: rgba(255,255,255,.9); font-weight: 700; font-family: "Malgun Gothic", sans-serif; line-height: 1.15; outline: none; min-width: 46px; box-sizing: content-box; }
/* ★주석 편집기 리본(09-08 사장님 2차 — PPT식 묶음 상자): 상자 = 아이콘 칸(2줄 격자) + 아래 제목, 전 묶음 같은 높이·끝단 정렬. 드롭다운 없음 */
.annot-body { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.annot-ribbon { display: flex; align-items: stretch; gap: 6px; flex-wrap: wrap; padding: 6px 8px; margin-bottom: 6px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg-soft); }
.annot-ribbon .rib-grp { display: flex; flex-direction: column; justify-content: space-between; border: 1px solid var(--line); border-radius: 6px; background: #fff; padding: 4px 6px 2px; min-height: 66px; }
.annot-ribbon .rib-cells { display: grid; grid-auto-flow: column; grid-template-rows: repeat(2, 24px); gap: 3px 3px; align-items: center; }
.annot-ribbon .rib-lbl { font-size: 10.5px; color: var(--muted); line-height: 1; text-align: center; padding-top: 3px; white-space: nowrap; }
.annot-ribbon .rib-grp.rib-act { border: none; background: transparent; justify-content: center; }
.annot-ribbon .rib-grp.rib-act .rib-cells { grid-template-rows: 26px; gap: 6px; }
.annot-ribbon .rib-grp.rib-act .rib-lbl { display: none; }
.rib-ico { width: 26px; height: 24px; padding: 0; border: 1px solid transparent; border-radius: 5px; background: transparent; color: var(--ink); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 700; line-height: 1; }
.rib-ico:hover { background: var(--hover); border-color: var(--line); }
.rib-ico.on { background: var(--brand); color: #fff; border-color: var(--brand); }
.rib-ico.sym { font-size: 13px; font-weight: 700; }
.annot-ribbon select.rib-sel, .annot-ribbon input.rib-num { height: 24px; padding: 0 4px; font-size: 12px; border: 1px solid var(--line); border-radius: 5px; background: #fff; }
.annot-ribbon input.rib-num { width: 40px; text-align: center; }
.annot-ribbon .rib-x { color: var(--muted); font-size: 12px; text-align: center; }
.annot-ribbon .color-pick { width: 24px; height: 22px; padding: 0; border: 1px solid var(--line); border-radius: 5px; background: #fff; cursor: pointer; }
.annot-ribbon .color-sw { width: 22px; height: 22px; }
.annot-ribbon .rib-zoom { font-size: 11.5px; color: var(--muted); min-width: 36px; text-align: center; }
.annot-ribbon .spacer { flex: 1; }
.annot-scroll { text-align: center; background: var(--bg); padding: 8px; border-radius: 8px; overflow: auto; height: 400px; flex: 0 0 auto; }
/* Shift 탭 팔레트 — 커서 옆(z 400: 자유 창·팝업 위) */
.annot-pal { position: fixed; z-index: 400; background: #fff; border: 1px solid var(--line); border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,.18); padding: 6px 8px; display: flex; flex-direction: column; gap: 3px; }
.annot-pal .pal-row { display: flex; align-items: center; gap: 2px; }
.annot-pal .pal-lbl { width: 44px; font-size: 11px; color: var(--muted); white-space: nowrap; }
.annot-pal .rib-ico { width: 24px; height: 22px; }
.annot-pal .color-sw.sm { width: 18px; height: 18px; margin: 0 2px; }

/* 반응형(태블릿/모바일) */
@media (max-width: 720px) {
  .form-grid { grid-template-columns: 1fr; }
  .topnav { height: auto; flex-direction: column; align-items: flex-start; padding: 10px 14px; gap: 8px; }
  .content { padding: 14px; }
}

/* ── 측정값·비고 입력 = 엑셀 셀 인상 전면 확장(07-25 사장님 — .oqc-meas 문법을 측정 입력 표 전체로) ──
   대상: 검사 입력(.insp-table 측정값·판정 select) · 검사 상세(.dim-table 측정값·판정 select·비고).
   테두리·라운드 없는 투명 셀 입력, 포커스만 파란 외곽선, NG = 셀 배경 틴트+빨간 숫자(테두리 없음).
   ※수리 검증 폼은 표가 아니라 한 줄 폼(행 격자 없음) — 셀 문법 비대상. 파일 끝 배치 = 기존 .meas 규칙 오버라이드. */
.insp-table td.meas-td, .dim-table td.meas-td { padding: 0; }
.insp-table input.meas, .insp-table select.meas { width: 100%; height: 26px; border: 0; border-radius: 0; background: transparent; padding: 0 8px; font: inherit; font-size: 12.5px; font-weight: 700; text-align: center; } /* 26px = 행 높이(07-28) */
.dim-table input.meas, .dim-table select.meas { width: 100%; height: 26px; border: 0; border-radius: 0; background: transparent; padding: 0 6px; font: inherit; font-size: 12.5px; font-weight: 700; text-align: center; }
.dim-table .note-in { border: 0; border-radius: 0; background: transparent; height: 26px; padding: 0 6px; font: inherit; font-size: 12.5px; }
.insp-table input.meas:focus, .insp-table select.meas:focus, .dim-table input.meas:focus, .dim-table select.meas:focus, .dim-table .note-in:focus { outline: 2px solid var(--brand); outline-offset: -2px; background: #fff; }
.insp-table .meas.ng, .dim-table .meas.ng { background: var(--danger-bg); border: 0; color: var(--danger); font-weight: 700; }
/* 내부 관리치수 초과 = 주황(07-28) — 고객 기준 OK인데 사내 tight 공차를 벗어남(관리 신호, 결과 판정과 무관) */
.insp-table .meas.warn-in, .dim-table .meas.warn-in, .oqc-meas input.meas.warn-in,
.vf-table .meas.warn-in { background: var(--warn-bg); border: 0; color: var(--amber-ink, #b45f06); font-weight: 700; } /* .vf-table = 수리 검증(08-03 13차 ② — §4-O 스코프 함정 9번째: 공용 클래스는 새 표 스코프에 규칙부터) */
.dim-table td .warn-in { color: var(--amber-ink, #b45f06); font-weight: 700; } /* 열람 전용(span) 표기 */
.insp-closed .dim-table .meas.warn-in { background: transparent; color: var(--amber-ink, #b45f06); }
/* 숫자 외 입력(badInput) — ui.js numGuard가 표시하고 blur 시 지운다(07-28) */
input.bad-num { outline: 2px solid var(--danger) !important; outline-offset: -2px; background: var(--danger-bg) !important; }
.insp-table input.meas::-webkit-outer-spin-button, .insp-table input.meas::-webkit-inner-spin-button,
.dim-table input.meas::-webkit-outer-spin-button, .dim-table input.meas::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* ── 수리 검증 측정 표 (.vf-table, 07-25 사장님 — 4번째 측정 표 문법 통일) ──
   구분(칩)90 | 항목 260(직접 행 = 검색형 드롭다운+항목명 세로 배치) | 기준 70 | 공차 60×2 |
   측정값 = 잔여 흡수·가변(엑셀 셀 입력) | 판정 92 | 조치 58. min-width는 JS 인라인(860). */
.vf-table { table-layout: fixed; width: 100%; }
.vf-table th:nth-child(1), .vf-table td:nth-child(1) { width: 90px; }   /* 구분 — 칩 66+여백 */
.vf-table th:nth-child(2), .vf-table td:nth-child(2) { width: 260px; }  /* 항목 */
.vf-table th:nth-child(3), .vf-table td:nth-child(3) { width: 70px; }   /* 기준 */
.vf-table th:nth-child(4), .vf-table td:nth-child(4) { width: 60px; }   /* +공차 */
.vf-table th:nth-child(5), .vf-table td:nth-child(5) { width: 60px; }   /* -공차 */
.vf-table th:nth-child(6), .vf-table td:nth-child(6) { width: 130px; }  /* 내부 관리(08-03 13차 ② — 열 추가로 판정·조치 nth 한 칸 이동, min-width 990 재계산) */
.vf-table th:nth-child(8), .vf-table td:nth-child(8) { width: 92px; }   /* 판정 */
.vf-table th:nth-child(9), .vf-table td:nth-child(9) { width: 58px; }   /* 조치(직접 행 삭제) — 측정값(7열)만 폭 미지정 = 잔여 */
.vf-table td.vf-in, .vm-table td.vf-in { background: var(--in-tint); }  /* 내부 관리 = 웜 틴트(rev02 S3 공통 짝) */
.vf-table td { height: 26px; } /* 행 26px(07-28 — 측정 표 4종 통일) */
.vf-table td.meas-td { padding: 0; }
.vf-table input.meas, .vf-table select.meas { width: 100%; height: 26px; border: 0; border-radius: 0; background: transparent; padding: 0 8px; font: inherit; font-size: 12.5px; font-weight: 700; text-align: center; }
.vf-table input.meas:focus, .vf-table select.meas:focus { outline: 2px solid var(--brand); outline-offset: -2px; background: #fff; }
.vf-table .meas.ng { background: var(--danger-bg); border: 0; color: var(--danger); font-weight: 700; }
/* NG였던 항목 행 = 앰버 틴트(rev02 S5 — 전 치수를 깔면서 재측정 대상이 한눈에. 'NG 항목' 칩과 같은 앰버 축 —
   빨강은 "지금 NG"(측정 셀 .ng) 전용이라 안 쓴다). 틴트행 격자선 §4-K: 옅은 앰버라 기본 선 대비 유지 실측 */
.vf-table tr.vf-ng td { background: var(--warn-bg); }
.vf-table tr.vf-ng td.meas-td { background: var(--warn-bg); }

/* ── 마스터 07-27 개선 ── */
/* ⑤ 읽기 전용 잠금 버튼 — 실제 차단은 캡처 리스너(클릭 시 토스트), 이건 누르기 전의 사전 시각 신호 */
.btn.locked { opacity: .45; }
/* ⑦ 편집 팝업 섹션 헤더(제품·금형 21필드 구획 — 기본/규격·중량/후처리/재고·계획) */
.fsec { font-size: 12.5px; font-weight: 700; color: var(--brand-dark); margin: 18px 0 10px; padding-top: 14px; border-top: 1px solid var(--line); }
.fsec.first { margin-top: 8px; padding-top: 0; border-top: none; } /* 섹션 제목(제품 정보) 아래 첫 중분류 — 붙지 않게(07-30) */
/* 좌우 2단 구획의 시작 구분선은 pf2col이 전폭 1줄로 담당 — 컬럼별 fsec 선 2토막(가운데 끊김) 방지 */
.pf2col { border-top: 1px solid var(--line); margin-top: 18px; }
.pf2col > div > .fsec:first-child { border-top: none; padding-top: 0; margin-top: 14px; }
/* 폼 grid 안 검색형 셀렉트(제품 콤보) = 칸 전폭 — 기본 140px 고정폭이 grid 셀과 어긋나는 것 방지 */
.field .ssel { width: 100%; min-width: 0; }
.field .ssel .ssel-in { width: 100%; min-width: 0; box-sizing: border-box; }
/* 제품 편집 폼 = 사장님 시안 배치(07-30): 기본 정보 전폭 1줄 → 좌(원소재 5칸·후처리 3칸×3줄) / 우(금형 규격 3칸·재고·계획 2×2)
   ★grid 블로우아웃 가드: input의 암묵 min-width(auto)가 칸 수만큼 쌓여 팝업 밖으로 넘친다 — min-width:0 필수 */
.pf2col { display: grid; grid-template-columns: 1fr 1fr; gap: 0 32px; align-items: start; }
.pf2col > div { min-width: 0; }
.pf2col .field, .pf2col .field input, .pf2col .field select { min-width: 0; }
.form-grid.pf-basic .field, .form-grid.pf-basic .field input, .form-grid.pf-basic .field select { min-width: 0; }
/* 고객사·제품군·품명(넓게)·강종·상태 — 상태(2택)는 값이 짧아 고정 96px, 남는 폭은 품명이 흡수(07-31) */
.form-grid.pf-basic { grid-template-columns: 1fr 1fr 1.6fr 1fr 96px; }
/* 원소재 5칸 = 폭 상한 128px(07-30 사용자 "가로폭 조금 줄여") — 숫자 칸이 전폭을 먹지 않게, 남는 폭은 여백 */
.form-grid.pf-mat { grid-template-columns: repeat(4, minmax(0, 128px)); justify-content: start; } /* 08-12: 7칸(T·W·P·Hv·비중·LOSS·단중) = 4+3 두 줄 */
.form-grid.pf-fin { grid-template-columns: repeat(3, 1fr); }        /* 후처리N | 협력업체1 | 협력업체2 */
.form-grid.pf-msz { grid-template-columns: repeat(3, minmax(0, 128px)); justify-content: start; } /* 제품 규격 3칸 — 원소재와 동일 폭 규격 */
.form-grid.pf-plan { grid-template-columns: 1fr 1fr; }              /* BOX·우선순위 / 기준일·기초재고 */
/* 금형(차수) 구획(07-30 3차 — "한 덩어리를 찢지 않는다"): 차수 1개 = 한 줄(번호·열·상태·규격·운영·삭제).
   전부 즉시 저장 — dirtyClose 제외 축(.pfm-sec). 제목 옆 힌트가 '번호 자동 부여' 설명을 담당. */
.fsec .fsec-hint { font-weight: 400; font-size: 12px; color: var(--muted); margin-left: 10px; }
/* ★운영 칩 고정폭 슬롯 + 버튼 우측 고정 그룹(08-04 사장님 — '수리중' 칩이 끼면 [도면]·[삭제]가 줄바꿈으로 밀리던 것):
   칩 유무와 무관하게 전 행이 같은 자리 — max-width도 슬롯(64+gap) 몫만큼 재계산(§4-O 열 추가 규칙). */
/* wrap 유지(1024px 등 좁은 화면 가로 넘침 방지) — 슬롯 덕에 전 행 내용 폭이 같아 꺾여도 균일(버튼 정렬 유지) */
.pfm-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 8px; max-width: 972px; }
.pfm-row.pfm-add { margin: 2px 0 0; }
.pfm-id { font-weight: 700; min-width: 96px; }
.pfm-lbl { font-size: 12px; color: var(--muted); margin-left: 14px; white-space: nowrap; }
.pfm-row input[type="number"] { width: 64px; }
.pfm-row input.num-in { width: 96px; }
.pfm-x { color: var(--muted); }
.pfm-st { width: 64px; flex: 0 0 auto; display: inline-flex; justify-content: center; }
.pfm-actions { margin-left: auto; display: inline-flex; gap: 8px; flex: 0 0 auto; }
@media (max-width: 1100px) { .pf2col { grid-template-columns: 1fr; } .form-grid.pf-mat { grid-template-columns: repeat(3, minmax(0, 128px)); } }
/* ② 누락 칩 진입 강조 — 편집 팝업이 열리며 해당 입력칸에 파란 외곽선(1.8초) */
.f-flash { outline: 2px solid var(--brand); outline-offset: 1px; }
/* ⑪ 이력 유형 구분(대분류) 서브헤더 행 */
.mst tr.group-h td { background: var(--bg-soft); color: var(--muted); font-weight: 700; font-size: 12px; height: 26px; padding-top: 0; padding-bottom: 0; }

/* EMR 차트 부서 라벨(07-27 A안) — 섹션 기록 주체 명시. 칩이 아니라 옅은 테두리 태그(칩 소음 최소화 컨셉) */
.dept-lbl { font-size: 11.5px; font-weight: 700; color: var(--muted); border: 1px solid var(--line); border-radius: 6px; padding: 1px 7px; }
/* 파란 thead 위 부서 태그(08-03 개발·Trial 표 헤더) — 기본색(뮤트+회색 테두리)은 파란 솔리드 배경에서 대비가 죽는다
   (§4-O "새 위치에 공용 클래스를 쓸 땐 그 스코프 규칙 확인" — .sub와 같은 계열 8번째 사례) */
thead .dept-lbl { color: var(--brand-bg-2); border-color: rgba(255, 255, 255, .45); }
/* 상세 팝업 표 폭 규격(07-27 제안2) — 전폭 균등 분배로 늘어지던 표들 */
.vm-table { table-layout: fixed; width: 100%; }   /* 수리 상세 검증 측정 기록: 항목220·기준100·내부 관리140·측정값120·판정80·스페이서=잔여 (08-03 13차 ② 열 추가 재계산) */
.vm-table td { height: 32px; }
.vm-table th:nth-child(1), .vm-table td:nth-child(1) { width: 220px; }
.vm-table th:nth-child(2), .vm-table td:nth-child(2) { width: 100px; }
.vm-table th:nth-child(3), .vm-table td:nth-child(3) { width: 140px; }  /* 내부 관리 */
.vm-table th:nth-child(4), .vm-table td:nth-child(4) { width: 120px; }  /* 측정값 */
.vm-table th:nth-child(5), .vm-table td:nth-child(5) { width: 80px; }   /* 판정 */
.cpv-table { table-layout: fixed; width: 100%; }  /* 수리 상세 조치 부품: 위치200·P/N=잔여·Rev90·구분80 */
.cpv-table td { height: 32px; }
.cpv-table th:nth-child(1), .cpv-table td:nth-child(1) { width: 200px; }
.cpv-table th:nth-child(3), .cpv-table td:nth-child(3) { width: 90px; }
.cpv-table th:nth-child(4), .cpv-table td:nth-child(4) { width: 80px; }
/* 검사 상세 치수 표: 값 폭 기준 고정(비고=잔여). 좁으면 표 내부 가로 스크롤(min-width) */
/* 07-28: '내부 관리' 칼럼(7) 삽입 — Cav. 이후 한 칸씩 밀림. min-width 1080+110 */
.dim-table { table-layout: fixed; width: 100%; min-width: 1190px; }
.dim-table th:nth-child(1), .dim-table td:nth-child(1) { width: 100px; }  /* 그룹 */
.dim-table th:nth-child(2), .dim-table td:nth-child(2) { width: 260px; }  /* 항목 */
.dim-table th:nth-child(3), .dim-table td:nth-child(3) { width: 90px; }   /* 관리구분 */
.dim-table th:nth-child(4), .dim-table td:nth-child(4) { width: 70px; }   /* 기준 */
.dim-table th:nth-child(5), .dim-table td:nth-child(5) { width: 60px; }   /* +공차 */
.dim-table th:nth-child(6), .dim-table td:nth-child(6) { width: 60px; }   /* -공차 */
.dim-table .dimin-col { width: 110px; }  /* 내부 관리(07-28) — 07-29 클래스 폭 전환: 내부 기준 없는 검사는 칼럼 자체 생략 */
/* ★피벗(07-28 사용자 — 항목 1행 × SPL 가로 칼럼, 검사 입력과 동일 문법): 7열부터 측정 70 균일(내부 관리는 .dimin-col 제외 — 칼럼 유무와 무관), 비고=잔여·삭제 56 */
.dim-table th:nth-child(n+7):not(.dimin-col):not(.note-col):not(.del-col), .dim-table td:nth-child(n+7):not(.dimin-col):not(.note-col):not(.del-col) { width: 70px; }
.dim-table .del-col { width: 56px; }
.dim-table td.note-col { padding-top: 0; padding-bottom: 0; } /* .note-in 26px가 행(26px)을 안 키우게 */

/* 수리 상세 라벨|내용 표(07-27 사장님) — 텍스트 항목의 파란 바 제목을 표 안 라벨 칼럼으로(헤더 난립 해소) */
.kv-table { table-layout: fixed; width: 100%; }
.kv-table td { height: 32px; }
.kv-table td.k { width: 130px; background: var(--bg-soft); color: var(--muted); font-weight: 700; font-size: 12px; text-align: center; }
/* 팝업 안 카테고리 헤더 아래 첫 표 — hist-sec 기본 상단 간격은 카테고리 헤더가 담당 */

/* EMR 부서 요약 = 담백한 1줄(07-27 사장님 — 생산 판단 .pj-stat 문법. 숫자 = 라벨과 동일 12.5px, 볼드로만 구분).
   margin-top 12 = 위 기본정보 kv와의 간격(붙어 보이던 것) */
/* 검사 상세 치수 표(07-27 사장님) — 측정값 값 = 오른쪽 정렬(헤더는 표준 가운데 유지) */
.dim-table input.meas { text-align: right; padding-right: 8px; } /* 우측정렬 값이 세로선에 붙지 않게 — .num 셀 8px 규격(rev11 사장님) */
.dim-table td.meas-td { text-align: right; }
.dim-table td.meas-td > span { padding-right: 8px; } /* 열람 전용(잠금) 값 = span — input과 같은 8px(rev11 사장님 "값이 선에 붙어있어") */

/* 양식 예시 미니 격자(07-27) — 엑셀 화면 인상: 입력자가 "내 엑셀이 이 모양인가"만 눈으로 대조 */
.xg { border-collapse: collapse; margin: 6px 0 0; }
.xg th, .xg td { border: 1px solid var(--line-2); padding: 3px 12px; font-size: 12px; height: 24px; text-align: left; background: #fff; }
.xg th { background: var(--gray-bg); font-weight: 700; text-align: center !important; }

/* ⑫ 데이터 폭에 맞는 마스터 표(07-27 2차) — 단순 목록(설비·작업자·이력 유형·관리구분·부품 코드)이
   전폭으로 늘어져 휑하던 것: 패널·표가 내용 폭만 차지(집중성). 컬럼은 데이터 최대치 기준 고정폭. */
.panel.fit { width: fit-content; min-width: 560px; max-width: 100%; }
.panel.fit .sub, .panel.fit .hint { max-width: 720px; } /* 긴 설명문이 fit-content 폭을 밀어내는 것 방지 */
.mst.fit { width: auto; table-layout: fixed; }
/* 설비: 설비No 90 · 설비명 200 · 톤수 80 · Core 100 · Die H 80 (550) */
.press-table th:nth-child(1) { width: 90px; }
.press-table th:nth-child(2) { width: 200px; }
.press-table th:nth-child(3) { width: 80px; }
.press-table th:nth-child(4) { width: 100px; }
.press-table th:nth-child(5) { width: 80px; }
/* 작업자: 소속 110 · 직급 100 · 이름 160 · 근무 상태 110 (480) */
.worker-table th:nth-child(1) { width: 110px; }
.worker-table th:nth-child(2) { width: 100px; }
.worker-table th:nth-child(3) { width: 160px; }
.worker-table th:nth-child(4) { width: 110px; }
/* 이력 유형: 순서 90 · 유형명 150 · 문제성 80 · 내용 프리셋 460 (780) */
.et-table th:nth-child(1) { width: 90px; }
.et-table th:nth-child(2) { width: 150px; }
.et-table th:nth-child(3) { width: 80px; }
.et-table th:nth-child(4) { width: 460px; }
/* 관리구분: 순서 90 · 이름 170 · NG 판정 170 (430) */
.mc-table th:nth-child(1) { width: 90px; }
.mc-table th:nth-child(2) { width: 170px; }
.mc-table th:nth-child(3) { width: 170px; }
/* 부품 코드: 코드 70 · 풀네임 210 · 중구분 100 · 계열 110 · 출처 80 (570) */
.pc-table th:nth-child(1) { width: 70px; }
.pc-table th:nth-child(2) { width: 210px; }
.pc-table th:nth-child(3) { width: 100px; }
.pc-table th:nth-child(4) { width: 110px; }
.pc-table th:nth-child(5) { width: 80px; }

/* ★마스터 제품·금형 표(08-12 사장님) — 규격 컬럼 확장(원소재 T/W/P/Hv/비중/LOSS/단중 · 제품 규격 · 금형 규격 분리).
   전 컬럼 고정폭(텍스트 최대치 기준, §4-H) + 표 내부 가로 스크롤(마스터 = 상시 열람 화면 아님 — 폭이 길어져도 된다).
   폭: No 56 · 고객사 70(전역) · 제품군 96 · 품명 270(우선순위 칩+누락 점+차수 칩 동거 — 08-12 2차) · 순회 74 ·
   강종 132("SUS316HN1_1/4H"=14자) · T/W/P/비중 64 · Hv 84("180~220") · LOSS 56 · 단중 72 ·
   제품/금형 규격 132("17.4×17.64×4.62"=15자 실측) · 후처리 84. 누락 정보 = 품명 옆 빨간 점+hover 팝업(전용 컬럼 폐지). */
.prod-table { table-layout: fixed; } /* 칼럼 폭·min-width = masters.js PCOLS(colgroup, 09-07 tablekit — 구 th:nth-child 폭 규칙 폐지: 칼럼 숨김 시 index가 밀린다) */
.prod-table td { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* 고정폭 표 — 넘치면 말줄임+툴팁 */
/* 품명 = 왼쪽 sticky(가로 스크롤해도 "어떤 제품의 정보인지" 보이게, 08-12 사장님).
   sticky 셀은 배경이 비면 밑 컬럼이 비쳐 보인다 — 행 상태(틴트·마감·호버)별 배경을 명시한다. */
.prod-table th.col-name, .prod-table td.col-name { position: sticky; left: 0; z-index: 1; background: #fff; border-right: 1px solid var(--line); }
.prod-table thead th.col-name { z-index: 3; background: var(--brand); }
.prod-table tbody tr:hover td.col-name { background: var(--hover); }
.prod-table tbody tr.row-miss td.col-name { background: var(--in-tint); }
.prod-table tbody tr.row-miss:hover td.col-name { background: var(--warn-bg); }
.prod-table tbody tr.row-closed td.col-name { background: var(--done-row); }
/* 행 색 마킹(rc1~3, 09-07 tablekit)도 sticky 품명 칸에 재선언 — 안 하면 흰 sticky 배경이 행 색을 가린다 */
.prod-table tbody tr.rc1 td.col-name { background: var(--mark-blue); }
.prod-table tbody tr.rc2 td.col-name { background: var(--mark-amber); }
.prod-table tbody tr.rc3 td.col-name { background: var(--mark-green); }
/* 품명 셀 내부 배치(08-12 2차): 칩 고정 + 품명 가변(ellipsis) + 누락 점 + 차수 칩 오른쪽 끝(§4-O flex 압착 가드) */
.prod-table .pn-cell { display: flex; align-items: center; gap: 6px; min-width: 0; width: 100%; }
.prod-table .pn-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prod-table .pn-stage { margin-left: auto; display: inline-flex; gap: 4px; flex: 0 0 auto; }

/* ★치수 측정 헤더 1210px 이하 1줄 유지(08-11 백로그 해소) — 08-07 버튼명이 길어져 좁은 창에서 2줄로 꺾였다.
   좁은 창에서만 버튼·라벨을 눌러 한 줄을 지킨다(실사용 1456px은 원래 규격 그대로). */
@media (max-width: 1210px) {
  .dim-meas-head { flex-wrap: nowrap; }
  .dim-meas-head h2 { white-space: nowrap; }
  .dim-meas-head .btn { padding: 3px 8px; font-size: 11.5px; white-space: nowrap; }
  .dim-meas-head .smp-pick > span:first-child { display: none; } /* '측정 SPL' 라벨 접기 — 셀렉트만 남긴다 */
}


/* ═══════════ tablekit(09-07 — 3200 견적앱 이식): 우클릭 팝업·행 색·셀 형광펜·셀 메모·칼럼 숨김·복수 선택·범위 필터·형광펜 문법 ═══════════ */
/* 행 색 마킹(rc1~3) — 로직 없는 임의 구분. sticky 칸이 있는 표는 그 칸에도 배경을 재선언할 것 */
table tr.rc1 td { background: var(--mark-blue); }
table tr.rc2 td { background: var(--mark-amber); }
table tr.rc3 td { background: var(--mark-green); }
table tr.rsink { opacity: .62; } /* 내려두기(표 맨 아래 그룹) = 흐림 */
table tbody tr.rowsel td { box-shadow: inset 0 0 0 999px rgba(61, 110, 181, .14); } /* 복수 선택 = 파란 인셋 틴트 */
/* 우클릭 통합 팝업(.rcpop): 왼쪽 [행]/[셀]/[메모] 박스 2~3단 + 오른쪽 동작 버튼 스택 */
.rcpop { position: fixed; z-index: 320; background: #fff; border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 8px 26px rgba(0, 0, 0, .18); padding: 8px; display: flex; gap: 8px; align-items: stretch; }
.rcpop .rccol { display: flex; flex-direction: column; gap: 6px; }
.rcpop .rcrow { display: flex; gap: 5px; align-items: center; border: 1px solid var(--line); border-radius: 8px; padding: 4px 6px; }
.rcpop .rclbl { font-size: 12px; color: var(--ink, var(--ink)); font-weight: 700; white-space: nowrap; padding: 0 4px 0 1px; min-width: 24px; }
.rcpop .rcacts { display: flex; flex-direction: column; gap: 6px; }
.rcpop .rcacts .swx { flex: 1; min-height: 30px; border-radius: 8px; padding: 0 14px; }
.rcpop .sw { width: 28px; height: 22px; border: 1px solid var(--line); border-radius: 4px; cursor: pointer; padding: 0; }
.rcpop .sw.rc1 { background: var(--mark-blue); }
.rcpop .sw.rc2 { background: var(--mark-amber); }
.rcpop .sw.rc3 { background: var(--mark-green); }
.rcpop .sw.on { outline: 2px solid var(--brand); outline-offset: 1px; }
.rcpop .sw.none { background: #fff; position: relative; }
.rcpop .sw.none::after { content: '∅'; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 13px; color: var(--muted, var(--muted)); }
.rcpop .swx { height: 22px; padding: 0 8px; border: 1px solid var(--line); border-radius: 4px; background: #fff; font: inherit; font-size: 12px; cursor: pointer; white-space: nowrap; color: var(--ink, var(--ink)); }
.rcpop .swx.on { outline: 2px solid var(--brand); outline-offset: 1px; }
.rcpop .swx.ngw { color: var(--danger-ink); font-weight: 700; }
.rcpop .sw.hy { background: var(--hl-y); }
.rcpop .sw.hr { background: var(--hl-r); }
.rcpop .sw.hg { background: var(--hl-g); }
/* 셀 형광펜 — td 내용을 감싼 span(글자 뒤 배경만) */
.cellhl { padding: 1px 3px; border-radius: 2px; }
.cellhl.hy { background: var(--hl-y); }
.cellhl.hr { background: var(--hl-r); }
.cellhl.hg { background: var(--hl-g); }
td .cellhl:empty { display: inline-block; min-width: 14px; height: 13px; vertical-align: -2px; }
/* 셀 메모 — 칸 왼쪽 위 파란 삼각형 + 호버 메모지 + 편집 팝업 */
td.hasmemo { position: relative; }
td.hasmemo::before { content: ''; position: absolute; left: 0; top: 0; width: 0; height: 0; pointer-events: none; z-index: 1;
  border-style: solid; border-width: 8px 8px 0 0; border-color: var(--brand) transparent transparent transparent; }
.memo-pop { position: fixed; z-index: 330; background: var(--memo-bg); border: 1px solid var(--memo-line); box-shadow: 0 4px 14px rgba(0, 0, 0, 0.16);
  padding: 6px 9px; font-size: 12.5px; color: var(--memo-ink); max-width: 260px; white-space: pre-wrap; pointer-events: none; }
.rcpop.cellmemo { display: flex; flex-direction: column; gap: 6px; padding: 8px 10px; min-width: 240px; }
.rcpop.cellmemo .memo-h { font-size: 12px; font-weight: 700; color: var(--brand-ink); }
.rcpop.cellmemo .memo-in { font: inherit; font-size: 12.5px; height: 26px; padding: 0 7px; border: 1px solid var(--line); width: 100%; box-sizing: border-box; }
.rcpop.cellmemo .memo-acts { display: flex; justify-content: flex-end; gap: 6px; }
.rcpop.cellmemo .swx.on, .rcpop .rcrow.memorow .swx.on { background: var(--brand); color: #fff; border-color: var(--brand); font-weight: 700; }
.rcpop .rcrow.memorow .memo-in { font: inherit; font-size: 12px; height: 22px; padding: 0 6px; border: 1px solid var(--line); width: 170px; }
/* 칼럼 숨김(colhide.js): th 우클릭 메뉴 + [숨김처리 n] 복원 팝업(칩 = .q-ancopy 문법) */
.rcpop.colhide { display: flex; flex-direction: column; gap: 6px; padding: 8px; }
th.ah-gap { box-shadow: inset 3px 0 0 var(--brand); }
th.ah-gap-r { box-shadow: inset -3px 0 0 var(--brand); }
.rcpop.colhide .swx { text-align: left; min-height: 26px; padding: 0 10px; }
.filterbar .colhide-host:empty, .panel-head .colhide-host:empty { display: none; }
.q-ancopy { width: max-content; max-width: 90vw; }
.q-ancopy .line { display: flex; align-items: center; gap: 8px; white-space: nowrap; }
.q-ancopy .line .k { font-size: 12.5px; font-weight: 700; color: var(--brand-ink); }
.q-ancopy .line .hint, .q-ancopy .hint { font-size: 12px; color: var(--muted, var(--muted)); }
.q-ancopy .sects { display: flex; flex-wrap: wrap; gap: 6px; }
.q-ancopy .sect { font: inherit; font-size: 12px; height: 24px; padding: 0 10px; border: 1px solid var(--line); background: #fff; color: var(--muted, var(--muted)); cursor: pointer; }
.q-ancopy .sect.on { background: var(--brand); border-color: var(--brand); color: #fff; font-weight: 700; }
.q-ancopy .acts { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
.q-colhide .sects { margin-top: 10px; max-width: 720px; }
.modal-box:has(.q-ancopy) { width: fit-content; min-width: 420px; max-width: min(1100px, 92vw); }
.modal-box:has(.q-ancopy) .modal-body { container-type: normal; } /* ★container-type: inline-size는 내용 폭 기여를 0으로 만든다 */
/* 범위 필터 [min ~ max] 단일 박스 + 그룹 라벨 칩 + 앰버 초기화 + 보기 토글 켬 */
.filterbar .fgl { font-size: 12px; font-weight: 700; color: var(--brand-ink); background: var(--brand-bg-3); padding: 2px 8px; border-radius: 6px; white-space: nowrap; }
.filterbar .rng { display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; white-space: nowrap; }
.filterbar .rng .k { color: var(--muted, var(--muted)); font-weight: 700; }
.filterbar .rngbox { display: inline-flex; align-items: center; border: 1px solid var(--line); border-radius: 6px; background: #fff; padding: 0 4px; }
.filterbar .rng input.rngin { width: 38px; text-align: center; font: inherit; font-size: 12.5px; border: none; padding: 4px 2px; background: transparent; }
.filterbar .rng .tilde { color: var(--muted, var(--muted)); padding: 0 2px; }
.btn.reset { color: var(--amber-ink, #b45f06); border-color: var(--warn-line); }
.btn.reset:hover { background: var(--warn-bg); }
.filterbar .btn.on { background: var(--brand-bg-2); border-color: var(--brand); color: var(--brand-ink); }
/* 형광펜 문법(값은 그대로, 글자 뒤 배경만) + 보기 세그먼트 토글 */
.hlv { background: var(--hl-y); padding: 2px 4px; }
.hlb { background: var(--brand-bg-3); color: var(--brand-ink); padding: 3px 6px; }
.gapp { background: var(--brand-bg-3); color: var(--brand-ink); padding: 0 5px; font-weight: 800; font-size: 11.5px; }
.hlm { background: var(--brand-bg-3); color: var(--brand-ink); padding: 2px 4px; font-weight: 800; }
.curseg { display: inline-flex; align-items: center; gap: 2px; padding: 2px; background: #fff; border: 1px solid var(--line); border-radius: 999px; }
.curseg .btn { min-width: 0; padding: 0 9px; height: 20px; line-height: 20px; font-size: 11.5px; border: none !important; border-radius: 999px; box-shadow: none; }
.curseg .btn.ghost { background: transparent !important; color: var(--muted, var(--muted)) !important; }
.curseg .btn:not(.ghost) { background: var(--brand) !important; color: #fff !important; }
/* 2줄 헤더 규격: 하위 행 sticky 겹침 방지(--th-h = 1줄 높이) + 마지막 하위 th 세로선 복원 + 파란 헤더 경계선 흰색 */
table.h2 thead tr:nth-child(2) th { top: var(--th-h, 30px); }
table.h2 thead tr:nth-child(2) th:last-child { border-right: 1px solid rgba(255, 255, 255, 0.55); }
table.h2 thead th { border-color: rgba(255, 255, 255, 0.55); }
@media print { .rcpop, .memo-pop { display: none !important; } }
/* 행 색이 마감/누락 행 틴트(.row-closed/.row-miss — 특이성 0,2,2)에 지던 것 — 마킹 색이 우선(09-07) */
table tr.row-closed.rc1 td, table tr.row-miss.rc1 td { background: var(--mark-blue); }
table tr.row-closed.rc2 td, table tr.row-miss.rc2 td { background: var(--mark-amber); }
table tr.row-closed.rc3 td, table tr.row-miss.rc3 td { background: var(--mark-green); }

/* ===== ★우클릭 업무 허브(09-09 사장님) — hub.js. 640px · 유동 높이(화면을 넘길 때만 내부 스크롤) · 7구획.
   폰트 = 12.5px 한 단계(제목 이름 13.5만 예외) · 칩 12 · 표 = 옅은 테두리(헤더 없음) — 사장님 09-09 2차 지적(폰트 제각각·설명 두서없음) ===== */
.hub-pop { position: fixed; z-index: 95; width: 740px; max-width: 94vw; background: #fff; border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 16px 48px rgba(0,0,0,.28); font-size: 12.5px; line-height: 1.5; color: var(--ink); }
.hub-pop .hub-loading { padding: 18px 16px; color: var(--muted); }
.hub-pop .hub-hd { display: flex; align-items: center; gap: 8px; padding: 11px 16px; border-bottom: 1px solid var(--line); flex-wrap: wrap; cursor: move; user-select: none; } /* 제목줄 드래그 이동(모달과 동일) */
.hub-pop .hub-hd .nm { font-weight: 800; font-size: 13.5px; }
.hub-pop .hub-hd .x { margin-left: auto; color: var(--muted); font-size: 15px; cursor: pointer; background: none; border: 0; }
.hub-pop .hub-hd .hub-urg { margin-left: auto; } /* 급함 칩 = 오른쪽 끝(✕ 앞) */
.hub-pop .hub-hd .hub-urg + .x { margin-left: 6px; }
.hub-pop .chip.sm, .hub-pop .chip, .hub-pop .hub-acts .btn { height: 22px; font-size: 12.5px; line-height: 1; padding: 0 9px; border-radius: 8px; box-sizing: border-box; } /* 팝업 안 칩·업무 버튼 = 한 규격(사장님 09-09 5차) */
/* 흐름 띠 — 점·선은 같은 y(top 7px 중심)에 절대 배치, 칸은 위 정렬(가운데 정렬이면 짧은 칸의 점이 밀린다 — 09-09 실측) */
.hub-flow { display: flex; align-items: flex-start; padding: 26px 16px 14px; position: relative; } /* 위아래 여유 +10(사장님 09-09 3차) */
.hub-flow .hub-flow-note { position: absolute; right: 16px; top: 6px; } /* 금형 조치 중 표시 — 띠 오른쪽 위 */
.hub-flow .st { flex: 1; text-align: center; font-size: 12.5px; color: var(--dim); position: relative; padding-top: 18px; line-height: 1.4; min-height: 52px; }
.hub-flow .st::before { content: ''; position: absolute; top: 3px; left: 50%; width: 9px; height: 9px; border-radius: 50%; background: var(--line); transform: translateX(-50%); z-index: 1; }
.hub-flow .st::after { content: ''; position: absolute; top: 7px; left: 50%; right: -50%; height: 1px; background: var(--line); }
.hub-flow .st:last-child::after { display: none; }
.hub-flow .st.done { color: var(--muted); } .hub-flow .st.done::before { background: var(--ok); } .hub-flow .st.done::after { background: var(--ok); }
.hub-flow .st.cur { color: var(--brand-dark); font-weight: 800; } .hub-flow .st.cur::before { background: var(--brand); width: 13px; height: 13px; top: 1px; box-shadow: 0 0 0 3px var(--chip); }
.hub-flow .st.stop { color: var(--danger); font-weight: 800; } .hub-flow .st.stop::before { background: var(--danger); width: 13px; height: 13px; top: 1px; box-shadow: 0 0 0 3px var(--danger-bg-2); }
.hub-flow .st .sub { display: block; font-size: 12.5px; font-weight: 400; color: var(--muted); }
/* 상태 칩 줄 + 한 줄 문장 */
/* 라벨 행(제품 현황 / 업무 구분) — 라벨 64px + 값 1줄 */
.hub-line { display: grid; grid-template-columns: 64px 1fr; align-items: center; gap: 10px; padding: 0 16px; }
.hub-line .lbl { font-size: 12.5px; color: var(--muted); font-weight: 700; white-space: nowrap; }
.hub-line .vals { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; min-width: 0; }
.hub-chips { padding-top: 4px; padding-bottom: 12px; }
.hub-hd + .hub-chips { padding-top: 18px; } /* 흐름 띠가 없는 팝업(금형 목록 등) — 제목과 제품 현황 사이 여유 */
.hub-warn { margin: 0 16px 10px; padding: 7px 10px; background: var(--warn-bg-2); color: var(--warn-ink); border-radius: 6px; font-size: 12.5px; }
.hub-acts { padding-bottom: 16px; }
.hub-acts .vals { flex-wrap: wrap; } /* 넘치면 줄바꿈(09-09 6차 — 팝업 밖으로 삐져나오던 것) */
/* 업무 버튼 = 제품 현황 칩과 같은 알약 모양 1줄(사장님 09-09 3차) — 파랑 = 주 행동, 흰 테두리 = 열람 */
.hub-acts .btn { font-weight: 700; white-space: nowrap; } /* 규격(22px·12.5·8px)은 위 공통 규칙 */
.hub-acts .btn.ghost { font-weight: 400; }
.hub-acts .btn.hub-none { background: var(--closed); border-color: var(--closed); color: var(--dim); opacity: 1; cursor: default; }
.hub-acts .btn.hub-dept { background: #fff; border-color: var(--brand); color: var(--brand); }
/* 판단 근거 · 최근 이력 = 2단, 각각 옅은 테두리 표 */
.hub-two { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; padding: 10px 16px 6px; border-top: 1px solid var(--line); }
.hub-two > div { min-width: 0; }
.hub-pop .ttl { font-size: 12.5px; color: var(--muted); font-weight: 700; margin-bottom: 5px; }
.hub-tbl { width: 100%; border-collapse: collapse; border: 1px solid var(--line-soft); font-size: 12.5px; table-layout: fixed; }
.hub-tbl td { padding: 4px 8px; border-bottom: 1px solid var(--gray-bg); height: 26px; vertical-align: middle; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hub-tbl tr:last-child td { border-bottom: 0; }
.hub-tbl td.k { color: var(--muted); width: 96px; border-right: 1px solid var(--gray-bg); background: var(--bg-soft); }
.hub-tbl td.v { font-weight: 700; font-variant-numeric: tabular-nums; }
.hub-tbl td.v .x { font-weight: 400; color: var(--muted); margin-left: 4px; }
.hub-tbl td.v.neg { color: var(--danger-ink); } .hub-tbl td.v.warn { color: var(--warn-ink); } .hub-tbl td.v.ok { color: var(--ok); }
.hub-two > div:last-child .hub-tbl td.k { width: 54px; }
/* 부서 현황 */
.hub-depts { padding: 10px 16px 14px; }
.hub-depts .kv { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
.hub-depts .row { display: grid; grid-template-columns: 44px auto 1fr; gap: 8px; align-items: center; height: 26px; flex-wrap: nowrap; }
.hub-depts .k { color: var(--muted); font-size: 12.5px; }
.hub-depts .k::before { content: '•'; margin-right: 5px; color: var(--dim); } /* 점 구분(사장님 09-09 3차) */
.hub-depts .t { font-weight: 400; color: var(--muted); font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hub-depts .row.me .k { color: var(--brand); font-weight: 800; }
.hub-foot { display: flex; align-items: center; gap: 8px; padding: 8px 16px; border-top: 1px solid var(--line); color: var(--muted); font-size: 12.5px; background: var(--bg-soft); border-radius: 0 0 10px 10px; }
.hub-foot .btn.sm { height: 28px; font-size: 12.5px; }
.hub-foot .btn.sm.has { font-style: italic; color: var(--ink); max-width: 360px; overflow: hidden; text-overflow: ellipsis; }
.hub-foot .btn.sm:last-child { margin-left: auto; }
/* 할 일 점(추가 제안 5) — 상태 칸 옆. 빨강 = 급함, 앰버 = 할 일 있음 */
.hub-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-left: 6px; vertical-align: 1px; }
.hub-dot.neg { background: var(--danger); } .hub-dot.amb { background: var(--warn); }
/* 오늘 할 일(추가 제안 6) — 부서 화면 상단 한 장 */
.hub-todo .table-wrap { max-height: calc(100vh - 210px); } /* 팝업 = 화면 세로를 충분히(사장님 09-09 7차 — 행 2배) */
.hub-todo-table td.strong { font-weight: 700; }
.hub-todo-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
/* 문제 카드(moldcard.js) */
.mold-card .mc-sec { margin-top: 18px; } /* 구획 간격(사장님 09-09 4차) */
.mold-card .mc-sec .panel-head { margin-bottom: 8px; }
.mold-card .mc-sec .table-wrap { margin-top: 4px; }
.mold-card .mc-sec.mc-dim { opacity: .55; }
.mold-card .kv-table td.k { width: 96px; }
.mold-card .kv-table td, .mold-card .ngref-table td { border-bottom-color: var(--line-soft); } /* 카드 안 표 선 = 옅게(사장님 09-09 5차 — 전역 #c4ccd7는 매트릭스용) */


/* ── 칼럼 묶음 접기/펼치기(09-12 — 3200 cg.js 이식, colhide.js head2 자동 배선 · 3100 동일 블록) ── */
/* 묶음 th = 라벨 + [−] · 접힘 = 26px 스텁(th.cgs [+] / td.cgx). 버튼 = currentColor(v5 밝은 머리·파란 머리 공통), 규격 = §4-S 표 안 컨트롤 22 · 12/800 · 직각 */
th .cgh { display: inline-flex; align-items: center; justify-content: center; gap: 6px; width: 100%; }
.cgb { border: 1px solid currentColor; background: transparent; color: inherit; width: 22px; height: 22px; line-height: 1; padding: 0; font: inherit; font-size: 12px; font-weight: 800; cursor: pointer; flex: none; opacity: .72; }
.cgb:hover { opacity: 1; background: color-mix(in srgb, currentColor 14%, transparent); }
th.cgs { padding: 0 !important; text-align: center !important; }
td.cgx { background: var(--bg-soft); padding: 0 !important; }
.hub-todo-table td.sent { white-space: normal; max-width: 460px; } /* 업무 칸(구 td:nth-child(8) — 묶음 접기로 index가 밀려 클래스로) */
