/* ═══════════════════════════════════════════════════════════════════════════
   이 보드 고유 화면 규칙
   ───────────────────────────────────────────────────────────────────────────
   공통 규칙은 @marunex/board-core 의 styles.css 가 준다. 여기 남은 것은 이
   프로젝트에만 있는 화면(협약 성과지표·사출기·추천·서열 …)과, 공통과 달라진 곳이다.

   ★ 이 파일은 꾸러미 styles.css **뒤에** 실린다. 같은 선택자면 여기가 이긴다.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 컨텐츠 영역 ─────────────────────────────────────────────────── */
.content {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 24px 28px;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

/* 세로가 짧은 화면에서 여백을 조인다.

   ★ **.content 를 여기 남겼으니 .content 의 @media 규칙도 여기 있어야 한다.**
     미디어 질의는 명시도를 올리지 않는다 — 기본 규칙만 이 파일(나중 로드)로 오고
     이것들이 꾸러미(먼저 로드)에 남으면 순서가 뒤집혀 **오류 없이 죽는다.**
     실제로 그랬다: 통합 전과 견줘 보니 880x760 에서 여백이 24/28 로 남아 있었고
     (원래는 16/22) 그 20px 이 표 열 폭까지 통째로 밀고 있었다.
     cheil-poc 은 처음부터 이렇게 함께 옮겨 두었다. */
@media (max-height: 780px) {
  .content { padding: 16px 22px; gap: 14px; }
}

@media (max-height: 700px) {
  .content { padding: 12px 20px; gap: 10px; }
}

@media (max-height: 820px) {
  .content { padding: 12px 18px; gap: 10px; }
}

/* 노트북 등 세로가 짧은 화면: 상단 고정 블록을 줄여 차트 자리를 확보 */
@media (max-height: 860px) {
  /* ※ KRI 배너(파란 줄) 관련 규칙은 여기 두지 않는다 — 아래 §KRI 배너 두께 조이기
     블록이 파일 뒤쪽에 있어 같은 특정도면 그쪽이 이긴다(여기 적으면 조용히 죽는다).
     짧은 창용 추가 압축은 그 블록 바로 뒤 미디어쿼리에 있다. */
  #layoutRoot.home-fill .home-kpi { padding: 10px 16px; }
  #layoutRoot.home-fill .home-kpi-v { font-size: 1.6rem; }
}

/* ── 홈 KRI 배너(파란 줄) 두께 조이기 ────────────────────────────────────────
   ★ 홈 전용이다(.home-fill). 같은 클래스를 쓰는 다른 화면의 총계 박스(.kri-totals)는
     건드리지 않는다 — 거기선 이 박스가 화면의 주인공이지만, 홈에서는 아래 차트 4장이
     주인공이고 이 줄은 고정 높이(flex:0 0 auto)라 두꺼워진 만큼 차트가 그대로 눌린다.
   ★ 줄인 건 여백·게이지 두께뿐이고 글자 크기·대비는 유지한다(§6-E 가독 기준). */
#layoutRoot.home-fill > .home-kri { padding: 8px 14px; }
#layoutRoot.home-fill .home-kri-cards { gap: 10px; }
#layoutRoot.home-fill .home-kri-card { padding: 7px 12px; }
#layoutRoot.home-fill .home-kri-goal { line-height: 1.35; }
#layoutRoot.home-fill .home-kri-goal b { font-size: 15px; }
#layoutRoot.home-fill .home-kri-desc { line-height: 1.4; margin-top: 3px; }
/* 진척 게이지 — 8px 는 이 카드에서 과하다. 6px 로도 채움 길이는 그대로 읽힌다 */
#layoutRoot.home-fill .kri-gauge { margin: 4px 0 3px; height: 6px; }
/* 짧은 창에서 한 단계 더 — 설명줄이 2줄로 접히는 게 이 배너 높이의 절반이라 먼저 줄인다 */
@media (max-height: 860px) {
  #layoutRoot.home-fill > .home-kri { padding: 6px 12px; }
  #layoutRoot.home-fill .home-kri-card { padding: 6px 11px; }
  #layoutRoot.home-fill .home-kri-desc { font-size: 10px; line-height: 1.35; }
}

/* ── 재고 레이어 요약 타일 (통계 카드 §6-D 하단형) ─────────────────────── */
/* ★ 이 카드의 주인공은 '완제품 재고 추이' 선그래프다. 카드 높이는 .home-bot 이
   남은 높이를 반씩 나눠 갖기 때문에 고정 — 타일을 키우면 그만큼 그래프가 눌린다.
   타일은 값 3개를 읽히게만 하면 되므로(추이·비교가 아니라 현재값) 수치는 KPI 카드보다
   한 단계 작게 잡고, 회수한 높이를 전부 그래프에 준다. 여기 값을 다시 키우지 말 것. */
#layoutRoot.home-fill .home-inv-row { gap: 10px; }
#layoutRoot.home-fill .home-inv {
  background: var(--jv-page); border: 1px solid var(--jv-border); border-radius: var(--nu-r-large); padding: 8px 10px;
}
#layoutRoot.home-fill .home-inv-l { font-size: 11px; color: var(--jv-txt3); margin-bottom: 3px; }
#layoutRoot.home-fill .home-inv-v {
  font-size: 20px; font-weight: 700; color: var(--jv-txt1);
  font-variant-numeric: tabular-nums; line-height: 1; letter-spacing: -0.02em;
}
#layoutRoot.home-fill .home-inv-v span { font-size: 12px; font-weight: 600; color: var(--jv-txt3); margin-left: 3px; }
#layoutRoot.home-fill .home-note { font-size: 10px; line-height: 1.35; color: var(--jv-txt4); margin-top: 6px; }

/* 재고 레이어 요약 — 타일·주석은 내용 높이 유지, 미니 추이 차트가 남는 공간을 채운다 */
#layoutRoot.home-fill .home-inv-row { flex: 0 0 auto; align-items: stretch; }
#layoutRoot.home-fill .home-inv-trend-t {
  flex: 0 0 auto; margin-top: 8px; font-size: 11px; font-weight: 700; color: var(--jv-txt2);
}
/* min-height 는 '이 밑으로 줄면 선 모양을 못 읽는다'는 하한선. 창이 더 짧아지면
   아래 max-height 미디어쿼리가 이 값을 낮춘다(하한선이 카드를 넘치게 하지 않도록). */
#layoutRoot.home-fill .home-inv-trend { position: relative; flex: 1 1 auto; min-height: 120px; margin-top: 4px; }

/* 짧은 창에서의 밀집 보정 — 무스크롤 규칙과 함께 동작 */
@media (max-height: 860px) {
  #layoutRoot.home-fill .jv-kpi { padding: 11px 14px; gap: 11px; }
  #layoutRoot.home-fill .jv-kpi-ico { width: 40px; height: 40px; border-radius: var(--nu-r-large); }
  #layoutRoot.home-fill .jv-kpi-ico svg { width: 19px; height: 19px; }
  #layoutRoot.home-fill .home-kpi-v { font-size: 22px; }
  /* 재고 타일은 기본값이 이미 20px 이라 더 줄인다(여기서 키우면 그래프를 뺏는다) */
  #layoutRoot.home-fill .home-inv-v { font-size: 18px; }
  #layoutRoot.home-fill .home-inv-trend { min-height: 96px; }
}
@media (max-height: 720px) {
  #layoutRoot.home-fill .jv-kpi-ico { width: 34px; height: 34px; }
  #layoutRoot.home-fill .jv-kpi-ico svg { width: 17px; height: 17px; }
  #layoutRoot.home-fill .home-kpi-v { font-size: 19px; }
  #layoutRoot.home-fill .home-inv-v { font-size: 16px; }
  /* 미니 추이 차트도 함께 낮춘다(캡션의 기간 표기는 접음) */
  #layoutRoot.home-fill .home-inv-trend-t { margin-top: 6px; }
  #layoutRoot.home-fill .home-inv-trend-t span { display: none; }
  #layoutRoot.home-fill .home-inv-trend { min-height: 44px; }
  #layoutRoot.home-fill .home-note { margin-top: 5px; }
}
/* 로고 — 다크 배경용 흰 칩이 흰 사이드바에서 안 보이므로 칩 제거. */
.brand-ci { background: transparent; box-shadow: none; padding: 0; }
/* 머리말 영역을 나누는 경계선과 밴드 높이는 이 파일 끝의
   [좌측 메뉴 — 머리말 경계선 정렬 · 접기] 블록이 정한다(상단 바와 한 줄로 이어야 하므로).
   여기서 padding-bottom·border-bottom 을 다시 선언하지 말 것 — 두 곳이 되면 또 어긋난다. */

/* ── 아이콘 거터 ───────────────────────────────────────────────────────
   그룹명 앞 아이콘이 차지하는 폭. 하위 항목은 아이콘이 없으므로 이 폭만큼
   들여써서 "그룹명 글자"와 "하위 항목 글자"의 왼쪽 선을 맞춘다 —
   아이콘 열이 하나의 거터로 읽혀야 목록이 흐트러지지 않는다.
   아이콘 크기를 바꾸면 이 값도 같이 바꿀 것(--nav-ico + gap). */
:root {
  --nav-ico: 16px; --nav-ico-gap: 7px;
  /* 하위 항목 들여쓰기 — 사이드바 폭을 정하는 값이라 한 곳에서만 관리한다.
     예전에는 이 계산식이 기본 규칙과 압축 미디어쿼리 두 곳에 복사돼 있어서 한쪽만 고치면
     데스크톱에서만 어긋났다. 변수로 빼서 그 사고를 구조적으로 막는다.
     --nav-sub-line   가이드선의 x 위치
     --nav-sub-indent 하위 항목 글자의 x 위치 (둘 다 사이드바 안쪽 여백 기준) */
  --nav-sub-line: 14px;
  /* 33px = summary 왼쪽 padding 10 + 아이콘 16 + 갭 7.
     하위 항목 글자의 왼쪽 선을 그룹명 글자에 맞춘다(2026-09-01 요청).
     ※ 꾸러미 원본은 25px 이었다 — 사이드바 폭을 아끼려고 일부러 덜 들여썼던 값이다.
       폭 예산: 여백10 + 33 + "설비별 생산현황"(약 91) + 우여백10 + 여백10 ≈ 154px < 180px 라
       지금 메뉴에서는 넘치지 않는다. 더 긴 항목을 넣을 땐 이 계산을 다시 할 것. */
  --nav-sub-indent: 33px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   좌측 메뉴 — 머리말 경계선 정렬 · 접기(본문 전체화면)
   앞쪽 규칙과 미디어쿼리(콤팩트 max-height:820px / 데스크톱 min-width:1201px)에
   흩어져 있던 값을 여기서 확정한다. 같은 특이도면 나중 블록이 이기므로 이 블록이 정본이다.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── ① 로고 밴드 높이 = 상단 바 높이 ───────────────────────────────────────
   사이드바 로고 아래 경계선과 본문 상단 바(.topbar) 아래 경계선이 화면을 가로지르는
   "한 줄"로 이어져야 한다. 어긋나 있던 이유는 두 가지였다.
     · 높이  — 로고 밴드는 사이드바 위여백(11) + 로고(32) + 아래여백(10) = 53px 였고 상단 바는 44px
     · 색    — 로고는 --jv-border-l(연한 선), 상단 바는 --jv-border 로 서로 다른 톤이었다
   높이를 --topbar-h 한 곳에서 읽게 하고 선 색도 같은 토큰으로 맞춘다. 값을 두 곳에
   적으면 한쪽만 고쳐 다시 어긋나므로 .topbar 도 이 변수를 쓴다.
   ★ 여백은 사이드바가 아니라 .nav 가 갖는다 — 사이드바에 위여백이 있으면 로고 밴드가
     그만큼 아래로 밀려 정렬이 다시 깨진다. (box-sizing: border-box 라 44px 안에 경계선 1px 포함) */
:root { --topbar-h: 44px; }
/* 로고는 밴드(44px - 경계선 1px) 안에 위아래 여백을 두고 들어가는 크기로 고정.
   앞쪽 규칙의 46px(기본)·32px(데스크톱)를 여기서 한 값으로 모은다. */
.brand-ci { height: 30px; }

.nav {
  padding: 8px 10px 12px;
  overflow-y: auto;
  min-height: 0;
  flex: 1;
  /* ★ .nav 는 grid 인데 flex:1 로 사이드바 높이를 채운다. 그리드의 기본 align-content 는
     stretch 라서, 내용이 짧아지면 **남는 높이가 행 사이로 배분된다** — 메뉴를 전부 접었을 때
     그룹명이 100px씩 떨어져 뜨던 원인이 이것이다(글자 크기 문제가 아니었다).
     start 로 고정해 행은 제 높이만 쓰고 남는 공간은 아래에 그대로 둔다 →
     펼쳤을 때와 접었을 때의 항목 간격(2px)·그룹 간격(8px)이 똑같이 유지된다. */
  align-content: start;
}

/* ═══ 신규 화면 (2026-08-12) — 추천·변동·수신상태·서열장·보정 ═══════════════════
   색은 전부 토큰 참조(색 리터럴 0 원칙). 표는 demand-grid 를 재사용하고
   여기서는 상태 표기(결품/부족/Δ/수신)만 얹는다. */

/* 추천 화면 — 커버 구간 강조·상태 배지 */
.demand-grid td.re-cover { background: var(--nu-primary-tint); }
.demand-grid thead th.re-cover-h { box-shadow: inset 0 -3px 0 var(--nu-primary); }
.demand-grid .re-rec { font-weight: 700; color: var(--nu-brand-text); }
.re-badge {
  display: inline-block; padding: 1px 7px; border-radius: var(--nu-r-pill);
  font-size: 0.72rem; font-weight: 700; vertical-align: 1px;
}
.re-urgent { background: var(--nu-alert-light);   color: var(--nu-alert-text);   border: 1px solid var(--nu-alert-border); }
.re-short  { background: var(--nu-warning-light); color: var(--nu-warning-text); border: 1px solid var(--nu-warning-border); }
.re-new    { background: var(--nu-success-light); color: var(--nu-success-text); border: 1px solid var(--nu-success-border); }
.re-gone   { background: var(--nu-surface-2);     color: var(--nu-txt3);         border: 1px solid var(--nu-border); }
.re-own    { background: var(--nu-info-light);    color: var(--nu-info-text);    border: 1px solid var(--nu-info-border); }
.demand-grid tr.re-row-urgent > td:first-child { box-shadow: inset 3px 0 0 var(--nu-alert); }
.demand-grid tr.re-row-short  > td:first-child { box-shadow: inset 3px 0 0 var(--nu-warning); }
.re-est { color: var(--nu-warning-text); font-weight: 700; margin-right: 2px; }
.re-warn { color: var(--nu-warning-text); font-weight: 700; }
.re-boxes { color: var(--nu-txt3); font-size: 0.78rem; }
/* ── 추천 표 컬럼 폭 (2026-08-18) ─────────────────────────────────────────
   v0.8.2 이식으로 컬럼이 10개 늘어 표가 가로로 넘쳤고, **정작 주인공인 추천량이
   화면 밖으로 밀렸다**(캡처로 확인). 데스크톱도 같은 이유로 '헤더 단축·폭 축소'를 했다.
   table-layout:fixed 라 **헤더 폭만 정하면 본문이 따라온다** — 그래서 th 에만 건다.
   품명은 폭을 주지 않고 남는 폭을 먹게 두고, 넘치면 말줄임(공통 규칙이 이미 걸려 있다). */
.re-grid thead th.re-w-st { width: 54px; }
.re-grid thead th.re-w-pn { width: 122px; }
.re-grid thead th.re-w-nm { width: 128px; }
.re-grid thead th.re-w-m  { width: 62px; }
.re-grid thead th.re-w-s  { width: 48px; }
.re-grid thead th.dm-day  { width: 38px; }
.re-grid thead th.re-t    { width: 56px; }
/* 좁아진 만큼 안쪽 여백도 줄인다 — 숫자가 잘리면 폭을 줄인 의미가 없다 */
.re-grid thead th, .re-grid tbody td { padding-left: 4px; padding-right: 4px; }

.re-kpi-urgent { color: var(--nu-alert-text); }
.re-kpi-short  { color: var(--nu-warning-text); }

/* ── 계획 대상일 줄 (2026-08-18, FlowTracer v0.8.2 PlanDateLabel 승계) ───────
   "D+1" 은 현장에서 안 읽힌다 — 오늘/내일/모레와 요일을 문장으로 쓴다.
   오늘분을 고치는 중이면 눈에 띄게, 지난 날짜면 경고색. 색만으로 알리지 않고 문장에 다 들어 있다. */
.re-plandate {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding: 7px 14px; border-radius: var(--nu-r-large);
  background: var(--nu-surface-2); border: 1px solid var(--nu-border);
  font-size: 0.9rem; color: var(--nu-txt1);
}
.re-plandate .re-pd-sub { font-size: 0.78rem; color: var(--nu-txt3); font-weight: 400; }
.re-pd-today { background: var(--nu-primary-tint); border-color: var(--nu-primary); color: var(--nu-brand-text); }
.re-pd-past  { background: var(--nu-alert-light);  border-color: var(--nu-alert-border); color: var(--nu-alert-text); }
.re-pd-btn {
  padding: 3px 10px; border-radius: var(--nu-r-pill); cursor: pointer;
  background: var(--nu-card); border: 1px solid var(--nu-border); color: var(--nu-txt2); font-size: 0.8rem;
}
.re-pd-btn:hover { border-color: var(--nu-primary); color: var(--nu-brand-text); }
/* 계획 대상일 컬럼 — 커버 구간(아래 실선)과 구분되게 위쪽에 표시한다 */
.demand-grid thead th.re-target-h { box-shadow: inset 0 -3px 0 var(--nu-primary), inset 0 3px 0 var(--nu-warning); }
/* 재고 근거 배지 — 색이 아니라 글자가 판정을 담는다(실사/계산/≈인수/—) */
.re-basis { font-size: 0.76rem; color: var(--nu-txt3); border-bottom: 1px dotted var(--nu-border); cursor: help; }
/* 재고 미상 — 결품(빨강)과 **다른 색**이어야 한다. 미상을 결품으로 읽게 하지 않는 것이 요점이다. */
.re-unknown { background: var(--nu-surface-2); color: var(--nu-txt3); border: 1px dashed var(--nu-border); }
.demand-grid tr.re-row-unknown > td:first-child { box-shadow: inset 3px 0 0 var(--nu-txt4); }
.demand-grid tr.re-row-unknown { opacity: 0.86; }

/* 사출 수량제안 — 금형 그룹 헤더 행 (금형 그룹핑 스티키는 표 헤더가 담당, 행은 구분띠만) */
.demand-grid tr.re-die-row > td {
  background: var(--nu-surface-2); color: var(--nu-txt2);
  font-weight: 700; font-size: 0.8rem; text-align: left; padding: 5px 10px;
  border-top: 2px solid var(--nu-border-strong);
}

/* 변동 분석 — Δ 방향색 (증가=경보 계열, 감소=정보 계열. 글자는 -text 톤으로 4.5:1 확보) */
.rd-up   { color: var(--nu-alert-text); font-weight: 600; }
.rd-down { color: var(--nu-info-text);  font-weight: 600; }

/* 수신 상태 — 수신/결측/주말 행 */
.rs-ok   { color: var(--nu-success-text); font-weight: 700; }
.rs-miss { color: var(--nu-alert-text);   font-weight: 700; }
.demand-grid tr.rs-weekend > td { color: var(--nu-txt4); }
.demand-grid tr.rs-missrow > td { background: var(--nu-alert-light-2); }

/* 보정 이력 — 취소(soft-cancel)된 이력은 흐리게 (이력 보존 lifecycle 표현) */
.demand-grid tr.corr-canceled > td { color: var(--nu-txt4); }
.demand-grid tr.corr-canceled .rd-up,
.demand-grid tr.corr-canceled .rd-down { color: var(--nu-txt4); }

/* 신규 화면의 넓은 표 — 열 폭 고정(서열계획 전용 규칙)에서 빠져나온다.
   ★ .demand-panel 은 fit-page 높이 배분(flex)을 담당하므로 그대로 두고, 표 레이아웃만 뒤집는다.
   서열계획 표는 좌측 5열을 못 박아 D+14 까지 한 화면에 넣는 설계지만, 여기 표들은 열 수가
   28개(추천)·17개(서열장)까지 늘어 같은 규칙을 쓰면 품번·헤더가 전부 말줄임으로 뭉개진다.
   → 내용에 맞춘 폭(auto) + 가로 스크롤(.demand-grid-wrap 이 이미 overflow:auto). */
.demand-panel.grid-auto .demand-grid { table-layout: auto; width: max-content; min-width: 100%; }
.demand-panel.grid-auto .demand-grid th,
.demand-panel.grid-auto .demand-grid td { overflow: visible; text-overflow: clip; }
/* 품명은 값이 길어(예: "FRT SECL LH 일체형 사출") 표 전체를 1920 밖으로 밀어낸다.
   열 자체를 좁히면 헤더까지 뭉개지므로 값만 말줄임하고 전체 문구는 title 툴팁으로 준다
   (1920x1080 무스크롤 기준 유지). */
.demand-panel.grid-auto .demand-grid .re-name {
  display: inline-block; max-width: 168px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; vertical-align: bottom;
}
/* 추천 표(32열)는 위 max-width 로도 1920 을 넘겼다 — 이 표에서만 더 조인다.
   전문은 title 툴팁에 그대로 있다(§0-4 '수치엔 출처·설명' 규약 유지). */
.demand-panel.grid-auto .demand-grid.re-grid .re-name { max-width: 116px; }
.re-grid .dm-bd { font-size: 0.72rem; }
/* 32열 표는 글자 한 단계를 낮춰야 1920 안에 들어온다. 데스크톱도 같은 이유로 폭을 줄였다
   ('판단에 안 쓰는 것을 걷어내 한 화면에 더 보이게', v0.8.2). */
.re-grid { font-size: 0.76rem; }
/* 상태 열은 맨 앞(항상 보이는 자리)에 둔다 — 28열 표라 우측 끝은 가로 스크롤로 밀린다. */
.demand-panel.grid-auto .demand-grid .re-st { min-width: 54px; }
/* 플레이스홀더 표는 빈 표라 남는 높이를 먹으면 화면 대부분이 흰 여백이 된다 — 제 높이만 쓴다. */
#layoutRoot.fit-page > .panel > .demand-grid-wrap.ph-wrap { flex: 0 0 auto; min-height: 0; max-height: none !important; }

/* ═══ 사출기 연동 — 키오스크 작업 전시부 (2026-08-13 연동 사전자료 반영) ═══════════
   작업흐름 ①~⑩ 중 화면이 담당하는 부분: 다음 작업의 금형·수량·레시피를 크게 전시하고,
   작업자가 금형을 장착한 뒤 [작업 시작]을 누르면 서버가 ③~⑥을 연달아 수행한다. */
.inj-now {
  border: 1px solid var(--nu-primary-lightest); border-left: 5px solid var(--nu-primary);
  border-radius: var(--nu-r-large); background: var(--nu-primary-tint);
  padding: 14px 16px; display: flex; flex-direction: column; gap: 10px;
}
.inj-now.run { border-color: var(--nu-warning-border); border-left-color: var(--nu-warning); background: var(--nu-warning-light-3); }
.inj-now-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.inj-now-tag {
  font-size: 0.74rem; font-weight: 800; padding: 2px 9px; border-radius: var(--nu-r-pill);
  background: var(--nu-primary); color: var(--nu-on-accent);
}
.inj-now.run .inj-now-tag { background: var(--nu-warning); color: var(--nu-ink); }
.inj-now-seq { font-size: 0.86rem; font-weight: 700; color: var(--nu-brand-text); }
.inj-now-item { font-size: 1.02rem; font-weight: 800; color: var(--nu-txt1); }
.inj-now-of { margin-left: auto; font-size: 0.78rem; color: var(--nu-txt3); }

.inj-now-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: 14px; align-items: stretch; }
@media (max-width: 1100px) { .inj-now-body { grid-template-columns: 1fr; } }
.inj-now-main { display: flex; flex-direction: column; gap: 6px; justify-content: center; }
.inj-now-kv { display: flex; align-items: baseline; gap: 10px; }
.inj-now-kv > span { width: 68px; flex: none; font-size: 0.78rem; color: var(--nu-txt3); }
.inj-now-kv > b { font-size: 0.98rem; color: var(--nu-txt1); }
/* 금형이름·수량은 작업자가 멀리서 확인하는 값이라 크게 — 키오스크 전시 목적 */
.inj-now-mold { font-size: 1.35rem !important; font-weight: 800; letter-spacing: 0.01em; font-family: 'Consolas', monospace; }
.inj-now-qty { font-size: 1.35rem !important; font-weight: 800; font-variant-numeric: tabular-nums; }
.inj-now-qty small { font-size: 0.8rem; font-weight: 600; color: var(--nu-txt3); margin-left: 2px; }

.inj-now-recipe { background: var(--nu-card); border: 1px solid var(--nu-border); border-radius: var(--nu-r-medium); padding: 10px 12px; }
.inj-rc-title { font-size: 0.82rem; font-weight: 700; color: var(--nu-txt2); margin-bottom: 7px; }
.inj-rc-title small { font-weight: 400; color: var(--nu-txt4); margin-left: 6px; }
.inj-rc-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 7px 12px; }
.inj-rc-item { display: flex; flex-direction: column; gap: 1px; }
.inj-rc-item span { font-size: 0.72rem; color: var(--nu-txt4); }
.inj-rc-item b { font-size: 0.9rem; color: var(--nu-txt1); }
.inj-rc-note { margin-top: 8px; font-size: 0.78rem; color: var(--nu-warning-text); }
.inj-rc-empty { font-size: 0.82rem; color: var(--nu-txt3); line-height: 1.5; }
.inj-rc-empty small { color: var(--nu-txt4); }

/* 금형 교체 분기 — "같은 금형이면 ⑦~⑩ 반복 / 다르면 ③ 장착부터 다시" */
.inj-mold-chg { font-size: 0.85rem; padding: 8px 12px; border-radius: var(--nu-r-medium); }
.inj-mc-keep   { background: var(--nu-success-light); color: var(--nu-success-text); }
.inj-mc-change { background: var(--nu-warning-light); color: var(--nu-warning-text); border: 1px solid var(--nu-warning-border); }
.inj-mc-mount  { background: var(--nu-info-light);    color: var(--nu-info-text);    border: 1px solid var(--nu-info-border); }
.inj-mc-none   { background: var(--nu-alert-light);   color: var(--nu-alert-text);   border: 1px solid var(--nu-alert-border); }

.inj-mount-chk { display: flex; align-items: center; gap: 8px; font-size: 0.86rem; color: var(--nu-txt2); cursor: pointer; }
.inj-mount-chk input { width: 17px; height: 17px; cursor: pointer; }

.inj-now-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.inj-now-actions .inj-precond { flex: 1 1 260px; margin: 0; }
.inj-start-lg {
  flex: none; padding: 11px 30px; font-size: 1rem; font-weight: 800;
  border: none; border-radius: var(--nu-r-medium); cursor: pointer;
  background: var(--nu-primary); color: var(--nu-on-accent);
}
.inj-start-lg:hover:not(:disabled) { background: var(--nu-primary-dark); }
.inj-start-lg:disabled { background: var(--nu-surface-4); color: var(--nu-txt4); cursor: default; }

/* 단계바 화살표 */
.inj-step-arrow { color: var(--nu-txt4); font-weight: 700; }

/* 목록의 금형 유지/교체 배지 + 다음 차례 행 강조 */
.inj-chg { font-size: 0.72rem; font-weight: 700; padding: 1px 7px; border-radius: var(--nu-r-pill); }
.inj-chg.keep   { background: var(--nu-success-light); color: var(--nu-success-text); }
.inj-chg.change { background: var(--nu-warning-light); color: var(--nu-warning-text); }
.inv-grid tr.inj-r-next > td:first-child { box-shadow: inset 3px 0 0 var(--nu-primary); }
/* 전시 카드는 목록 높이를 덜 먹도록 조인다 — 1920x1080 한 화면에 목록까지 들어와야 한다. */
.inj-now { padding: 11px 14px; gap: 8px; }
.inj-now-body { gap: 12px; }
.inj-now-mold, .inj-now-qty { font-size: 1.22rem !important; }
.inj-rc-grid { gap: 5px 12px; }
.inj-now-actions { gap: 10px; }
/* 전송 이력은 참고 자료 — 남는 높이는 작업지시 목록이 먼저 가져간다 */
/* ★ fit-page 규칙이 .inv-grid-wrap 의 max-height 를 !important 로 풀어 버리므로 여기서 되돌린다 —
   안 그러면 이력이 자기 높이만큼 늘어나 정작 중요한 작업지시 목록이 두어 줄로 눌린다. */
#layoutRoot.fit-page > .panel > .inv-grid-wrap.inj-hist-wrap { flex: 0 0 auto; max-height: 132px !important; }

/* ═══ 협약 성과지표(KPI) 화면 — SIM-TD3-018/019/020 ══════════════════════════
   색은 tokens.css 의 --kpi-* 만 쓴다(hex 리터럴 0). 상태색은 채움 전용이고
   글자는 --nu-*-text 톤을 써서 4.5:1 을 지킨다(색 규칙 4). */
.kpi-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.kpi-head-title { font-size: 1.05rem; font-weight: 800; color: var(--nu-txt1); }
.kpi-head-title small { font-weight: 500; font-size: 0.78rem; color: var(--nu-txt3); margin-left: 8px; }
.kpi-head-sub { margin-top: 3px; font-size: 0.82rem; color: var(--nu-txt3); }
.kpi-muted { color: var(--nu-txt4); }

.kpi-cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 1100px) { .kpi-cards { grid-template-columns: 1fr; } }
.kpi-card {
  border: 1px solid var(--nu-border); border-left: 5px solid var(--nu-surface-4);
  border-radius: var(--nu-r-large); background: var(--nu-card);
  padding: 14px 16px; display: flex; flex-direction: column; gap: 8px;
}
.kpi-card.link { cursor: pointer; }
.kpi-card.link:hover { border-color: var(--nu-primary-lightest); box-shadow: var(--nu-elev-low); }
.kpi-c-achieved { border-left-color: var(--nu-primary); }
.kpi-c-on_track { border-left-color: var(--kpi-st-good); }
.kpi-c-warn     { border-left-color: var(--kpi-st-warn); }
.kpi-c-risk     { border-left-color: var(--kpi-st-risk); }
.kpi-c-no_data  { border-left-color: var(--nu-surface-4); }

.kpi-card-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.kpi-card-id { font-size: 0.72rem; font-weight: 800; color: var(--nu-txt4); font-family: 'Consolas', monospace; }
.kpi-card-name { font-size: 0.95rem; font-weight: 700; color: var(--nu-txt1); }
.kpi-badge { font-size: 0.72rem; font-weight: 700; padding: 1px 8px; border-radius: var(--nu-r-pill); }
.kpi-b-achieved { background: var(--nu-primary-tint);  color: var(--nu-brand-text); }
.kpi-b-on_track, .kpi-b-good { background: var(--nu-success-light); color: var(--nu-success-text); }
.kpi-b-warn     { background: var(--nu-warning-light); color: var(--nu-warning-text); }
.kpi-b-serious  { background: var(--nu-warning-light-2); color: var(--nu-warning-text-2); }
.kpi-b-risk     { background: var(--nu-alert-light);   color: var(--nu-alert-text); }
.kpi-b-no_data  { background: var(--nu-surface-2);     color: var(--nu-txt3); }
.kpi-b-method   { background: var(--nu-info-light);    color: var(--nu-info-text); }

.kpi-value { font-size: 2.1rem; font-weight: 800; color: var(--nu-txt1); line-height: 1.1; }
.kpi-value small { font-size: 0.95rem; font-weight: 700; color: var(--nu-txt3); margin-left: 4px; }
.kpi-sub { font-size: 0.84rem; color: var(--nu-txt3); }
.kpi-improve { margin-left: 8px; font-weight: 800; }
.kpi-improve.up   { color: var(--nu-brand-text); }   /* 개선(감소) — 파랑 ▼ */
.kpi-improve.down { color: var(--nu-alert-text); }   /* 악화 */
.kpi-foot { display: flex; justify-content: space-between; font-size: 0.78rem; color: var(--nu-txt3); }

/* 진척 게이지 — 채움 MIN(진척,120)/120, 100% 위치 눈금 고정 */
.kpi-gauge { position: relative; height: 10px; border-radius: var(--nu-r-pill); background: var(--nu-surface-3); overflow: hidden; }
.kpi-gauge-fill { height: 100%; border-radius: var(--nu-r-pill); transition: width 0.3s; }
.kpi-g-achieved { background: var(--nu-primary); }
.kpi-g-on_track { background: var(--kpi-st-good); }
.kpi-g-warn     { background: var(--kpi-st-warn); }
.kpi-g-risk     { background: var(--kpi-st-risk); }
.kpi-g-no_data  { background: var(--nu-surface-4); }
.kpi-gauge-100 { position: absolute; top: 0; bottom: 0; left: 83.33%; width: 2px; background: var(--nu-txt4); opacity: 0.6; }

/* 산출 불가 — 값을 지어내지 않고 사유와 막힌 소스를 보여준다 */
.kpi-nodata { font-size: 1.35rem; font-weight: 800; color: var(--nu-txt4); }
.kpi-nodata-why { font-size: 0.84rem; color: var(--nu-warning-text); }
.kpi-block-list { margin: 2px 0 0; padding-left: 18px; font-size: 0.8rem; color: var(--nu-txt3); }
.kpi-quality { font-size: 0.76rem; color: var(--nu-txt4); border-top: 1px solid var(--nu-border-l); padding-top: 7px; }
.kpi-quality.low { color: var(--nu-alert-text); }

.kpi-def-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 1100px) { .kpi-def-grid { grid-template-columns: 1fr; } }
.kpi-def { background: var(--nu-page); border-radius: var(--nu-r-medium); padding: 10px 13px; font-size: 0.84rem; color: var(--nu-txt2); }
.kpi-def b { display: block; margin-bottom: 3px; color: var(--nu-txt1); }

/* 산출식 전개 — 수식에 이번 기간 실제 값을 대입해 보여준다 */
.kpi-fx-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 1100px) { .kpi-fx-grid { grid-template-columns: 1fr; } }
.kpi-formula { border: 1px solid var(--nu-border); border-radius: var(--nu-r-medium); padding: 11px 14px; background: var(--nu-card); }
.kpi-fx-head { font-size: 0.86rem; font-weight: 700; color: var(--nu-txt2); margin-bottom: 8px; }
.kpi-fx-body { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.kpi-fx-out { font-size: 1.2rem; font-weight: 800; color: var(--nu-brand-text); }
.kpi-fx-eq { color: var(--nu-txt3); }
.kpi-fx-frac { display: inline-flex; flex-direction: column; text-align: center; font-size: 0.86rem; color: var(--nu-txt2); }
.kpi-fx-frac em { font-style: normal; padding: 0 8px 3px; border-bottom: 1px solid var(--nu-border-strong); }
.kpi-fx-frac i { font-style: normal; padding: 3px 8px 0; }
.kpi-fx-why { margin-top: 7px; font-size: 0.8rem; color: var(--nu-warning-text); }

/* 백데이터 표 — 보간·수기 구간 구분(색만으로 구분하지 않고 배지 병기) */
.kpi-flag { font-size: 0.7rem; font-weight: 700; padding: 1px 6px; border-radius: var(--nu-r-pill); }
.kpi-flag.est { background: var(--nu-warning-light); color: var(--nu-warning-text); }
.kpi-flag.man { background: var(--nu-info-light);    color: var(--nu-info-text); }
.inv-grid tr.kpi-r-est > td { background: var(--nu-warning-light-3); }

/* 충족률 격자 — 아이콘 + 라벨 + 색 3중 표기(색만으로 구분 금지) */
.kpi-legend { display: flex; gap: 10px; flex-wrap: wrap; font-size: 0.78rem; }
.kpi-lg { color: var(--nu-txt3); }
.kpi-lg-ok   { color: var(--nu-success-text); }
.kpi-lg-est  { color: var(--nu-warning-text); }
.kpi-lg-miss { color: var(--nu-alert-text); }
.kpi-lg-na   { color: var(--nu-txt4); }
.kpi-q-grid th.kpi-cell, .kpi-q-grid td.kpi-cell { width: 26px; min-width: 26px; text-align: center; padding: 4px 2px; font-size: 0.7rem; }
.kpi-cell-ok   { color: var(--nu-success-text); }
.kpi-cell-est  { color: var(--nu-warning-text); background: var(--nu-warning-light-3); }
.kpi-cell-miss { color: var(--nu-alert-text);   background: var(--nu-alert-light-2); }
.kpi-cell-na   { color: var(--nu-txt-disabled); }
/* 홈 KRI 배너 — 협약 성과지표 진척을 얹은 카드 */
.home-kri-card.kri-link { cursor: pointer; }
.kri-now { margin-left: 8px; font-size: 0.84rem; font-weight: 700; color: var(--nu-on-accent); opacity: 0.95; }
.kri-imp { margin-left: 6px; font-size: 0.82rem; font-weight: 800; color: var(--nu-on-accent); }
.home-kri-badge.kri-nd { background: var(--nu-alert-light); color: var(--nu-alert-text); }
.kri-gauge { margin: 6px 0 4px; height: 8px; background: rgba(255,255,255,0.25); }
/* KPI 화면 추가 — 산정월 선택·산출식 보조설명·합계행 */
.kpi-month { font-size: 0.84rem; color: var(--nu-txt3); display: flex; align-items: center; gap: 6px; }
.kpi-month select { padding: 5px 9px; border: 1px solid var(--nu-border); border-radius: var(--nu-r-medium);
  background: var(--nu-card); color: var(--nu-txt1); font-size: 0.84rem; }
.kpi-fx-sub { margin-top: 7px; font-size: 0.78rem; color: var(--nu-txt3); }
.inv-grid tr.kpi-r-sum > td { background: var(--nu-primary-tint); font-weight: 700; }
/* 잠정치 — 확정 전 값이라 '달성' 색을 쓰지 않는다(회색 계열로 눌러 표시) */
.kpi-c-provisional { border-left-color: var(--nu-txt4); }
.kpi-b-provisional { background: var(--nu-surface-2); color: var(--nu-txt2); }
.kpi-g-provisional { background: var(--nu-surface-4); }

/* ═══ 시뮬레이션 수행 중 영상 — 화면을 덮지 않는 보조 패널 ═══════════════════
   [스케줄링 시작] ~ 완료까지 우측 하단에 뜬다. 영상은 frontend/public/media/sim/ 이 정한다.
   ★ 원래 화면이 주인공이다. 스크림을 깔거나 화면 가운데를 차지하면 "영상을 보는 화면"이 되어
     정작 봐야 할 '생성중인 생산계획' 표가 가려진다 → 스크림 없음 + 우측 하단 고정 + 작은 폭.
   ★ 컨테이너는 pointer-events:none — 영상이 떠 있어도 뒤 화면을 그대로 클릭·조작할 수 있다.
     (카드만 auto 로 되돌려 버튼은 눌린다) */
.sim-video-ov {
  position: fixed; inset: 0; z-index: 1200;
  display: flex; align-items: flex-start; justify-content: center;   /* 중앙 상단 */
  padding: 18px 20px;
  pointer-events: none;            /* 뒤 화면 조작을 막지 않는다 */
}
.sim-video-box {
  pointer-events: auto;
  width: 510px; max-width: calc(100vw - 40px);
  background: var(--nu-card);
  border: 1px solid var(--nu-border);
  border-radius: var(--nu-r-large);
  box-shadow: var(--nu-elev-high);
  overflow: hidden;
  display: flex; flex-direction: column;
  animation: simVideoIn 0.22s ease-out;
}
/* 조용히 내려온다 — 갑자기 나타나면 그것대로 시선을 뺏는다(위치가 상단이라 방향도 위에서) */
@keyframes simVideoIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }

.sim-video-head {
  display: flex; align-items: center; gap: 7px;
  padding: 7px 8px 7px 11px;
  background: var(--nu-primary-tint);
  color: var(--nu-brand-text);
  border-bottom: 1px solid var(--nu-border);
}

.sim-video-title { font-size: 0.86rem; font-weight: 700; }
.sim-video-time { margin-left: auto; font-size: 0.8rem; font-variant-numeric: tabular-nums; }
.sim-video-x {
  flex: none; width: 20px; height: 20px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: none; border-radius: var(--nu-r-small);
  background: transparent; color: var(--nu-txt3);
  font-size: 0.8rem; cursor: pointer;
}
.sim-video-note {
  margin-right: auto; font-size: 0.74rem; color: var(--nu-txt4);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sim-video-btn {
  flex: none; padding: 3px 9px; font-size: 0.74rem; font-weight: 600;
  border: 1px solid var(--nu-border); border-radius: var(--nu-r-medium);
  background: var(--nu-card); color: var(--nu-txt3); cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
}

/* ═══ 개발품(샘플) 일정 등록 ══════════════════════════════════════════════════
   2026-08-13 오토젠 회의 요구. 색은 전부 토큰 참조 — 상태색(alert/warning)은 상태 전용이라
   차트 시리즈 색으로 쓰지 않고, 반대로 여기서도 시리즈 색을 상태 표시에 끌어오지 않는다.
   글자에는 채움색(--nu-alert)이 아니라 --nu-*-text 를 쓴다(대비 4.5:1 — 색 규칙 4). */

/* ── D-day — 회의의 "반짝반짝 띄워 달라". 색만으로 알리지 않고 글자('D+3 초과')도 같이 준다 ── */
.di-dday { display: inline-block; min-width: 62px; font-variant-numeric: tabular-nums; font-size: 0.85rem; }
.di-d-crit { color: var(--nu-alert-text);   font-weight: 800; }   /* D-2 이내 또는 기한 경과 */
.di-d-warn { color: var(--nu-warning-text); font-weight: 700; }   /* D-3 ~ D-5 */
.di-d-ok   { color: var(--nu-txt2); }
.di-d-done { color: var(--nu-txt4); }                             /* 완료·취소 건은 재촉하지 않는다 */

.di-grid tr.di-row { cursor: pointer; }
.di-grid tr.di-row-cxl td { color: var(--nu-txt4); text-decoration: line-through; }
.di-sub { display: block; font-size: 0.74rem; font-weight: 400; color: var(--nu-txt3); }
.di-unset { color: var(--nu-txt4); }
.di-remain { color: var(--nu-alert-text); }

/* 상태·계획반영·우선순위 배지 — .re-badge(pill) 위에 색만 얹는다 */
.di-st-reg   { background: var(--nu-surface-2);       color: var(--nu-txt2); }
.di-st-plan  { background: var(--nu-info-light);      color: var(--nu-info-text); }
.di-st-prog  { background: var(--nu-primary-tint);    color: var(--nu-brand-text); }
.di-st-done  { background: var(--nu-success-light);   color: var(--nu-success-text); }
.di-st-cxl   { background: var(--nu-surface-3);       color: var(--nu-txt4); }
.di-pl-yes   { background: var(--nu-success-light);   color: var(--nu-success-text); }
.di-pl-no    { background: var(--nu-surface-2);       color: var(--nu-txt3); }
.di-pr-urgent{ background: var(--nu-alert-light);     color: var(--nu-alert-text); font-weight: 800; }

.di-toolbar { flex-wrap: wrap; row-gap: 8px; }
/* 필터가 많아 검색칸이 눌린다 — 남는 폭을 검색이 가져가고 [신규 등록]은 오른쪽 끝에 붙인다 */
.di-toolbar input[type="text"] { flex: 1 1 200px; min-width: 160px; }
.di-toolbar .di-new { flex: none; }
.di-chips { display: inline-flex; align-items: center; gap: 5px; font-size: 0.84rem; color: var(--nu-txt3); }
.di-chip {
  padding: 3px 11px; border: 1px solid var(--nu-border);
  border-radius: var(--nu-r-pill); background: var(--nu-card);
  color: var(--nu-txt2); font-size: 0.8rem; cursor: pointer;
}
.di-chip:hover { background: var(--nu-hover); }
.di-chip.on { background: var(--nu-primary); border-color: var(--nu-primary); color: var(--nu-on-accent); font-weight: 700; }
.di-sum-card { cursor: pointer; }
/* 날짜 입력은 전용 클래스를 쓴다 — .popup-form-date 는 달력 아이콘에 invert(1) 을 걸어 두고 있어
   라이트 톤(흰 배경)에서 아이콘이 하얗게 지워진다. */
.di-date, .di-toolbar input[type="date"] {
  padding: 5px 9px; border: 1px solid var(--nu-border); border-radius: var(--nu-r-medium);
  background: var(--nu-card); color: var(--nu-txt1); font-size: 0.84rem; font-family: inherit;
}

/* ── 상세·등록 팝업 ─────────────────────────────────────────────────────── */
.di-popup { width: 720px; max-width: calc(100vw - 48px); max-height: calc(100vh - 64px); overflow-y: auto; }
.di-pop-sub { margin: -6px 0 12px; font-size: 0.86rem; color: var(--nu-txt3); display: flex; align-items: center; gap: 10px; }
.di-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--nu-border); margin-bottom: 14px; }
.di-tab {
  padding: 7px 16px; border: none; background: transparent;
  color: var(--nu-txt3); font-size: 0.88rem; font-weight: 600; cursor: pointer;
  border-bottom: 2px solid transparent;
}
.di-tab.on { color: var(--nu-primary); border-bottom-color: var(--nu-primary); }

.di-f-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; font-size: 0.87rem; }
.di-f-row-top { align-items: flex-start; }
.di-f-row > label:first-child { min-width: 104px; text-align: right; color: var(--nu-txt3); flex: none; }
.di-req { color: var(--nu-alert-text); }
.di-unit { font-size: 0.8rem; color: var(--nu-txt4); }
.di-f-hint, .di-f-note { font-size: 0.78rem; color: var(--nu-txt3); line-height: 1.5; }
.di-f-note {
  margin: 4px 0 14px 114px; padding: 7px 11px;
  background: var(--nu-primary-tint); color: var(--nu-brand-text);
  border-radius: var(--nu-r-medium);
}
.di-f-hint { margin-top: 5px; color: var(--nu-txt4); }
.di-mach-box { flex: 1; }
.di-mach-chk { display: inline-flex; align-items: center; gap: 5px; margin: 0 12px 4px 0; font-size: 0.84rem; cursor: pointer; }
.di-mach-chk input { width: 15px; height: 15px; accent-color: var(--nu-primary); cursor: pointer; }
.di-f-meta {
  margin: 12px 0 0 114px; padding-top: 10px; border-top: 1px solid var(--nu-border-l);
  font-size: 0.78rem; color: var(--nu-txt3); line-height: 1.6;
}
.di-f-meta code { background: var(--nu-surface-2); padding: 1px 5px; border-radius: var(--nu-r-small); }
.di-form textarea { resize: vertical; font-family: inherit; }

/* ── 실적 탭 ────────────────────────────────────────────────────────────── */
.di-prog { margin-bottom: 14px; }
.di-prog-nums { display: flex; gap: 18px; align-items: baseline; font-size: 0.86rem; color: var(--nu-txt3); margin-bottom: 6px; }
.di-prog-nums b { font-size: 1.05rem; color: var(--nu-txt1); font-variant-numeric: tabular-nums; }
.di-prog-pct { margin-left: auto; font-weight: 800; color: var(--nu-txt2); font-variant-numeric: tabular-nums; }
.di-gauge { height: 10px; }
.di-r-form {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 11px 13px; margin-bottom: 12px;
  background: var(--nu-row-alt); border: 1px solid var(--nu-border); border-radius: var(--nu-r-medium);
  font-size: 0.84rem; color: var(--nu-txt3);
}
.di-r-form label { display: flex; align-items: center; gap: 6px; }
.di-r-memo-l { flex: 1; min-width: 180px; }
.di-r-wrap { max-height: 240px; overflow-y: auto; border: 1px solid var(--nu-border); border-radius: var(--nu-r-medium); margin-bottom: 10px; }
.di-r-act { white-space: nowrap; }
.di-r-act button + button { margin-left: 5px; }
/* 저장 후 팝업을 닫지 않는 흐름(실적 연속 입력)에서 "됐다"를 알리는 짧은 안내 */
.di-toast {
  display: none; margin: 8px 0 0; padding: 6px 11px;
  background: var(--nu-success-light); color: var(--nu-success-text);
  border-radius: var(--nu-r-medium); font-size: 0.82rem; font-weight: 600;
}
.di-toast.on { display: block; }

/* ── 홈 대시보드 '기한 임박 개발품' 줄 ──────────────────────────────────────
   임박 건이 0이면 아예 렌더하지 않으므로(app.js devSoonStrip) 평소 홈 레이아웃은 그대로다.
   뜰 때만 한 줄을 차지하고, 아래 차트가 flex 로 그만큼 양보한다.
   ★ 그래서 이 줄은 **얇아야 한다** — 뜬 순간 아래 차트 2줄이 각각 그 절반씩 낮아진다.
     눈에 띄는 건 두께가 아니라 색(alert/warning)과 D-표기가 맡는다. 여백·글자를
     다시 키우지 말 것. 한 줄 높이 약 30px(테두리 포함)이 상한이다. */
#layoutRoot.home-fill > .di-home { flex: 0 0 auto; }
.di-home {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 5px 12px; cursor: pointer; line-height: 1.3;
  background: var(--nu-warning-light); color: var(--nu-warning-text);
  border: 1px solid var(--nu-warning-border); border-radius: var(--nu-r-large);
  font-size: 0.8rem;
}
.di-home.crit { background: var(--nu-alert-light); color: var(--nu-alert-text); border-color: var(--nu-alert-border); }
.di-home:hover { filter: brightness(0.98); }
.di-home-t { font-weight: 800; flex: none; }
.di-home-list { display: flex; gap: 6px; flex-wrap: wrap; min-width: 0; }
.di-home-item {
  padding: 1px 8px; border-radius: var(--nu-r-pill);
  background: var(--nu-card); color: var(--nu-txt2);
  font-size: 0.76rem; white-space: nowrap;
}
.di-home-item b { color: var(--nu-warning-text); font-variant-numeric: tabular-nums; }
.di-home-item.crit b { color: var(--nu-alert-text); }
.di-home-item i { font-style: normal; color: var(--nu-txt3); }
.di-home-more { font-size: 0.79rem; opacity: 0.8; }

@media (max-width: 1100px) {
  .di-popup { width: auto; }
  .di-f-note, .di-f-meta { margin-left: 0; }
  .di-f-row { flex-wrap: wrap; }
  .di-f-row > label:first-child { min-width: 0; text-align: left; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   금형 레시피 관리 (#mold-master) — 키오스크 전시 정보 등록 화면
   ─────────────────────────────────────────────────────────────────────────── */
.mm-sum .home-kri-card { cursor: default; }
.mm-toolbar { display: flex; align-items: center; gap: 10px; }
.mm-toolbar #mmSearch { min-width: 320px; }
.mm-spacer { flex: 1 1 auto; }
.mm-note { line-height: 1.6; }

.mm-grid td { vertical-align: middle; }
.mm-thumb-c { text-align: center; }
.mm-thumb {
  width: 40px; height: 40px; object-fit: contain;
  background: var(--nu-surface-2); border-radius: var(--nu-r-small);
  vertical-align: middle;
}
.mm-noimg { color: var(--nu-txt4); }
.mm-upd { color: var(--nu-txt3); font-size: 0.8rem; }
.mm-row { cursor: pointer; }
.mm-row-ghost { background: var(--nu-warning-light-3); }
.mm-ghost-msg { color: var(--nu-warning-text); font-size: 0.82rem; }

/* 대조 배지 — 색만으로 알리지 않는다. 글자에 판정이 그대로 들어 있다(§0-4 색 규칙). */
.mm-m-ok   { background: var(--nu-success-light); color: var(--nu-success-text); }
.mm-m-none { background: var(--nu-warning-light); color: var(--nu-warning-text); }
.mm-m-off  { background: var(--nu-alert-light);   color: var(--nu-alert-text); }

/* ── 등록·수정 팝업 ──────────────────────────────────────────────────────── */
.mm-popup { width: 980px; max-width: 96vw; }
.mm-pop-sub {
  margin: -4px 0 14px; padding: 8px 12px;
  background: var(--nu-warning-light-3); color: var(--nu-warning-text);
  border-radius: var(--nu-r-medium); font-size: 0.82rem; line-height: 1.5;
}
.mm-form { display: grid; grid-template-columns: minmax(0, 1fr) 260px; gap: 20px; }
.mm-col { min-width: 0; }
.mm-f-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; font-size: 0.87rem; }
.mm-f-row-top { align-items: flex-start; }
.mm-f-row > label:first-child { min-width: 104px; text-align: right; color: var(--nu-txt3); flex: none; }
.mm-f-row .popup-form-input { flex: 1 1 auto; min-width: 0; }
.mm-f-trio span { display: inline-flex; align-items: center; gap: 4px; }
.mm-f-trio i { font-style: normal; color: var(--nu-txt4); font-size: 0.8rem; }
.mm-match-line { margin: -4px 0 10px 114px; }
.mm-ml { font-size: 0.8rem; line-height: 1.5; }
.mm-ml-idle { color: var(--nu-txt4); }
.mm-ml-ok   { color: var(--nu-success-text); }
.mm-ml-warn { color: var(--nu-alert-text); }

/* 이미지 — 파일 선택 + 드래그&드롭 */
.mm-img-title { font-size: 0.85rem; font-weight: 700; color: var(--nu-txt2); margin-bottom: 8px; }
.mm-img-title small { font-weight: 400; color: var(--nu-txt4); margin-left: 6px; }
.mm-drop {
  height: 200px; display: flex; align-items: center; justify-content: center;
  background: var(--nu-surface-2); border: 1px dashed var(--nu-border-strong);
  border-radius: var(--nu-r-medium); overflow: hidden;
}
.mm-drop.has { border-style: solid; background: var(--nu-card); }
.mm-drop.over { border-color: var(--nu-primary); background: var(--nu-primary-tint); }
.mm-drop-hint { color: var(--nu-txt4); font-size: 0.8rem; text-align: center; line-height: 1.6; }
.mm-img-prev { max-width: 100%; max-height: 100%; object-fit: contain; }
.mm-img-meta { margin-top: 8px; font-size: 0.78rem; color: var(--nu-txt3); word-break: break-all; }
.mm-img-btns { margin-top: 8px; display: flex; gap: 6px; }
.mm-pick { display: inline-block; }
.mm-img-hint { margin-top: 8px; font-size: 0.76rem; color: var(--nu-txt4); line-height: 1.5; }

/* 사출조건 편집 */
.mm-params { margin-top: 16px; }
.mm-p-head {
  display: flex; align-items: center; gap: 8px;
  font-size: 0.85rem; font-weight: 700; color: var(--nu-txt2); margin-bottom: 8px;
}
.mm-p-head small { font-weight: 400; color: var(--nu-txt4); flex: 1 1 auto; }
.mm-p-wrap { max-height: 260px; overflow: auto; border: 1px solid var(--nu-border); border-radius: var(--nu-r-medium); }
.mm-p-grid { margin: 0; }
.mm-p-grid th { position: sticky; top: 0; z-index: 1; }
.mm-p-grid td { padding: 4px 6px; }
.mm-p-grid .popup-form-input { width: 100%; }
.mm-p-act { display: flex; gap: 4px; justify-content: center; align-items: center; }
/* 행 이동·삭제 버튼은 아이콘 하나짜리다 — 기본 padding 을 그대로 두면 칸을 밀어낸다. */
.mm-p-act button { padding: 3px 0; min-width: 26px; line-height: 1.2; }
.mm-toast { margin-top: 6px; }

@media (max-width: 1100px) {
  .mm-popup { width: auto; }
  .mm-form { grid-template-columns: minmax(0, 1fr); }
  .mm-match-line { margin-left: 0; }
  .mm-f-row { flex-wrap: wrap; }
  .mm-f-row > label:first-child { min-width: 0; text-align: left; }
}

/* ── 사출기 연동·키오스크 전시 카드에 얹히는 제품 이미지·사출조건 ───────────
   레시피 원천은 위 관리 화면이다. 이미지는 주소만 받아 <img> 가 따로 가져온다
   (2초 폴링 응답에 사진 바이트를 싣지 않는다). */
.inj-rc-body { display: flex; gap: 12px; align-items: flex-start; }
.inj-rc-img {
  flex: none; width: 132px; height: 132px;
  display: flex; align-items: center; justify-content: center;
  background: var(--nu-surface-2); border-radius: var(--nu-r-medium); overflow: hidden;
}
.inj-rc-img img { max-width: 100%; max-height: 100%; object-fit: contain; }
.inj-rc-main { flex: 1 1 auto; min-width: 0; }
.inj-rc-params { margin-top: 9px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.inj-rc-chip {
  display: inline-flex; align-items: baseline; gap: 5px;
  padding: 3px 9px; border-radius: var(--nu-r-pill);
  background: var(--nu-surface-2); font-size: 0.78rem; white-space: nowrap;
}
.inj-rc-chip i { font-style: normal; color: var(--nu-txt3); }
.inj-rc-chip b { color: var(--nu-txt1); }
.inj-rc-more summary {
  cursor: pointer; font-size: 0.78rem; color: var(--nu-brand-text);
  padding: 3px 4px; list-style: none;
}
.inj-rc-more summary::-webkit-details-marker { display: none; }
.inj-rc-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }

/* ═══════════════════════════════════════════════════════════════════════════
   출하 실적 입력 (#ship-actual) — 미출하·서열장 지원 인라인 입력 그리드
   ─────────────────────────────────────────────────────────────────────────── */
.sa-toolbar { display: flex; align-items: center; gap: 10px; }
.sa-toolbar #saSearch { min-width: 240px; }
.sa-note { line-height: 1.6; }

.sa-grid td { vertical-align: middle; }
.sa-grid .sa-in { padding: 3px 5px; }
/* 입력 열은 헤더부터 구분해 둔다 — 어디를 채워야 하는지 한눈에 보여야 한다. */
.sa-th-in { background: var(--nu-primary-tint); }
.sa-num, .sa-txt {
  width: 100%; box-sizing: border-box;
  padding: 4px 6px; font-size: 0.85rem;
  color: var(--nu-txt1); background: var(--nu-card);
  border: 1px solid var(--nu-border); border-radius: var(--nu-r-small);
}
.sa-num { text-align: right; font-variant-numeric: tabular-nums; }
.sa-num:focus, .sa-txt:focus { outline: none; border-color: var(--nu-primary); background: var(--nu-primary-tint); }
/* 입력값이 있는 행만 진하게 — 나머지는 '미입력'이라는 사실이 보여야 한다. */
.sa-row.on { background: var(--nu-primary-tint); }
.sa-row.on td { font-weight: 600; }
.sa-oracle { color: var(--nu-txt3); }
.sa-ship b { font-variant-numeric: tabular-nums; }
.sa-neg { color: var(--nu-alert-text); }
.sa-d-minus { color: var(--nu-alert-text); }
.sa-d-plus { color: var(--nu-success-text); }
.sa-planchg {
  display: inline-block; margin-left: 6px; padding: 1px 6px;
  border-radius: var(--nu-r-pill); font-size: 0.7rem;
  background: var(--nu-warning-light); color: var(--nu-warning-text);
}
.sa-b-missing { margin-left: 6px; background: var(--nu-alert-light); color: var(--nu-alert-text); }
.sa-yard-txt { color: var(--nu-txt3); font-size: 0.82rem; }
/* 지원 수량이 있는데 서열장이 비면 눈에 띄게 — 저장은 막지 않지만 알려는 준다. */
.sa-f-yard.need { border-color: var(--nu-warning-border); background: var(--nu-warning-light-3); }
.sa-dirty {
  display: none; padding: 3px 10px; border-radius: var(--nu-r-pill);
  background: var(--nu-warning-light); color: var(--nu-warning-text); font-size: 0.8rem;
}
.sa-dirty.on { display: inline-block; }

/* 출하현황(#shipment)에 얹는 보정 열 — 원천이 다르므로 배경으로 구분한다. */
.sh-adj-th { background: var(--nu-primary-tint); }
.sh-adj { background: var(--nu-row-alt); }
/* 며칠분이 반영된 보정인지 — 기간 합계만 보면 하루만 입력한 품번이 '전 기간 완료'로 읽힌다. */
.sh-adj-d { display: block; font-style: normal; font-size: 0.7rem; color: var(--nu-txt4); }

/* ═══════════════════════════════════════════════════════════════════════════
   계획 외 물량 (#dev-items) — 긴급 물량 / 개발품 구분
   ─────────────────────────────────────────────────────────────────────────── */
/* 구분 배지 — 색만으로 알리지 않는다. 글자에 구분이 그대로 들어 있다(§0-4 색 규칙). */
.di-ot-urgent { background: var(--nu-warning-light); color: var(--nu-warning-text); }
.di-ot-dev    { background: var(--nu-surface-2);     color: var(--nu-txt2); }
.di-reason { color: var(--nu-warning-text); }

/* 등록 팝업의 구분 선택 */
.di-ot-pick { display: flex; gap: 8px; }
.di-ot-opt {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 14px; cursor: pointer;
  background: var(--nu-card); color: var(--nu-txt2);
  border: 1px solid var(--nu-border); border-radius: var(--nu-r-pill);
  font-size: 0.85rem;
}
.di-ot-opt:hover { background: var(--nu-hover); }
.di-ot-opt.on {
  background: var(--nu-primary-tint); border-color: var(--nu-primary);
  color: var(--nu-brand-text); font-weight: 700;
}
.di-ot-help { line-height: 1.6; }
/* 필수(*)가 아니라 권장 — 막지는 않지만 넣는 편이 낫다는 표시 */
.di-rec {
  margin-left: 5px; padding: 1px 6px; border-radius: var(--nu-r-pill);
  background: var(--nu-warning-light); color: var(--nu-warning-text);
  font-size: 0.68rem; font-weight: 700;
}

/* 계획 화면 상단 알림 배너 — 홈 배너(.di-home)와 같은 모양을 쓰되 여백만 조정한다. */
.di-plan-banner { margin: 0 0 12px; }

/* 계획 외 물량 — 생산 실적 직접 입력 (2026-08-13 회의 §다-4)
   양산품은 공정별 바코드 리딩으로 MES에 실적이 자동 집계되지만, 계획 외 물량은 그 통로가 없다. */
.di-prod-cell { cursor: pointer; }
.di-prod-cell:hover { background: var(--nu-primary-tint); }
/* 실적이 0인 칸은 '0'이 아니라 '입력'이라고 적는다 — 0은 "안 만들었다"로 읽히지만
   실제로는 "아직 안 넣었다"인 경우가 대부분이다. */
.di-prod-none {
  padding: 1px 8px; border-radius: var(--nu-r-pill);
  background: var(--nu-warning-light); color: var(--nu-warning-text);
  font-size: 0.74rem; font-weight: 700;
}
.di-why {
  margin: 10px 0 6px; padding: 9px 12px;
  background: var(--nu-surface-2); color: var(--nu-txt2);
  border-radius: var(--nu-r-medium); font-size: 0.82rem; line-height: 1.6;
}
.di-why.urgent { background: var(--nu-warning-light-3); color: var(--nu-warning-text); }

/* ── 자료 업로드 화면 (2026-08-18, FlowTracer 업로드 이관) ────────────────── */
.up-drop {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 22px 16px; border: 2px dashed var(--nu-border); border-radius: var(--nu-r-large);
  background: var(--nu-surface-2); color: var(--nu-txt2); text-align: center;
}
.up-drop[aria-disabled="true"] { opacity: 0.75; }
.up-drop-ico { font-size: 22px; line-height: 1; color: var(--nu-txt3); }
.up-drop-sub { font-size: 0.8rem; color: var(--nu-txt3); }
.up-tbl { font-size: 0.76rem; color: var(--nu-txt3); }
.up-warn { background: var(--nu-warning-light); border-color: var(--nu-warning-border); color: var(--nu-warning-text); }
.up-notes { margin: 0; padding-left: 18px; color: var(--nu-txt2); font-size: 0.85rem; display: flex; flex-direction: column; gap: 4px; }

/* ═══════════════════════════════════════════════════════════════════════════
   화면 공통 표기 — 접은 유의사항 · 더 있는 표
   앞의 app.js NOTATION 상수가 어느 요소에 걸지 정하고, 여기는 모양만 맡는다.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 접어 둔 데이터 유의사항 ──
   닫힘 상태는 한 줄(약 26px). 펼치면 원문이 그대로 나온다. */
.data-note { margin: 0; }

.data-note > summary::before { content: "D8"; font-size: 0.82rem; line-height: 1; }
.data-note > summary::after { content: "BE"; font-size: 0.62rem; color: var(--nu-txt4); }
.data-note[open] > summary::after { content: "B4"; }

.data-note[open] > summary { margin-bottom: 6px; }
/* 접힌 안쪽 본문은 제 배경·테두리를 벗는다 — 상자 안에 상자가 겹쳐 보인다. */
.data-note > .inv-note,
.data-note > .home-note,
.data-note > .sched-mold-note,
.data-note > .di-f-note,
.data-note > .sa-note,
.data-note > .sa-f-note,
.data-note > .mm-f-note { background: none; border: 0; padding: 0 2px; margin: 0; }

/* ── 아직 더 있는 표 — 아래를 옅게 흐린다 ──
   .has-more 는 app.js 의 markScrollableTables() 가 실제 넘침을 재서 붙인다.
   ※ 카드에 건다(스크롤 상자에 걸면 내용과 같이 밀려 올라간다). */
#layoutRoot .panel.has-more,
#layoutRoot .viz-card.has-more,
#layoutRoot .home-card.has-more,
#layoutRoot .util-card.has-more,
#layoutRoot .ep-card.has-more,
#layoutRoot .inv-card.has-more,
#layoutRoot .sh-card.has-more,
#layoutRoot .sched-section.has-more { position: relative; }
#layoutRoot .panel.has-more::after,
#layoutRoot .viz-card.has-more::after,
#layoutRoot .home-card.has-more::after,
#layoutRoot .util-card.has-more::after,
#layoutRoot .ep-card.has-more::after,
#layoutRoot .inv-card.has-more::after,
#layoutRoot .sh-card.has-more::after,
#layoutRoot .sched-section.has-more::after {
  content: ""; position: absolute; left: 1px; right: 1px; bottom: 1px; height: 26px;
  background: linear-gradient(to bottom, transparent, var(--panel) 80%);
  border-radius: 0 0 var(--nu-r-large) var(--nu-r-large);
  pointer-events: none;
}
/* .sched-section 만 라운드가 한 단계 작다 — 그대로 두면 모서리에서 그림자가 삐져나온다. */
#layoutRoot .sched-section.has-more::after {
  border-radius: 0 0 var(--nu-r-medium) var(--nu-r-medium);
}


/* ═══════════════════════════════════════════════════════════════════════════
   §  style= 를 걷어내며 생긴 규칙들
   CSP 의 style-src 를 켜려면 마크업에 style= 가 하나도 없어야 한다. 값이 고정인 것은
   여기로 오고, 표 열너비처럼 그 표만의 수는 board-shell 의 paintInlineStyles 가 나른다.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 패널 몸통 ────────────────────────────────────────────────────────────
   .panel 자체는 안쪽 여백이 없다. 화면마다 무엇을 담느냐에 따라 넷으로 갈린다. */

/* 표 하나를 담는 패널 — 제목·조회줄·표가 세로로 선다. */
.panel.is-table-body {
  padding: 12px 16px 14px;
  display: flex; flex-direction: column; gap: 8px;
}

/* 설비 카드 격자를 담는 패널. 칸 수는 화면이 --ep-cols 로 넣어 준다. */
.panel.is-card-grid {
  padding: 12px 16px 14px;
  display: flex; flex-direction: column; gap: 10px;
}

/* 위젯 여럿을 세로로 쌓는 패널. */
.panel.is-widget-stack {
  padding: 18px 20px;
  display: flex; flex-direction: column; gap: 12px;
}

/* 설계 골격 화면 — 글이 주인이라 여백을 넓게 준다. */
.panel.is-outline {
  padding: 24px 28px;
  display: flex; flex-direction: column; gap: 14px;
}
/* 남는 높이를 안쪽에 넘겨야 할 때. flex 자식이 안 줄어드는 것을 푼다.
   ★ 아이디로 짚는다. 좁은 폭에서 #layoutRoot.fit-page > .panel 이 min-height: auto 로
     덮기 때문이다 — 종전에는 인라인이라 그것을 이기고 있었다. 클래스만으로는 진다. */
#layoutRoot .panel.is-outline.is-shrink { min-height: 0; }

/* 안내문만 있는 패널 — 아직 자료가 없거나 조건이 안 맞을 때 세운다. */
.panel.is-notice { padding: 28px; }

/* 자료를 부르는 동안 세우는 패널 안의 곁말. */
.pnl-note { color: var(--nu-txt3); }

/* ── 패널 안의 글 ─────────────────────────────────────────────────────── */

.pnl-title { margin: 0 0 8px; }
/* 바로 아래 설명이 따라붙는 제목은 더 좁게. */
.pnl-title.is-tight { margin-bottom: 4px; }

.pnl-desc { color: var(--nu-txt3); font-size: 0.9rem; }

/* 아직 확정되지 않은 것을 알리는 상자. */
.pnl-warn {
  padding: 12px 16px; border-radius: var(--nu-r-medium);
  background: var(--nu-warning-light); border: 1px solid var(--nu-warning-border);
  color: var(--nu-warning-text); font-size: 0.9rem;
}
/* 참고로 덧붙이는 상자 — 경고보다 한 단 낮다. */
.pnl-info {
  padding: 12px 16px; border-radius: var(--nu-r-medium);
  background: var(--nu-info-light); border: 1px solid var(--nu-info-border);
  color: var(--nu-info-text); font-size: 0.85rem;
}

.pnl-list {
  margin: 0; padding-left: 18px;
  color: var(--nu-txt2); font-size: 0.85rem;
  display: flex; flex-direction: column; gap: 4px;
}

/* 한 줄에 나란히 세우는 조각들. */
.pnl-row { display: flex; gap: 10px; align-items: center; }
/* 좁은 폭에서 접히는 변형 — 조각이 많은 줄에 쓴다. */
.pnl-row.is-wrap { gap: 12px; flex-wrap: wrap; }

/* ── 위젯 제목 사이 띄우기 ─────────────────────────────────────────────
   .viz-title 은 margin-bottom 만 갖는다. 한 패널에 위젯이 여럿일 때 위쪽도 띄운다. */
.viz-title.is-flush { margin: 0; }
.viz-title.is-gap { margin: 4px 0 0; }
.viz-title.is-gap-lg { margin: 6px 0 0; }

/* ── 그 밖 ────────────────────────────────────────────────────────────── */

/* 설비 칩 — 꾸러미 기본(130/120)보다 한 치수 좁게 세운다. */
.ep-mach-card.is-narrow { flex: 1 1 110px; min-width: 100px; }

/* 표 안에 들어가는 작은 배지. 꾸러미 기본은 단독으로 설 때의 크기다. */
.inj-badge.is-s { font-size: 0.72rem; padding: 1px 8px; }

/* 목록 머리말이 줄 맨 앞에 설 때 — 앞의 조각이 없으므로 들여쓰기를 뺀다. */
.inv-count.is-flush { margin-left: 0; }

/* 줄 오른쪽 끝으로 밀어 두는 버튼. */
.inj-del-btn.is-right { margin-left: auto; }

/* 시간·수량처럼 자릿수를 맞춰 읽는 칸. */
.dt-num { text-align: right; }

/* 팝업 안 좁은 선택기 — 교대처럼 값이 짧은 칸은 늘어나면 오히려 읽기 나쁘다. */
.popup-form-sel.is-narrow { max-width: 120px; }

/* ═══════════════════════════════════════════════════════════════════════════
   병합으로 옮겨 온 것 — 옛 styles.css 에 있던 이 보드 고유 규칙 (2026-09-01)
   ───────────────────────────────────────────────────────────────────────────
   꾸러미 도입 전에 styles.css 에 쌓아 둔 화면 규칙이다. 그 파일이 없어졌으므로
   여기로 옮긴다. 관리 화면(.theme-actions·.site-name-input)은 꾸러미가 제 것을
   들고 있어 옮기지 않았다.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 서버가 자리를 고정한 앞 4항목 — 접힘 목록의 나머지와 구별되게 세운다. */
.inj-rc-chip.key { background: var(--nu-primary-tint); font-weight: 600; }
.inj-rc-chip.key i { color: var(--nu-brand-text); }
.inj-rc-src { font-size: 0.74rem; color: var(--nu-txt4); margin-left: 2px; }

/* 스케줄확정 — 시뮬레이션 확정분 표시 (2026-08-19).
   현장 확정분(Oracle)과 이 시스템의 확정분을 한 표에 담되 출처를 구분한다.
   색이 아니라 글자('시뮬')가 판정을 담는다 — 색만으로 정보를 전달하지 않는다(§0-4). */
.sc-sim { background: var(--nu-info-light); color: var(--nu-info-text); border: 1px solid var(--nu-info-border); margin-left: 4px; }
/* 스케줄확정 — 확정분이 다른 계획일에 있을 때의 안내줄 */
.sc-hint { margin-top: 4px; }
.sc-hint .sc-jump { color: var(--nu-on-accent); text-decoration: underline; cursor: pointer; }

/* 스케줄확정 — [작업요청] 줄 (2026-08-19). 표 아래 우측에 둔다(목록을 다 본 뒤 누르는 동작이라). */
.sc-req-bar { display: flex; align-items: center; justify-content: flex-end; gap: 12px; padding-top: 4px; }
.sc-req-note { font-size: 0.82rem; color: var(--nu-txt3); }
.sc-req-btn {
  padding: 8px 22px; border-radius: var(--nu-r-medium); border: 0; cursor: pointer;
  background: var(--nu-primary); color: var(--nu-on-accent); font-size: 0.92rem; font-weight: 700;
}
.sc-req-btn:hover { filter: brightness(1.06); }
.sc-req-btn:disabled { cursor: not-allowed; opacity: 0.75; }
/* 완료 상태 — 색만이 아니라 글자('작업완료')가 상태를 담는다 */
.sc-req-btn.done { background: var(--nu-success-light); color: var(--nu-success-text); border: 1px solid var(--nu-success-border); }

/* ── 금형정보 관리 (015) — 금형자료 목록 + 상세(레시피·금형번호 매핑·제품/이미지) ──
   왼쪽은 훑는 목록, 오른쪽은 한 건을 깊게 본다. 매핑이 비어 있는 금형을 눈에 띄게 두는 것이
   이 화면의 일이라, '미지정'·'0' 은 흐리게가 아니라 **경고색**으로 둔다. */
/* ★위=금형목록, 아래=제품목록. 두 표는 성격이 다르다 — 위는 금형을 **찾는** 표,
   아래는 제품을 **관리하는** 표(사진을 붙인다). 한 표에 섞으면 금형 한 줄이 제품 수만큼
   늘어나 금형을 훑을 수 없게 된다. */
.mi-list, .mi-detail { padding: 12px 14px; margin-bottom: 14px; }
/* 목록은 높이를 묶는다 — 36건이 다 펼쳐지면 아래 제품 표가 화면 밖으로 밀린다 */
.mi-grid-wrap { max-height: 340px; overflow: auto; }
.mi-cap { margin-right: 12px; font-size: 14px; font-weight: 800; color: var(--nu-txt2); }
.mi-grid thead th small { margin-left: 6px; font-weight: 500; color: var(--nu-txt4); }
.mi-pcd { font-family: 'Consolas', monospace; }
.mi-psub { color: var(--nu-txt3); margin-left: 6px; }
.mi-more-n { margin-left: 6px; font-size: 11px; color: var(--nu-txt4); }
.mi-b-img { background: var(--nu-success-light); color: var(--nu-success-text); }
.mi-cnt { margin-left: 6px; color: var(--nu-brand-text); }
/* ★금형 목록은 줄 배경색을 쓰지 않는다 — 얼룩(zebra)·hover·선택 전부.
   이 표에는 이미 「미지정」·「제품 미매핑」 경고색이 칸 단위로 들어가 있어서, 줄 배경까지 깔면
   무엇이 경고이고 무엇이 그냥 짝수 줄인지 구분이 안 된다. 색은 경고에만 남긴다.
   ※ .inv-grid 공통 규칙(얼룩·hover)을 여기서만 덮어쓴다 — 다른 화면은 그대로 둔다. */
.mi-grid tbody tr { cursor: pointer; }
.mi-grid tbody tr,
.mi-grid tbody tr:nth-child(even),
.mi-grid tbody tr:hover,
.mi-grid tbody tr:hover td,
.mi-row.sel td { background: transparent; }

/* 선택 표시는 배경 대신 **왼쪽 막대 + 굵은 글자**로 — 배경을 뺐으니 다른 신호가 필요하다 */
.mi-row.sel td { font-weight: 700; }
.mi-row.sel td:first-child { box-shadow: inset 3px 0 0 var(--nu-primary); }
.mi-grid tbody tr:hover td { text-decoration-color: var(--nu-border-strong); }
.mi-name { font-family: 'Consolas', monospace; font-weight: 700; }
.mi-none { color: var(--nu-txt4); }
.mi-warn { color: var(--nu-warning-text); font-weight: 700; }

.mi-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 4px 2px 12px; }
.mi-h-name { font-size: 22px; font-weight: 800; font-family: 'Consolas', monospace; }
.mi-h-sub { margin-top: 4px; font-size: 13px; color: var(--nu-txt3); }
.mi-h-tag { flex: none; padding: 3px 12px; border-radius: var(--nu-r-pill);
  background: var(--nu-surface-2); color: var(--nu-txt2); font-size: 12px; font-weight: 700; }

.mi-sec { padding: 12px 0; border-top: 1px solid var(--nu-border); }
.mi-sec-t { font-size: 15px; font-weight: 800; color: var(--nu-txt2); margin-bottom: 10px; }
.mi-sec-t small { margin-left: 8px; font-size: 12px; font-weight: 500; color: var(--nu-txt3); }
.mi-sec-t2 { margin-top: 14px; }

.mi-tiles { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
@media (max-width: 1600px) { .mi-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.mi-tile { padding: 8px 10px; border-radius: var(--nu-r-medium); background: var(--nu-surface-2); }
.mi-tile > span { display: block; font-size: 12px; color: var(--nu-txt3); }
.mi-tile > b { display: block; margin-top: 2px; font-size: 17px; font-weight: 800; word-break: break-all; }
.mi-tiles-sm .mi-tile > b { font-size: 14px; }

/* ── 수기 등록 레시피 절 (금형정보 관리, 2026-09-06 합침) ──────────────────
   따로 있던 「금형 레시피 관리」 화면을 이 상세 칸으로 들였다. 값은 여기서 안 고치고
   기존 팝업을 그대로 연다 — 그 팝업이 사출조건 행 조작과 이미지를 이미 갖고 있다. */
.mi-rc-none {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 2px; font-size: 13px; color: var(--nu-txt3);
}
.mi-rc-foot {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: 8px; font-size: 12px; color: var(--nu-txt3);
}
.mi-rc-n b { color: var(--nu-txt1); font-weight: 800; }
/* 준비 메모가 있다는 것만 알린다 — 본문은 툴팁으로. 단말에는 안 띄우는 값이라
   여기서도 크게 펼치지 않는다 */
.mi-rc-note {
  padding: 1px 7px; border-radius: var(--nu-r-pill);
  background: var(--nu-primary-tint); color: var(--nu-brand-text); font-weight: 700;
}
/* 언제·누가 고쳤는지는 오른쪽 끝으로 민다 — 단추가 그 다음이다 */
.mi-rc-when { margin-left: auto; font-variant-numeric: tabular-nums; }

.mi-more summary { cursor: pointer; font-size: 14px; font-weight: 800; color: var(--nu-brand-text); padding: 10px 2px; }
.mi-more summary small { margin-left: 8px; font-size: 12px; font-weight: 500; color: var(--nu-txt3); }
.mi-more[open] > .mi-tiles { margin-top: 8px; }
.mi-dwrap { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.mi-dblock { display: flex; gap: 10px; align-items: baseline; }
.mi-dkind { flex: none; width: 92px; font-size: 12px; font-weight: 700; color: var(--nu-txt3); }
.mi-dlines { display: flex; flex-wrap: wrap; gap: 6px; }
.mi-dlines i { font-style: normal; font-size: 12px; padding: 2px 10px;
  border-radius: var(--nu-r-pill); background: var(--nu-surface-2); white-space: nowrap; }

.mi-form { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: flex-end; }
.mi-form label { display: flex; flex-direction: column; gap: 3px; font-size: 12px; color: var(--nu-txt3); }
.mi-form input, .mi-form select { min-width: 160px; }
.mi-form .mi-wide input { min-width: 280px; }
.mi-addrow { margin-top: 10px; }

.mi-ptable td { vertical-align: middle; }
.mi-p-img { width: 74px; }
.mi-p-img img { width: 64px; height: 44px; object-fit: contain;
  background: var(--nu-surface-2); border-radius: var(--nu-r-small); }
.mi-p-cd { font-family: 'Consolas', monospace; font-weight: 700; white-space: nowrap; }
.mi-p-primary td { background: var(--nu-success-light); }
.mi-badge { margin-left: 6px; padding: 1px 8px; border-radius: var(--nu-r-pill);
  background: var(--nu-primary); color: var(--nu-on-accent); font-size: 11px; font-weight: 700; }
.mi-p-act { white-space: nowrap; }
.mi-mini { margin-left: 4px; padding: 3px 10px; border-radius: var(--nu-r-small);
  border: 1px solid var(--nu-border-strong); background: var(--nu-card);
  font-family: inherit; font-size: 12px; cursor: pointer; }
.mi-mini.mi-del { color: var(--nu-alert-text); border-color: var(--nu-alert-text); }
/* 파일 입력은 브라우저마다 모양이 달라 버튼처럼 보이게 감싼다 */
.mi-upload { display: inline-block; padding: 3px 10px; border-radius: var(--nu-r-small);
  border: 1px solid var(--nu-border-strong); background: var(--nu-card);
  font-size: 12px; cursor: pointer; }
.mi-upload input { display: none; }

.mi-msg { margin-top: 10px; padding: 10px 14px; border-radius: var(--nu-r-large); font-weight: 700; }
.mi-msg.good { background: var(--nu-success-light); color: var(--nu-success-text); }
.mi-msg.fail { background: var(--nu-alert-light); color: var(--nu-alert-text); }

/* ── 사출기 연동 · 현장 화면 미러 (2026-08-26) ─────────────────────────────
   8/21 회의 §5 — 사무실에서 키오스크와 **같은 그림**을 본다. 다른 점은 조작이 잠겨 있다는 것뿐.
   A안일 때만 [생산시작]이 살아난다(현장이 준비완료를 보낸 뒤). */
.inj-mirror { padding: 12px 16px; margin-bottom: 14px; }
.inj-mirror-cap { display: flex; align-items: center; gap: 10px; font-size: 15px; font-weight: 800; color: var(--nu-txt2); margin-bottom: 10px; }
.inj-mirror-cap small { font-weight: 500; font-size: 12px; color: var(--nu-txt3); }
.inj-mode-sw { margin-left: auto; font-size: 12px; color: var(--nu-txt3); display: flex; align-items: center; gap: 6px; }
.inj-mode-btn { padding: 4px 14px; border-radius: var(--nu-r-pill); border: 1px solid var(--nu-border-strong);
  background: var(--nu-card); font-family: inherit; font-size: 12px; font-weight: 700; cursor: pointer; }
.inj-mode-btn.on { background: var(--nu-primary); color: var(--nu-on-accent); border-color: var(--nu-primary); }

.inj-mirror-body { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: 14px; align-items: stretch; }
@media (max-width: 1200px) { .inj-mirror-body { grid-template-columns: 1fr; } }
.inj-mcard { padding: 14px 18px; border-radius: var(--nu-r-large); background: var(--nu-surface-2); display: flex; flex-direction: column; gap: 8px; }
.inj-mhead { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.inj-mseq { padding: 2px 12px; border-radius: var(--nu-r-pill); background: var(--nu-primary-tint); color: var(--nu-brand-text); font-size: 13px; font-weight: 800; }
.inj-mitem { font-size: 20px; font-weight: 800; }
.inj-mpause { padding: 2px 10px; border-radius: var(--nu-r-pill); background: var(--nu-warning-light); color: var(--nu-warning-text); font-size: 13px; font-weight: 800; }
.inj-mkv { display: flex; align-items: baseline; gap: 14px; }
.inj-mkv > span { width: 44px; flex: none; font-size: 13px; color: var(--nu-txt3); }
.inj-mkv > b { font-size: 26px; font-weight: 800; font-family: 'Consolas', monospace; }
.inj-mkv > b i { font-style: normal; font-size: 13px; color: var(--nu-txt3); margin-left: 4px; font-family: inherit; }
.inj-mqty { margin-top: 4px; padding: 10px 14px; border-radius: var(--nu-r-medium); background: var(--nu-warning-light); }
.inj-mqty-head { display: flex; align-items: baseline; justify-content: space-between; font-size: 13px; font-weight: 700; color: var(--nu-warning-text); }
.inj-mqty-head i { font-style: normal; font-size: 11px; opacity: 0.8; }
.inj-mqty-num { font-size: 30px; font-weight: 900; font-variant-numeric: tabular-nums; margin: 2px 0 6px; }
.inj-mqty-num small { font-size: 15px; color: var(--nu-txt3); font-weight: 700; }
.inj-mqty-sub { margin-top: 6px; font-size: 12px; color: var(--nu-txt3); }
.inj-mwait { margin-top: 4px; padding: 14px; border-radius: var(--nu-r-medium); background: var(--nu-card); color: var(--nu-txt3); font-size: 15px; font-weight: 700; text-align: center; }

.inj-mside { display: flex; flex-direction: column; gap: 10px; justify-content: center; }
.inj-mhint { padding: 12px 14px; border-radius: var(--nu-r-medium); background: var(--nu-surface-2); font-size: 13px; font-weight: 600; color: var(--nu-txt2); line-height: 1.5; }
.inj-macts { display: flex; gap: 10px; }
.inj-mbtn { flex: 1; min-height: 62px; border: none; border-radius: var(--nu-r-large);
  font-family: inherit; font-size: 22px; font-weight: 900; color: var(--nu-on-accent); cursor: pointer; }
.inj-mbtn:disabled { background: var(--nu-surface-4); color: var(--nu-txt4); cursor: default; }
.inj-mbtn.start { background: var(--nu-primary); }
.inj-mbtn.pause { background: var(--kpi-st-warn, #b7791f); }
.inj-mbtn.end { background: var(--k-miss, #d93025); flex: 0 0 130px; }
.inj-mbtn.wait { background: var(--nu-surface-4); color: var(--nu-txt3); }

/* 호기 카드 → 설비 상세현황 링크 (2026-08-26)
   누를 수 있다는 것이 보여야 한다 — 손 커서·테두리·살짝 떠오름. 색은 쓰지 않는다
   (카드 색은 달성률 등급을 뜻하므로, 링크 표시에 색을 쓰면 등급과 헷갈린다). */
.ep-card.ep-link { cursor: pointer; transition: transform 0.08s, box-shadow 0.12s, border-color 0.12s; }
.ep-card.ep-link:hover { transform: translateY(-2px); box-shadow: var(--nu-elev-medium); border-color: var(--nu-border-strong); }
.ep-card.ep-link:focus-visible { outline: 3px solid var(--nu-primary); outline-offset: 2px; }
.ep-card.ep-link::after {
  content: '상세 ›'; position: absolute; right: 12px; bottom: 10px;
  font-size: 11px; font-weight: 700; color: var(--nu-txt3); opacity: 0; transition: opacity 0.12s;
}
.ep-card.ep-link { position: relative; }
.ep-card.ep-link:hover::after, .ep-card.ep-link:focus-visible::after { opacity: 1; }

/* 접은 메뉴 (2026-08-27) — 지운 것이 아니라 **감춘** 것이다.
   라우트·코드·권한은 그대로여서 주소로는 열린다. 되살리기는 HTML 에서 class 만 빼면 된다.
   근거: docs/화면정리_검토_2026-08-27.md */
.nav-sub a.nav-folded { display: none; }
/* ── 사이드바 층 소제목 (2026-09-06 재구성) ───────────────────────────────
   기준정보 / 업무 / 분석 / 운영 넷을 가르는 줄이다. **접히지 않는다** —
   층까지 <details> 로 만들면 3단이 되어 항목 하나 찾는 데 두 번 펴야 한다.

   글자는 묶음 머리(--nu-txt3)와 항목(--nu-txt2)보다 한 단 위라 --nu-txt1 이다.
   ★ 색 리터럴을 쓰지 않는다. 꾸러미 기본값은 어두운 사이드바를 전제하는데 이
     보드는 흰 면이라, 흰색 알파를 적었더니 글자가 통째로 안 보였다. 토큰을 쓰면
     톤을 바꿔도 따라 돈다. */
.nav-section {
  /* 여백은 되도록 아낀다 — 소제목 넷이 사이드바를 205px 늘렸고(실측 1214->1419)
     보이는 높이는 1036 이라 이미 스크롤된다 */
  margin: 9px 0 1px;
  padding: 5px 12px 4px;
  color: var(--nu-txt1);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  border-top: 1px solid var(--nu-border-l);
}
/* 첫 층은 홈 바로 아래라 선을 긋지 않는다 — 홈과 갈라 놓을 것이 없다 */
.nav-section:first-of-type { margin-top: 10px; border-top: none; }

/* 층 바로 아래 평평하게 두는 링크. 묶을 만큼 화면이 많지 않은 자리에 쓴다
   (기준정보 · 분석). 꾸러미의 .nav-group .nav-sub a 와 같은 들여쓰기·크기라
   묶음 안의 항목과 나란히 보인다. */
.nav-flat { display: grid; gap: 5px; }
.nav-flat a { padding-left: 24px; font-size: 0.88rem; }
.nav-flat a.nav-folded { display: none; }


/* ── CSP 대응 (2026-09-01) ────────────────────────────────────────────────
   style= 속성은 style-src 가 막는다(꾸러미 0.11.0). 값이 그때그때 다른 것은
   data-fill-w 로 넘겨 셸이 칠하고, 고정값은 여기 이름을 붙인다. */
.inv-empty.inj-mirror-empty { padding: 26px; }   /* 현장 화면 미러 — 빈 상태 */
.k-track.inj-mtrack { height: 14px; }            /* 미러의 진행 막대는 본 화면보다 낮다 */
.panel.inv-empty.mi-empty { padding: 24px; }     /* 금형정보 — 금형을 고르기 전 안내 */

/* ── 그룹 헤더를 제목처럼 세운다 (2026-09-01 요청) ─────────────────────────
   꾸러미 원본은 그룹 헤더를 "제목"이 아니라 **작고 자간 넓은 라벨**(11px/700,
   데스크톱 10.5px)로 두었다. 여기서는 그 판단을 뒤집어 크고 굵게 간다 —
   그룹이 9개라 훑을 때 먼저 걸리는 것이 그룹명이어야 한다는 요청이다.

   ★ 이 한 줄이 꾸러미의 기본 규칙과 데스크톱 미디어쿼리(min-width:1201px)를
     한꺼번에 이긴다 — 미디어 질의는 명시도를 올리지 않고, 이 파일이 나중에 실린다.
     그래서 여기 값을 지우면 10.5px 로 되돌아간다(두 곳을 고칠 필요는 없다).
   ★ 자간은 줄인다. 0.06em 은 작은 라벨이라 넣었던 값이고, 13px 에서는 글자가
     흩어져 보인다.
   ★ 높이 예산 — 그룹 하나당 약 +4px(9그룹 = 약 +36px). 모든 그룹을 펼친
     관리자 화면에서는 사이드바가 스크롤될 수 있다. 그때는 항목 padding 을
     5px → 4px 로 줄여 되사면 된다(항목 1px = 전체 약 28px). */
.nav-group > summary {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.01em;
}

/* ── 스케줄확정 — 소요시간·시작/완료 예상 · 금형교체 (2026-09-01) ────────
   회의 요구(08-13 작업지시별 소요시간·예상 시각 / 05-21·07-30 금형교체 횟수). */
.sc-dur { font-variant-numeric: tabular-nums; white-space: nowrap; }
/* 차종 대표 C/T 로 낸 추정치 표시 — 색이 아니라 기호가 뜻을 담는다(§0-4) */
.sc-est { margin-left: 3px; color: var(--nu-txt3); font-weight: 700; }
.sc-goal-sub { margin-left: 6px; font-size: 0.78rem; font-weight: 500; color: var(--nu-txt3); }
/* 목표를 넘긴 금형교체 — 상태색은 채움 전용이라 글자에는 text 톤을 쓴다 */
.home-kri-goal b.sc-over { color: var(--nu-warning-text); }

/* ═══ 「생성중인 생산계획」 6단계 진행 보드 (2026-09-01) ══════════════════
   cheil_poc 에서 역이식했다. 원래 SimAPS 의 단계 표시를 저쪽이 가져가 다듬은 것을
   다시 받아 온 것이다. 칸은 **과정을 보여 주는 것**이지 구간을 잰 계측값이 아니다
   (근거·규칙은 app.js 의 SIM_STEPS 머리주석).
   ★ 깜빡임(simVideoPulse)은 꾸러미 styles.css 가 이미 정의해 두었다 — 다시 만들지 말 것. */
.sched-steps-slot { margin-bottom: 10px; }

.sched-steps-board { border: 1px solid var(--border); border-radius: var(--nu-r-large);
  background: var(--panel); padding: 12px 14px 14px; }
/* 실행 중인 작업이 없을 때 — 칸 없이 한 줄. 박스도 그만큼 낮아진다. */
.sched-steps-board.is-idle { padding: 10px 14px; }
.sched-steps-empty { font-size: .84rem; color: var(--nu-txt4); }

.sched-steps-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 12px; flex-wrap: wrap; }
.sched-steps-name { font-size: .95rem; font-weight: 800; color: var(--nu-txt1); }
.sched-steps-meta { font-size: .78rem; color: var(--nu-txt3); }
.sched-steps-time { margin-left: auto; font-size: .82rem; color: var(--nu-txt2);
  font-variant-numeric: tabular-nums; }
.sched-steps-time b { font-weight: 800; color: var(--nu-warning-text); }
.sched-steps-time.is-done { color: var(--nu-success-text); font-weight: 700; }
.sched-steps-time.is-done b { color: var(--nu-success-text); }

.sched-steps { display: flex; align-items: stretch; gap: 6px; }
.sched-step { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column;
  align-items: center; gap: 7px; padding: 14px 8px 12px;
  background: var(--nu-surface-2); border: 1px solid var(--border);
  border-radius: var(--nu-r-large); transition: background .2s, border-color .2s; }
.sched-step-no { display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: var(--nu-r-pill);
  background: var(--nu-surface-3); color: var(--nu-txt4); font-size: .82rem; font-weight: 800; }
.sched-step-label { font-size: .78rem; font-weight: 600; line-height: 1.35;
  color: var(--nu-txt3); text-align: center; }
.sched-step-state { min-height: 16px; font-size: .74rem; font-weight: 700; color: transparent; }
.sched-step-arrow { align-self: center; color: var(--nu-txt4); font-size: 1rem; flex: none; }

/* 끝난 칸 — 번호를 성공색으로, 상태는 ✓ */
.sched-step.is-done .sched-step-no { background: var(--nu-success-text); color: var(--nu-on-accent); }
.sched-step.is-done .sched-step-label { color: var(--nu-txt2); }
.sched-step.is-done .sched-step-state { color: var(--nu-success-text); }

/* 지금 도는 칸 — 강조 테두리 + 깜빡이는 '진행중' */
.sched-step.is-active { background: var(--nu-primary-tint); border-color: var(--nu-primary); }
.sched-step.is-active .sched-step-no { background: var(--accent2); color: var(--nu-on-accent); }
.sched-step.is-active .sched-step-label { color: var(--nu-txt1); }
.sched-step-state.is-run { color: var(--nu-warning-text); animation: simVideoPulse 1.2s ease-in-out infinite; }

@media (max-width: 1100px) {
  .sched-step-label { font-size: .72rem; }
  .sched-step-arrow { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .sched-step-state.is-run { animation: none; }
}

/* ─── 엔진이 낸 시뮬레이션 결과 ────────────────────────────────────────────────
   표본 결과와 컬럼이 달라 표시도 갈라 둔다. 어느 쪽을 보고 있는지가 화면에
   드러나야 한다 — 같은 모양이면 표본을 실제로 착각한다. */
.simr-engine-tag {
  margin-left: .5rem; padding: .12rem .5rem; border-radius: 999px;
  font-size: .76rem; color: var(--nu-txt3);
  background: var(--nu-bg3); border: 1px solid var(--nu-line);
}
.simr-engine-summary {
  display: flex; flex-wrap: wrap; gap: .35rem .9rem;
  padding: .55rem .75rem; margin-bottom: .6rem;
  background: var(--nu-bg2); border: 1px solid var(--nu-line); border-radius: 6px;
}
.simr-sum-cell { font-size: .82rem; color: var(--nu-txt3); }
.simr-sum-cell b { font-size: .95rem; color: var(--nu-txt1); margin-right: .15rem; }

/* 시간축에서 창 안에 못 끝낸 자원 — 병목이 어디인지 한눈에 보이게 한다 */
.sched-table tr.is-blocked td { background: color-mix(in srgb, var(--kpi-st-warn) 12%, transparent); }
.sched-table tr.is-blocked td:first-child { font-weight: 600; }

/* 엔진이 안 떠 있는 것을 화면이 말하는 자리. 조용한 빈 화면과 구분한다 */
.sched-steps-board.is-engine-down {
  border-color: var(--nu-warn, #c2703a);
  background: var(--nu-bg2);
}
.sched-hint { margin-top: .5rem; font-size: .8rem; color: var(--nu-txt4); }
/* 스케줄링 설정 — 하단 액션 바의 [스케줄링 요청현황] 은 오른쪽 끝에 세운다.
   왼쪽은 '이 화면에서 정하는 것'(옵션·이름·비가동), 오른쪽은 '여기서 나가는 길'이라
   자리로 역할이 갈린다. 바가 flex 라 margin-left:auto 하나면 된다. */
.sched-action-bar .sched-status-btn { margin-left: auto; }

/* 비가동 화면 하단 — [스케줄링 설정] 과 [스케줄링 시작] 이 붙지 않게 사이를 띄운다.
   꾸러미의 .sched-bottom-bar 는 flex-end 만 걸려 있고 gap 이 없다. 결과 화면의 같은
   바에는 영향이 없도록 이 화면으로 한정한다. */
#layoutRoot.sim-downtime-page .sched-bottom-bar { gap: 8px; }

/* ── 스케줄링 요청내역 표 ──────────────────────────────────────────────
   자동 정렬 판정(applyTableAlignment)에서 뺀 표라 정렬을 여기서 정한다.
   전부 가운데, 스케줄링명만 왼쪽 — 이름은 읽는 값이라 왼쪽이 눈이 편하고
   나머지는 형식이 일정한 일시·코드라 가운데가 줄이 맞는다.
   너비는 table-layout:fixed 로 못박는다. auto 로 두면 내용 길이에 따라
   열이 매번 달라져 "폭을 키웠다"가 자료에 따라 도로 좁아진다. */
.sched-hist-wrap .sched-hist-table { table-layout: fixed; }
.sched-hist-wrap .sched-hist-table th,
.sched-hist-wrap .sched-hist-table td { text-align: center; }

/* 스케줄링명 — 왼쪽 정렬. 길면 말줄임하고 전체는 title 로 보인다(잘린 줄 모르면 안 된다). */
.sched-hist-wrap .sched-hist-table th:nth-child(1),
.sched-hist-wrap .sched-hist-table td:nth-child(1) {
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 날짜 열이 내용보다 100px 씩 벌어져 있던 여유를 스케줄링명으로 옮긴다(127px → 313px). */
.sched-hist-wrap .sched-hist-table th:nth-child(1) { width: 19%; }
.sched-hist-wrap .sched-hist-table th:nth-child(2) { width: 11%; }
.sched-hist-wrap .sched-hist-table th:nth-child(3),
.sched-hist-wrap .sched-hist-table th:nth-child(4),
.sched-hist-wrap .sched-hist-table th:nth-child(5) { width: 12%; }
.sched-hist-wrap .sched-hist-table th:nth-child(6) { width: 8%; }
.sched-hist-wrap .sched-hist-table th:nth-child(7) { width: 5%; }
.sched-hist-wrap .sched-hist-table th:nth-child(8) { width: 8%; }
.sched-hist-wrap .sched-hist-table th:nth-child(9) { width: 13%; }
