/* ═══════════════════════════════════════════════════════════════════
   화면 스타일 — 색 리터럴(#hex)이 이 파일에 단 하나도 없다.
   색·라운드·간격은 전부 tokens.css 의 토큰을 참조하고,
   톤 교체는 themes.css 가 그 토큰만 덮어써서 처리한다.
   ※ 로드 순서: tokens.css → styles.css → themes.css
   ※ 여기에 새 색을 쓸 일이 생기면 hex를 적지 말고 tokens.css 에 토큰을 먼저 만들 것.
═══════════════════════════════════════════════════════════════════ */
/* ── 기본 ──────────────────────────────────────────────────────── */
* {
  box-sizing: border-box;
  word-break: keep-all;
  overflow-wrap: break-word;
}

/* §3-A 전역 타이포 — Pretendard + 한글 자간 보정(-0.01em), 제목은 -0.02em */
html {
  font-family: 'Pretendard Variable', 'Pretendard', 'Noto Sans KR', 'Malgun Gothic', '맑은 고딕',
               -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  letter-spacing: -0.01em;
  text-rendering: optimizeLegibility;
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
h1, h2, h3 { letter-spacing: -0.02em; }

/* §4-D 얇은 스크롤바 · ::selection (전역) */
::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: var(--nu-surface-3); }
::-webkit-scrollbar-thumb { background: var(--nu-surface-4); border-radius: var(--nu-r-small); }
::-webkit-scrollbar-thumb:hover { background: var(--jv-primary); }
::selection { background: var(--nu-primary-selection); color: var(--jv-txt1); }

html, body {
  height: 100%;
}

body {
  margin: 0;
  font-family: inherit;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  overflow: hidden;
}

/* ── 앱 레이아웃 ────────────────────────────────────────────────── */
.app-shell {
  display: grid;
  grid-template-columns: 240px 1fr;
  height: 100vh;
}

.sidebar-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.72);
  z-index: 250;
}
.sidebar-backdrop.show { display: block; }

/* ── 사이드바 ───────────────────────────────────────────────────── */
.sidebar {
  display: flex;
  flex-direction: column;
  padding: 24px;
  gap: 24px;
  background: var(--sidebar);
  border-right: 1px solid rgba(255,255,255,0.08);
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.brand {
  display: flex;
  align-items: center;
  gap: 14px;
}

.logo {
  width: 46px;
  height: 46px;
  border-radius: var(--nu-r-large);
  background: linear-gradient(135deg, var(--brand-ci) 0%, var(--brand-ci-dark) 100%);
  box-shadow: 0 2px 8px rgba(237,28,36,0.35);
  flex-shrink: 0;
}

/* (주)오토젠 CI 마크 — 다크 사이드바 위 흰 칩에 배치 */
.brand-ci {
  height: 46px;
  width: auto;
  background: var(--nu-card);
  border-radius: var(--nu-r-large);
  padding: 6px 9px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.22);
  flex-shrink: 0;
}

.brand span {
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--nu-on-accent);
  letter-spacing: -0.01em;
}

.nav {
  display: grid;
  gap: 6px;
}

.nav a {
  display: block;
  padding: 11px 16px;
  text-decoration: none;
  color: rgba(255,255,255,0.75);
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.07);
  border-radius: var(--nu-r-large);
  font-size: 0.92rem;
  font-weight: 500;
  transition: background 0.15s, color 0.15s;
}

.nav a:hover,
.nav a.active {
  background: rgba(255,255,255,0.15);
  color: var(--nu-on-accent);
  border-color: rgba(255,255,255,0.18);
}

/* ── 8분류 그룹 네비게이션 (오토젠_웹_화면설계_기초자료 §1~8) ── */
.nav-group { display: grid; gap: 6px; }
.nav-group > summary {
  list-style: none;
  cursor: pointer;
  padding: 8px 12px 6px;
  color: rgba(255,255,255,0.5);
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  display: flex;
  align-items: center;
  justify-content: space-between;
  user-select: none;
}
.nav-group > summary::-webkit-details-marker { display: none; }
.nav-group > summary::after {
  content: '▸';
  font-size: 0.68rem;
  opacity: 0.55;
  transition: transform 0.15s;
}
.nav-group[open] > summary::after { transform: rotate(90deg); }
.nav-group .nav-sub { display: grid; gap: 5px; }
.nav-group .nav-sub a { padding-left: 24px; font-size: 0.88rem; }

/* ── 반응형: 좁은 화면(태블릿/모바일 가로)에서는 사이드바를 드로어로 전환 ──── */
@media (max-width: 1200px) {
  .app-shell { grid-template-columns: 1fr; }

  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    width: 240px;
    height: 100vh;
    z-index: 300;
    transform: translateX(-100%);
    transition: transform 0.22s ease;
    box-shadow: 4px 0 24px rgba(0,0,0,0.3);
  }
  .sidebar.open { transform: translateX(0); }
}
@media (min-width: 1201px) {
  .sidebar-backdrop { display: none !important; }
}

/* ── 메인 콘텐츠 ────────────────────────────────────────────────── */
.main-content {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  min-width: 0;
}

/* ── 탑바 ───────────────────────────────────────────────────────── */
.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 28px;
  height: 56px;
  background: var(--header);
  border-bottom: 1px solid rgba(255,255,255,0.08);
  position: sticky;
  top: 0;
  z-index: 10;
  flex-shrink: 0;
}

.topbar-left {
  display: flex;
  align-items: center;
  gap: 14px;
}

.menu-btn {
  width: 34px;
  height: 34px;
  border: none;
  border-radius: var(--nu-r-medium);
  background: rgba(255,255,255,0.1);
  color: var(--nu-on-accent);
  cursor: pointer;
  font-size: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
}

.page-title {
  font-size: 1rem;
  font-weight: 700;
  color: var(--nu-on-accent);
  letter-spacing: -0.01em;
}

.topbar-right {
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 0.85rem;
  font-weight: 600;
  color: rgba(245,245,245,0.8);
}

.user-chip {
  padding: 5px 12px;
  border: none;
  border-radius: var(--nu-r-pill);
  background: rgba(255,255,255,0.1);
  color: var(--nu-on-accent);
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s;
}
.user-chip:hover { background: rgba(255,255,255,0.2); }

.logout-btn {
  padding: 5px 14px;
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: var(--nu-r-medium);
  background: rgba(255,255,255,0.05);
  color: rgba(255,255,255,0.85);
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.logout-btn:hover {
  background: rgba(255,255,255,0.15);
  color: var(--nu-on-accent);
}

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

/* ── 히어로 ─────────────────────────────────────────────────────── */
.hero {
  display: grid;
  gap: 2px;
  padding: 8px 28px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-xl);
  box-shadow: var(--shadow);
}

.hero-title {
  font-size: 2.2rem;
  font-weight: 800;
  line-height: 1.15;
  text-align: center;
  color: var(--text);
  letter-spacing: -0.02em;
}

.hero-subtitle {
  text-align: center;
  color: var(--muted);
  font-size: 0.95rem;
  line-height: 1.2;
  min-height: 1.2em;
}

.hero-title,
.hero-subtitle,
.page-title {
  word-break: keep-all;
}

/* ── 공통 레이아웃 ─────────────────────────────────────────────── */
.layout-root {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 18px;
}

/* ── 반응형 공통 규칙 (기준 해상도 1920×1080) ──────────────────────
   그리드/플렉스 자식은 기본값이 min-width:auto 라서 "내용의 최소 폭" 아래로는 줄지 않는다.
   Chart.js 캔버스는 렌더 시점 폭이 인라인 style로 박히므로, 넓은 화면에서 열어둔 뒤 창을
   좁히면 그 캔버스 폭에 레이아웃이 잠겨 아무 반응이 없다(새로 열면 정상 → 재현 조건이 헷갈림).
   캔버스는 컨테이너가 줄어야 줄고 컨테이너는 캔버스 때문에 못 주는 교착이라, 아래 min-width:0
   으로 바닥을 풀어줘야 한다. 1920에서는 시각적 변화가 없다. */
.content, .layout-root, .layout-root > * { min-width: 0; }
.home-kri-cards > *, .home-kpi-row > *, .home-mid > *, .home-bot > *,
.viz-grid > *, .inj-grid > *, .prod-layout > *, .ed-grid > *,
.layout-grid > *, .tables-grid > *, .dash-stat-row > *, .dash-mid-section > *,
.sh-factory-row > *, .sh-footer > *, .util-row > *, .ep-card-grid > * { min-width: 0; }
.panel, .viz-card, .home-card, .home-kpi, .home-kri-card { min-width: 0; }
canvas { max-width: 100%; }

/* 브라우저 한 화면 무스크롤: 페이지를 창 높이에 맞추고 넘치는 표만 내부 스크롤.
   표에 걸린 max-height(px·calc)는 창 높이마다 어긋나므로 "남은 공간을 채우는" 방식으로 대체한다.
   ※ 브라우저 실제 뷰포트는 주소창·탭바 때문에 모니터 해상도보다 100~150px 작다(1080 → 약 937). */
#layoutRoot.fit-page { display: flex; flex-direction: column; flex: 1; min-height: 0; }
#layoutRoot.fit-page > .panel,
#layoutRoot.fit-page > .inv-tab-content,
#layoutRoot.fit-page > .demand-panel { flex: 1; min-height: 0; display: flex; flex-direction: column; }
/* 남은 높이를 먹는 표는 "플렉스 열의 직계 자식"인 것만 대상으로 한다.
   더 깊이 중첩된 표(예: 생산실적의 좌우 2단 안쪽)는 부모가 높이를 제한하지 않아
   max-height를 풀면 표가 무한히 늘어난다 — 그런 화면은 기존 계산식을 그대로 둔다. */
#layoutRoot.fit-page > .panel > .inv-grid-wrap,
#layoutRoot.fit-page > .panel > .demand-grid-wrap,
#layoutRoot.fit-page > .panel > .sc-table-wrap,
#layoutRoot.fit-page > .panel > .ep-table-wrap,
#layoutRoot.fit-page > .panel > .simr-table-wrap,
#layoutRoot.fit-page > .panel > .wr-table-wrap,
#layoutRoot.fit-page > .panel > .ed-table-wrap,
#layoutRoot.fit-page > .panel > .table-wrapper,
#layoutRoot.fit-page > .panel > .home-card > .inv-grid-wrap,
#layoutRoot.fit-page > .inv-tab-content > .panel > .inv-grid-wrap,
#layoutRoot.fit-page > .demand-panel > .demand-grid-wrap { flex: 1 1 auto; min-height: 96px; max-height: none !important; overflow: auto; }
/* 재고현황은 탭 구조라 본문이 .inv-tab-content > .panel 로 한 단계 더 들어간다.
   그 .panel 이 남는 높이를 받아 안에서 다시 표에 넘겨준다. */
#layoutRoot.fit-page > .inv-tab-content > .panel { flex: 1; min-height: 0; display: flex; flex-direction: column; }
#layoutRoot.fit-page > .panel > .home-card { flex: 1 1 auto; }
/* 차트가 든 카드도 남은 높이에 맞춰 늘고 준다(고정 높이면 짧은 창에서 표를 밀어낸다) */
#layoutRoot.fit-page .home-card { display: flex; flex-direction: column; min-height: 0; }
/* 카드가 여러 줄인 블록은 남는 높이만큼만 쓰고, 모자라면 그 블록 안에서만 스크롤한다
   (페이지 전체가 스크롤되는 것보다 낫다 — 표·차트는 항상 화면에 남는다) */
/* 호기 카드 줄은 제 높이를 지킨다(눌리면 아래 차트와 겹친다) — 남는 높이는 아래 차트가 먹는다 */
#layoutRoot.fit-page > .panel > .util-row { flex: 0 0 auto; }
#layoutRoot.fit-page > .panel > .inj-grid { flex: 1 1 auto; min-height: 0; }
#layoutRoot.fit-page > .panel > .inj-grid > .viz-card { overflow: auto; min-height: 0; }
/* 표 위에 오는 요약·차트·필터 줄은 자기 높이 유지(표만 늘어나고 줄어든다) */
#layoutRoot.fit-page .inv-filter-bar,
#layoutRoot.fit-page .fr-banner,
#layoutRoot.fit-page .viz-grid,
#layoutRoot.fit-page .viz-card,
#layoutRoot.fit-page .ep-mach-row,
#layoutRoot.fit-page .inv-note { flex: 0 0 auto; }

/* ── 1100↓ 무스크롤 해제 (홈 외 전 화면) ────────────────────────────
   fit-page는 "창 높이에 맞추고 표만 내부 스크롤"이 전제다. 좁은 화면에서 차트 카드가
   1열로 접히면 같은 높이에 내용이 2배로 들어가 카드가 짓눌린다(홈 대시보드와 같은 원인).
   폭이 좁아지면 세로로 길어지는 게 정상이므로 페이지 스크롤을 허용한다.
   ※ .content 는 이미 overflow-y:auto 라 별도 처리가 필요 없다. */
@media (max-width: 1100px) {
  #layoutRoot.fit-page { flex: 0 0 auto; min-height: auto; }
  #layoutRoot.fit-page > .panel,
  #layoutRoot.fit-page > .inv-tab-content,
  #layoutRoot.fit-page > .inv-tab-content > .panel,
  #layoutRoot.fit-page > .demand-panel { flex: 0 0 auto; min-height: auto; }
  /* 표는 화면 높이 기준으로 되돌린다 — 안 그러면 수천 행이 그대로 늘어난다 */
  #layoutRoot.fit-page .inv-grid-wrap,
  #layoutRoot.fit-page .demand-grid-wrap { flex: 0 0 auto; max-height: 60vh !important; }
  /* 차트는 폭에 비례한 고정 높이 */
  #layoutRoot.fit-page .viz-wrap,
  #layoutRoot.fit-page .ep-viz-wrap { flex: 0 0 auto; height: clamp(180px, 40vw, 280px); }
  #layoutRoot.fit-page .viz-card { overflow: hidden; }
}

/* ── 창 높이가 짧을 때 단계 축소 (모든 화면 공통) ─────────────────── */
@media (max-height: 900px) {
  .hero { padding: 6px 24px; }
  .hero-title { font-size: 1.75rem; }
  .hero-subtitle { font-size: 0.86rem; }
  .util-card { padding: 9px 11px; }
}
@media (max-height: 780px) {
  .content { padding: 16px 22px; gap: 14px; }
  .hero { padding: 4px 20px; }
  .hero-title { font-size: 1.4rem; }
  .hero-subtitle { display: none; }
  .util-row { gap: 9px; }
  .util-card { padding: 7px 9px; }
  .util-mn { font-size: 0.86rem; }
  .util-sub { font-size: 0.72rem; }
  .viz-card { padding: 8px 12px; }
  .fr-banner { padding: 6px 12px; font-size: 0.8rem; }
  .kri-totals .home-kri-card { padding: 6px 10px; }
  .kri-totals .home-kri-desc { display: none; }
  .inj-form { gap: 7px; }
  .inj-steps { margin: 2px 0 7px; }
  .inj-mon { margin-top: 9px; padding-top: 9px; }
  .inj-mon-num b { font-size: 1.25rem; }
}
@media (max-height: 700px) {
  .content { padding: 12px 20px; gap: 10px; }
  .hero { display: none; }
  /* 가동현황 — 호기 카드를 더 낮게(한 줄 배치는 유지, 게이지는 vh로 자동 축소) */
  .util-row { gap: 7px; }
  .util-card { padding: 6px 7px; }
  .util-card .util-sub:last-child { display: none; }
  /* 사출기 연동 — 배너·카드 압축 */
  .fr-banner { font-size: 0.75rem; padding: 5px 10px; }
  .inj-machine-hdr { padding: 6px 12px; }
  .inj-precond { padding: 5px 9px; font-size: 0.74rem; }
  .inj-form { gap: 5px; }
  .inj-form label { font-size: 0.8rem; }
  .inj-step { font-size: 0.72rem; padding: 3px 8px; }
  .inj-badge { font-size: 0.84rem; padding: 4px 11px; }
  .inj-mon { margin-top: 7px; padding-top: 7px; }
  .inj-mon-num b { font-size: 1.1rem; }
  .inj-addr, .inj-mon-sub { font-size: 0.7rem; }
  .viz-card { padding: 7px 10px; }
}

.layout-grid {
  display: grid;
  gap: 18px;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}

/* ── 위젯 패널 (공통 카드) ─────────────────────────────────────── */
.widget-panel {
  padding: 20px 22px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-xl);
  box-shadow: var(--shadow);
}

.widget-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 14px;
}

.widget-title {
  font-size: 1rem;
  font-weight: 700;
  color: var(--text);
}

/* 표를 담는 패널이 부모로부터 유한한 높이를 받으면, 헤더는 고정하고
   표 영역만 내부 스크롤되게 함 (페이지 전체는 스크롤되지 않도록) */
.table-widget-panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.table-widget-panel .widget-header { flex: 0 0 auto; }
.table-scroll-wrap {
  flex: 1;
  min-height: 0;
  overflow: auto;
}
.table-scroll-wrap th {
  position: sticky;
  top: 0;
  z-index: 1;
}

/* ── 기본 테이블 ─────────────────────────────────────────────────── */
table {
  width: 100%;
  border-collapse: collapse;
  color: var(--text);
}

th, td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}

th {
  text-align: left;
  background: var(--th-bg);
  color: var(--th-text);
  font-size: 0.88rem;
  font-weight: 600;
}

tbody tr:hover {
  background: var(--row-hover);
}

tbody tr:nth-child(even) {
  background: var(--row-alt);
}

/* ── 필터 ────────────────────────────────────────────────────────── */
.filters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 14px;
  padding: 18px 0;
}

.filter-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.filter-group label {
  font-size: 0.88rem;
  color: var(--muted);
}

.filter-group select {
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--nu-r-large);
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text);
  font-size: 0.88rem;
}

.filter-group select option {
  background: var(--nu-card);
  color: var(--text);
}

.filter-group select:focus {
  outline: none;
  border-color: var(--nu-primary);
  box-shadow: 0 0 0 3px rgba(130,10,209,0.12);
}

/* ── 카드 그리드 ─────────────────────────────────────────────────── */
.cards-row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
}

.info-card {
  padding: 20px;
  border-radius: var(--nu-r-xl);
  background: var(--panel);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
}

.info-label {
  font-size: 0.88rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  margin-bottom: 10px;
  color: var(--muted);
  word-break: keep-all;
}

.info-value {
  font-size: 1.9rem;
  font-weight: 700;
  color: var(--text);
}

.info-detail {
  margin-top: 8px;
  color: var(--muted);
  font-size: 0.85rem;
}

.red-card    { border-left: 5px solid var(--nu-alert); }
.yellow-card { border-left: 5px solid var(--nu-warning); }
.green-card  { border-left: 5px solid var(--nu-success); }
.blue-card   { border-left: 5px solid var(--nu-primary); }

/* ── 차트 ────────────────────────────────────────────────────────── */
.charts-grid {
  display: grid;
  grid-template-columns: 2fr 1.2fr;
  gap: 18px;
}

.chart-box,
.table-card {
  padding: 20px 22px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-xl);
  box-shadow: var(--shadow);
}

.chart-title,
.card-title {
  margin-bottom: 14px;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--text);
}

.chart-box canvas {
  width: 100% !important;
  height: 300px !important;
}

/* ── 대시보드 Stat Cards ─────────────────────────────────────────── */
.dash-stat-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}

.dash-stat-card {
  padding: 3px 16px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-left: 5px solid transparent;
  border-radius: var(--nu-r-large);
  display: flex;
  flex-direction: column;
  gap: 2px;
  box-shadow: var(--shadow);
}

.dash-stat-title {
  font-size: 0.92rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  color: var(--text);
}

.dash-stat-body {
  display: grid;
  grid-template-columns: 1fr 52px;
  gap: 10px;
  align-items: center;
}

.dash-stat-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.dash-stat-line {
  display: flex;
  align-items: baseline;
  gap: 4px;
  font-size: 0.9rem;
}

.dash-stat-lbl {
  color: var(--muted);
  white-space: nowrap;
}

.dash-stat-num {
  color: var(--text);
  font-weight: 700;
}

.dash-stat-gauge {
  position: relative;
  width: 52px;
  height: 52px;
  flex-shrink: 0;
}

.dash-stat-gauge canvas {
  width: 100% !important;
  height: 100% !important;
}

.dash-stat-ring-label {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  pointer-events: none;
}

.ring-lbl {
  font-size: 0.5rem;
  color: var(--muted);
}

.ring-pct {
  font-size: 0.82rem;
  font-weight: 800;
  color: var(--text);
}

/* ── 대시보드: 홈 화면을 뷰포트 높이에 맞춰 스크롤 없이 채움 ──────────── */
.layout-root.dash-fill {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
.layout-root.dash-fill .dash-stat-row  { flex: 0 0 auto; }
.layout-root.dash-fill .dash-equip-section { flex: 0 0 auto; }
.layout-root.dash-fill .dash-mid-section {
  flex: 1 1 0;
  min-height: 120px;
  height: auto;
}

/* ── 대시보드 Middle Section ─────────────────────────────────────── */
.dash-mid-section {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: 1fr;
  height: 370px;
  gap: 16px;
  align-items: stretch;
}

.dash-mid-left {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
  overflow-y: auto;
}

.dash-mid-right {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.dash-line-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.dash-line-wrap {
  flex: 1;
  min-height: 0;
  position: relative;
}

.dash-line-wrap canvas {
  width: 100% !important;
  height: 100% !important;
}

/* ── Progress Panel: 월/일 계획을 좌우로 배치해 높이를 절반으로 줄임 ──── */
.dash-progress-panel {
  display: flex;
  flex-direction: column;
  flex: 0 0 auto;
  padding: 8px 22px;
}

.dash-progress-panel .widget-header { margin-bottom: 2px; }

.prog-row {
  display: flex;
  flex-direction: row;
  gap: 22px;
}

.prog-item {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
  min-width: 0;
}

.prog-meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.88rem;
  color: var(--muted);
  line-height: 1.6;
}

.prog-num {
  color: var(--text);
  font-weight: 700;
  font-size: 0.95rem;
  margin-left: 4px;
}

.prog-track {
  height: 28px;
  background: var(--nu-surface-3);
  border-radius: var(--nu-r-medium);
  overflow: hidden;
}

.prog-fill {
  height: 100%;
  border-radius: var(--nu-r-medium);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  min-width: 60px;
  transition: width 0.7s ease;
}

.prog-pct {
  padding-right: 14px;
  font-weight: 800;
  font-size: 1rem;
  color: var(--nu-on-accent);
  text-shadow: 0 1px 3px rgba(0,0,0,0.3);
}

.grad-red-yellow   { background: linear-gradient(90deg, var(--nu-alert) 0%, var(--nu-warning) 100%); }
.grad-orange-green { background: linear-gradient(90deg, var(--nu-warning) 0%, var(--nu-success) 100%); }
.grad-blue-cyan     { background: linear-gradient(90deg, var(--nu-primary) 0%, var(--nu-primary-light) 100%); }

/* ── Distribution Panel: 남는 공간을 채워 오른쪽 차트 박스 하단과 맞춤 ── */
.dash-dist-panel {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  padding: 8px 22px;
}

.dash-dist-panel .widget-header {
  flex: 0 0 auto;
  margin-bottom: 8px;
}

/* 제목 아래 남은 공간 안에서 도넛+리스트를 세로 중앙 정렬 (제목과 절대 겹치지 않음) */
.dash-dist-body {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 1fr 110px;
  gap: 14px;
  align-items: center;
  align-content: center;
}

.dash-dist-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 12px;
}

.dash-dist-item {
  font-size: 0.88rem;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 3px;
}

.dash-dist-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex-shrink: 0;
  margin-right: 3px;
}

.dash-dist-name { font-weight: 700; }
.dash-dist-val  { color: var(--text); font-weight: 700; }

.dash-dist-total {
  grid-column: 1 / -1;
  margin-top: 6px;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--text);
  border-top: 1px solid var(--border);
  padding-top: 6px;
}

.dash-dist-donut { width: 110px; height: 110px; flex-shrink: 0; }
.dash-dist-donut canvas { width: 100% !important; height: 100% !important; }

/* ═══════════════════════════════════════════════════════════════════
   생산실적 (production) — 한 화면에 맞춰 3개 패널이 세로로 채워짐
═══════════════════════════════════════════════════════════════════ */
.layout-root.prod-fill {
  flex: 1;
  min-height: 0;
  grid-template-rows: auto 1fr;
}

.prod-target-panel { padding: 12px 22px; }
.prod-target-panel .widget-header { margin-bottom: 8px; }

.prod-target-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
}

.prod-target-item {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.prod-target-label {
  font-size: 0.92rem;
  color: var(--muted);
}

.prod-target-num {
  color: var(--text);
  font-weight: 700;
  margin-left: 4px;
}

.prod-chart-panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.prod-chart-wrap {
  flex: 1;
  min-height: 0;
  position: relative;
}

.prod-chart-wrap canvas {
  width: 100% !important;
  height: 100% !important;
}

/* ── Equipment Bars ─────────────────────────────────────────────── */
.dash-equip-section { overflow: hidden; }

.equip-bars-wrap {
  display: flex;
  gap: 6px;
  align-items: flex-end;
  overflow-x: auto;
  height: 160px;
  padding-bottom: 2px;
  scrollbar-width: thin;
  scrollbar-color: var(--nu-txt4) transparent;
}

.equip-bars-wrap::-webkit-scrollbar { height: 4px; }
.equip-bars-wrap::-webkit-scrollbar-thumb { background: var(--nu-surface-4); border-radius: var(--nu-r-small); }

.equip-bar-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 46px;
  flex: 1;
  height: 100%;
}

.equip-status {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: 34px;
  font-size: 0.62rem;
  color: var(--nu-alert-text);
  line-height: 1.3;
  text-align: center;
  font-weight: 600;
}

.equip-track {
  flex: 1;
  width: 100%;
  background: var(--nu-surface-3);
  border-radius: 4px 4px 0 0;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
}

.equip-fill {
  width: 100%;
  border-radius: 4px 4px 0 0;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  min-height: 4px;
  transition: height 0.6s ease;
}

.equip-pct {
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--nu-on-accent);
  padding-top: 4px;
  text-shadow: 0 1px 2px rgba(0,0,0,0.4);
}

.equip-name {
  font-size: 0.62rem;
  color: var(--muted);
  text-align: center;
  margin-top: 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

/* ── 공통 Stat Card (다른 페이지용) ──────────────────────────────── */
.dashboard-stat-card {
  padding: 8px 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-xl);
  display: flex;
  flex-direction: column;
  gap: 4px;
  box-shadow: var(--shadow);
}

.dashboard-stat-header {
  color: var(--muted);
  font-size: 0.88rem;
  font-weight: 600;
}

.dashboard-stat-value {
  color: var(--text);
  font-size: 1.6rem;
  font-weight: 700;
}

.dashboard-top-row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
}

.dashboard-summary-section {
  display: grid;
  grid-template-columns: 1.8fr 1.2fr;
  gap: 18px;
  margin-bottom: 18px;
}

.dashboard-summary-left,
.dashboard-summary-right { display: grid; gap: 18px; }

.progress-row {
  padding: 18px 20px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-large);
  box-shadow: var(--shadow);
}

.progress-label {
  display: flex;
  justify-content: space-between;
  color: var(--muted);
  margin-bottom: 8px;
  font-size: 0.88rem;
}

.progress-values {
  display: flex;
  justify-content: space-between;
  color: var(--text);
  font-weight: 700;
  margin-bottom: 8px;
}

.progress-bar {
  height: 10px;
  background: var(--nu-surface-3);
  border-radius: var(--nu-r-pill);
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--nu-alert), var(--nu-warning));
}

.distribution-list { display: grid; gap: 10px; }

.distribution-item {
  display: flex;
  justify-content: space-between;
  color: var(--text);
  font-size: 0.92rem;
}

.utilization-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 14px;
  margin-top: 18px;
}

.utilization-bar-card {
  padding: 16px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-large);
  box-shadow: var(--shadow);
}

.utilization-name {
  color: var(--muted);
  margin-bottom: 8px;
  font-size: 0.88rem;
}

.utilization-value {
  color: var(--text);
  font-size: 1.05rem;
  font-weight: 700;
  margin-bottom: 8px;
}

.utilization-bar-track {
  width: 100%;
  height: 10px;
  background: var(--nu-surface-3);
  border-radius: var(--nu-r-pill);
  overflow: hidden;
}

.utilization-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--nu-success), var(--nu-primary));
}

.stat-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
}

.stat-card {
  padding: 20px 22px;
  border-radius: var(--nu-r-large);
  background: var(--panel);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
}

.stat-card .info-label  { margin-bottom: 10px; }
.stat-card .info-value  { font-size: 1.9rem; font-weight: 700; }
.stat-card .info-detail { margin-top: 8px; color: var(--muted); }

.table-wrapper { overflow-x: auto; }

.tables-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}

.error-msg {
  padding: 24px;
  color: var(--muted);
  text-align: center;
}

/* ── 시뮬레이션 Form ──────────────────────────────────────────────── */
.simulation-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}

.simulation-form label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 0.92rem;
  color: var(--muted);
}

.simulation-form input {
  width: 100%;
  padding: 9px 12px;
  border-radius: var(--nu-r-large);
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text);
  font-size: 0.88rem;
}

.primary-btn {
  padding: 10px 16px;
  border: none;
  border-radius: var(--nu-r-large);
  background: var(--accent4);
  color: var(--nu-on-accent);
  font-weight: 700;
  cursor: pointer;
  font-size: 0.9rem;
}

.primary-btn:hover { background: var(--nu-primary-dark); }

/* ── 가동현황 필터 ────────────────────────────────────────────────── */
/* 브라우저 창 높이가 얼마든 한 화면에 맞추고, 넘치면 표 내부만 스크롤되게 함 */
#layoutRoot.util-page {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  gap: 8px;
}
#layoutRoot.util-page > .util-filter-bar { flex: 0 0 auto; }

.util-filter-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 0;
}

.util-content {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  gap: 14px;
}
.util-content > .dashboard-top-row   { flex: 0 0 auto; }
.util-content > .dash-equip-section  { flex: 0 0 auto; }
.util-content > .table-widget-panel  { flex: 1 1 auto; min-height: 0; }

.util-filter-label {
  font-size: 0.9rem;
  color: var(--muted);
  white-space: nowrap;
}

.util-plant-select {
  padding: 8px 14px;
  border-radius: var(--nu-r-large);
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text);
  font-size: 0.88rem;
  cursor: pointer;
  min-width: 140px;
}

.util-plant-select option { background: var(--nu-card); color: var(--text); }
.util-plant-select:focus  { outline: none; border-color: var(--accent4); }

/* ── 재고현황 ─────────────────────────────────────────────────────── */
#layoutRoot.inv-page { gap: 8px; }

/* ── 재고 3분류 탭 (원단/제품/부자재) ── */
.inv-tab-bar {
  display: flex;
  gap: 4px;
  border-bottom: 2px solid var(--border);
}
.inv-tab {
  padding: 6px 22px;
  border: none;
  background: transparent;
  color: var(--muted);
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  border-bottom: 3px solid transparent;
  margin-bottom: -2px;
}
.inv-tab:hover { color: var(--text); }
.inv-tab.active { color: var(--accent4); border-bottom-color: var(--accent4); }
.inv-tab-content { display: flex; flex-direction: column; gap: 8px; }
/* 총계 박스 → 그래프 → 검색줄 → 표 순. 사이 간격은 다른 화면과 같은 기준(8px)으로 통일하고,
   검색줄 자체 마진은 없앤다 — 회수한 높이는 표가 가져간다. */
#layoutRoot.inv-page .inv-filter-bar { margin: 0; }
#layoutRoot.inv-page .inv-note { margin: 0; }
#layoutRoot.inv-page .viz-card { padding: 9px 12px; }
#layoutRoot.inv-page .viz-title { margin-bottom: 6px; }
/* 그래프는 3장 한 줄 — 구성(도넛) + 보조 2종(막대). 3장이 안 들어가는 폭에서만 접힌다. */
.inv-viz-grid { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
#layoutRoot.inv-page .viz-wrap { height: clamp(130px, 18vh, 210px); }

.inv-pending-badge {
  margin-left: 6px;
  padding: 2px 10px;
  border-radius: var(--nu-r-pill);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--accent2);
  background: rgba(229,163,10,0.15);
  border: 1px solid var(--accent2);
  vertical-align: middle;
}
.inv-placeholder {
  padding: 60px 24px;
  text-align: center;
  background: var(--panel);
  border: 1px dashed var(--border);
  border-radius: var(--nu-r-large);
  margin-top: 8px;
}
.inv-placeholder-title { font-size: 1.1rem; font-weight: 700; color: var(--accent2); margin-bottom: 8px; }
.inv-placeholder-desc { color: var(--muted); font-size: 0.9rem; }

/* .inv-section-header / .inv-section-title / .inv-unit 은 재고 탭 상단이
   공통 총계 박스(.kri-totals)로 전환되면서 제거됨 */

.inv-layout {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: 20px;
  align-items: start;
}

.inv-table-col { overflow-x: auto; }

.inv-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

.inv-table thead th {
  background: var(--th-bg);
  color: var(--th-text);
  padding: 10px 10px;
  text-align: center;
  border: 1px solid var(--jv-border);
  font-weight: 600;
  white-space: nowrap;
}

.inv-table td {
  padding: 8px 10px;
  border: 1px solid var(--border);
  color: var(--text);
  vertical-align: middle;
}

.inv-td-plant {
  text-align: center;
  background: var(--row-alt);
  font-weight: 600;
  white-space: nowrap;
}

.inv-td-name  { color: var(--accent4); font-weight: 600; }
.inv-td-num   { text-align: right; font-variant-numeric: tabular-nums; }
.inv-td-center { text-align: center; }

.inv-row-subtotal td {
  background: var(--nu-page);
  font-weight: 600;
  color: var(--text);
}

.inv-row-total td {
  background: var(--nu-surface-3);
  font-weight: 700;
  color: var(--text);
}

.inv-charts-col {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.inv-plant-section {
  padding: 14px 16px 18px;
}

.inv-plant-title {
  font-size: 0.88rem;
  font-weight: 700;
  color: var(--muted);
  margin-bottom: 10px;
}

.inv-chart-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.inv-chart-box {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.inv-chart-title {
  font-size: 0.95rem;
  font-weight: 700;
  margin-bottom: 8px;
  color: var(--text);
}

.inv-chart-box canvas { width: 100% !important; height: 200px !important; }

/* ─── Scheduling / Simulation ─────────────────────────────────────── */
.sched-top-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0;
}

.sched-settings-right {
  display: flex;
  align-items: center;
  gap: 10px;
}

.sched-plant-tabs { display: flex; gap: 8px; }

.sched-tab {
  padding: 6px 18px;
  border-radius: var(--nu-r-xxl);
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--muted);
  cursor: pointer;
  font-size: 0.83rem;
  font-weight: 600;
  transition: background 0.15s;
}

.sched-tab.active {
  background: var(--th-bg);
  color: var(--nu-on-accent);
  border-color: var(--th-bg);
}

.sched-req-btn {
  padding: 7px 20px;
  background: var(--accent4);
  color: var(--nu-on-accent);
  border: none;
  border-radius: var(--nu-r-medium);
  cursor: pointer;
  font-size: 0.88rem;
  font-weight: 600;
}

.sched-section {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-medium);
  padding: 14px 16px;
  margin-bottom: 14px;
  box-shadow: var(--shadow);
}

.sched-section-title {
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 10px;
}

.sched-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
  flex-wrap: wrap;
  gap: 8px;
}

.sched-hist-filter {
  display: flex;
  align-items: center;
  gap: 6px;
}

.sched-table-wrap { overflow-x: auto; }

.sched-hist-wrap {
  max-height: 388px; /* 헤더 1줄 + 데이터 10줄 높이 */
  overflow-y: auto;
}

.sched-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.82rem;
  min-width: 600px;
}

.sched-table th {
  background: var(--th-bg);
  color: var(--th-text);
  padding: 8px 10px;
  text-align: center;
  border-bottom: 1px solid var(--jv-border);
  white-space: nowrap;
  position: sticky;
  top: 0;
  z-index: 1;
  font-size: 0.8rem;
}

.sched-table td {
  padding: 7px 10px;
  text-align: center;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  white-space: nowrap;
}

.sched-table tr:hover td        { background: var(--row-hover); }
.sched-table tr:nth-child(even) td { background: var(--row-alt); }
.sched-table tr:nth-child(even):hover td { background: var(--row-hover); }

.sched-link      { color: var(--accent4) !important; cursor: pointer; }
.sched-small     { font-size: 0.72rem; }
.sched-bold      { font-weight: 700; color: var(--text) !important; }
.sched-highlight { color: var(--nu-info-text) !important; font-weight: 600; }

.sched-empty {
  text-align: center;
  color: var(--muted);
  padding: 22px;
}

.sched-label     { color: var(--muted); font-size: 0.83rem; }

.sched-date-input {
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 5px 8px;
  border-radius: var(--nu-r-medium);
  font-size: 0.8rem;
}

.sched-green-date {
  background: var(--nu-success-light);
  border-color: var(--nu-success);
  color: var(--nu-success-text);
}

.sched-search-btn {
  padding: 5px 14px;
  background: var(--nu-success);
  color: var(--nu-on-accent);
  border: none;
  border-radius: var(--nu-r-medium);
  cursor: pointer;
  font-size: 0.8rem;
  font-weight: 600;
}

.sched-del-btn {
  padding: 5px 14px;
  background: var(--nu-alert);
  color: var(--nu-on-accent);
  border: none;
  border-radius: var(--nu-r-medium);
  cursor: pointer;
  font-size: 0.8rem;
  font-weight: 600;
}

.sched-del-req {
  color: var(--accent) !important;
  cursor: pointer;
  font-weight: 700;
}

.sched-gray-btn {
  padding: 5px 14px;
  background: var(--nu-page);
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-medium);
  cursor: pointer;
  font-size: 0.8rem;
}

.sched-blue-btn {
  padding: 7px 20px;
  background: var(--accent4);
  color: var(--nu-on-accent);
  border: none;
  border-radius: var(--nu-r-medium);
  cursor: pointer;
  font-size: 0.85rem;
  font-weight: 600;
}

.sched-orders-wrapper {
  overflow-x: auto;
  overflow-y: auto;
  max-height: calc(100vh - 396px);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-medium);
  margin-bottom: 8px;
}

.sched-orders-table { min-width: 900px; }

.sched-priority-cell { text-align: center; }
.sched-priority-marked {
  color: var(--nu-alert-text);
  font-weight: 700;
}

.sched-action-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: var(--nu-page);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-medium);
  flex-wrap: wrap;
}

/* ── 금형교환 기준(C2) 설정 패널 ── */
.sched-mold-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 8px 12px;
  margin-top: 6px;
  background: var(--nu-warning-light);
  border: 1px solid var(--accent2);
  border-radius: var(--nu-r-medium);
  flex-wrap: wrap;
  font-size: 0.88rem;
  color: var(--text);
}
.sched-mold-item { display: inline-flex; align-items: center; gap: 4px; }
.sched-mold-num {
  width: 56px;
  padding: 4px 6px;
  border: 1px solid var(--border);
  border-radius: var(--nu-r-small);
  text-align: center;
  font-size: 0.86rem;
}
.sched-mold-note { color: var(--muted); font-size: 0.78rem; margin-left: auto; }

.sched-select {
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 5px 8px;
  border-radius: var(--nu-r-medium);
  font-size: 0.82rem;
}

.sched-name-input {
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 5px 10px;
  border-radius: var(--nu-r-medium);
  font-size: 0.82rem;
  width: 180px;
}

#layoutRoot.sim-downtime-page { gap: 8px; }

.sched-plant-label {
  color: var(--nu-warning-text);
  font-weight: 800;
  font-size: 1rem;
  margin-bottom: 0;
}

.sched-downtime-filter {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 0;
  flex-wrap: wrap;
}

.sched-filter-right {
  margin-left: auto;
  display: flex;
  gap: 6px;
}

.sched-sel-bar { display: flex; gap: 5px; margin-bottom: -6px; }

.sched-selall-btn {
  padding: 2px 8px;
  background: var(--nu-page);
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-small);
  cursor: pointer;
  font-size: 0.68rem;
}

.sched-downtime-wrap {
  max-height: calc(100vh - 360px);
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--nu-r-medium);
  margin-bottom: 0;
}

.sched-bottom-bar { display: flex; justify-content: flex-end; }
.sched-start-btn  { min-width: 130px; }
.sched-elapsed    { color: var(--nu-warning-text) !important; font-weight: 800; font-size: 1.25rem; text-align: center; }
.simr-name-link   { cursor: pointer; text-decoration: underline; }

/* ── Simulation result ─────────────────────────────────────────── */
#layoutRoot.sim-result-page { gap: 8px; }

.simr-filter-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 0;
  flex-wrap: wrap;
}

.simr-plant-lbl {
  color: var(--nu-warning-text);
  font-weight: 800;
  font-size: 1rem;
  min-width: 50px;
}

.simr-mode-lbl {
  color: var(--nu-warning-text);
  font-weight: 700;
  font-size: 0.9rem;
  flex: 1;
  text-align: center;
}

.simr-top-btns { display: flex; gap: 8px; margin-left: auto; }

.simr-top-btn {
  padding: 7px 18px;
  background: var(--nu-page);
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-medium);
  cursor: pointer;
  font-size: 0.85rem;
  font-weight: 600;
}

.simr-top-btn:hover { background: var(--nu-surface-3); }

.simr-table-wrap {
  overflow-x: auto;
  overflow-y: auto;
  max-height: calc(100vh - 280px);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-medium);
  margin-bottom: 0;
}

.simr-table    { min-width: 1100px; font-size: 0.78rem; }
.simr-table th { font-size: 0.76rem; padding: 7px 6px; }
.simr-table td { padding: 6px 6px; }

.simr-seq  { font-weight: 700; color: var(--accent4) !important; }
.simr-proj { text-align: left !important; max-width: 160px; white-space: normal; word-break: keep-all; }
.simr-zone { font-weight: 700; color: var(--text) !important; white-space: nowrap; }
.simr-dt   { font-size: 0.74rem; line-height: 1.5; white-space: nowrap; }
.simr-date { color: var(--muted) !important; }

.simr-overdue {
  color: var(--nu-on-accent) !important;
  background: var(--nu-alert);
  font-weight: 700;
  border-radius: var(--nu-r-small);
  padding: 2px 6px;
}

/* 금형교환(C2) 표시 */
.simr-mold-change {
  color: var(--accent2) !important;
  font-weight: 700;
}
.simr-mold-none { color: var(--muted) !important; }
.simr-mold-info {
  margin-left: auto;
  padding: 4px 12px;
  border-radius: var(--nu-r-pill);
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--accent2);
  background: rgba(229,163,10,0.13);
  border: 1px solid var(--accent2);
}

.simr-special {
  background: var(--nu-warning);
  color: var(--nu-on-accent) !important;
  font-weight: 700;
  border-radius: var(--nu-r-small);
}

.simr-order-cell { white-space: nowrap; }
/* 순서변경 칸은 오른쪽에 붙여 둔다 — 열이 15개라 넓은 화면에서도 표가 가로로 넘치는데,
   ▲▼ 를 누르려고 매번 오른쪽 끝까지 스크롤해야 하면 쓸 수 없다.
   td 배경은 홀/짝·hover 규칙과 같은 값을 다시 준다(투명하면 밑의 열이 비쳐 보인다). */
.simr-table th:last-child,
.simr-table td:last-child { position: sticky; right: 0; z-index: 2; }
.simr-table td:last-child { background: var(--panel); box-shadow: -6px 0 6px -7px rgba(0, 0, 0, 0.45); }
.simr-table tr:nth-child(even) td:last-child { background: var(--row-alt); }
.simr-table tr:hover td:last-child,
.simr-table tr:nth-child(even):hover td:last-child { background: var(--row-hover); }
.simr-table th:last-child { z-index: 3; }

.simr-arrow-btn {
  background: transparent;
  border: none;
  color: var(--nu-success-text);
  font-size: 1rem;
  cursor: pointer;
  padding: 0 3px;
  line-height: 1;
}

.simr-arrow-btn:hover { color: var(--nu-success-text); }

.simr-bottom-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 0;
  flex-wrap: wrap;
  gap: 10px;
}

.simr-sched-name { color: var(--text); font-size: 1rem; font-weight: 600; }
.simr-bottom-btns { display: flex; gap: 8px; }

.simr-confirm-btn {
  padding: 7px 20px;
  background: var(--accent4);
  color: var(--nu-on-accent);
  border: none;
  border-radius: var(--nu-r-medium);
  cursor: pointer;
  font-size: 0.85rem;
  font-weight: 600;
}

.simr-confirm-btn:disabled { cursor: default; background: var(--nu-primary-lightest); }

/* ═══════════════════════════════════════════════════════════════════
   설비 그룹별 생산현황 (equip-production)
═══════════════════════════════════════════════════════════════════ */
.ep-filter-wrap {
  display: flex;
  flex-direction: row;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  padding: 10px 16px;
  background: var(--nu-page);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-medium);
  margin-bottom: 10px;
}

.ep-product-lbl {
  font-size: 1.1rem;
  font-weight: 800;
  color: var(--nu-warning-text);
  white-space: nowrap;
}

.ep-select {
  padding: 6px 12px;
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--nu-r-medium);
  font-size: 0.85rem;
  min-width: 160px;
}

.ep-select-sm { min-width: 140px; }

.ep-cb-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--text);
  font-size: 0.9rem;
  cursor: pointer;
}

.ep-cb-wrap input { width: 16px; height: 16px; cursor: pointer; accent-color: var(--th-bg); }

.ep-table-wrap {
  overflow-x: auto;
  overflow-y: auto;
  max-height: calc(100vh - 340px);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-medium);
  margin-bottom: 14px;
}

.ep-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.83rem;
  min-width: 700px;
}

.ep-table thead th {
  background: var(--th-bg);
  color: var(--th-text);
  padding: 8px 10px;
  text-align: center;
  border-bottom: 1px solid var(--jv-border);
  white-space: nowrap;
  position: sticky;
  top: 0;
  z-index: 1;
}

.ep-table td {
  padding: 7px 10px;
  text-align: center;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  vertical-align: middle;
}

.ep-table tr:hover td        { background: var(--row-hover); }
.ep-table tr:nth-child(even) td { background: var(--row-alt); }
.ep-table tr:nth-child(even):hover td { background: var(--row-hover); }
.ep-table tr.ep-row-done td        { background: rgba(26,174,92,0.10) !important; }
.ep-table tr.ep-row-done:hover td  { background: rgba(26,174,92,0.18) !important; }
.ep-table tr.ep-row-overdue td     { background: rgba(229,34,45,0.09) !important; }
.ep-table tr.ep-row-overdue:hover td { background: rgba(229,34,45,0.16) !important; }

.ep-td-proj    { text-align: left !important; max-width: 180px; white-space: normal; word-break: keep-all; }
.ep-td-product { white-space: nowrap; }
.ep-td-num     { text-align: right !important; font-variant-numeric: tabular-nums; }

.ep-overdue {
  background: var(--nu-alert) !important;
  color: var(--nu-on-accent) !important;
  font-weight: 700;
  border-radius: var(--nu-r-small);
  padding: 2px 6px;
}

.ep-btn-row {
  display: flex;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
}

.ep-detail-btn {
  padding: 12px 48px;
  background: var(--th-bg);
  color: var(--nu-on-accent);
  border: none;
  border-radius: var(--nu-r-large);
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  letter-spacing: 0.04em;
  box-shadow: 0 2px 8px rgba(83,7,137,0.25);
}

.ep-detail-btn:hover { background: var(--nu-primary-deep); }

.ep-mobile-btn {
  padding: 12px 28px;
  background: var(--nu-success-light);
  color: var(--nu-success-text);
  border: 1px solid var(--nu-success);
  border-radius: var(--nu-r-large);
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
}

.ep-mobile-btn:hover { background: var(--nu-success-light-2); }

/* ═══════════════════════════════════════════════════════════════════
   생산 스케줄 확정 (schedule-confirm)
═══════════════════════════════════════════════════════════════════ */
#layoutRoot.sc-page { gap: 8px; }

.sc-filter-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding: 10px 14px;
  background: var(--nu-page);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-medium);
  margin-bottom: 0;
}

.sc-cb-lbl {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--text);
  font-size: 0.88rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}

.sc-cb-lbl input { width: 16px; height: 16px; accent-color: var(--th-bg); }

.sc-filters {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  flex: 1;
}

.sc-sel {
  padding: 5px 10px;
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--nu-r-medium);
  font-size: 0.82rem;
  min-width: 100px;
}

.sc-date {
  padding: 5px 8px;
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--nu-r-medium);
  font-size: 0.82rem;
}

.sc-table-wrap {
  overflow-x: auto;
  overflow-y: auto;
  max-height: calc(100vh - 320px);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-medium);
  margin-bottom: 0;
}

.sc-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.78rem;
  min-width: 1100px;
}

.sc-table thead th {
  background: var(--th-bg);
  color: var(--th-text);
  padding: 8px 8px;
  text-align: center;
  border-bottom: 1px solid var(--jv-border);
  white-space: nowrap;
  position: sticky;
  top: 0;
  z-index: 1;
}

.sc-table td {
  padding: 6px 8px;
  text-align: center;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  white-space: nowrap;
}

.sc-table tr:hover td        { background: var(--row-hover); }
.sc-table tr:nth-child(even) td { background: var(--row-alt); }
.sc-table tr:nth-child(even):hover td { background: var(--row-hover); }

.sc-seq   { font-weight: 700; color: var(--accent4) !important; }
.sc-link  { color: var(--accent4) !important; cursor: pointer; }
.sc-equip { color: var(--nu-warning-text) !important; font-weight: 700; }
.sc-proj  { text-align: left !important; max-width: 160px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sc-zone  { font-weight: 700; color: var(--text) !important; max-width: 90px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sc-dt    { font-size: 0.72rem; line-height: 1.5; }
.sc-num   { text-align: right !important; font-variant-numeric: tabular-nums; }

.sc-overdue {
  background: var(--nu-alert) !important;
  color: var(--nu-on-accent) !important;
  font-weight: 700;
  border-radius: var(--nu-r-small);
  padding: 2px 4px;
}

.sc-footer {
  display: flex;
  align-items: center;
  gap: 28px;
  padding: 12px 18px;
  background: var(--nu-page);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-medium);
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.sc-footer-stat { color: var(--muted); font-size: 0.92rem; }
.sc-footer-stat strong { color: var(--text); font-size: 1.05rem; margin-left: 4px; }

.sc-footer-btns { margin-left: auto; display: flex; gap: 10px; }

.sc-btn-blue {
  padding: 8px 24px;
  background: var(--accent4);
  color: var(--nu-on-accent);
  border: none;
  border-radius: var(--nu-r-medium);
  font-size: 0.9rem;
  font-weight: 700;
  cursor: pointer;
}

.sc-btn-orange {
  padding: 8px 24px;
  background: var(--nu-warning);
  color: var(--nu-on-accent);
  border: none;
  border-radius: var(--nu-r-medium);
  font-size: 0.9rem;
  font-weight: 700;
  cursor: pointer;
}

/* ═══════════════════════════════════════════════════════════════════
   설비 상세현황 (equip-detail)
═══════════════════════════════════════════════════════════════════ */
.ed-shell {
  display: grid;
  grid-template-columns: 360px 1fr;
  gap: 16px;
  align-items: start;
  min-height: calc(100vh - 220px);
}

.ed-left {
  display: flex;
  flex-direction: column;
  gap: 14px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-large);
  padding: 18px 16px;
  box-shadow: var(--shadow);
}

.ed-top-row { display: flex; align-items: center; gap: 12px; }

.ed-product-lbl {
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--nu-warning-text);
  min-width: 60px;
}

.ed-equip-sel {
  flex: 1;
  padding: 7px 12px;
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: var(--nu-r-medium);
  font-size: 0.9rem;
  font-weight: 700;
}

.ed-doc-box {
  background: var(--nu-row-alt);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-medium);
  padding: 10px 12px;
}

.ed-doc-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}

.ed-doc-lbl    { color: var(--muted); font-size: 0.82rem; }
.ed-doc-num    { color: var(--accent4); font-size: 1.1rem; font-weight: 700; flex: 1; }
.ed-doc-status { color: var(--muted); font-size: 0.82rem; }

.ed-prog-track {
  height: 28px;
  background: var(--nu-surface-3);
  border-radius: var(--nu-r-medium);
  overflow: hidden;
}

.ed-prog-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--nu-success), var(--nu-success-soft));
  border-radius: var(--nu-r-medium);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  min-width: 40px;
  transition: width 0.6s ease;
}

.ed-prog-pct { padding-right: 10px; font-size: 0.85rem; font-weight: 700; color: var(--nu-on-accent); }

.ed-nav-row { display: flex; align-items: stretch; gap: 8px; }

.ed-nav-btn {
  width: 32px;
  flex-shrink: 0;
  background: var(--nu-page);
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: var(--nu-r-medium);
  cursor: pointer;
  font-size: 1rem;
  align-self: center;
  padding: 16px 0;
}

.ed-nav-btn:hover { background: var(--nu-surface-3); color: var(--text); }

.ed-info-card {
  flex: 1;
  background: var(--nu-row-alt);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-medium);
  padding: 14px 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.ed-info-row { display: flex; align-items: flex-start; gap: 8px; font-size: 0.9rem; }

.ed-info-row-split { display: flex; gap: 12px; align-items: flex-start; }

.ed-info-lbl { color: var(--muted); white-space: nowrap; }
.ed-info-val { color: var(--text); font-weight: 600; word-break: keep-all; }

.ed-photo {
  flex-shrink: 0;
  width: 80px;
  height: 90px;
  border-radius: var(--nu-r-medium);
  overflow: hidden;
  border: 1px solid var(--border);
}

.ed-photo-placeholder {
  width: 100%;
  height: 100%;
  background: var(--nu-gradient);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  font-weight: 800;
  color: var(--nu-on-accent);
}

.ed-status-row { display: flex; align-items: center; gap: 14px; padding-top: 4px; }
.ed-status-lbl { color: var(--muted); font-size: 0.92rem; }

.ed-status-btn {
  padding: 10px 32px;
  border: none;
  border-radius: var(--nu-r-medium);
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  flex: 1;
}

.ed-active   { background: var(--nu-success); color: var(--nu-on-accent); }
.ed-inactive { background: var(--nu-alert); color: var(--nu-on-accent); }

.ed-right {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-large);
  padding: 18px 16px;
  min-height: calc(100vh - 220px);
  box-shadow: var(--shadow);
}

.ed-right-header {
  font-size: 1rem;
  font-weight: 700;
  color: var(--text);
  padding-bottom: 8px;
  border-bottom: 2px solid var(--border);
}

.ed-daily-prog-wrap { padding: 4px 0 6px; }

.ed-daily-prog-track {
  position: relative;
  height: 32px;
  background: var(--nu-surface-3);
  border-radius: var(--nu-r-medium);
  overflow: hidden;
}

.ed-daily-prog-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--nu-success), var(--nu-success-soft));
  border-radius: var(--nu-r-medium);
  min-width: 4px;
  transition: width 0.6s ease;
}

.ed-daily-prog-pct {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--text);
}

.ed-right-table-wrap {
  flex: 1;
  min-width: 0;
  min-height: 0;
  overflow-x: auto;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--nu-r-medium);
}

.ed-right-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.78rem;
  table-layout: fixed;
}

.ed-right-table thead th {
  background: var(--th-bg);
  color: var(--th-text);
  padding: 7px 4px;
  text-align: center;
  border-bottom: 1px solid var(--jv-border);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  position: sticky;
  top: 0;
  z-index: 1;
}

.ed-right-table td {
  padding: 6px 4px;
  text-align: center;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ed-right-table tr:hover td        { background: var(--row-hover); }
.ed-right-table tr:nth-child(even) td { background: var(--row-alt); }
.ed-right-table tr.ed-row-done td        { background: rgba(26,174,92,0.10) !important; }
.ed-right-table tr.ed-row-done:hover td  { background: rgba(26,174,92,0.18) !important; }
.ed-right-table tr.ed-row-overdue td     { background: rgba(229,34,45,0.09) !important; }
.ed-right-table tr.ed-row-overdue:hover td { background: rgba(229,34,45,0.16) !important; }

.ed-proj    { text-align: left !important; white-space: normal; word-break: break-all; overflow-wrap: break-word; max-width: 180px; overflow: hidden; }
.ed-num     { text-align: right !important; font-variant-numeric: tabular-nums; }
.ed-dt      { font-size: 0.72rem; }
.ed-overdue { background: var(--nu-alert) !important; color: var(--nu-on-accent) !important; font-weight: 700; border-radius: var(--nu-r-small); padding: 2px 4px; }

@media (max-width: 900px) { .ed-shell { grid-template-columns: 1fr; } }

/* ═══════════════════════════════════════════════════════════════════
   철선소요예정량 (wire-req)
═══════════════════════════════════════════════════════════════════ */
.wr-section {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-large);
  padding: 16px 18px;
  box-shadow: var(--shadow);
}

.wr-section-title {
  font-size: 1rem;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 12px;
}

.wr-table-wrap { overflow-x: auto; overflow-y: auto; }

.wr-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.83rem;
  min-width: 600px;
}

.wr-orange-row th {
  background: var(--nu-warning);
  color: var(--nu-on-accent);
  padding: 10px 12px;
  text-align: center;
  border: 1px solid var(--nu-warning-text-2);
  font-weight: 700;
  white-space: nowrap;
  position: sticky;
  top: 0;
  z-index: 1;
}

.wr-table td {
  padding: 9px 12px;
  text-align: center;
  border-bottom: 1px solid var(--border);
  border-right: 1px solid var(--border);
  color: var(--text);
}

.wr-table tr:nth-child(even) td { background: var(--row-alt); }
.wr-table tr:hover td           { background: var(--row-hover); }

.wr-center { text-align: center !important; }
.wr-num    { text-align: right !important; font-variant-numeric: tabular-nums; }

/* ═══════════════════════════════════════════════════════════════════
   계획대비 출하현황 (shipment)
═══════════════════════════════════════════════════════════════════ */
#layoutRoot.sh-page { gap: 10px; }

.sh-section-title {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 0;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--border);
}

.sh-pending-badge {
  margin-left: 10px;
  padding: 2px 10px;
  border-radius: var(--nu-r-pill);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--accent2);
  background: rgba(229,163,10, 0.15);
  border: 1px solid var(--accent2);
  vertical-align: middle;
}

.sh-factory-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}

.sh-factory-col {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-large);
  padding: 14px 16px;
  box-shadow: var(--shadow);
}

.sh-factory-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 10px;
}

.sh-factory-name { font-size: 1rem; font-weight: 700; color: var(--text); }
.sh-unit         { font-size: 0.78rem; color: var(--muted); }

.sh-table-wrap { overflow-x: auto; margin-bottom: 12px; }

.sh-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.82rem;
}

.sh-table thead th {
  background: var(--th-bg);
  color: var(--th-text);
  padding: 7px 10px;
  text-align: center;
  border: 1px solid var(--jv-border);
  white-space: nowrap;
}

.sh-table td {
  padding: 7px 10px;
  border: 1px solid var(--border);
  color: var(--text);
  text-align: center;
}

.sh-table tr:hover td { background: var(--row-hover); }

.sh-name { text-align: left !important; font-weight: 600; }
.sh-num  { text-align: right !important; font-variant-numeric: tabular-nums; }

.sh-subtotal td {
  background: var(--nu-page);
  font-weight: 700;
  color: var(--text);
}

.sh-charts-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.sh-chart-box {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.sh-chart-title {
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 8px;
  text-align: center;
}

.sh-chart-box canvas { width: 100% !important; height: 200px !important; }

.sh-footer {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  padding: 10px 18px;
  background: var(--nu-page);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-large);
}

.sh-footer-item { display: flex; align-items: baseline; gap: 12px; }
.sh-footer-lbl  { color: var(--muted); font-size: 0.92rem; }
.sh-footer-val  { color: var(--text); font-size: 1.3rem; font-weight: 800; }

/* ═══════════════════════════════════════════════════════════════════
   공통 팝업 모달
═══════════════════════════════════════════════════════════════════ */
.popup-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  z-index: 3000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.popup-box {
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-large);
  min-width: 460px;
  max-width: 660px;
  max-height: 90vh;
  overflow-y: auto;
  padding: 28px 32px 24px;
  position: relative;
  box-shadow: 0 8px 40px var(--shadow-lg);
}

.popup-box-wide { min-width: 540px; }

.popup-title {
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 22px;
}

.popup-close-btn {
  position: absolute;
  top: 16px;
  right: 18px;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 1.25rem;
  cursor: pointer;
  line-height: 1;
  padding: 2px 6px;
  border-radius: var(--nu-r-small);
  transition: color 0.15s, background 0.15s;
}
.popup-close-btn:hover { color: var(--text); background: var(--row-hover); }

.popup-section-label {
  font-size: 0.8rem;
  color: var(--muted);
  margin-bottom: 8px;
  margin-top: 4px;
}

.popup-reqno {
  font-size: 1.25rem;
  font-weight: 800;
  color: var(--accent4);
  margin-bottom: 16px;
}

.popup-info-box {
  background: var(--row-alt);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-medium);
  padding: 16px 20px;
  margin-bottom: 16px;
}

.popup-priority-row {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 0.92rem;
  color: var(--text);
}

.popup-priority-input {
  width: 88px;
  padding: 6px 10px;
  background: var(--nu-card);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-small);
  color: var(--text);
  font-size: 0.92rem;
  text-align: center;
}

.popup-detail-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 24px;
  margin-bottom: 6px;
  font-size: 0.86rem;
  color: var(--text);
}
.popup-detail-row-full {
  margin-bottom: 6px;
  font-size: 0.86rem;
  color: var(--text);
}

.popup-lbl {
  color: var(--muted);
  display: inline-block;
  min-width: 56px;
}

.popup-bottom {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 20px;
}

/* 팝업 폼 공통 */
.popup-form-row {
  display: flex;
  align-items: center;
  margin-bottom: 13px;
  gap: 10px;
  font-size: 0.9rem;
}

.popup-form-lbl {
  min-width: 86px;
  color: var(--muted);
  text-align: right;
  flex-shrink: 0;
}

.popup-form-val {
  color: var(--text);
  font-weight: 600;
}

.popup-form-sel,
.popup-form-input,
.popup-form-date {
  flex: 1;
  padding: 7px 10px;
  background: var(--nu-card);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-small);
  color: var(--text);
  font-size: 0.88rem;
  min-width: 0;
}

.popup-form-input-sm {
  width: 110px;
  padding: 7px 10px;
  background: var(--nu-card);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-small);
  color: var(--text);
  font-size: 0.88rem;
}

.popup-form-date {
  flex: none;
  width: auto;
  padding: 6px 10px;
  background: var(--nu-success);
  border-color: var(--nu-success);
  color: var(--nu-on-accent);
  cursor: pointer;
}
.popup-form-date::-webkit-calendar-picker-indicator { filter: invert(1); cursor: pointer; }

.popup-check-row {
  display: flex;
  align-items: center;
  gap: 20px;
  font-size: 0.9rem;
  color: var(--text);
}
.popup-check-row label { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.popup-check-row input[type="checkbox"] { width: 15px; height: 15px; accent-color: var(--nu-primary); cursor: pointer; }

/* 복수 추가 설비 테이블 */
.popup-equip-ctrl {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
}

.popup-equip-table-wrap {
  max-height: 180px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--nu-r-small);
  margin-bottom: 12px;
}

.popup-equip-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

.popup-equip-table th {
  background: var(--header);
  color: var(--th-text);
  padding: 7px 10px;
  text-align: center;
  position: sticky;
  top: 0;
}

.popup-equip-table td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  text-align: center;
}

.popup-equip-table tr:hover td { background: var(--row-hover); }
.popup-equip-table tr.equip-selected td { background: rgba(130,10,209,0.12); }

.popup-date-range {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
}

.popup-date-sep { color: var(--muted); }

/* 팝업 버튼 공통 */
.popup-btn-apply  { padding: 8px 26px; background: var(--nu-primary); color: var(--nu-on-accent); border: none; border-radius: var(--nu-r-medium); font-size: 0.9rem; font-weight: 600; cursor: pointer; }
.popup-btn-reg    { padding: 8px 26px; background: var(--nu-primary); color: var(--nu-on-accent); border: none; border-radius: var(--nu-r-medium); font-size: 0.9rem; font-weight: 600; cursor: pointer; }
.popup-btn-cancel { padding: 8px 20px; background: var(--nu-txt2); color: var(--nu-on-accent); border: none; border-radius: var(--nu-r-medium); font-size: 0.9rem; font-weight: 600; cursor: pointer; }
.popup-btn-edit   { padding: 8px 20px; background: var(--nu-primary); color: var(--nu-on-accent); border: none; border-radius: var(--nu-r-medium); font-size: 0.9rem; font-weight: 600; cursor: pointer; }
.popup-btn-reset  { padding: 8px 20px; background: var(--nu-txt2); color: var(--nu-on-accent); border: none; border-radius: var(--nu-r-medium); font-size: 0.9rem; font-weight: 600; cursor: pointer; }
.popup-btn-del    { padding: 8px 20px; background: var(--nu-alert); color: var(--nu-on-accent); border: none; border-radius: var(--nu-r-medium); font-size: 0.9rem; font-weight: 600; cursor: pointer; }
.popup-btn-xs     { padding: 4px 10px; background: var(--nu-txt2); color: var(--nu-on-accent); border: none; border-radius: var(--nu-r-small); font-size: 0.8rem; cursor: pointer; }
.popup-btn-xs:hover { background: var(--nu-primary); color: var(--nu-on-accent); }
.popup-btn-xs-red { padding: 4px 10px; background: var(--nu-alert-text-2); color: var(--nu-alert-border); border: none; border-radius: var(--nu-r-small); font-size: 0.8rem; cursor: pointer; }
.popup-btn-xs-red:hover { background: var(--nu-alert); color: var(--nu-on-accent); }

/* ── 반응형 ─────────────────────────────────────────────────────── */
@media (max-width: 1200px) {
  .cards-row,
  .charts-grid,
  .tables-grid { grid-template-columns: 1fr; }
}

@media (max-width: 1100px) {
  .dash-stat-row   { grid-template-columns: repeat(2, 1fr); }
  .dash-mid-section { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
  .sh-factory-row { grid-template-columns: 1fr; }
  .sh-footer      { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════
   콤팩트 모드 — 4:3 비율 등 세로 공간이 좁은 화면에서 한 화면에 맞춤
   (타이틀/여백을 줄여 스크롤 없이 최대한 표시)
═══════════════════════════════════════════════════════════════════ */
@media (max-height: 820px) {
  /* 사이드바 */
  .sidebar   { padding: 14px; gap: 14px; }
  .brand     { gap: 10px; }
  .logo      { width: 36px; height: 36px; border-radius: var(--nu-r-large); }
  .brand span{ font-size: 1rem; }
  .nav a     { padding: 8px 12px; font-size: 0.85rem; }

  /* 탑바 */
  .topbar     { height: 42px; padding: 0 18px; }
  .page-title { font-size: 0.86rem; }

  /* 콘텐츠 여백 */
  .content     { padding: 12px 18px; gap: 10px; }
  .layout-root { gap: 10px; }
  .layout-grid { gap: 10px; }

  /* 히어로(페이지 타이틀) */
  .hero          { padding: 10px 18px; gap: 3px; border-radius: var(--nu-r-large); }
  .hero-title    { font-size: 1.3rem; }
  .hero-subtitle { font-size: 0.76rem; }

  /* 위젯 패널 공통 */
  .widget-panel  { padding: 12px 14px; border-radius: var(--nu-r-large); }
  .widget-header { margin-bottom: 8px; }
  .widget-title  { font-size: 0.88rem; }
  .card-title    { margin-bottom: 8px; font-size: 0.86rem; }

  /* 표 공통 (기본 + 페이지별 테이블) */
  th, td,
  .inv-table th, .inv-table td,
  .sched-table th, .sched-table td,
  .ep-table th, .ep-table td,
  .sc-table th, .sc-table td,
  .ed-right-table th, .ed-right-table td,
  .wr-table th, .wr-table td,
  .sh-table th, .sh-table td {
    padding: 5px 8px;
  }
  .inv-table, .sched-table, .ep-table, .sc-table,
  .ed-right-table, .wr-table, .sh-table {
    font-size: 0.74rem;
  }
  .sched-hist-wrap { max-height: 200px; }
  .sched-section   { padding: 10px 12px; margin-bottom: 10px; }

  /* 대시보드 차트/카드 */
  .chart-box canvas      { height: 210px !important; }
  .dash-stat-card  { padding: 12px 14px; gap: 8px; }
  .dash-stat-body  { grid-template-columns: 1fr 80px; }
  .dash-stat-gauge { width: 80px; height: 80px; }
  .dash-mid-section{ gap: 10px; }
  .dash-mid-left   { gap: 10px; }
  .dash-progress-panel { gap: 12px; }
  .dash-dist-donut { width: 96px; height: 96px; }
  .equip-bars-wrap { height: 140px; }

  /* 재고/출하 차트 */
  .inv-chart-box canvas { height: 140px !important; }
  .sh-chart-box canvas  { height: 140px !important; }

  /* 설비상세 */
  .ed-right { min-height: calc(100vh - 150px); }
}

/* ── 사용자 관리(관리자) ────────────────────────────────────────────── */
.admin-page .content { overflow-y: auto; }

.admin-btn-primary {
  padding: 10px 16px;
  background: var(--accent4);
  color: var(--nu-on-accent);
  border: none;
  border-radius: var(--nu-r-large);
  font-size: 0.85rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.18s;
}
.admin-btn-primary:hover { background: var(--nu-primary-dark); }

.admin-btn-ghost {
  padding: 10px 16px;
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: var(--nu-r-large);
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}
.admin-btn-ghost:hover { background: var(--row-hover); }

.admin-btn-small {
  padding: 5px 12px;
  border-radius: var(--nu-r-medium);
  border: 1px solid var(--border);
  background: var(--nu-card);
  color: var(--text);
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
  margin-right: 6px;
}
.admin-btn-small:hover { background: var(--row-hover); }
.admin-btn-danger { color: var(--nu-alert-text); border-color: rgba(229,34,45,0.35); }
.admin-btn-danger:hover { background: rgba(229,34,45,0.09); }

.admin-row-actions { white-space: nowrap; }

.admin-form {
  margin-top: 18px;
  padding: 16px 18px;
  border: 1px solid var(--border);
  border-radius: var(--nu-r-large);
  background: var(--row-alt);
  display: grid;
  gap: 10px;
  max-width: 360px;
}

.admin-form-title { font-size: 0.95rem; font-weight: 700; color: var(--text); }

.admin-form-row { display: grid; gap: 4px; }
.admin-form-row label { font-size: 0.82rem; font-weight: 600; color: var(--muted); }
.admin-form-row input,
.admin-form-row select {
  padding: 9px 11px;
  border-radius: var(--nu-r-medium);
  border: 1px solid var(--border);
  background: var(--nu-card);
  color: var(--text);
  font-size: 0.88rem;
  font-family: inherit;
}
.admin-form-row input:disabled { background: var(--row-alt); color: var(--muted); }

.admin-form-error { font-size: 0.8rem; font-weight: 600; color: var(--nu-alert-text); min-height: 1em; }
.admin-form-error.admin-form-success { color: var(--accent3); }

.admin-form-actions { display: flex; gap: 8px; }

.admin-perm-body { display: grid; gap: 12px; }
.admin-perm-hint { font-size: 0.85rem; color: var(--muted); line-height: 1.6; }

/* ── 역할 × 메뉴 권한 매트릭스 ──
   행 = 역할, 열 = 메뉴(12종).
   ※ 열 제목을 세로쓰기(writing-mode: vertical-rl)로 세우지 않는다 — 그 기법은 알파벳용이고,
     한글은 글자가 선 채로 쌓여 rotate(180deg)까지 걸면 아래에서 위로 읽히게 된다.
     12열 × 66px + 역할열 = 약 1,000px라 가로로 그냥 들어간다. 단어 단위로만 줄바꿈한다. */
.admin-perm-wrap { overflow: auto; border: 1px solid var(--border); border-radius: var(--nu-r-large); }
.admin-perm-table { border-collapse: collapse; width: 100%; font-size: 0.85rem; }
.admin-perm-table thead th {
  position: sticky; top: 0; z-index: 2; background: var(--sidebar); color: var(--nu-on-accent);
  padding: 7px 6px; font-weight: 600; vertical-align: bottom;
  font-size: 0.74rem; line-height: 1.32; white-space: normal; word-break: keep-all; min-width: 62px;
}
.admin-perm-table th.apm-role {
  position: sticky; left: 0; z-index: 3; text-align: left; min-width: 132px;
  padding: 8px 12px; background: var(--sidebar); color: var(--nu-on-accent);
}
.admin-perm-table tbody th.apm-role { background: var(--row-alt); color: var(--text); font-weight: 700; }
.admin-perm-table tbody th.apm-role small { display: block; font-weight: 500; font-size: 0.72rem; color: var(--muted); margin-top: 2px; }
.admin-perm-table tbody td { padding: 7px 4px; text-align: center; border-top: 1px solid var(--border); }
.admin-perm-table tbody tr:hover td { background: var(--row-hover); }
.admin-perm-table input[type=checkbox] { width: 16px; height: 16px; accent-color: var(--th-bg); cursor: pointer; }
.admin-perm-table td.apm-act, .admin-perm-table th.apm-act { white-space: nowrap; padding-right: 12px; }
.apm-msg { margin-left: 8px; font-size: 0.76rem; font-weight: 600; }
.apm-msg.apm-ok { color: var(--nu-success-text); }
.apm-msg.apm-fail { color: var(--nu-alert-text); }

/* ── 비밀번호 변경 모달 ──────────────────────────────────────────────── */
.pwd-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.72);
  z-index: 400;
  display: flex;
  align-items: center;
  justify-content: center;
}
.pwd-modal-card {
  width: 320px;
  max-width: calc(100vw - 40px);
  padding: 28px 26px;
  background: var(--panel);
  border-radius: var(--nu-r-xl);
  box-shadow: var(--shadow-lg);
  display: grid;
  gap: 10px;
}

/* ── 서열계획(HMC 수요) §3-1 피벗 그리드 ── */
.demand-panel { display: flex; flex-direction: column; gap: 12px; }
.demand-toolbar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; font-size: 0.85rem; }
.demand-toolbar label { display: flex; align-items: center; gap: 6px; color: var(--muted); font-weight: 500; }
.demand-toolbar select, .demand-toolbar input[type="text"] {
  padding: 6px 10px; border: 1px solid var(--border); border-radius: var(--nu-r-medium);
  background: var(--nu-card); color: var(--text); font-size: 0.85rem;
}
.demand-toolbar input[type="text"] { min-width: 220px; }
.demand-toolbar .dm-check { cursor: pointer; }
/* .dm-freshness(스냅샷 출처)는 총계 박스 '총 수요' 카드 설명줄로 이동 */
.demand-grid-wrap { overflow: auto; max-height: calc(100vh - 210px); border: 1px solid var(--border); border-radius: var(--nu-r-large); }
.demand-grid { border-collapse: collapse; width: 100%; font-size: 0.82rem; white-space: nowrap; }
/* ── 열 폭 고정은 서열계획(.demand-panel) 표에만 적용한다 ──
   ※ .demand-grid 는 원단소요예정량 표와 공용이다. 여기에 table-layout:fixed 를 걸면
     colgroup이 없는 그 표까지 전 열이 균등폭이 되어 재질명·공급사가 잘린다(2026-08 회귀).
   서열계획은 좌측 5개 열을 실제 값 최대 길이에 맞춰 못 박고, 남는 폭은 폭 미지정 열
   (D+n 일자)이 균등하게 나눠 갖는다 → D+14(15열)까지 가로 스크롤 없이 들어온다.
   값 최대 길이 실측(2026-08, 오토젠 생산품): BD_KEY 15자 · 차종 6 · 부위 6 · ALC 4 · 컬러 6 */
.demand-panel .demand-grid { table-layout: fixed; }
.demand-panel .demand-grid col.dm-w-veh   { width: 66px; }
.demand-panel .demand-grid col.dm-w-bd    { width: 146px; }
.demand-panel .demand-grid col.dm-w-part  { width: 76px; }
.demand-panel .demand-grid col.dm-w-alc   { width: 60px; }
.demand-panel .demand-grid col.dm-w-color { width: 72px; }
.demand-panel .demand-grid col.dm-w-total { width: 78px; }
/* 폭을 고정했으니 넘치는 값은 잘라서 표시(전체 값은 title 툴팁) */
.demand-panel .demand-grid th, .demand-panel .demand-grid td { overflow: hidden; text-overflow: ellipsis; }
/* 차종·부위·ALC·컬러는 값 길이가 짧고 일정해 가운데 정렬이 읽기 좋다(품번은 좌측 유지) */
.demand-grid .dm-c { text-align: center; }
.demand-grid thead th {
  position: sticky; top: 0; z-index: 2; background: var(--sidebar); color: var(--nu-on-accent);
  padding: 7px 8px; text-align: center; font-weight: 600; border-bottom: 1px solid var(--border);
}
.demand-grid thead th .dm-date { font-weight: 400; opacity: 0.75; font-size: 0.72rem; }
.demand-grid tbody td { padding: 6px 8px; border-bottom: 1px solid var(--border); }
.demand-grid tbody tr:nth-child(even) { background: var(--row-alt); }
.demand-grid tbody tr:hover { background: var(--row-hover); }
.demand-grid .dm-num { text-align: right; font-variant-numeric: tabular-nums; }
.demand-grid .dm-bd { font-family: 'Consolas', monospace; font-size: 0.78rem; }
.demand-grid .dm-zero { color: var(--nu-txt-disabled); }
.demand-grid .dm-total { font-weight: 700; background: rgba(229,163,10,0.06); }
/* 합계 열 헤더: 배경이 밝은 베이지라 흰 글씨가 안 보임 → 검은색으로 */
.demand-grid thead th.dm-total { color: var(--nu-ink); background: rgba(229,163,10,0.18); }
.demand-grid .dm-weekend { background: rgba(83,7,137,0.05); }
.demand-grid thead th.dm-weekend { background: var(--nu-txt1); }
.demand-grid tfoot td {
  position: sticky; bottom: 0; background: var(--nu-page); font-weight: 700; color: var(--nu-ink);
  padding: 8px 10px; border-top: 2px solid var(--border);
}
.demand-grid .dm-empty { text-align: center; color: var(--muted); padding: 28px; }

/* ── 재고현황 (오토젠 실 재고 레이어: 원단롤/재단품/완제품) ── */
.inv-note { margin: 8px 0 4px; padding: 9px 14px; 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.84rem; }
.inv-filter-bar { display: flex; align-items: center; gap: 12px; margin: 10px 0; flex-wrap: wrap; font-size: 0.85rem; }
.inv-filter-bar label { display: flex; align-items: center; gap: 6px; color: var(--muted); }
.inv-filter-bar select, .inv-filter-bar input[type="text"] {
  padding: 6px 10px; border: 1px solid var(--border); border-radius: var(--nu-r-medium); background: var(--nu-card); color: var(--text); font-size: 0.85rem; }
.inv-filter-bar input[type="text"] { min-width: 240px; }
.inv-filter-bar .inv-count { margin-left: auto; color: var(--muted); font-weight: 600; }
.inv-grid-wrap { overflow: auto; max-height: calc(100vh - 250px); border: 1px solid var(--border); border-radius: var(--nu-r-large); }
.inv-grid { border-collapse: collapse; width: 100%; font-size: 0.83rem; white-space: nowrap; }
.inv-grid thead th { position: sticky; top: 0; z-index: 2; background: var(--sidebar); color: var(--nu-on-accent);
  padding: 8px 12px; text-align: left; font-weight: 600; }
.inv-grid thead th.inv-num { text-align: right; }
.inv-grid tbody td { padding: 6px 12px; border-bottom: 1px solid var(--border); }
.inv-grid tbody tr:nth-child(even) { background: var(--row-alt); }
.inv-grid tbody tr:hover { background: var(--row-hover); }
.inv-grid .inv-num { text-align: right; font-variant-numeric: tabular-nums; }
.inv-grid .inv-empty { text-align: center; color: var(--muted); padding: 28px; }
.inv-color-chip { display: inline-block; padding: 1px 8px; border-radius: var(--nu-r-large); font-size: 0.76rem;
  background: var(--nu-page); border: 1px solid var(--border); color: var(--text); }

/* ── 출하현황 (SHIPPING_INVENTORY_TRAJECTORY 실데이터) ──
   .sh-kpi* / .sh-period 는 전 화면 공통 총계 박스(.kri-totals)로 대체되어 제거됨 */
/* 표 위(차트 2장 + 검색줄) 여백은 다른 화면과 같은 기준으로 압축하되, 차트 높이는 확보한다.
   좌측 카드에 요약 줄(.sh-viz-foot)이 붙어 카드가 더 높아지는데, 두 카드는 그리드에서 같은
   높이로 늘어나므로 우측 막대 차트가 그 차이만큼 더 높아진다(막대 가독성 확보). */
.sh-panel .inv-filter-bar { margin: 0; }
.sh-panel .viz-card { padding: 9px 12px; display: flex; flex-direction: column; }
.sh-panel .viz-title { margin-bottom: 6px; }
.sh-panel .viz-wrap { height: clamp(140px, 20vh, 230px); flex: 1 1 auto; min-height: 130px; }
.sh-panel .viz-grid { gap: 10px; }
/* 도넛 아래 요약 3종 — 달성율·부족분·불량 */
.sh-viz-foot { display: flex; gap: 12px; margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--border); }
.sh-viz-foot span { flex: 1 1 0; min-width: 0; font-size: 0.72rem; color: var(--muted); }
.sh-viz-foot em { display: block; font-style: normal; font-size: 0.7rem; font-weight: 600; color: var(--muted); }
.sh-viz-foot b { font-size: 1.05rem; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; }

/* ── 원단 발주현황 리드타임 칩 ──
   전용 줄(.wr-lead-row)을 없애고 표 위 검색줄 왼쪽에 얹었다 — 한 줄 절약하면서
   리드타임은 표(발주일·입고예정) 바로 옆에 남아 맥락이 유지된다. */
.wr-lead-lbl { font-weight: 700; color: var(--text); font-size: 0.82rem; }
.wr-lead-chip { display: inline-block; padding: 2px 9px; border-radius: var(--nu-r-large); font-size: 0.78rem;
  background: rgba(229,163,10,0.1); border: 1px solid var(--accent2); color: var(--accent2); }
.wr-bar { gap: 8px; }
.wr-bar .wr-spacer { flex: 1 1 auto; }
.wr-bar label, .wr-bar .inv-count { margin-left: 0; }
.wr-panel .inv-filter-bar { margin: 0; }
.wr-panel .viz-card { padding: 9px 12px; }
.wr-panel .viz-title { margin-bottom: 6px; }

/* ── 생산실적 (MES 양품 미러) ── */
.prod-layout { display: grid; grid-template-columns: 340px minmax(0, 1fr); gap: 14px; align-items: stretch; }
.prod-chart-card { background: var(--panel); border: 1px solid var(--border); border-radius: var(--nu-r-large); padding: 12px; display: flex; flex-direction: column; }
.prod-chart-fill { position: relative; flex: 1 1 auto; min-height: 240px; }
.prod-chart-title { font-weight: 700; font-size: 0.9rem; margin-bottom: 8px; color: var(--text); }
.prod-table-col { min-width: 0; }
/* 필터줄 상하 마진 제거 — 좌측 '차종별 양품' 그래프 박스 상단과 '차종' 검색조건 줄 상단을 맞춘다
   (두 열은 같은 y에서 시작하므로, 마진만 없으면 위쪽 선이 정확히 일치한다) */
.prod-layout .inv-filter-bar { margin: 0 0 10px; }
@media (max-width: 1200px) { .prod-layout { grid-template-columns: 1fr; } }

/* ── 스케줄확정 호기 카드(칩) ── */
.ep-mach-row { display: flex; gap: 8px; flex-wrap: wrap; }
.ep-mach-card { flex: 1 1 130px; min-width: 120px; text-align: left; cursor: pointer;
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--nu-r-large); padding: 6px 11px; }
.ep-mach-card.active { border-color: var(--accent2); box-shadow: 0 0 0 2px rgba(229,163,10,0.18); }
.ep-mach-name { font-weight: 700; font-size: 0.9rem; color: var(--text); }
.ep-mach-good { font-size: 1.25rem; font-weight: 800; color: var(--accent2); font-variant-numeric: tabular-nums; }
.ep-mach-good span { font-size: 0.72rem; color: var(--muted); font-weight: 500; margin-left: 3px; }
.ep-mach-bar { height: 6px; background: var(--nu-page); border-radius: var(--nu-r-small); overflow: hidden; margin: 4px 0; }
.ep-mach-bar > div { height: 100%; background: var(--accent2); }
.ep-mach-items { font-size: 0.76rem; color: var(--muted); }
/* 검색조건 한 줄(계획일·호기·건수·작업지시서) — 상하 여백을 없애 남는 높이를 표에 준다.
   건수의 margin-left:auto 가 자기 뒤 요소(작업지시서 버튼)까지 함께 오른쪽 끝으로 민다. */
.sc-panel .inv-filter-bar { margin: 0; }
.sc-panel .ep-mach-good { font-size: 1.1rem; }

/* ── 설비별 생산현황: 호기별 계획 대비 실적 카드(반원 게이지) ──
   1920 폭에서 호기 7대가 한 줄에 균등 배치되고, 아래 비교 차트가 남은 높이를 채운다. */
/* 좁은 화면은 auto-fit으로 접히고, 넓은 화면(1360↑)에서는 호기 대수(--ep-cols, JS가 카드 수를 넣음)
   만큼 한 줄에 균등 배치한다 — 마지막 호기 한 대만 다음 줄로 떨어지는 일이 없게. */
.ep-card-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; }
@media (min-width: 1360px) { .ep-card-grid { grid-template-columns: repeat(var(--ep-cols, 7), minmax(0, 1fr)); } }
.ep-card { display: flex; flex-direction: column; background: var(--panel); border: 1px solid var(--border);
  border-top-width: 4px; border-radius: var(--nu-r-large); padding: 10px 12px 11px; box-shadow: 0 1px 3px rgba(0,0,0,0.05); }
.ep-card-top { display: flex; justify-content: space-between; align-items: center; gap: 6px; }
.ep-card-name { font-weight: 700; font-size: 0.95rem; color: var(--text); }
/* 호기 정체성 색 점 — 게이지 호·하단 도넛 조각과 같은 색(달성률이 낮아 호가 짧아도 색을 읽을 수 있게) */
.ep-dot { display: inline-block; width: 9px; height: 9px; border-radius: var(--nu-r-small); margin-right: 6px; vertical-align: baseline; }
.ep-card-badge { font-size: 0.68rem; font-weight: 700; padding: 2px 8px; border-radius: var(--nu-r-pill); white-space: nowrap; }
/* 반원 게이지 — 캔버스 아래 중앙(호의 안쪽)에 달성률 수치를 겹쳐 놓는다 */
.ep-gauge { position: relative; height: clamp(72px, 9.5vh, 108px); margin: 4px 0 2px; }
.ep-gauge-txt { position: absolute; left: 0; right: 0; bottom: 4px; text-align: center; line-height: 1.12; pointer-events: none; }
.ep-gauge-txt em { display: block; font-style: normal; font-size: 0.66rem; font-weight: 600; color: var(--muted); }
.ep-gauge-txt b { font-size: 1.32rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.ep-card-nums { display: flex; gap: 8px; margin-top: 6px; padding-top: 7px; border-top: 1px dashed var(--border); }
.ep-num { flex: 1 1 0; min-width: 0; }
.ep-num em { display: block; font-style: normal; font-size: 0.68rem; font-weight: 600; color: var(--muted); }
.ep-num b { font-size: 1.02rem; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; }
.ep-num-plan b { color: var(--muted); }
.ep-card-sub { margin-top: 6px; font-size: 0.71rem; color: var(--muted); }
/* 진행 막대 — 사출기 연동 화면(injFill)이 함께 쓴다 */
.ep-card-track { position: relative; height: 10px; background: var(--nu-page); border-radius: var(--nu-r-medium); overflow: hidden; }
.ep-card-fill { height: 100%; border-radius: var(--nu-r-medium); transition: width .3s ease; }
/* 달성 상태 색상 — 상단 보더·게이지 수치·배지 */
.ep-good  { border-top-color: var(--nu-success); } .ep-good  .ep-gauge-txt b { color: var(--nu-success-text); } .ep-good  .ep-card-badge { background: var(--nu-success-light); color: var(--nu-success-text); }
.ep-warn  { border-top-color: var(--nu-warning); } .ep-warn  .ep-gauge-txt b { color: var(--nu-warning-text); } .ep-warn  .ep-card-badge { background: var(--nu-warning-light); color: var(--nu-warning-text); }
.ep-low   { border-top-color: var(--nu-alert); } .ep-low   .ep-gauge-txt b { color: var(--nu-alert-text); } .ep-low   .ep-card-badge { background: var(--nu-alert-light); color: var(--nu-alert-text); }
.ep-noplan{ border-top-color: var(--nu-border-strong); } .ep-noplan .ep-gauge-txt b { color: var(--nu-txt4); } .ep-noplan .ep-card-badge { background: var(--nu-page); color: var(--nu-txt3); }

/* 카드 아래 비교 차트 2단 — 좌: 계획대비실적 혼합차트, 우: 실적 구성 도넛.
   위 호기 카드 그리드와 '같은 트랙'(--ep-cols 열 · 같은 gap)을 쓰고 4열 / 3열로 나눠 span 시킨다.
   → 두 박스의 경계가 INJT04 오른쪽 끝 · INJT05 왼쪽 끝 선과 정확히 일치한다(7대 기준 4:3).
   fr 비율(4fr:3fr)로 나누면 gap 때문에 1~2px 어긋나므로 트랙을 공유하는 이 방식을 쓴다. */
.ep-viz-grid { display: grid; grid-template-columns: repeat(var(--ep-cols, 7), minmax(0, 1fr)); gap: 10px; }
.ep-viz-grid > :first-child { grid-column: 1 / span 4; }
.ep-viz-grid > :last-child  { grid-column: span 3 / -1; }
/* 카드가 auto-fit으로 접히기 시작하는 구간부터는 열 맞춤이 의미 없다 — 4:3 비율만 유지 */
@media (max-width: 1359px) {
  .ep-viz-grid { grid-template-columns: minmax(0, 4fr) minmax(0, 3fr); }
  .ep-viz-grid > :first-child, .ep-viz-grid > :last-child { grid-column: auto; }
}
@media (max-width: 1000px) { .ep-viz-grid { grid-template-columns: 1fr; } }

/* ── 시각화 카드 그리드(출하/재고/원단 발주현황 공통) ── */
.viz-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 12px; }
.viz-card { background: var(--panel); border: 1px solid var(--border); border-radius: var(--nu-r-large); padding: 12px 14px; }
.viz-title { font-weight: 700; font-size: 0.9rem; color: var(--text); margin-bottom: 8px; }
.viz-title span { font-weight: 400; font-size: 0.76rem; color: var(--muted); margin-left: 6px; }
/* 차트 높이는 화면(창) 높이에 비례 — 노트북에서도 한 화면에 들어가도록 */
.viz-wrap { position: relative; height: clamp(140px, 20vh, 240px); }
.viz-wrap.viz-wrap-lg { height: clamp(150px, 24vh, 280px); }
.viz-empty { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--muted); font-size: 0.85rem; }

/* ── 원단소요예정량 ──
   ※ 원단소요예정량 화면에서는 .fr-banner(노란 안내 박스)를 걷어냈다 — 예시 데이터 고지는
     총계 박스의 '예시' 배지와 차트 제목 부제가 대신한다(표기는 유지, 높이는 표에 돌려줌).
     아래 .fr-banner 스타일은 원단 발주현황·사출기 연동 화면이 계속 쓰므로 남긴다. */
.fr-banner { background: var(--nu-warning-light); border: 1px solid var(--nu-warning-border); color: var(--nu-warning-text); font-size: 0.85rem; font-weight: 600; padding: 9px 14px; border-radius: var(--nu-r-medium); }
.fr-mat-dot { display: inline-block; width: 10px; height: 10px; border-radius: var(--nu-r-small); margin-right: 7px; vertical-align: middle; }
.fr-panel .inv-filter-bar { margin: 0; }
.fr-panel .viz-card { padding: 9px 12px; }
.fr-panel .viz-title { margin-bottom: 6px; }
/* 표 행 수가 재질 수(5종)로 고정이라 표를 늘려도 빈 줄만 생긴다.
   → 표는 제 높이만 쓰고(0 1 auto), 남는 높이는 위 차트가 전부 가져간다.
     패널은 다른 화면과 같이 화면 아래까지 차므로 박스 아래 끝선도 그대로 맞는다. */
#layoutRoot.fit-page > .fr-panel > .viz-card { flex: 1 1 auto; min-height: 170px; display: flex; flex-direction: column; }
#layoutRoot.fit-page > .fr-panel > .viz-card > .viz-wrap { height: auto; flex: 1 1 auto; min-height: 140px; }
/* 0 0 auto — 절대 눌리지 않는다. 재질 5행은 항상 전부 보여야 한다(줄어들면 표 안이 스크롤된다). */
#layoutRoot.fit-page > .fr-panel > .demand-grid-wrap { flex: 0 0 auto; min-height: 0; }
#layoutRoot.fit-page > .fr-panel { overflow-y: auto; }
.nav-ext-ico { margin-left: 6px; font-size: 0.8em; opacity: 0.7; }

/* ── 사출기 연동 화면 ── */
.inj-machine-hdr { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: var(--panel); border: 1px solid var(--border); border-left: 5px solid var(--accent2); border-radius: var(--nu-r-large); padding: 12px 16px; flex-wrap: wrap; }
.inj-mh-name { font-size: 1.15rem; font-weight: 800; color: var(--text); }
.inj-mh-sub { margin-left: 10px; font-size: 0.8rem; color: var(--muted); }
.inj-mh-right { display: flex; align-items: center; gap: 12px; }
.inj-mh-mold { font-size: 0.9rem; color: var(--muted); }
.inj-mh-mold b { color: var(--text); }
.inj-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 1100px) { .inj-grid { grid-template-columns: 1fr; } }
.inj-mc.sel { border-color: var(--accent2); box-shadow: 0 0 0 2px rgba(229,163,10,0.18); }
.inj-mode { font-size: 0.72rem; font-weight: 700; padding: 1px 8px; border-radius: var(--nu-r-large); }
.inj-mode-수동 { background: var(--nu-success-light); color: var(--nu-success-text); }
.inj-mode-자동 { background: var(--nu-alert-light); color: var(--nu-alert-text); }
.inj-mode-정지 { background: var(--nu-surface-2); color: var(--nu-txt3); }
.inj-mc-st { font-size: 1.05rem; font-weight: 800; margin: 4px 0 2px; }
.inj-st-대기 { color: var(--nu-success-text); } .inj-st-작업중 { color: var(--nu-primary); } .inj-st-정지 { color: var(--nu-txt4); }
.inj-form { display: flex; flex-direction: column; gap: 10px; padding: 4px 2px; }
.inj-form label { font-size: 0.86rem; color: var(--text); display: flex; align-items: center; gap: 8px; }
.inj-form select, .inj-form input[type="number"] { padding: 6px 9px; border: 1px solid var(--border); border-radius: var(--nu-r-medium); font-family: inherit; }
.inj-check { cursor: pointer; }
.inj-check small { color: var(--muted); font-weight: 400; }
.inj-btns { display: flex; gap: 10px; margin-top: 4px; }
.inj-btns button:disabled { opacity: 0.5; cursor: default; }
.inj-precond { font-size: 0.8rem; padding: 8px 10px; border-radius: var(--nu-r-medium); }
.inj-precond.ok { background: var(--nu-success-light); color: var(--nu-success-text); }
.inj-precond.no { background: var(--nu-warning-light); color: var(--nu-warning-text); border: 1px solid var(--nu-warning-border); }
.inj-steps { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 4px 0 10px; }
.inj-step { font-size: 0.78rem; font-weight: 600; padding: 5px 10px; border-radius: var(--nu-r-medium); background: var(--nu-page); color: var(--nu-txt4); }
.inj-step.active { background: var(--nu-warning-light-2); color: var(--nu-warning-text); box-shadow: 0 0 0 1px var(--nu-warning-border); }
.inj-step.done { background: var(--nu-success-light); color: var(--nu-success-text); }
.inj-badge { display: inline-block; font-weight: 800; font-size: 0.95rem; padding: 6px 14px; border-radius: var(--nu-r-medium); }
.inj-badge small { font-weight: 500; opacity: 0.8; }
.inj-b-idle { background: var(--nu-surface-2); color: var(--nu-txt2); }
.inj-b-busy { background: var(--nu-warning-light-2); color: var(--nu-warning-text); }
.inj-b-good { background: var(--nu-success-light); color: var(--nu-success-text); }
.inj-b-warn { background: var(--nu-warning-light); color: var(--nu-warning-text); }
.inj-b-fail { background: var(--nu-alert-light); color: var(--nu-alert-text); }
/* ── 작업지시 목록 (사출기 연동의 출발점) ────────────────────────────────── */
/* 순서 셀 — 클릭하면 숫자 ↔ X 토글. 삭제 버튼이 X 표시된 건들을 일괄 처리한다. */
.inj-wo-grid .inj-seq {
  text-align: center; font-weight: 700; font-variant-numeric: tabular-nums;
  cursor: pointer; user-select: none; border-radius: var(--nu-r-medium); transition: background 0.12s, color 0.12s;
}
.inj-wo-grid .inj-seq:hover { background: var(--row-hover); }
.inj-wo-grid .inj-seq.x { color: var(--nu-alert-text); font-weight: 800; background: var(--nu-alert-light); }
.inj-wo-grid tr.inj-r-mark > td { background: var(--nu-alert-light-2) !important; }
/* 작업상태별 라인 색상 (엑셀 확인표: 완료 시 해당 라인 색상 변경) */
.inj-wo-grid tr.inj-r-done > td { background: var(--nu-success-light); color: var(--nu-success-text); }
.inj-wo-grid tr.inj-r-run  > td { background: var(--nu-primary-tint); }
.inj-wo-grid tr.inj-r-fail > td { background: var(--nu-alert-light); }
.inj-wo-grid td { vertical-align: middle; }
.inj-td-mold select {
  width: 100%; max-width: 148px; padding: 3px 6px; font-size: 0.78rem;
  border: 1px solid var(--border); border-radius: var(--nu-r-medium); background: var(--nu-card); color: var(--text);
}
.inj-td-move { white-space: nowrap; text-align: center; }
.inj-mv {
  border: 1px solid var(--border); background: var(--nu-card); color: var(--muted);
  border-radius: var(--nu-r-small); cursor: pointer; font-size: 0.62rem; line-height: 1; padding: 3px 4px; margin: 0 1px;
}
.inj-mv:hover { border-color: var(--jv-primary); color: var(--jv-primary); }
/* 상태 배지 — 표 안이라 작게 */
.inj-st-badge { display: inline-block; font-size: 0.72rem; font-weight: 700; padding: 2px 8px; border-radius: var(--nu-r-pill); }
.inj-sb-대기   { background: var(--nu-surface-2); color: var(--nu-txt2); }
.inj-sb-진행중 { background: var(--nu-info-light); color: var(--nu-info-text); }
.inj-sb-완료   { background: var(--nu-success-light); color: var(--nu-success-text); }
.inj-sb-실패   { background: var(--nu-alert-light); color: var(--nu-alert-text); }
/* 삭제 버튼 — 파괴적 동작이라 다른 버튼과 색을 구분한다 */
.inj-del-btn {
  border: 1px solid var(--nu-alert-border); background: var(--nu-card); color: var(--nu-alert-text);
  font-size: 0.82rem; font-weight: 700; border-radius: var(--nu-r-medium); padding: 5px 14px; cursor: pointer;
}
.inj-del-btn:hover:not(:disabled) { background: var(--nu-alert-light); border-color: var(--nu-alert); }
.inj-del-btn:disabled { opacity: 0.45; cursor: default; }
/* 조작 결과 안내 줄 */
.inj-msg { font-size: 0.82rem; padding: 7px 11px; border-radius: var(--nu-r-medium); }
.inj-m-good { background: var(--nu-success-light); color: var(--nu-success-text); }
.inj-m-warn { background: var(--nu-warning-light); color: var(--nu-warning-text); }
.inj-m-busy { background: var(--nu-warning-light-2); color: var(--nu-warning-text); }
.inj-m-fail { background: var(--nu-alert-light); color: var(--nu-alert-text); }

.inj-mon { margin-top: 14px; border-top: 1px solid var(--border); padding-top: 12px; }
.inj-mon-t { font-weight: 700; font-size: 0.86rem; color: var(--text); }
.inj-mon-t span { font-weight: 400; font-size: 0.76rem; color: var(--muted); margin-left: 6px; }
.inj-mon-num { margin: 6px 0; font-size: 0.9rem; color: var(--muted); }
.inj-mon-num b { font-size: 1.5rem; color: var(--text); font-variant-numeric: tabular-nums; }
.inj-mon-pct { float: right; font-weight: 800; color: var(--accent2); }
.inj-mon-dim { color: var(--muted); }
/* 모드 램프 4종(1000~1003) + 알람(1004) — LS 확정 주소 그대로 표시 */
.inj-lamps { display: inline-flex; gap: 4px; }
.inj-lamp { display: inline-flex; flex-direction: column; align-items: center; line-height: 1.15;
  font-size: 0.74rem; font-weight: 700; padding: 3px 9px; border-radius: var(--nu-r-medium); background: var(--nu-page); color: var(--nu-txt4); border: 1px solid transparent; }
.inj-lamp small { font-size: 0.62rem; font-weight: 500; opacity: 0.75; }
.inj-lamp.on { background: var(--nu-success-light); color: var(--nu-success-text); border-color: var(--nu-success-border); }
.inj-lamp-alarm.on { background: var(--nu-alert-light); color: var(--nu-alert-text); border-color: var(--nu-alert-border); }
.inj-st-알람 { color: var(--nu-alert-text); }
.inj-wait { font-size: 0.82rem; padding: 9px 11px; border-radius: var(--nu-r-medium); background: var(--nu-info-light); color: var(--nu-info-text); border: 1px solid var(--nu-info-border); }
.inj-mon-sub { margin-top: 8px; font-size: 0.8rem; color: var(--muted); }
.inj-mon-sub b { color: var(--text); font-variant-numeric: tabular-nums; }
.inj-mon-sub small { color: var(--muted); }
.inj-addr { margin-top: 6px; font-size: 0.74rem; color: var(--muted); }
.fr-banner.inj-ok { background: var(--nu-success-light); border-color: var(--nu-success-border); color: var(--nu-success-text); }
.fr-banner code { background: rgba(0,0,0,0.06); padding: 1px 6px; border-radius: var(--nu-r-small); }

/* ── 홈 대시보드 (Oracle 통합 실 KPI) ── */
.home-kpi-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; margin-bottom: 14px; }
.home-kpi { background: var(--panel); border: 1px solid var(--border); border-radius: var(--nu-r-large); padding: 16px 18px; }
.home-kpi-l { font-size: 0.85rem; color: var(--muted); margin-bottom: 6px; }
.home-kpi-v { font-size: 1.9rem; font-weight: 800; font-variant-numeric: tabular-nums; line-height: 1.1; }
.home-kpi-s { font-size: 0.78rem; color: var(--muted); margin-top: 4px; }
.home-mid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin-bottom: 14px; }
.home-bot { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.home-card { padding: 14px 16px; border: 1px solid var(--border); border-radius: var(--nu-r-large); background: var(--panel); }
.home-card-t { font-weight: 700; font-size: 0.92rem; color: var(--text); margin-bottom: 10px; }
.home-card-hint { font-weight: 400; font-size: 0.72rem; color: var(--muted, var(--nu-txt4)); margin-left: 6px; }
.home-inv-row { display: flex; gap: 12px; }
.home-inv { flex: 1; text-align: center; background: var(--row-alt); border: 1px solid var(--border); border-radius: var(--nu-r-large); padding: 14px 8px; }
.home-inv-l { font-size: 0.82rem; color: var(--muted); margin-bottom: 6px; }
.home-inv-v { font-size: 1.4rem; font-weight: 800; color: var(--text); font-variant-numeric: tabular-nums; }
.home-inv-v span { font-size: 0.72rem; color: var(--muted); font-weight: 500; margin-left: 3px; }
.home-note { font-size: 0.76rem; color: var(--muted); margin-top: 10px; }
/* 차트 높이는 1920×1080 한 화면을 채우도록 화면 높이에 비례(clamp). 1080에서 상단 291 / 하단 194px.
   ※ 홈 대시보드(.home-fill)에서는 아래 무스크롤 규칙이 이 값을 덮어쓰고 남은 공간을 채운다. */
.home-chart-wrap { position: relative; height: clamp(190px, 27vh, 320px); }
.home-chart-wrap.sm { height: clamp(140px, 18vh, 220px); }

/* ── 홈 대시보드 전용: 브라우저 한 화면 무스크롤 ────────────────────
   브라우저는 주소창·탭바 때문에 실제 뷰포트가 화면 해상도보다 100~150px 작다(1080 모니터 →
   보통 937px). 그래서 고정 높이(px/vh)로 맞추면 어떤 PC에서는 넘치고 어떤 PC에서는 빈다.
   KRI·KPI는 내용 높이대로 두고, 차트 2줄이 "남은 높이"를 나눠 갖게 해 항상 정확히 한 화면에 맞춘다. */
.content:has(> #layoutRoot.home-fill) { overflow: hidden; }
#layoutRoot.home-fill { display: flex; flex-direction: column; flex: 1; min-height: 0; gap: 12px; }
#layoutRoot.home-fill > .home-kri,
#layoutRoot.home-fill > .home-kpi-row { flex: 0 0 auto; margin-bottom: 0; }
/* 차트 2줄은 남은 높이를 균등 분할 — 가운데(차종별 양품)와 하단(설비 가동) 높이를 같게 */
#layoutRoot.home-fill > .home-mid { flex: 1 1 0; min-height: 0; margin-bottom: 0; }
#layoutRoot.home-fill > .home-bot { flex: 1 1 0; min-height: 0; }
#layoutRoot.home-fill .home-card { display: flex; flex-direction: column; min-height: 0; }
#layoutRoot.home-fill .home-card-t { flex: 0 0 auto; }
#layoutRoot.home-fill .home-chart-wrap { height: auto; flex: 1 1 auto; min-height: 0; }
#layoutRoot.home-fill .home-inv-row { flex: 1 1 auto; align-items: center; }
#layoutRoot.home-fill .home-note { flex: 0 0 auto; }

/* 노트북 등 세로가 짧은 화면: 상단 고정 블록을 줄여 차트 자리를 확보 */
@media (max-height: 860px) {
  #layoutRoot.home-fill .home-kri { padding: 9px 14px; }
  #layoutRoot.home-fill .home-kri-title { margin-bottom: 6px; font-size: 0.88rem; }
  #layoutRoot.home-fill .home-kri-card { padding: 7px 12px; }
  #layoutRoot.home-fill .home-kri-desc { font-size: 0.73rem; line-height: 1.4; }
  #layoutRoot.home-fill .home-kpi { padding: 10px 16px; }
  #layoutRoot.home-fill .home-kpi-v { font-size: 1.6rem; }
}
@media (max-height: 720px) {
  #layoutRoot.home-fill .home-kri-desc { display: none; }
  #layoutRoot.home-fill .home-kpi-v { font-size: 1.4rem; }
  #layoutRoot.home-fill .home-kpi-s { display: none; }
}
@media (max-height: 660px) {
  .content:has(> #layoutRoot.home-fill) { padding: 12px 20px; gap: 10px; }
  #layoutRoot.home-fill { gap: 8px; }
  #layoutRoot.home-fill .home-card { padding: 10px 12px; }
}

/* ── 설비 상세현황 (호기 스펙·금형매핑·최근실적) ── */
/* 검색조건 2줄 — ① 호기 버튼 줄 ② 작업일·교대 + 건수 줄.
   두 줄 모두 패널의 직계 자식이라 좌·우 끝이 아래 표(.inv-grid-wrap)의 양 끝과 정확히 맞는다.
   (건수는 .inv-filter-bar .inv-count 의 margin-left:auto 로 표 오른쪽 끝에 붙는다) */
#layoutRoot.ed-page .inv-filter-bar { margin: 0; }
.ed-mbtn-row { display: flex; gap: 6px; flex-wrap: wrap; }
.ed-mbtn { padding: 6px 13px; border: 1px solid var(--border); border-radius: var(--nu-r-medium); background: var(--panel);
  cursor: pointer; font-weight: 700; color: var(--text); display: flex; align-items: baseline; gap: 6px; }
.ed-mbtn span { font-size: 0.72rem; color: var(--muted); font-weight: 500; }
.ed-mbtn.active { background: var(--sidebar); color: var(--nu-on-accent); border-color: var(--sidebar); }
.ed-mbtn.active span { color: rgba(255,255,255,0.7); }
/* .ed-spec-row(스펙 카드 4장)는 상단 총계 박스(.kri-totals)로 승격되어 제거됨 */
.ed-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); gap: 14px; }
@media (max-width: 1200px) { .ed-grid { grid-template-columns: 1fr; } }

/* ── 설비 가동현황 (호기별 가동율 ≈추정) ── */
/* 호기 카드 — 설비별 생산현황과 같이 넓은 화면에서 호기 대수(--ep-cols)만큼 한 줄에 균등 배치 */
.util-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; }
@media (min-width: 1360px) { .util-row { grid-template-columns: repeat(var(--ep-cols, 7), minmax(0, 1fr)); } }
.util-card { background: var(--panel); border: 1px solid var(--border); border-radius: var(--nu-r-large); padding: 10px 12px 11px; text-align: center; }
.util-mn { font-weight: 700; font-size: 0.95rem; color: var(--text); }
/* 가동율 게이지 — .ep-gauge(설비별 생산현황과 공용)를 240° 속도계형으로 키워 쓴다.
   도형 높이 = 반지름×1.5 라서 아래 height를 키운 만큼 호가 실제로 커진다(반원이면 카드 폭이
   반지름을 제한해 높이를 줘도 빈 공간만 늘어난다). 수치는 원 안쪽 가운데에 놓는다. */
.util-card .ep-gauge { height: clamp(104px, 14vh, 158px); margin: 6px 0 4px; }
.util-card .ep-gauge-txt { top: 0; bottom: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; }
.util-card .ep-gauge-txt em { font-size: 0.7rem; }
.util-card .ep-gauge-txt b { font-size: 1.6rem; }
.util-card .ep-gauge-txt b.sm { font-size: 1.15rem; }
.util-sub { font-size: 0.74rem; color: var(--muted); }

/* ── 설비 가동현황 비가동 표시 ── */
.util-card-non { border-color: var(--accent); background: rgba(229,34,45,0.04); }
.util-badge { display: inline-block; padding: 1px 8px; border-radius: var(--nu-r-large); font-size: 0.7rem; font-weight: 700;
  background: var(--accent); color: var(--nu-on-accent); vertical-align: middle; }

/* ── 홈 대시보드 프로젝트 KRI 배너 ── */
.home-kri { background: var(--nu-gradient); border-radius: var(--nu-r-large); padding: 12px 18px; margin-bottom: 14px; }
.home-kri-title { color: var(--nu-on-accent); font-weight: 800; font-size: 0.95rem; margin-bottom: 8px; }
.home-kri-title span { font-weight: 500; font-size: 0.76rem; color: rgba(255,255,255,0.6); margin-left: 6px; }
.home-kri-cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }

/* ── 홈 대시보드 반응형 사다리 (1920 기준 → 좁아질 때 단계적으로 접힘) ──
   1200↓ 사이드바 드로어(위 §반응형) · 1100↓ 2열 → 1열 · 900↓ KPI 4열 → 2열 */
@media (max-width: 1100px) {
  .home-mid, .home-bot, .home-kri-cards { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 900px) {
  .home-kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .home-kpi-v { font-size: 1.6rem; }
  .home-inv-row { flex-wrap: wrap; }
}

/* ── 1100↓ 무스크롤 해제 ─────────────────────────────────────────────
   홈은 1920 기준 '한 화면 무스크롤'(.home-fill)로 짜여 있다. 2열이 1열로 접히면
   같은 세로 공간에 카드가 2배로 들어가는데, .home-mid/.home-bot 이 여전히 남은 높이를
   반씩 나눠 갖고 .content가 overflow:hidden 이라 카드가 짓눌려 차트가 아래 제목 위로
   넘쳐 보였다. 좁은 화면에서 무스크롤은 지킬 수도 없고 지킬 이유도 없다 → 스크롤 허용.
   ※ 데스크톱(1100↑) 무스크롤 규약은 그대로다. */
@media (max-width: 1100px) {
  .content:has(> #layoutRoot.home-fill) { overflow: auto; }
  #layoutRoot.home-fill { flex: 0 0 auto; min-height: auto; }
  #layoutRoot.home-fill > .home-mid,
  #layoutRoot.home-fill > .home-bot { flex: 0 0 auto; min-height: auto; }
  /* 세로로 늘어나도 되니 차트는 화면 폭에 비례한 고정 높이를 다시 갖는다 */
  #layoutRoot.home-fill .home-chart-wrap { flex: 0 0 auto; height: clamp(190px, 42vw, 300px); }
  #layoutRoot.home-fill .home-chart-wrap.sm { height: clamp(160px, 34vw, 240px); }
  #layoutRoot.home-fill .home-inv-row { flex: 0 0 auto; }
  /* 차트가 카드 밖으로 새어나가지 않게 하는 마지막 방어선(리사이즈 중 한 프레임 대비) */
  #layoutRoot.home-fill .home-card { overflow: hidden; }
}
.home-kri-card { background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.14); border-radius: var(--nu-r-large); padding: 10px 14px; }
.home-kri-goal { color: var(--nu-on-accent); font-size: 1.02rem; font-weight: 700; }
.home-kri-goal b { color: var(--nu-warning-soft); font-size: 1.3rem; }
.home-kri-badge { display: inline-block; padding: 1px 8px; border-radius: var(--nu-r-large); font-size: 0.7rem; font-weight: 700; background: var(--nu-warning); color: var(--nu-on-accent); vertical-align: middle; margin-left: 4px; }
.home-kri-desc { color: rgba(255,255,255,0.72); font-size: 0.77rem; margin-top: 4px; line-height: 1.5; }

/* ═══════════════════════════════════════════════════════════════════════════
   홈 대시보드 전용 레이아웃 (DESIGN.md · Nubank NuDS)
   퍼플 프라이머리 + 중성 그레이 배경의 업무용 밀집형 대시보드.
   ★ 모든 선택자를 #layoutRoot.home-fill 안으로 한정한다. 홈 대시보드는 이 클래스를
     renderDashboardPage()에서만 부여하므로, 다른 화면에는 절대 영향이 없다.
   ※ 색 토큰은 :root(NuDS)에서 그대로 상속받는다 — 여기서 값을 재정의하지 않는다
     (DESIGN.md Don'ts "hex 직접 사용 금지 / 토큰은 한 곳에서만 관리").
   ═══════════════════════════════════════════════════════════════════════════ */
#layoutRoot.home-fill {
  /* §3-A 타이포 — Pretendard + 한글 자간 보정 */
  font-family: 'Pretendard Variable', 'Pretendard', 'Noto Sans KR', -apple-system,
               BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  letter-spacing: -0.01em;
  color: var(--jv-txt1);
}
/* §2-B 페이지 배경 — 쿨그레이 (홈 대시보드일 때의 콘텐츠 영역에만).
   ※ --jv-* 는 #layoutRoot에 정의돼 있어 부모인 .content에서는 참조 불가 → 리터럴 값 사용 */
.content:has(> #layoutRoot.home-fill) { background: var(--nu-page); }

/* ── §6-D KPI 카드: 아이콘 박스 좌 + 26px 수치 우 ───────────────────────── */
#layoutRoot.home-fill .home-kpi-row { gap: 12px; }
#layoutRoot.home-fill .jv-kpi {
  display: flex; align-items: center; gap: 14px;
  background: var(--jv-card); border: 1px solid var(--jv-border); border-radius: var(--nu-r-large);
  box-shadow: var(--jv-shadow); padding: 14px 16px;
  transition: box-shadow 0.15s, border-color 0.15s, transform 0.15s;   /* §6-C card-hover */
}
#layoutRoot.home-fill .jv-kpi:hover {
  box-shadow: 0 4px 16px rgba(130,10,209,0.12); border-color: var(--jv-primary-mid);
  transform: translateY(-1px);
}
#layoutRoot.home-fill .jv-kpi-ico {
  flex-shrink: 0; width: 46px; height: 46px; border-radius: var(--nu-r-large);
  display: flex; align-items: center; justify-content: center;
}
#layoutRoot.home-fill .jv-kpi-ico svg { width: 22px; height: 22px; }
#layoutRoot.home-fill .jv-t-primary { background: var(--jv-primary-light); color: var(--jv-primary); }
#layoutRoot.home-fill .jv-t-success { background: var(--jv-success-light); color: var(--jv-success); }
#layoutRoot.home-fill .jv-t-violet  { background: var(--jv-violet-light);  color: var(--jv-violet); }
#layoutRoot.home-fill .jv-t-warning { background: var(--jv-warning-light); color: var(--jv-warning); }
#layoutRoot.home-fill .jv-kpi-body { min-width: 0; }                    /* §10-B ③ truncate 대비 */
#layoutRoot.home-fill .home-kpi-l {
  margin: 0; font-size: 12px; font-weight: 500; color: var(--jv-txt3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#layoutRoot.home-fill .home-kpi-v {                                      /* §3-B 26px KPI 수치 */
  margin-top: 3px; font-size: 26px; font-weight: 700; line-height: 1;
  color: var(--jv-txt1); font-variant-numeric: tabular-nums; letter-spacing: -0.02em;
}
#layoutRoot.home-fill .jv-kpi-u { font-size: 13px; font-weight: 600; color: var(--jv-txt3); margin-left: 3px; }
#layoutRoot.home-fill .home-kpi-s { margin-top: 4px; font-size: 10px; color: var(--jv-txt4); }

/* ── §6-D 강조 카드(프라이머리 채움) — KRI 목표 배너 ─────────────────────
   ★ 홈 대시보드의 KRI 배너 + 총계 박스(.kri-totals)가 이 스타일을 공유한다.
     .kri-totals 를 붙인 화면(설비별 생산현황·출하계획·생산실적)은 본문 최상단에
     같은 파란 박스로 페이지 총계를 표시한다. 값은 여기 한 곳에서만 관리 —
     화면을 늘릴 때 선택자만 덧붙이고 수치는 절대 복제하지 않는다. */
#layoutRoot.home-fill .home-kri,
#layoutRoot .home-kri.kri-totals {
  /* 배경·그림자는 아래 §Colors 블록이 최종적으로 --nu-gradient / --nu-elev-low 로 덮어쓴다.
     여기 남은 값은 그 블록이 없을 때의 안전값 — 톤 고정 리터럴을 두면 다크에서 보라 그림자가
     남으므로 토큰으로만 적는다. */
  background: var(--jv-primary); border-radius: var(--nu-r-large); padding: 12px 16px;
  box-shadow: var(--nu-elev-low);
}
#layoutRoot.home-fill .home-kri-title,
#layoutRoot .kri-totals .home-kri-title { font-size: 13px; font-weight: 700; color: var(--nu-on-accent); margin-bottom: 8px; }
#layoutRoot.home-fill .home-kri-title span,
#layoutRoot .kri-totals .home-kri-title span { font-size: 11px; font-weight: 500; color: rgba(255,255,255,0.72); }
#layoutRoot.home-fill .home-kri-card,
#layoutRoot .kri-totals .home-kri-card {
  background: rgba(255,255,255,0.12); border: 1px solid rgba(255,255,255,0.18); border-radius: var(--nu-r-large); padding: 9px 13px;
}
#layoutRoot.home-fill .home-kri-goal,
#layoutRoot .kri-totals .home-kri-goal { font-size: 13px; font-weight: 700; color: var(--nu-on-accent); }
#layoutRoot.home-fill .home-kri-goal b,
#layoutRoot .kri-totals .home-kri-goal b { font-size: 16px; color: var(--nu-on-accent); }
#layoutRoot.home-fill .home-kri-badge,                                   /* §6-E 배지 10px pill */
#layoutRoot .kri-totals .home-kri-badge {
  font-size: 10px; font-weight: 700; padding: 1px 8px; border-radius: var(--nu-r-pill);
  background: rgba(255,255,255,0.22); color: var(--nu-on-accent); border: 1px solid rgba(255,255,255,0.28);
}
#layoutRoot.home-fill .home-kri-desc,
#layoutRoot .kri-totals .home-kri-desc { font-size: 11px; color: rgba(255,255,255,0.78); line-height: 1.45; margin-top: 4px; }

/* 총계 박스 공통 — 본문 최상단 고정 높이. 카드 수(3~4장)는 auto-fit이 알아서 나눈다.
   재고처럼 탭 안쪽(.inv-tab-content)에 놓이는 경우가 있어 직계 제한을 두지 않는다. */
#layoutRoot .home-kri.kri-totals { flex: 0 0 auto; margin-bottom: 0; }
#layoutRoot .kri-totals .home-kri-cards { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
#layoutRoot .kri-totals .home-kri-goal b { font-variant-numeric: tabular-nums; }
/* 예시(미연동) 데이터 화면용 회색 변형 — 현재 붙은 화면 없음(원단소요예정량이 쓰다가
   2026-08 전 화면 색 통일로 뗐다. 예시 고지는 카드의 '예시' 배지·설명줄이 담당).
   미연동 화면을 새로 만들 때 다시 쓸 수 있게 스타일만 남겨 둔다. */
#layoutRoot .home-kri.kri-mock { background: var(--nu-txt3); box-shadow: none; }
#layoutRoot .kri-mock .home-kri-badge { background: rgba(255,255,255,0.18); border-color: rgba(255,255,255,0.30); }

/* 총계 박스가 차지한 높이만큼 아래 본문이 줄어드니, 넘치는 영역만 내부 스크롤 ── */
/* 설비별 생산현황 — 호기 카드 줄은 제 높이를 지키고(0 1 auto), 남는 높이는 아래 비교 차트가 먹는다.
   기준일 필터 줄은 상하 여백을 없애 카드가 화면 위쪽에 바짝 붙게 한다. */
#layoutRoot.ep-page .inv-filter-bar { margin: 0; }
/* flex: 0 0 auto — 카드 줄이 두 줄이 돼도 절대 눌리지 않는다(눌리면 아래 차트와 겹친다) */
#layoutRoot.ep-page > .panel { overflow-y: auto; }
#layoutRoot.ep-page > .panel > .ep-card-grid { flex: 0 0 auto; align-content: start; }
/* 아래 4:3 차트 2단은 설비별 생산현황·설비 가동현황이 공유한다 — 화면이 아니라 클래스로 스코프 */
#layoutRoot.fit-page > .panel > .ep-viz-grid { flex: 1 1 auto; min-height: 180px; }
#layoutRoot.fit-page .ep-viz-grid > .viz-card { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }
#layoutRoot.fit-page .ep-viz-wrap { height: auto; flex: 1 1 auto; min-height: 130px; }
#layoutRoot.fit-page .ep-viz-grid > .viz-card > .inv-grid-wrap {
  flex: 1 1 auto; min-height: 96px; max-height: none !important; overflow: auto;
}
/* 생산실적 — 표가 .panel 직계가 아니라(prod-layout > prod-table-col) 공통 fit 규칙이
   닿지 않는다. 매직넘버 calc() 대신 여기서도 "남은 공간 채우기"로 맞춘다. */
#layoutRoot.fit-page > .panel > .prod-layout { flex: 1 1 auto; min-height: 0; }
#layoutRoot.fit-page .prod-table-col { display: flex; flex-direction: column; min-height: 0; }
#layoutRoot.fit-page .prod-table-col > .inv-grid-wrap {
  flex: 1 1 auto; min-height: 96px; max-height: none !important; overflow: auto;
}

/* ── §6-C 카드 + 차트 패널 ─────────────────────────────────────────────── */
#layoutRoot.home-fill .home-mid, #layoutRoot.home-fill .home-bot { gap: 12px; }
#layoutRoot.home-fill .home-card {
  background: var(--jv-card); border: 1px solid var(--jv-border); border-radius: var(--nu-r-large);
  box-shadow: var(--jv-shadow); padding: 12px 16px;
}
#layoutRoot.home-fill .home-card-t {                                     /* §3-B 13px 섹션 제목 */
  font-size: 13px; font-weight: 700; color: var(--jv-txt1);
  letter-spacing: -0.02em; margin-bottom: 8px;
}
#layoutRoot.home-fill .home-card-hint { font-size: 10px; font-weight: 400; color: var(--jv-txt4); margin-left: 6px; }

/* ── 재고 레이어 요약 타일 (통계 카드 §6-D 하단형) ─────────────────────── */
#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: 12px 10px;
}
#layoutRoot.home-fill .home-inv-l { font-size: 11px; color: var(--jv-txt3); margin-bottom: 5px; }
#layoutRoot.home-fill .home-inv-v {
  font-size: 26px; 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: 13px; font-weight: 600; color: var(--jv-txt3); margin-left: 3px; }
#layoutRoot.home-fill .home-note { font-size: 10px; color: var(--jv-txt4); margin-top: 8px; }

/* 재고 레이어 요약 — 타일은 내용 높이 유지, 미니 추이 차트가 남는 공간을 채운다 */
#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: 12px; font-size: 11px; font-weight: 700; color: var(--jv-txt2);
}
#layoutRoot.home-fill .home-inv-trend-t span { font-weight: 400; font-size: 10px; color: var(--jv-txt4); margin-left: 6px; }
#layoutRoot.home-fill .home-inv-trend { position: relative; flex: 1 1 auto; min-height: 64px; margin-top: 4px; }
#layoutRoot.home-fill .home-inv-trend-empty {
  flex: 1 1 auto; display: flex; align-items: center; justify-content: center;
  margin-top: 12px; border: 1px dashed var(--jv-border); border-radius: var(--nu-r-large);
  font-size: 11px; color: var(--jv-txt4);
}

/* ── §8 모션: 진입 애니메이션 ──────────────────────────────────────────── */
@keyframes jvSlideIn { from { transform: translateY(6px); opacity: 0; } to { transform: none; opacity: 1; } }
#layoutRoot.home-fill > * { animation: jvSlideIn 0.18s ease-out; }

/* ── §4-D 얇은 스크롤바 (홈 대시보드 내부 한정) ────────────────────────── */
#layoutRoot.home-fill ::-webkit-scrollbar { width: 5px; height: 5px; }
#layoutRoot.home-fill ::-webkit-scrollbar-track { background: var(--nu-surface-3); }
#layoutRoot.home-fill ::-webkit-scrollbar-thumb { background: var(--nu-surface-4); border-radius: var(--nu-r-small); }
#layoutRoot.home-fill ::-webkit-scrollbar-thumb:hover { background: var(--jv-primary); }

/* 짧은 창에서의 밀집 보정 — 무스크롤 규칙과 함께 동작 */
@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; }
  #layoutRoot.home-fill .home-inv-v { font-size: 22px; }
}
@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: 19px; }
  /* 미니 추이 차트도 함께 낮춘다(캡션의 기간 표기는 접음) */
  #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; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   사이드바 — 8분류 그룹 네비게이션
   ───────────────────────────────────────────────────────────────────────────
   설계 의도(고쳐 쓸 때 이 전제를 깨지 말 것):
   ① 위계는 "크기"가 아니라 "역할"로 만든다.
      그룹 헤더 = 작지만 자간 넓은 라벨(txt4) · 메뉴 항목 = 본문 크기(13px, txt2).
      예전엔 그룹 헤더가 항목보다 작고 진해서 위계가 뒤집혀 읽혔다.
   ② 그룹 경계는 "선"이 아니라 "여백"으로. 그룹 사이만 넓히면 8개 그룹이
      한 덩어리로 뭉치지 않는다(얇은 가이드선은 흰 배경에서 어차피 안 보였다).
   ③ 활성 표시는 진한 채움 대신 [연한 tint + 좌측 3px 바 + 프라이머리 글자].
      밀집형 목록에서 진한 알약 하나가 떠 있으면 오히려 산만하고, 이 조합이
      어떤 톤(다크 포함)에서도 대비가 유지된다.
   ④ 지금 보고 있는 화면이 속한 그룹의 헤더도 함께 강조한다(:has) — 8그룹에서
      "내가 어디 있는지"가 한눈에 보인다.
   ⑤ 1920×1080 무스크롤 유지 — 항목을 키우되 총 높이는 뷰포트 안에 들어와야 한다.
   ═══════════════════════════════════════════════════════════════════════════ */
.sidebar {
  background: var(--jv-card);
  border-right: 1px solid var(--jv-border);
  box-shadow: 2px 0 8px rgba(0,0,0,0.04);
  font-family: 'Pretendard Variable', 'Pretendard', 'Noto Sans KR', -apple-system, system-ui, sans-serif;
  letter-spacing: -0.01em;
}
/* 로고 — 다크 배경용 흰 칩이 흰 사이드바에서 안 보이므로 칩 제거.
   메뉴와 로고 사이에 경계선을 둬 머리말 영역을 분리한다. */
.brand-ci { background: transparent; box-shadow: none; padding: 0; }
.brand span { color: var(--jv-txt1); font-weight: 800; }
.brand {
  padding-bottom: 12px;
  border-bottom: 1px solid var(--jv-border-l);
}

/* ── 아이콘 거터 ───────────────────────────────────────────────────────
   그룹명 앞 아이콘이 차지하는 폭. 하위 항목은 아이콘이 없으므로 이 폭만큼
   들여써서 "그룹명 글자"와 "하위 항목 글자"의 왼쪽 선을 맞춘다 —
   아이콘 열이 하나의 거터로 읽혀야 목록이 흐트러지지 않는다.
   아이콘 크기를 바꾸면 이 값도 같이 바꿀 것(--nav-ico + gap). */
:root {
  --nav-ico: 16px; --nav-ico-gap: 7px;
  /* 하위 항목 들여쓰기 — 사이드바 폭을 정하는 값이라 한 곳에서만 관리한다.
     예전에는 이 계산식이 기본 규칙과 압축 미디어쿼리 두 곳에 복사돼 있어서 한쪽만 고치면
     데스크톱에서만 어긋났다. 변수로 빼서 그 사고를 구조적으로 막는다.
     --nav-sub-line   가이드선의 x 위치
     --nav-sub-indent 하위 항목 글자의 x 위치 (둘 다 사이드바 안쪽 여백 기준) */
  --nav-sub-line: 14px;
  --nav-sub-indent: 25px;
}
.nav-ico {
  width: var(--nav-ico);
  height: var(--nav-ico);
  flex-shrink: 0;
  /* stroke는 currentColor — 비활성·hover·현재그룹 강조 색을 그대로 따라간다 */
}

/* ── 메뉴 항목 ─────────────────────────────────────────────────────────── */
.nav a {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--nav-ico-gap);
  background: transparent;
  border: none;
  border-radius: var(--nu-r-medium);
  padding: 7px 10px;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--jv-txt2);
  transition: background 0.12s, color 0.12s;
}
.nav a:hover {
  background: var(--jv-hover);
  color: var(--jv-txt1);
}
/* 활성 — tint 배경 + 좌측 바. 채움(흰 글자)이 아니라서 톤이 바뀌어도 안전하다 */
.nav a.active {
  background: var(--nu-primary-tint);
  color: var(--nu-brand-text);
  font-weight: 700;
}
.nav a.active::before {
  content: '';
  position: absolute;
  left: 0; top: 50%;
  width: 3px; height: 16px;
  transform: translateY(-50%);
  border-radius: 0 var(--nu-r-small) var(--nu-r-small) 0;
  background: var(--nu-primary);
}

/* ── 그룹 헤더 — "제목"이 아니라 "라벨". 작게, 자간 넓게, 연하게 ────────── */
.nav-group > summary {
  color: var(--jv-txt3);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  border-radius: var(--nu-r-medium);
  padding: 6px 10px;
  /* 아이콘 + 그룹명은 왼쪽에 붙이고 접기 화살표만 오른쪽 끝으로 민다
     (기본 space-between이면 아이콘·글자·화살표가 3등분으로 흩어진다) */
  justify-content: flex-start;
  gap: var(--nav-ico-gap);
  transition: color 0.12s, background 0.12s;
}
.nav-group > summary:hover { background: var(--jv-hover); color: var(--jv-txt2); }
.nav-group > summary::after {
  content: '›';
  margin-left: auto;
  font-size: 15px;
  line-height: 1;
  color: var(--jv-txt4);
  opacity: 0.9;
  transition: transform 0.15s, color 0.12s;
}
.nav-group[open] > summary::after { transform: rotate(90deg); }
.nav-group > summary:hover::after { color: var(--jv-txt2); }
/* 지금 보고 있는 화면이 속한 그룹은 헤더도 프라이머리로 — 현재 위치가 한눈에 */
.nav-group:has(a.active) > summary { color: var(--nu-brand-text); }
.nav-group:has(a.active) > summary::after { color: var(--nu-brand-text); }

/* ── 하위 항목 — 세로 가이드선으로 묶는다 ──────────────────────────────────
   그룹을 여러 개 열어 두면 어느 항목이 어느 그룹 소속인지 여백만으로는 흐려진다.
   → 열린 그룹의 하위 목록 왼쪽에 세로선을 세워 한 묶음으로 읽히게 한다.
   선 위치·글자 위치는 --nav-sub-line / --nav-sub-indent 가 정한다(위 :root 참고).
   ★ 하위 항목을 그룹명 글자(33px)에 맞춰 정렬하지 않는다 — 그렇게 하면 가장 긴 항목
     ("설비별 생산현황")이 사이드바 폭을 33px 만큼 밀어올린다. 가이드선이 소속을 이미
     말해 주므로 정렬은 선에 맡기고 들여쓰기는 25px 로 줄여 그만큼 본문에 돌려준다.
   (닫힌 그룹은 <details> 가 하위 목록을 렌더하지 않으므로 선도 함께 사라진다) */
.nav-group .nav-sub {
  margin-left: var(--nav-sub-line);
  padding-left: 0;
  border-left: 1px solid var(--jv-border);
}
/* 글자 x = --nav-sub-indent 가 되도록, 선까지의 거리(margin + 선 1px)를 뺀 만큼만 padding */
.nav-group .nav-sub a {
  padding-left: calc(var(--nav-sub-indent) - var(--nav-sub-line) - 1px);
  font-size: 13px;
}
/* 활성 항목은 가이드선 그 자리를 프라이머리로 덮어 "줄기 위에서 여기가 켜졌다"로 읽히게 한다 */
.nav-group .nav-sub a.active::before {
  left: -1px; width: 2px; height: 20px; border-radius: 0;
}

/* 외부 링크 아이콘은 오른쪽 끝으로 밀어 정렬을 맞춘다 */
.nav-ext-ico { color: var(--jv-txt4); opacity: 1; margin-left: auto; padding-left: 6px; }
.nav a.active .nav-ext-ico { color: var(--nu-brand-text); }
/* §4-D 얇은 스크롤바 */
.sidebar::-webkit-scrollbar { width: 5px; }
.sidebar::-webkit-scrollbar-track { background: transparent; }
.sidebar::-webkit-scrollbar-thumb { background: var(--nu-surface-4); border-radius: var(--nu-r-small); }
.sidebar::-webkit-scrollbar-thumb:hover { background: var(--jv-primary); }

/* §5-D 헤더 — 흰 배경 + 하단 경계선, 15px 볼드 타이틀
   슬림 헤더: 전 화면 공통 44px(본문 무스크롤 영역 확보). */
.topbar {
  background: var(--jv-card);
  border-bottom: 1px solid var(--jv-border);
  height: 44px;
  padding: 0 20px;
  font-family: 'Pretendard Variable', 'Pretendard', 'Noto Sans KR', -apple-system, system-ui, sans-serif;
  letter-spacing: -0.01em;
}
.page-title {
  font-size: 15px; font-weight: 700; color: var(--jv-txt1); letter-spacing: -0.02em;
}
.topbar-right { color: var(--jv-txt3); font-size: 12px; font-weight: 500; }
#currentTime { color: var(--jv-txt3); font-variant-numeric: tabular-nums; }
/* 아이콘 버튼 §6-A BTN_ICON */
.menu-btn {
  background: transparent; color: var(--jv-txt3); border-radius: var(--nu-r-medium); transition: background 0.12s, color 0.12s;
  width: 30px; height: 30px;
}
.menu-btn:hover { background: var(--jv-hover); color: var(--jv-txt1); }
/* 사용자 칩 — primary-light pill */
.user-chip {
  background: var(--jv-primary-light); color: var(--jv-primary);
  font-size: 12px; font-weight: 700; padding: 4px 10px;
}
.user-chip:hover { background: var(--nu-primary-tint-2); }
/* 로그아웃 — §6-A BTN_SECONDARY */
.logout-btn {
  background: var(--jv-card); border: 1px solid var(--jv-border); color: var(--jv-txt2);
  font-size: 12px; font-weight: 600; border-radius: var(--nu-r-medium); padding: 4px 10px;
  transition: border-color 0.12s, background 0.12s, color 0.12s;
}
.logout-btn:hover {
  background: var(--jv-card); border-color: var(--nu-primary-lightest); color: var(--jv-primary);
}

/* ═══════════════════════════════════════════════════════════════════════════
   공통 컴포넌트 정합 — 전 화면 (DESIGN.md §Shapes · §Components)
   토큰 매핑만으로 색은 이미 전환된다. 여기서는 라운드·그림자·버튼·인풋·탭처럼
   "레시피"가 정해진 요소를 지침 값으로 맞춘다.
   ═══════════════════════════════════════════════════════════════════════════ */
/* §4-A 라운드 / §4-B 그림자 — 카드는 테두리 + 얕은 그림자를 항상 함께 */
.panel, .viz-card, .home-card, .util-card, .ep-card, .inv-card, .sh-card {
  border-radius: var(--nu-r-large);
}
.panel { border: 1px solid var(--jv-border); box-shadow: var(--jv-shadow); }

/* ── 표면 3단 — 페이지 > 큰 박스 > 개별 박스 ──────────────────────────────
   설비별 생산현황처럼 패널(.panel) 안에 카드가 또 들어가는 화면은 2·3단계가 같은
   --nu-card 라 층이 안 보였다. 안쪽 카드만 한 단계 위 표면(--nu-card-2)으로 올린다.
   · 라이트 톤: --nu-card-2 = --nu-card 라 값이 같다 → 보이는 변화 없음
   · 다크 톤  : themes.css 가 한 단계 밝은 값을 주므로 3단 깊이가 생긴다
   ※ .panel 안에 있을 때만 적용한다 — .home-card 처럼 자기가 곧 큰 박스(.panel.home-card)인
     경우까지 밝히면 2단계가 통째로 올라가 층 구분이 도로 사라진다. */
.panel .viz-card, .panel .ep-card, .panel .util-card,
.panel .inv-card, .panel .sh-card, .panel .home-card {
  background: var(--nu-card-2);
}

/* §6-A 버튼 — 주요(프라이머리) / 보조(흰 배경 + 테두리) */
.primary-btn, .admin-btn-primary, .sched-blue-btn {
  background: var(--jv-primary); color: var(--nu-on-accent); border: none; border-radius: var(--nu-r-medium);
  font-weight: 600; transition: background 0.12s;
}
.primary-btn:hover, .admin-btn-primary:hover, .sched-blue-btn:hover { background: var(--jv-primary-hover); }
.simr-top-btn, .admin-btn-ghost {
  background: var(--jv-card); color: var(--jv-txt2); border: 1px solid var(--jv-border);
  border-radius: var(--nu-r-medium); transition: border-color 0.12s, color 0.12s;
}
.simr-top-btn:hover, .admin-btn-ghost:hover {
  background: var(--jv-card); border-color: var(--jv-primary-mid); color: var(--jv-primary);
}
.simr-top-btn:disabled, .sched-blue-btn:disabled, .primary-btn:disabled { opacity: 0.5; cursor: default; }

/* §6-B 입력 — 포커스는 outline이 아니라 연한 블루 테두리로 통일 */
input[type="text"], input[type="number"], input[type="password"], input[type="date"],
input[type="search"], select, textarea {
  border-radius: var(--nu-r-medium); border: 1px solid var(--jv-border); color: var(--jv-txt1);
  font-family: inherit; letter-spacing: -0.01em;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--jv-primary-mid); }
::placeholder { color: var(--jv-txt4); }

/* §6-F 탭 — 활성은 프라이머리 */
.inv-tab.active { color: var(--jv-primary); border-bottom-color: var(--jv-primary); }
.inv-tab { transition: color 0.12s; }

/* 표 — 헤더는 밝은 배경 + 진한 글자(토큰), 행 hover는 hover 토큰 */
thead th { font-weight: 600; }
.inv-grid tbody tr:hover, .inv-table tbody tr:hover, .demand-grid tbody tr:hover { background: var(--jv-hover); }

/* 다크 테마 시절 잔재 정리 */
.ed-photo-placeholder { background: linear-gradient(135deg, var(--jv-primary), var(--nu-primary-light)); }

/* 다크 네이비를 "채움"으로 쓰던 요소들 — 밝은 테마에서 흰 글자가 사라지므로 프라이머리로 전환 */
.inv-grid thead th, .demand-grid thead th {
  background: var(--jv-page); color: var(--jv-txt2); border-bottom: 1px solid var(--jv-border);
}
.demand-grid thead th.dm-weekend { background: var(--nu-surface-3); color: var(--jv-txt3); }
.demand-grid thead th.dm-total { background: var(--jv-warning-light); color: var(--jv-warning-text); }
.demand-grid tfoot td { background: var(--jv-page); color: var(--jv-txt1); border-top: 1px solid var(--jv-border); }
.demand-grid .dm-total { background: rgba(229,163,10,0.06); }
.demand-grid .dm-weekend { background: rgba(0,0,0,0.035); }
.demand-grid .dm-zero { color: var(--jv-txt4); }
.inv-color-chip { background: var(--jv-page); }
.sched-tab.active { background: var(--jv-primary); color: var(--nu-on-accent); border-color: var(--jv-primary); }
.ep-detail-btn { background: var(--jv-primary); color: var(--nu-on-accent); border-radius: var(--nu-r-medium); }
.ep-detail-btn:hover { background: var(--jv-primary-hover); }
.ed-mbtn.active { background: var(--jv-primary); color: var(--nu-on-accent); border-color: var(--jv-primary); }
.ed-mbtn.active span { color: rgba(255,255,255,0.75); }

/* 서열계획 합계 행(sticky tfoot) — 주말·합계 열의 반투명 배경이 그대로면 아래 데이터 행이
   비쳐 글자가 겹쳐 보인다. sticky로 떠 있는 셀은 불투명 배경이어야 한다. */
.demand-grid tfoot td.dm-weekend { background: var(--nu-surface-2); }
.demand-grid tfoot td.dm-total   { background: var(--nu-warning-light-3); }
.demand-grid tfoot td { background: var(--jv-page); }

/* 짧은 창에서 차트 높이 추가 축소 — .viz-wrap 기본 정의보다 뒤에 와야 적용된다(CSS 순서) */
@media (max-height: 700px) {
  .viz-wrap { height: clamp(112px, 17vh, 200px); }
  .viz-wrap.viz-wrap-lg { height: clamp(120px, 19vh, 220px); }
}

/* ── 좌측 메뉴 압축 (전 화면) ──────────────────────────────────────────────
   ① 좌우 폭 240 → 180px (콘텐츠 60px 확보)  ② 상하 여백·항목 높이를 줄여
   1920×1080은 물론 브라우저 실제 뷰포트(약 937px)에서도 메뉴가 스크롤되지 않게 한다.
   ※ min-width 1201px 안에 둔다 — 좁은 화면에서는 사이드바가 드로어로 바뀌므로 그대로 둔다.

   ▣ 폭 예산 — 180px 는 아래 두 최장 줄이 들어가는 최소치에 여유 약 32px 를 둔 값이다.
     하위 항목  여백10 + 들여쓰기25 + "설비별 생산현황"(12.5px, 약 91) + 우여백10 + 여백10 ≈ 147px
     그룹 헤더  여백10 + 패딩10 + 아이콘16 + 갭7 + "생산 모니터링"(10.5px, 약 66)
                + 화살표14 + 우여백10 + 여백10 ≈ 143px
     더 긴 메뉴명을 추가하면 이 예산을 다시 재고 폭이나 --nav-sub-indent 를 조정할 것. */
@media (min-width: 1201px) {
  .app-shell { grid-template-columns: 180px 1fr; }
  .sidebar { padding: 11px 10px; gap: 8px; }
  /* 로고 영역 */
  .brand { gap: 9px; padding-bottom: 10px; }
  .brand-ci { height: 32px; }
  .brand span { font-size: 0.98rem; }

  /* ★ 높이 예산 — 관리자 로그인(8그룹 + 14항목 전부 표시)에서도 사이드바가
     스크롤되지 않아야 한다. 실측 기준 약 780px / 뷰포트 약 800px.
     항목 여백을 여기서 더 키우면 메뉴가 스크롤되기 시작한다(항목 padding 1px = 전체 28px,
     그룹 margin 1px = 전체 8px). 메뉴를 추가할 때는 이 예산을 다시 재 볼 것. */

  /* 항목 사이는 좁게(2px), 그룹 사이는 넓게(8px) — 여백만으로 묶음이 생긴다.
     이 대비가 이 메뉴의 가독성을 좌우한다. 둘을 같은 값으로 되돌리지 말 것. */
  .nav { gap: 2px; }
  .nav-group { gap: 2px; margin-top: 7px; }
  .nav > a + .nav-group { margin-top: 8px; }

  .nav a { padding: 5px 10px; font-size: 12.5px; }
  .nav-group > summary { padding: 4px 10px; font-size: 10.5px; }
  .nav-group .nav-sub { gap: 2px; }
  /* 들여쓰기는 --nav-sub-* 가 이미 정했다 — 여기서 다시 계산식을 쓰지 말 것.
     (예전에 이 줄이 padding-left 를 재선언해 두는 바람에 기본 규칙과 어긋났었다) */
  .nav-group .nav-sub a { font-size: 12.5px; }
}

/* 상단 바 제목 — "메뉴명 - 화면명"(서브 화면이 있을 때). 본문 제목 박스(hero)는 제거됨 */
.page-title .pt-menu { font-weight: 700; color: var(--jv-txt1); }
.page-title .pt-sep  { margin: 0 7px; color: var(--jv-txt4); font-weight: 400; }
.page-title .pt-view { font-weight: 600; color: var(--jv-txt3); }

/* ── 설비 상세현황 전용: 표 헤더(타이틀 줄) 강조 ──────────────────────────
   흰 카드·쿨그레이 배경과 구분되도록 프라이머리 톤을 얹고, 헤더 문구는 가운데 정렬한다.
   #layoutRoot.ed-page 로 스코프 — 같은 .inv-grid를 쓰는 다른 화면에는 영향이 없다. */
#layoutRoot.ed-page .inv-grid thead th,
#layoutRoot.ed-page .inv-grid thead th.inv-num {
  text-align: center;
  background: var(--nu-primary-tint);
  color: var(--nu-brand-text);
  font-weight: 700;
  border-bottom: 2px solid var(--jv-primary-mid);
}

/* 설비 상세현황 표 — 세로 구분선 + 데이터 유형별 정렬
   · 교대(주간/야간)처럼 값 형식·길이가 일정한 열은 가운데
   · 품번·품목명·차종 등 텍스트는 왼쪽, 수량은 오른쪽
   · 좌/우 정렬 셀은 세로 구분선에 글자가 붙지 않도록 안쪽 여백을 준다 */
#layoutRoot.ed-page .inv-grid th,
#layoutRoot.ed-page .inv-grid td { border-right: 1px solid var(--jv-border); }
#layoutRoot.ed-page .inv-grid th:last-child,
#layoutRoot.ed-page .inv-grid td:last-child { border-right: none; }
#layoutRoot.ed-page .inv-grid td.ed-al-c { text-align: center; }
#layoutRoot.ed-page .inv-grid td.ed-al-l { text-align: left;  padding-left: 14px; }
#layoutRoot.ed-page .inv-grid td.ed-al-r,
#layoutRoot.ed-page .inv-grid td.inv-num { text-align: right; padding-right: 14px; }
#layoutRoot.ed-page .inv-grid td.inv-empty { border-right: none; text-align: center; }
/* 헤더 줄은 배경이 파란 톤이라 회색 세로선이 묻힌다 → 한 단계 진한 블루로 */
#layoutRoot.ed-page .inv-grid thead th { border-right-color: var(--nu-primary-lightest); }

/* 표 밀도 — 글자 크기는 그대로 두고 행 안쪽 여백만 줄여 한 화면에 더 많은 행을 보여준다
   (행 높이 약 30px → 26px, 같은 높이에서 4~5행 더). */
#layoutRoot.ed-page .inv-grid thead th { padding: 6px 12px; }
#layoutRoot.ed-page .inv-grid tbody td { padding: 4px 10px; }
#layoutRoot.ed-page .inv-grid td.ed-al-l { padding-left: 12px; }
#layoutRoot.ed-page .inv-grid td.ed-al-r,
#layoutRoot.ed-page .inv-grid td.inv-num { padding-right: 12px; }

/* ═══════════════════════════════════════════════════════════════════════════
   표 공통 스타일 (전 화면) — 설비 상세현황에서 정한 규칙을 표가 있는 모든 화면에 적용
   ① 헤더(타이틀 줄): 가운데 정렬 + 프라이머리 톤 배경으로 강조
   ② 세로 구분선: 셀마다 우측 1px(마지막 열 제외)
   ③ 정렬: 숫자=오른쪽 · 길이가 일정한 짧은 코드=가운데 · 텍스트=왼쪽 (app.js가 열별 자동 판정)
   ④ 좌/우 정렬 셀은 구분선에 글자가 붙지 않도록 안쪽 여백
   ═══════════════════════════════════════════════════════════════════════════ */
.layout-root thead th {
  text-align: center;
  background: var(--nu-primary-tint);
  color: var(--nu-brand-text);
  font-weight: 700;
  border-bottom: 2px solid var(--jv-primary-mid);
  border-right: 1px solid var(--nu-primary-lightest);
}
.layout-root thead th:last-child { border-right: none; }
.layout-root tbody td { border-right: 1px solid var(--jv-border); }
.layout-root tbody td:last-child { border-right: none; }

/* 열별 자동 판정 결과 */
.layout-root tbody td.tb-al-c { text-align: center; }
.layout-root tbody td.tb-al-l { text-align: left;  padding-left: 14px; }
.layout-root tbody td.tb-al-r { text-align: right; padding-right: 14px; }
/* 빈 상태 안내 행은 구분선·정렬 예외 */
.layout-root tbody td.inv-empty, .layout-root tbody td.dm-empty,
.layout-root tbody td[colspan] { border-right: none; text-align: center; }

/* 서열계획 — 주말·합계 열은 고유 배경을 유지(위 공통 헤더 배경보다 뒤에 와야 이긴다) */
.layout-root .demand-grid thead th.dm-weekend { background: var(--nu-surface-3); color: var(--jv-txt3); border-right-color: var(--nu-border-strong); }
.layout-root .demand-grid thead th.dm-total   { background: var(--jv-warning-light); color: var(--jv-warning-text); border-right-color: var(--nu-warning-border-2); }

/* ═══════════════════════════════════════════════════════════════════════════
   NuDS 정합 레이어 (DESIGN.md) — 색 토큰만으로는 안 바뀌는 "형태·상태" 규칙
   ★ 이 블록이 스타일시트 맨 끝이다. 앞선 규칙을 이기도록 마지막에 둔다.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── §Shapes 오블롱 — 액션과 라벨은 pill ──────────────────────────────────
   "Formas oblongas… buttons e chips frequentemente usando pill"(DESIGN.md).
   표 안쪽 셀 요소는 밀도 때문에 medium(8px)을 유지하고, 화면 레벨 액션만 pill로 간다. */
.primary-btn, .admin-btn-primary, .admin-btn-ghost, .admin-btn-danger,
.sched-blue-btn, .simr-top-btn, .simr-confirm-btn, .logout-btn,
.ep-detail-btn, .ep-mobile-btn, .ed-nav-btn, .ed-mbtn,
.popup-btn-apply, .popup-btn-reg, .popup-btn-cancel, .popup-btn-edit,
.popup-btn-reset, .popup-btn-del, .popup-btn-xs, .popup-btn-xs-red {
  border-radius: var(--nu-r-pill);
}
/* 배지·태그·램프 — 상태 라벨은 전부 pill */
.home-kri-badge, .inj-badge, .inj-step, .inj-lamp, .inj-sb-대기, .inj-sb-진행중,
.inj-sb-완료, .inj-sb-실패, .ep-card-badge, .util-badge, .inj-mode-수동,
.inj-mode-자동, .inj-mode-정지 {
  border-radius: var(--nu-r-pill);
}

/* ── §Accessibility 포커스 가시성 ────────────────────────────────────────
   NuDS는 "screen readers · text resizing · 대비 4.5:1"을 컴포넌트마다 요구한다.
   테두리 색만 바꾸는 포커스는 키보드 사용자에게 약하다 → 프라이머리 링을 함께 준다. */
input:focus-visible, select:focus-visible, textarea:focus-visible,
button:focus-visible, a:focus-visible, summary:focus-visible {
  outline: 2px solid var(--nu-primary);
  outline-offset: 2px;
  border-radius: var(--nu-r-small);
}
input:focus, select:focus, textarea:focus { border-color: var(--nu-primary); }

/* ── §Elevation 떠 있는 요소만 그림자 ────────────────────────────────────
   라이트 모드는 flat 기조(흰색 vs #F5F5F5 색 분리)로 두고,
   콘텐츠 위로 "떠 있는" 것에만 elevation을 준다. */
.popup-overlay, .sidebar-backdrop { background: rgba(0,0,0,var(--nu-op-scrim)); }
.popup-box { box-shadow: var(--nu-elev-high); border-radius: var(--nu-r-xxl); }
.sidebar.open { box-shadow: var(--nu-elev-highest); }

/* ── §Colors 브랜드 그라디언트 — 강조 배너 1곳에만 ───────────────────────
   "Purple is Nubank… 로 유일한 강한 색". KRI 총계 배너를 브랜드 면으로 세운다. */
#layoutRoot.home-fill .home-kri,
#layoutRoot .home-kri.kri-totals {
  background: var(--nu-gradient);
  box-shadow: var(--nu-elev-low);
}
/* 미연동(예시) 배너는 중성 회색 — 브랜드 면과 구분 */
#layoutRoot .home-kri.kri-mock { background: var(--nu-txt3); box-shadow: none; }

/* ── §Colors 상태색은 상태에만 ───────────────────────────────────────────
   좌측 컬러바 카드(.red/.yellow/.green/.blue-card)의 '파랑'은 상태가 아니라
   중립 정보였다 → 브랜드 퍼플로 바꿔 상태 3색(위험·주의·정상)과 섞이지 않게 한다. */
.red-card    { border-left: 5px solid var(--nu-alert); }
.yellow-card { border-left: 5px solid var(--nu-warning); }
.green-card  { border-left: 5px solid var(--nu-success); }
.blue-card   { border-left: 5px solid var(--nu-primary); }

/* ── §Components 비활성 상태 ─────────────────────────────────────────────*/
button:disabled, .primary-btn:disabled, .simr-top-btn:disabled,
.sched-blue-btn:disabled, .simr-confirm-btn:disabled {
  opacity: var(--nu-op-disabled);
  cursor: default;
}

/* ── 선택·스크롤바 — 브랜드 톤 ──────────────────────────────────────────*/
::selection { background: var(--nu-primary-lightest); color: var(--nu-txt1); }
::-webkit-scrollbar-thumb:hover,
.sidebar::-webkit-scrollbar-thumb:hover { background: var(--nu-primary); }

/* ═══════════════════════════════════════════════════════════════════════════
   사이트 관리 > 화면 테마
   ═══════════════════════════════════════════════════════════════════════════ */
.theme-panel { display: flex; flex-direction: column; gap: 16px; }
.theme-help {
  margin: 0; padding: 10px 14px; font-size: 0.86rem; line-height: 1.6;
  color: var(--nu-txt2); background: var(--nu-primary-tint);
  border: 1px solid var(--nu-primary-lightest); border-radius: var(--nu-r-medium);
}
.theme-help b { color: var(--nu-brand-text); }

.theme-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
}
.theme-card {
  display: flex; flex-direction: column; gap: 8px; align-items: flex-start;
  padding: 14px; text-align: left; cursor: pointer;
  font-family: inherit; letter-spacing: -0.01em;
  background: var(--nu-card); color: var(--nu-txt1);
  border: 1px solid var(--nu-border); border-radius: var(--nu-r-large);
  transition: border-color 0.12s, box-shadow 0.12s, transform 0.12s;
}
.theme-card:hover { border-color: var(--nu-primary-lightest); transform: translateY(-1px); box-shadow: var(--nu-elev-low); }
.theme-card.selected { border-color: var(--nu-primary); box-shadow: 0 0 0 2px var(--nu-primary-tint); }

/* 색 견본 — 배경 / 강조배경 / 주색 3단. 톤의 성격이 한눈에 보이게 겹쳐 놓는다 */
.theme-card-sw { display: flex; align-items: center; }
.theme-card-sw i {
  width: 30px; height: 30px; border-radius: 50%;
  border: 2px solid var(--nu-card); box-shadow: 0 0 0 1px var(--nu-border);
}
.theme-card-sw i + i { margin-left: -10px; }

.theme-card-name { display: flex; align-items: center; gap: 6px; font-size: 0.98rem; font-weight: 700; }
/* '현재 적용' 배지는 저장된 톤에만 — 미리보기만 한 카드에는 뜨지 않는다 */
.theme-card-cur {
  display: none; padding: 1px 8px; border-radius: var(--nu-r-pill);
  font-size: 0.68rem; font-weight: 700;
  background: var(--nu-success-light); color: var(--nu-success-text);
}
.theme-card.is-saved .theme-card-cur { display: inline-block; }
.theme-card-desc { font-size: 0.78rem; line-height: 1.5; color: var(--nu-txt3); }

/* ── 로고 관리 ────────────────────────────────────────────────────────────
   로고는 밝은 사이드바와 검은 사이드바 양쪽에 놓인다 → 두 배경을 나란히 보여 준다.
   두 칸의 배경색은 토큰이 아니라 고정값이 맞다. "라이트 톤에서 어떻게 보이나"를
   확인하는 칸이 지금 톤을 따라가 버리면 확인 자체가 안 된다. */
.brand-preview-row { display: flex; flex-wrap: wrap; align-items: stretch; gap: 12px; }
.brand-preview {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  min-width: 190px; padding: 18px 22px;
  border: 1px solid var(--nu-border); border-radius: var(--nu-r-large);
}
.brand-preview img { height: 46px; width: auto; max-width: 150px; object-fit: contain; }
.brand-preview em {
  font-style: normal; font-size: 0.72rem; font-weight: 600; letter-spacing: -0.01em;
}
.brand-preview-light { background: #FFFFFF; }
.brand-preview-light em { color: #6B7280; }
.brand-preview-dark  { background: #14161A; }
.brand-preview-dark  em { color: #97A1B0; }
.brand-current {
  display: flex; flex-direction: column; justify-content: center; gap: 4px;
  padding: 0 4px; font-size: 0.84rem; color: var(--nu-txt2);
}
.brand-current b { color: var(--nu-txt1); }
.brand-current-sub { font-size: 0.76rem; color: var(--nu-txt3); }

.theme-actions { display: flex; align-items: center; gap: 10px; }
.theme-msg { font-size: 0.82rem; font-weight: 600; color: var(--nu-txt3); }
.theme-msg.ok { color: var(--nu-success-text); }
.theme-msg.fail { color: var(--nu-alert-text); }

/* ═══════════════════════════════════════════════════════════════════════════
   KPI 대시보드
   ───────────────────────────────────────────────────────────────────────────
   1920×1080 한 화면 무스크롤 기준. 위에서부터 기간머리 → 카드 6 → 차트 2 →
   각주 → 표 순으로 쌓고, 남는 높이는 표가 먹고 표 안에서만 스크롤한다.
   색 리터럴 0개 — 전부 토큰 참조(§디자인 색 규칙 1).
   ═══════════════════════════════════════════════════════════════════════════ */

#layoutRoot.kpi-page { display: flex; flex-direction: column; gap: 12px; flex: 1; min-height: 0; }

/* ── 기간 머리 + 탭 ── */
.kpi-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.kpi-period { display: flex; align-items: baseline; gap: 10px; font-size: 0.86rem; color: var(--nu-txt3); }
.kpi-period strong { font-size: 0.95rem; color: var(--nu-txt1); font-weight: 700; }

.kpi-tabs { display: flex; gap: 4px; padding: 3px; background: var(--nu-surface-2);
  border: 1px solid var(--border); border-radius: var(--nu-r-pill); }
.kpi-tab { padding: 6px 18px; border: 0; background: transparent; cursor: pointer;
  border-radius: var(--nu-r-pill); font-size: 0.84rem; font-weight: 600; color: var(--nu-txt3);
  font-family: inherit; transition: background .15s, color .15s; }
.kpi-tab:hover { color: var(--nu-txt1); }
.kpi-tab.is-on { background: var(--nu-primary); color: var(--nu-on-accent); }

/* ── KPI 카드 6개 ── */
/* 6열 고정이면 좁은 창에서 카드가 한 줄에 눌려 글자가 겹친다 — auto-fit 으로 접는다. */
.kpi-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 8px; }
.kpi-card { padding: 8px 12px; background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--nu-r-large); box-shadow: var(--shadow); min-width: 0; }
.kpi-card-label { font-size: 0.74rem; font-weight: 600; color: var(--nu-txt3); margin-bottom: 2px; }
.kpi-card-value { font-size: 1.24rem; font-weight: 800; color: var(--nu-txt1); line-height: 1.15;
  font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kpi-card-unit { font-size: 0.86rem; font-weight: 600; color: var(--nu-txt3); margin-left: 3px; }
.kpi-card-sub { margin-top: 1px; font-size: 0.7rem; color: var(--nu-txt3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ── 차트 2단 ── */
.kpi-charts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
/* Chart.js 반응형 컨테이너 규약 — 부모는 position:relative + 확정 높이, 캔버스는 absolute.
   ★ 캔버스를 그냥 흘려 두면 Chart.js 가 생성 시점의 부모 높이를 못 읽어 제 크기대로
     커지고, 범례가 상자 밖으로 삙지나와 아래 각주 위에 겹쳐 그려진다. */
/* 높이를 240px 로 두면 아래 상세 표가 62px(약 1.8행) 잘린다 — 연도별 11행이 한 화면에
   들어가도록 차트를 줄여 표에 넘긴다. 표는 flex:1 이라 남는 높이를 그대로 받는다.
   ※ 월별(120행)은 어차피 내부 스크롤이다. 맞추는 기준은 연도별 11행. */
.kpi-canvas { position: relative; height: 165px; }
.kpi-canvas > canvas { position: absolute; inset: 0; width: 100% !important; height: 100% !important; }

/* ── 부분 연도 각주 ── */
/* ★ 경고색을 쓰지 않는다. 이 글은 '위험'이 아니라 '읽는 법'이라 본문 옆의 주석처럼
   중립으로 둔다 — 노란 박스로 세워 두면 화면을 열 때마다 본문보다 먼저 눈에 든다. */
.kpi-note { margin: 0; padding: 8px 12px; font-size: 0.76rem; line-height: 1.5;
  color: var(--nu-txt3); background: var(--nu-surface-2);
  border: 1px solid var(--nu-border-l); border-radius: var(--nu-r-medium); }
.kpi-note strong { color: var(--nu-txt2); }

/* ── 접어 둔 데이터 유의사항 ──
   닫힘 상태는 한 줄(약 26px)이다. 펼치면 원문이 그대로 나온다. */
.data-note { margin: 0; }
.data-note > summary { list-style: none; cursor: pointer; display: inline-flex;
  align-items: center; gap: 5px; padding: 2px 10px 2px 8px;
  font-size: 0.72rem; font-weight: 600; color: var(--nu-txt3);
  background: var(--nu-surface-2); border: 1px solid var(--nu-border-l);
  border-radius: var(--nu-r-pill); user-select: none; }
.data-note > summary::-webkit-details-marker { display: none; }
.data-note > summary::before { content: "ⓘ"; font-size: 0.82rem; line-height: 1; }
.data-note > summary::after { content: "▾"; font-size: 0.62rem; color: var(--nu-txt4); }
.data-note[open] > summary::after { content: "▴"; }
.data-note > summary:hover { color: var(--nu-txt2); border-color: var(--nu-border); }
.data-note[open] > summary { margin-bottom: 6px; }
.data-note > .kpi-note { background: none; border: 0; padding: 0 2px; }

/* ── 상세 표 — 남은 높이를 먹고 내부에서만 스크롤 ── */
.kpi-table-box { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.kpi-table-wrap { flex: 1; min-height: 0; overflow: auto; margin-top: 10px; max-width: 100%; }
/* 표가 넓어도 화면(body)을 가로로 밀지 않는다 — 넘침은 이 상자 안에서만 일어난다. */
.chart-box, .prod-line-box, .kpi-table-box { min-width: 0; }
.kpi-table { width: 100%; border-collapse: collapse; font-size: 0.8rem; }
.kpi-table th { position: sticky; top: 0; z-index: 1; background: var(--th-bg); color: var(--th-text);
  font-weight: 700; padding: 8px 10px; white-space: nowrap; border-bottom: 1px solid var(--border); }
.kpi-table td { padding: 7px 10px; white-space: nowrap; color: var(--nu-txt1);
  border-bottom: 1px solid var(--nu-border-l); font-variant-numeric: tabular-nums; }
.kpi-table tbody tr:nth-child(even) { background: var(--row-alt); }
.kpi-table tbody tr:hover { background: var(--row-hover); }
/* 부분 연도 행 — 차트의 흐린 막대와 같은 뜻. 숨기지 않고 낮춘다. */
.kpi-table tr.is-partial td { color: var(--nu-txt3); font-style: italic; }
.kpi-table .ta-n { text-align: right; }
.kpi-table .ta-c { text-align: center; }

/* ═══════════════════════════════════════════════════════════════════════════
   간트차트 — 하루치 LOT 타임라인
   KPI 화면의 카드(.kpi-cards)·표(.kpi-table)를 그대로 쓰고, 여기선 날짜 이동 줄과
   타임라인 상자만 정의한다. 색 리터럴 0개 — 전부 토큰 참조.
   ═══════════════════════════════════════════════════════════════════════════ */

#layoutRoot.gantt-page { display: flex; flex-direction: column; gap: 12px; flex: 1; min-height: 0; }

/* ── 날짜 이동 + 역산 표기 ── */
.gantt-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.gantt-nav { display: flex; align-items: center; gap: 8px; }
.gantt-btn { width: 30px; height: 30px; display: grid; place-items: center; cursor: pointer;
  border: 1px solid var(--border); background: var(--panel); color: var(--nu-txt1);
  border-radius: var(--nu-r-medium); font-size: 1.1rem; line-height: 1; font-family: inherit; }
.gantt-btn:hover:not(:disabled) { background: var(--nu-hover); }
.gantt-btn:disabled { opacity: var(--nu-op-disabled); cursor: not-allowed; }
.gantt-date { padding: 6px 10px; border: 1px solid var(--border); background: var(--panel);
  color: var(--nu-txt1); border-radius: var(--nu-r-medium); font-size: 0.88rem;
  font-weight: 600; font-family: inherit; }
.gantt-daymeta { margin-left: 6px; font-size: 0.78rem; color: var(--nu-txt3); }

/* 시각이 실측이 아니라 역산이라는 표기. 눈에 띄되 경보처럼 보이지 않게 정보 톤. */
.gantt-derived { padding: 4px 12px; font-size: 0.76rem; font-weight: 700; cursor: help;
  color: var(--nu-txt2); background: var(--nu-surface-2);
  border: 1px dashed var(--nu-border-strong); border-radius: var(--nu-r-pill); }
.gantt-over { color: var(--nu-alert-text); font-weight: 700; }

/* ── 타임라인 ── */
.gantt-chart-box { flex: 0 0 auto; }
.gantt-canvas { position: relative; height: 210px; }
.gantt-canvas > canvas { position: absolute; inset: 0; width: 100% !important; height: 100% !important; }
.gantt-sub { margin-left: 6px; font-size: 0.82rem; font-weight: 600; color: var(--nu-txt3); }

.gantt-legend { float: right; display: flex; align-items: center; gap: 6px;
  font-size: 0.76rem; font-weight: 600; color: var(--nu-txt3); }
.gl-swatch { width: 11px; height: 11px; border-radius: 3px; display: inline-block; }
.gl-swatch + .gl-swatch { margin-left: 8px; }
.gl-setup { background: repeating-linear-gradient(45deg,
    var(--nu-surface-3) 0 2px, var(--nu-txt3) 2px 4px); }
.gl-run   { background: var(--chart-1); }
.gl-down  { background: var(--nu-alert); }
.gl-break { background: var(--nu-surface-3); border: 1px solid var(--border); }

/* ── LOT 상세 표 ── */
/* LOT 은 하루 3~4건뿐이라 표를 늘리지 않는다 — flex:1 로 두면 빈 카드가 화면 절반을 먹는다. */
.gantt-table-box { flex: 0 1 auto; min-height: 0; display: flex; flex-direction: column; }
.gantt-table-wrap { flex: 1; min-height: 0; overflow: auto; margin-top: 10px; }
.gantt-table .ta-l { text-align: left; }
/* 품종 색 칩 — 표에서도 차트와 같은 색을 쓴다(색은 인라인 style 로 JS가 넣는다). */
.gantt-chip { width: 9px; height: 9px; border-radius: 2px; display: inline-block; margin-right: 6px; }
/* 품종이 바뀐 지점 = Setup 이 붙는 이유. 눈으로 바로 짚이게 표시한다. */
.gantt-flag { padding: 1px 7px; font-size: 0.7rem; font-weight: 700; border-radius: var(--nu-r-pill);
  color: var(--nu-warning-text); background: var(--nu-warning-soft); border: 1px solid var(--nu-warning-border); }

/* ── 피더 보충 모니터 (간트 화면의 머리·표 스타일 재사용) ── */
#layoutRoot.feeder-page { display: flex; flex-direction: column; gap: 12px; flex: 1; min-height: 0; }
.feeder-charts { display: grid; grid-template-columns: 1.35fr 1fr; gap: 12px; }
.fd-whatif { display: inline-flex; align-items: center; gap: 6px; margin-left: 10px;
  font-size: 0.8rem; font-weight: 600; color: var(--nu-txt3); }
.fd-select { margin-left: 8px; padding: 3px 8px; border: 1px solid var(--border);
  background: var(--panel); color: var(--nu-txt1); border-radius: var(--nu-r-medium);
  font-size: 0.78rem; font-weight: 600; font-family: inherit; }
.fd-delta { color: var(--nu-success-text); font-weight: 700; }
.gl-remain { background: var(--chart-1); }
.gl-thresh { background: var(--nu-warning); }
/* 보충 지연으로 라인이 선 이벤트 — 표에서 바로 짚이게 */
.fd-trigger.is-bad { padding: 1px 7px; border-radius: var(--nu-r-pill); font-weight: 700;
  color: var(--nu-alert-text); background: var(--nu-alert-light-2); }
.kpi-table tr.is-stop td { background: var(--nu-alert-light-2); }

/* ── 시나리오 A/B 비교 ── */
#layoutRoot.scenario-page { display: flex; flex-direction: column; gap: 12px; flex: 1; min-height: 0; }

/* 두 규칙과 결론 한 줄 — 화면을 열자마자 무엇이 달라지는지 읽히게 */
.sc-verdict { display: grid; grid-template-columns: 1fr auto 1fr auto; align-items: center; gap: 16px;
  padding: 14px 18px; background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--nu-r-large); box-shadow: var(--shadow); }
.sc-head-a, .sc-head-b { font-size: 0.92rem; font-weight: 700; color: var(--nu-txt1); }
.sc-head-a em, .sc-head-b em { display: block; margin-top: 3px; font-style: normal;
  font-size: 0.76rem; font-weight: 500; color: var(--nu-txt3); }
.sc-tag { display: inline-grid; place-items: center; width: 20px; height: 20px; margin-right: 7px;
  border-radius: var(--nu-r-small); font-size: 0.74rem; font-weight: 800;
  color: var(--nu-on-accent); background: var(--chart-4); }
.sc-tag.is-b { background: var(--chart-2); }
.sc-arrow { font-size: 1.2rem; color: var(--nu-txt4); }
.sc-punch { padding-left: 18px; border-left: 1px solid var(--border); text-align: right; white-space: nowrap;
  font-size: 0.95rem; font-weight: 700; color: var(--nu-txt1); }
.sc-punch strong { font-size: 1.5rem; color: var(--nu-success-text); }
.sc-punch span { display: block; margin-top: 3px; font-size: 0.76rem; font-weight: 500; color: var(--nu-txt3); }

.sc-body { display: grid; grid-template-columns: 1.15fr 1fr 1fr; gap: 12px; flex: 1; min-height: 0; }
.sc-table-box { display: flex; flex-direction: column; }
.sc-table { margin-top: 8px; }
.sc-table th.ta-l { position: static; background: transparent; color: var(--nu-txt2); font-weight: 600; }
.sc-table thead th { background: var(--th-bg); color: var(--th-text); }
.sc-note { display: block; font-size: 0.7rem; font-weight: 500; color: var(--nu-txt4); }
/* 좋아진 쪽/나빠진 쪽을 색으로 — 부호만으로는 어느 방향이 좋은지 알 수 없다 */
.sc-delta { font-weight: 700; color: var(--nu-txt3); }
.sc-delta.is-better { color: var(--nu-success-text); }
.sc-delta.is-worse { color: var(--nu-alert-text); }
.sc-canvas { position: relative; flex: 1; min-height: 200px; }
.sc-canvas > canvas { position: absolute; inset: 0; width: 100% !important; height: 100% !important; }
.sc-body > .chart-box { display: flex; flex-direction: column; min-height: 0; }
.gl-a { background: var(--chart-4); }
.gl-b { background: var(--chart-2); }

/* ── 생산 스케줄링 관리 ── */
#layoutRoot.schedule-page { display: flex; flex-direction: column; gap: 12px; flex: 1; min-height: 0; }
.sch-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px;
  padding: 14px 18px; background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--nu-r-large); box-shadow: var(--shadow); }
.sch-form { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; }
.sch-form label { display: flex; flex-direction: column; gap: 4px;
  font-size: 0.76rem; font-weight: 600; color: var(--nu-txt3); }
.sch-msg { font-size: 0.8rem; font-weight: 600; color: var(--nu-txt3); }
.sch-msg.is-fail { color: var(--nu-alert-text); }

/* 어느 엔진이 계산하는지 항상 보이게 — 스텁 결과를 실물로 오해하면 안 된다 */
.sch-engine { display: flex; align-items: center; gap: 7px; padding: 6px 14px; white-space: nowrap;
  font-size: 0.82rem; color: var(--nu-txt2); background: var(--nu-surface-2);
  border: 1px solid var(--border); border-radius: var(--nu-r-pill); }
.sch-engine-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--nu-success); }
.sch-engine.is-off .sch-engine-dot { background: var(--nu-txt4); }
.sch-engine em { font-style: normal; font-size: 0.74rem; color: var(--nu-txt4); }

.sch-body { display: grid; grid-template-columns: 1.25fr 1fr; gap: 12px; flex: 1; min-height: 0; }
.sch-list-box, .sch-detail-box { display: flex; flex-direction: column; min-height: 0; }
.sch-detail { flex: 1; min-height: 0; overflow: auto; margin-top: 10px;
  font-size: 0.82rem; color: var(--nu-txt3); }
/* ── 목표 대비 달성 스코어보드 (스케줄링 결과 맨 위) ──
   PoC 의 결론 한 줄이 들어가는 자리다. 상태색은 '달성/미달' 판정에만 쓴다. */
.sch-score { margin: 2px 0 12px; padding: 12px 14px 10px;
  background: var(--nu-surface); border: 1px solid var(--border);
  border-radius: var(--nu-r-md, 10px); }
.sch-score-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.sch-score-head h3 { margin: 0; font-size: 0.9rem; font-weight: 700; }
.sch-score-basis { font-size: 0.74rem; color: var(--nu-txt3); }
.sch-score-grid { display: grid; grid-template-columns: 1fr auto 1fr 1fr;
  align-items: stretch; gap: 10px; margin-top: 10px; }
.sch-score-cell { padding: 10px 12px; background: var(--nu-surface-2);
  border: 1px solid var(--border); border-radius: var(--nu-r-md, 10px); }
.sch-score-cell.is-sim { background: var(--nu-primary-tint); border-color: var(--nu-primary-light); }
.sch-score-cell.is-target.is-met { background: var(--nu-success-light-2); border-color: var(--nu-success); }
.sch-score-cell.is-target.is-miss { background: var(--nu-warning-light-2); border-color: var(--nu-warning-border); }
/* 연동 대기 — 값이 아직 없는 칸. 점선으로 '비어 있음'을 성질로 보인다. */
.sch-score-cell.is-pending { background: transparent; border-style: dashed;
  border-color: var(--nu-txt4); }
.sch-score-wait { font-size: 1.02rem; font-weight: 700; color: var(--nu-txt3); }
.sch-score-track.is-empty { background: repeating-linear-gradient(135deg,
  var(--chart-track) 0 6px, transparent 6px 12px); }
.sch-score-lbl { font-size: 0.72rem; font-weight: 700; color: var(--nu-txt3); }
.sch-score-val { margin-top: 2px; font-size: 1.7rem; font-weight: 700; line-height: 1.15;
  font-variant-numeric: tabular-nums; }
.sch-score-sub { font-size: 0.72rem; color: var(--nu-txt3); }
.sch-score-up { color: var(--nu-success-text); }
.sch-score-dn { color: var(--nu-alert-text); }
.sch-score-arrow { align-self: center; font-size: 1.1rem; color: var(--nu-txt4); }

.sch-score-bars { position: relative; margin: 12px 0 2px; padding-bottom: 16px; }
.sch-score-barrow { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.sch-score-barlbl { width: 30px; font-size: 0.7rem; color: var(--nu-txt3); }
.sch-score-track { flex: 1; height: 9px; background: var(--chart-track);
  border-radius: var(--nu-r-pill); overflow: hidden; }
.sch-score-track > i { display: block; height: 100%; background: var(--nu-txt4);
  border-radius: var(--nu-r-pill); }
.sch-score-track > i.is-sim { background: var(--nu-primary); }
/* 목표선 — 트랙(라벨 30px + 간격 8px)에 맞춰 왼쪽을 밀어 준다 */
.sch-score-mark { position: absolute; bottom: 0; top: 0; margin-left: 38px;
  border-left: 2px dashed var(--nu-alert); pointer-events: none; }
.sch-score-mark > span { position: absolute; bottom: -2px; left: 4px; white-space: nowrap;
  font-size: 0.68rem; font-weight: 700; color: var(--nu-alert-text); }
@media (max-width: 1100px) {
  .sch-score-grid { grid-template-columns: 1fr 1fr; }
  .sch-score-arrow { display: none; }
}

.sch-sum { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.sch-meta { margin: 10px 0 6px; font-size: 0.76rem; color: var(--nu-txt3); }
.sch-warn { margin-left: 8px; padding: 1px 8px; border-radius: var(--nu-r-pill); font-weight: 700;
  color: var(--nu-warning-text); background: var(--nu-warning-soft); border: 1px solid var(--nu-warning-border); }
.sch-seq { max-height: 320px; }

.sch-row { cursor: pointer; }
.sch-row.is-sel td { background: var(--nu-primary-tint); }
.sch-acts { white-space: nowrap; }
.sch-eng { font-size: 0.72rem; font-weight: 700; color: var(--nu-txt3); }
.sch-accepted { margin-left: 6px; padding: 1px 7px; border-radius: var(--nu-r-pill);
  font-size: 0.68rem; font-weight: 700; color: var(--nu-on-accent); background: var(--nu-primary); }
.sch-chip { padding: 2px 9px; border-radius: var(--nu-r-pill); font-size: 0.72rem; font-weight: 700; }
.sch-chip.is-done { color: var(--nu-success-text); background: var(--nu-success-light-2); }
.sch-chip.is-run  { color: var(--nu-warning-text); background: var(--nu-warning-soft); }
.sch-chip.is-fail { color: var(--nu-alert-text);   background: var(--nu-alert-light-2); }

/* ── 생산현황 (설비 가동 구성 · 스테이션 프로파일) ── */
#layoutRoot.prod-page { display: flex; flex-direction: column; gap: 8px; flex: 1; min-height: 0; }
/* 이 화면은 실적 집계라 '역산'·'시뮬레이션' 배지와 구분되는 중립 표기를 쓴다 */
.prod-badge { padding: 4px 12px; font-size: 0.76rem; font-weight: 700; cursor: help;
  color: var(--nu-brand-text); background: var(--nu-primary-tint);
  border: 1px solid var(--nu-primary-light); border-radius: var(--nu-r-pill); }
.prod-mid { display: grid; grid-template-columns: 0.8fr 1.5fr 1.1fr; gap: 8px; }
.prod-mid > .chart-box { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
/* ★ 3열 고정이라 좁은 창에서 차트·표가 읽을 수 없는 폭으로 눌렸다(기준정보·긴급오더가
   특히 심했다). 폭에 따라 2열 → 1열로 접는다. */
@media (max-width: 1280px) {
  .prod-mid, .ship-mid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
}
@media (max-width: 860px) {
  .prod-mid, .ship-mid, .prod-bot { grid-template-columns: 1fr !important; }
  .charts-grid { grid-template-columns: 1fr; }
  .dash-stat-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* ★ 기준정보 화면이 좁은 창에서 깨지던 진짜 원인 — 칸을 2개 차지하라는 인라인 지정
     (style="grid-column: span 2")이 1열 격자에서도 살아 있어 없는 둘째 칸을 만들어 낸다.
     그 칸만큼 화면 밖으로 밀려 가로 스크롤이 생겼다. 접힐 때는 지정을 무르게 한다. */
  .prod-mid > *, .ship-mid > *, .prod-bot > * { grid-column: auto !important; }
}
.prod-canvas { position: relative; height: 190px; }
.prod-canvas > canvas { position: absolute; inset: 0; width: 100% !important; height: 100% !important; }
.prod-stopnote { margin: 8px 0 0; font-size: 0.74rem; line-height: 1.5; color: var(--nu-txt3); }
.prod-station-box { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.prod-station-canvas { position: relative; flex: 1; min-height: 170px; margin-top: 8px; }
.prod-station-canvas > canvas { position: absolute; inset: 0; width: 100% !important; height: 100% !important; }
.gl-run2   { background: var(--chart-2); }
.gl-setup2 { background: var(--nu-txt4); }
.gl-down2  { background: var(--nu-alert); }
.gl-st     { background: var(--chart-1); }
.gl-stneck { background: var(--nu-alert); }
.gl-tact   { background: var(--nu-warning); }

/* ═══════════════════════════════════════════════════════════════════════════
   MES 데이터셋 화면 (2026-08 재구성)
   ───────────────────────────────────────────────────────────────────────────
   원천을 10년 가상 MES 데이터(mes_* 테이블)로 갈아끼우며 더한 규칙.
   기존 클래스(.kpi-*, .prod-*, .sch-*, .gantt-head)를 최대한 그대로 쓰고,
   여기서는 새로 생긴 배치·상태 표기만 정의한다. 색 리터럴 0개 — 전부 토큰 참조.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 흐르는 본문 화면 ──────────────────────────────────────────────────────
   fit-page(창 높이에 맞춤)의 반대. 홈·생산현황·수주·자재는 표와 차트가 많아
   한 화면에 담으면 차트가 읽을 수 없는 높이로 눌린다. 자연 높이로 두고
   .content 의 세로 스크롤에 맡긴다. */
#layoutRoot.scroll-page { display: flex; flex-direction: column; gap: 8px;
  flex: 0 0 auto; min-height: auto; }
#layoutRoot.scroll-page .kpi-table-box { flex: 0 0 auto; }
#layoutRoot.scroll-page .kpi-table-wrap { flex: 0 0 auto; max-height: 420px; }

/* ── 한 화면에 최대한 담기 위한 여백 압축 ──────────────────────────────────
   업무 화면은 스크롤 없이 한눈에 읽히는 것이 낫다. 카드·차트 상자의 안쪽 여백과
   제목 아래 간격을 줄여 세로 길이를 걷어낸다. 폰트 크기는 건드리지 않는다 —
   글자를 줄이면 읽기가 나빠져서 얻은 높이를 도로 잃는다. */
#layoutRoot.scroll-page .chart-box,
#layoutRoot.prod-page .chart-box { padding: 11px 13px; border-radius: var(--nu-r-large); }
#layoutRoot.scroll-page .chart-title,
#layoutRoot.prod-page .chart-title { margin-bottom: 7px; font-size: 0.88rem; }
#layoutRoot.scroll-page .kpi-table-wrap { margin-top: 6px; }
#layoutRoot.scroll-page .gantt-head { margin-bottom: 0; }
#layoutRoot.scroll-page .prod-canvas { height: 168px; }
#layoutRoot.scroll-page .prod-stopnote { margin-top: 5px; }
/* 화면이 낮으면 차트를 더 줄인다 — 표는 자체 스크롤이 있으니 차트가 먼저 양보한다. */
@media (max-height: 900px) {
  #layoutRoot.scroll-page .prod-canvas { height: 150px; }
  #layoutRoot.scroll-page .kpi-table-wrap { max-height: 340px; }
}
@media (max-height: 780px) {
  #layoutRoot.scroll-page .prod-canvas { height: 132px; }
  #layoutRoot.scroll-page .kpi-table-wrap { max-height: 260px; }
  #layoutRoot.scroll-page .chart-box { padding: 9px 11px; }
  .kpi-card { padding: 6px 10px; }
  .kpi-card-value { font-size: 1.12rem; }
}

/* ── 라인 전환 비교 (홈) ── */
.kpi-line-box .kpi-table-wrap { max-height: none; }
.kpi-table td.is-good { color: var(--nu-success-text); font-weight: 700; }
.kpi-table td.is-bad  { color: var(--nu-alert-text); font-weight: 700; }
/* 자동화 라인 행 — 차트의 다른 계열색과 같은 뜻(설비가 바뀐 구간이다) */
.kpi-table tr.is-auto td { background: var(--nu-primary-tint); }
.kpi-table tr.is-auto:hover td { background: var(--row-hover); }

/* 라인체계 비교는 열이 10개라 반 폭에서 잘린다 — 이 화면의 본론이므로 전체 폭을 준다 */
.prod-line-box .kpi-table-wrap { max-height: none; }

/* ── 하단 2단 (생산현황·수주·자재) ── */
/* 출하 분석 — 차트 3단은 균등 폭이 읽기 좋다(생산현황은 0.8/1.5/1.1 로 비대칭이지만
   여기는 세 차트의 정보량이 비슷하다). */
.ship-mid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.prod-bot { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; align-items: start; }
.prod-bot > .chart-box { min-width: 0; }
.prod-bot .kpi-table-wrap { max-height: 340px; }

/* ── Plant Simulation 결과 등록 ──────────────────────────────────────────
   COM 연동 전까지 PS 결과를 보드로 들여오는 유일한 경로다. 붙여 넣기 칸이라
   가독성(고정폭·줄바꿈 유지)이 중요하다. */
.sch-import { margin-top: 10px; }
.sch-import-lbl { display: block; margin-bottom: 6px; font-size: 0.78rem; font-weight: 700; color: var(--nu-txt2); }
.sch-import-ta { width: 100%; box-sizing: border-box; padding: 10px 12px; resize: vertical;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.76rem; line-height: 1.5; color: var(--nu-txt1);
  background: var(--nu-surface-2); border: 1px solid var(--border); border-radius: var(--nu-r-medium); }
.sch-import-ta:focus { outline: none; border-color: var(--nu-primary); }
.sch-import-acts { display: flex; align-items: center; gap: 8px; margin-top: 8px; flex-wrap: wrap; }

/* 시뮬레이션 결과를 같은 달 실적과 맞대는 표 */
.sch-actual { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--nu-border-l); }
.sch-actual .kpi-table-wrap { max-height: none; }
/* 엔진 표기 — 내장과 Plant Simulation 을 색으로도 갈라 둔다(오해 방지) */
.sch-eng.is-psim { color: var(--nu-brand-text); }
.sch-chip.is-run { white-space: nowrap; }

/* ── 보정 데이터셋 v2 표시 ─────────────────────────────────────────────
   스케줄링 화면만 재구성본을 본다. 어느 원천인지 늘 눈에 보여야 한다. */
.sch-src {
  display: inline-block; margin-left: 8px; padding: 1px 8px;
  border-radius: var(--nu-r-pill); font-size: .7rem; font-weight: 700;
  color: var(--nu-brand-text); background: var(--nu-primary-tint);
  border: 1px solid var(--nu-primary-lightest); vertical-align: middle;
}
.sch-src.is-off { color: var(--nu-alert-text); background: var(--nu-alert-light-2);
                  border-color: var(--nu-alert-light); }
.sch-gain { color: var(--nu-success-text) !important; font-weight: 600; }
.sch-loss { color: var(--nu-alert-text)   !important; font-weight: 600; }

.sch-rules { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 10px; margin-top: 10px; }
.sch-rule  { display: grid; grid-template-columns: 44px 1fr; gap: 10px; align-items: start;
             padding: 10px 12px; border: 1px solid var(--nu-border-l); border-radius: var(--nu-r-medium); }
.sch-rule-id { font-size: .72rem; font-weight: 800; color: var(--nu-brand-text); padding-top: 1px; }
.sch-rule-t  { font-size: .84rem; font-weight: 700; color: var(--nu-txt1); line-height: 1.45; }
.sch-rule-d  { font-size: .78rem; color: var(--nu-txt3); line-height: 1.6; margin-top: 3px; }
.sch-rule-f  { font-size: .74rem; color: var(--nu-success-text); font-weight: 600; margin-top: 4px; }
.sch-unfixed { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--nu-border-l);
               font-size: .78rem; color: var(--nu-txt3); line-height: 1.7;
               display: flex; flex-direction: column; gap: 3px; }
.sch-unfixed strong { color: var(--nu-txt2); }

/* ── 비노출 화면 안내 ──────────────────────────────────────────────────────
   빈 화면을 그리거나 조용히 홈으로 튕기는 대신, 무엇을 볼 수 없고 무엇이 있으면
   되살아나는지 밝힌다(§절대원칙 1). */
.retired-panel { max-width: 860px; margin: 0 auto; padding: 32px 36px; }
.retired-badge { display: inline-block; padding: 3px 12px; margin-bottom: 14px;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.02em;
  color: var(--nu-warning-text); background: var(--nu-warning-soft);
  border: 1px solid var(--nu-warning-border); border-radius: var(--nu-r-pill); }
.retired-title { margin: 0 0 6px; font-size: 1.35rem; font-weight: 800; color: var(--nu-txt1); }
.retired-lead { margin: 0 0 20px; font-size: 0.9rem; color: var(--nu-txt2); }
.retired-dl { margin: 0; display: grid; grid-template-columns: 190px minmax(0, 1fr); gap: 10px 18px; }
.retired-dl dt { font-size: 0.8rem; font-weight: 700; color: var(--nu-txt3); }
.retired-dl dd { margin: 0; font-size: 0.84rem; line-height: 1.65; color: var(--nu-txt1); }
.retired-dl code { padding: 1px 5px; font-size: 0.78rem;
  background: var(--nu-surface-2); border: 1px solid var(--nu-border-l); border-radius: var(--nu-r-small); }
.retired-acts { display: flex; align-items: center; gap: 10px; margin-top: 24px; }
.retired-acts .admin-btn-primary { text-decoration: none; display: inline-flex; align-items: center; }
.retired-warn { margin: 16px 0 0; padding: 9px 14px; font-size: 0.78rem; line-height: 1.5;
  color: var(--nu-txt2); background: var(--nu-warning-soft);
  border: 1px solid var(--nu-warning-border); border-radius: var(--nu-r-medium); }

/* ── 좁은 화면 ── */
@media (max-width: 1280px) {
  .prod-bot { grid-template-columns: minmax(0, 1fr); }
  .retired-dl { grid-template-columns: minmax(0, 1fr); gap: 4px 0; }
  .retired-dl dd { margin-bottom: 10px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   좌측 메뉴 — 머리말 경계선 정렬 · 접기(본문 전체화면) · 그룹 일괄 접기
   (SimAPS-board 의 같은 이름 블록을 이식. 같은 특이도면 나중 블록이 이기므로
    이 블록이 정본이다 — 앞쪽의 .brand padding/border 를 여기서 다시 정한다.)
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── ① 로고 밴드 높이 = 상단 바 높이 ───────────────────────────────────────
   사이드바 로고 아래 경계선과 본문 상단 바(.topbar) 아래 경계선이 화면을 가로지르는
   "한 줄"로 이어져야 한다. 높이를 --topbar-h 한 곳에서 읽게 하고 선 색도 같은
   토큰(--jv-border)으로 맞춘다. 값을 두 곳에 적으면 한쪽만 고쳐 다시 어긋난다.
   ★ 여백은 사이드바가 아니라 .nav 가 갖는다 — 사이드바에 위여백이 있으면 로고 밴드가
     그만큼 아래로 밀려 정렬이 다시 깨진다. (box-sizing: border-box 라 44px 안에 경계선 1px 포함) */
:root { --topbar-h: 44px; }

.topbar { height: var(--topbar-h); }

.sidebar {
  padding: 0;
  gap: 0;
  overflow: hidden;   /* 스크롤은 .nav 가 맡는다 → 메뉴가 길어져도 로고 밴드는 제자리 */
}
.brand {
  height: var(--topbar-h);
  flex-shrink: 0;
  padding: 0 10px;
  border-bottom: 1px solid var(--jv-border);
}
/* 로고는 밴드(44px - 경계선 1px) 안에 위아래 여백을 두고 들어가는 크기로 고정 */
.brand-ci { height: 30px; }

.nav {
  padding: 8px 10px 12px;
  overflow-y: auto;
  min-height: 0;
  flex: 1;
  /* ★ .nav 는 grid 인데 flex:1 로 사이드바 높이를 채운다. 그리드의 기본 align-content 는
     stretch 라서, 내용이 짧아지면 남는 높이가 행 사이로 배분된다 — 메뉴를 전부 접았을 때
     그룹명이 뚝뚝 떨어져 뜨는 원인. start 로 고정해 접든 펴든 간격이 똑같이 유지되게 한다. */
  align-content: start;
}
.nav::-webkit-scrollbar { width: 5px; }
.nav::-webkit-scrollbar-track { background: transparent; }
.nav::-webkit-scrollbar-thumb { background: var(--nu-surface-4); border-radius: var(--nu-r-small); }
.nav::-webkit-scrollbar-thumb:hover { background: var(--nu-primary); }

/* ── ② 좌측 메뉴 접기 — 본문을 화면 전체로 ─────────────────────────────────
   상단 바의 ☰ 로 여닫는다. 격자 열과 사이드바를 한 클래스로 동시에 끈다.
   ★ 클래스 2개(0,2,0)라 @media 안의 .app-shell(0,1,0)보다 강하다 — 반응형 규칙이
     뒤에 오든 앞에 오든 이긴다. 그래서 미디어쿼리마다 복사할 필요가 없다.
   ※ 좁은 화면(≤1200px)에서는 사이드바가 이미 드로어라 이 클래스를 쓰지 않는다.
     거기서 ☰ 는 예전처럼 드로어를 여닫는다 — 뷰포트 분기는 app.js 가 한다.
   전환 애니메이션은 두지 않는다. 폭이 바뀌는 동안 차트가 매 프레임 리사이즈되면
   무스크롤 화면에서 눈에 보이게 버벅인다. */
.app-shell.nav-off { grid-template-columns: 1fr; }
.app-shell.nav-off > .sidebar { display: none; }

/* ── ③ 메뉴 그룹 일괄 접기/펴기 버튼 ───────────────────────────────────────
   로고 밴드 오른쪽 끝(margin-left:auto)에 붙는다. 44px 밴드 안에 들어가야 하므로
   버튼 24px / 아이콘 16px. 아이콘은 두 개를 넣어 두고 상태에 따라 하나만 보여준다
   (innerHTML 을 갈아치우면 SVG 를 문자열로 들고 있어야 해서 index.html 의 아이콘
   관리 방식과 어긋난다). */
.nav-toggle-all {
  margin-left: auto;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: var(--nu-r-medium);
  background: transparent;
  color: var(--jv-txt3);
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.nav-toggle-all:hover { background: var(--jv-hover); color: var(--jv-txt1); }
.nav-toggle-all svg { width: 16px; height: 16px; }
/* 펼쳐진 상태에서는 '모두 접기'만, 전부 접힌 상태에서는 '모두 펴기'만 보인다 */
.nav-toggle-all .nav-ico-expand { display: none; }
.nav-toggle-all.all-closed .nav-ico-collapse { display: none; }
.nav-toggle-all.all-closed .nav-ico-expand { display: block; }
