/* =========================================================================
   안전캠 백오피스 — Back-office shell & components
   Built on colors_and_type.css. Slightly lifted dark for data-entry density.
   ========================================================================= */

* { box-sizing: border-box; }
html { margin: 0; padding: 0; height: 100%; }
body {
  min-height: 100%;
  margin: 0;
  padding: 0;
  font-family: var(--font-ui);
  color: var(--fg);
  background: var(--bg-app-btm);
  -webkit-font-smoothing: antialiased;
  font-size: 15px;
}
button { font-family: inherit; }
a { color: inherit; text-decoration: none; }
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: rgba(55,83,118,.18); }
::-webkit-scrollbar-thumb { background: #5a636f; border-radius: 6px; border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background: #6e7884; background-clip: padding-box; border: 2px solid transparent; }

/* surface tokens — 셸 개편 시안 값 (docs/admin/design/bo-shell-redesign.dc.html).
   이름 변경 금지: 템플릿 인라인 스타일 484곳이 var(--bo-*) 를 직접 참조한다 (계획 5절). */
:root {
  --bo-app:      #20252c;   /* main workspace bg */
  --bo-side:     #262b36;   /* sidebar */
  --bo-side-2:   #262d36;
  --bo-top:      #1f232b;   /* header + breadcrumb bar */
  --bo-card:     #2f3741;   /* panels, tables */
  --bo-card-2:   #353e49;   /* raised rows / sticky head */
  --bo-input:    #20262e;   /* input fill (a bit lighter than control room) */
  --bo-input-foc:#1a1f26;
  --bo-line:     rgba(120,138,160,.22);
  --bo-line-2:   #434c59;
  --row-h: 46px;            /* comfortable */
}
body[data-density="compact"] { --row-h: 38px; }

/* ===================================================================== */
/* APP SHELL — 풀폭 헤더(56px) + [사이드바 | 콘텐츠]                        */
/* 콘텐츠 래퍼(bo-shell/bo-main/bo-page)에 transform·backdrop-filter·filter 금지
   — .scrim 등 position:fixed 오버레이의 기준을 깨뜨린다 (계획 PR1 룰).      */
/* ===================================================================== */

/* ---- 풀폭 헤더 ---- */
.bo-hd {
  height: 56px; position: sticky; top: 0; z-index: 45;
  display: flex; align-items: center; gap: 14px; padding: 0 20px;
  background: var(--bo-top); border-bottom: 1px solid var(--bo-line);
}
.bo-hd__mark { width: 92px; height: 26px; background: url(/css/assets/logo-bcfe4072c0ebad1c6cf6c04becab856f.png) left center/contain no-repeat; flex-shrink: 0; }
.bo-hd__div { width: 1px; height: 18px; background: var(--bo-line-2); flex-shrink: 0; }
.bo-hd .bo-tag {
  font-size: 11px; font-weight: 700; letter-spacing: .08em; color: var(--cyan);
  border: 1px solid rgba(0,178,255,.45); border-radius: 3px; padding: 2px 7px; white-space: nowrap;
}
.bo-hd__right { margin-left: auto; display: flex; align-items: center; gap: 18px; }

.bo-shell { display: grid; grid-template-columns: 248px 1fr; min-height: calc(100vh - 56px); }
body[data-nav="collapsed"] .bo-shell { grid-template-columns: 68px 1fr; }

/* ---- Sidebar ---- */
.bo-side {
  background: var(--bo-side);
  border-right: 1px solid var(--bo-line);
  display: flex; flex-direction: column;
  position: sticky; top: 56px; height: calc(100vh - 56px);
}

.bo-nav { flex: 1; overflow-y: auto; padding: 16px 12px 24px; }
.bo-nav__div { height: 1px; background: var(--bo-line); margin: 8px 10px; }
.bo-side__foot { padding: 14px 18px; font-size: 11px; color: var(--fg-subtle); border-top: 1px solid var(--bo-line); }

.bo-nav__item {
  display: flex; align-items: center; gap: 11px;
  height: 34px; padding: 0 12px 0 24px; border-radius: 0 6px 6px 0;
  border-left: 2px solid transparent;
  color: var(--fg-muted); font-size: 13.5px; cursor: pointer;
  position: relative; transition: background .14s, color .14s, border-color .14s; margin-bottom: 1px;
}
.bo-nav__item:hover { background: var(--bo-side-2); color: var(--fg); }
.bo-nav__item.on { background: rgba(33,88,168,.55); border-left-color: var(--cyan-bright); color: var(--fg-strong); font-weight: 500; }
.bo-nav__item.is-disabled { color: #5f6670; cursor: default; pointer-events: none; }
.bo-nav__item.is-disabled:hover { background: transparent; }

/* ---- 그룹 접이식 네비 (셸 개편 PR2 — IA 는 BoMenuRegistry 와 동일 표) ---- */
.bo-grp { margin-bottom: 2px; }
.bo-grp__hd {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 8px 10px; background: none; border: 0; border-radius: 6px; cursor: pointer;
  font: inherit; font-size: 12px; font-weight: 700; letter-spacing: .04em;
  color: var(--fg-subtle); text-align: left;
}
.bo-grp__hd:hover { color: var(--fg-muted); background: var(--bo-side-2); }
.bo-grp__hd .caret {
  width: 0; height: 0; flex: none;
  border-left: 5px solid currentColor; border-top: 4px solid transparent; border-bottom: 4px solid transparent;
  transition: transform .15s;
}
.bo-grp.is-open > .bo-grp__hd .caret { transform: rotate(90deg); }
.bo-grp__items { display: none; flex-direction: column; }
.bo-grp.is-open > .bo-grp__items { display: flex; }
.bo-nav__item .ic { width: 19px; height: 19px; flex-shrink: 0; background: var(--ic) center/contain no-repeat; opacity: .85; }
.bo-nav__item.on .ic { opacity: 1; }
.bo-nav__item .txt { white-space: nowrap; overflow: hidden; }
.bo-nav__item .cnt {
  margin-left: auto; font-size: 11px; font-weight: 700; color: var(--fg-subtle);
  background: rgba(255,255,255,.06); border-radius: 500px; padding: 1px 7px; min-width: 20px; text-align: center;
}
.bo-nav__item.on .cnt { color: var(--cyan); background: rgba(0,178,255,.12); }
body[data-nav="collapsed"] .bo-nav__item { justify-content: center; padding: 0; }
body[data-nav="collapsed"] .bo-nav__item .txt,
body[data-nav="collapsed"] .bo-nav__item .cnt { display: none; }

/* ---- Breadcrumb 바 (헤더 아래) ---- */
.bo-main { display: flex; flex-direction: column; min-width: 0; background: var(--bo-app); }
.bo-top {
  height: 44px; flex-shrink: 0; position: sticky; top: 56px; z-index: 30;
  background: var(--bo-top); border-bottom: 1px solid var(--bo-line);
  display: flex; align-items: center; gap: 16px; padding: 0 26px;
}
.bo-crumb { display: flex; align-items: center; gap: 9px; min-width: 0; }
.bo-crumb .root { font-size: 13px; color: var(--fg-subtle); }
.bo-crumb .sep { color: var(--fg-subtle); font-size: 13px; opacity: .55; }
.bo-crumb .grp { font-size: 13px; color: var(--fg-muted); white-space: nowrap; }
.bo-crumb .mid { font-size: 13px; color: var(--fg-muted); white-space: nowrap; }
.bo-crumb a.mid:hover, .bo-crumb a.mid:focus-visible { color: var(--cyan); text-decoration: underline; }
.bo-crumb .cur { font-size: 13.5px; font-weight: 700; color: var(--fg-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.bo-top__right { margin-left: auto; display: flex; align-items: center; gap: 18px; }
.bo-clock { font-size: 14px; font-weight: 500; color: var(--fg-muted); font-variant-numeric: tabular-nums; }
.bo-user { display: flex; align-items: center; gap: 7px; font-size: 13.5px; color: var(--fg-muted); }
.bo-user b { font-weight: 700; color: var(--fg-strong); }
.bo-user span { font-size: 12px; color: var(--fg-subtle); }
.bo-logout {
  height: 32px; padding: 0 13px; border-radius: var(--radius-btn); border: 1px solid var(--bo-line-2);
  background: transparent; cursor: pointer; font-size: 13px; color: var(--fg-muted); font-weight: 500;
}
.bo-logout:hover { background: var(--blue); border-color: var(--blue); color: #fff; }

/* ===================================================================== */
/* PAGE                                                                  */
/* ===================================================================== */
.bo-page { padding: 20px 24px 64px; width: 100%; }
.page-head { display: flex; align-items: flex-end; gap: 16px; margin-bottom: 16px; padding-bottom: 14px; border-bottom: 1px solid var(--bo-line-2); }
.page-head .ph-title { font-size: 20px; font-weight: 700; color: var(--fg-strong); line-height: 1.15; }
.page-head .ph-sub { font-size: 13px; color: var(--fg-subtle); margin-top: 5px; }
.page-head .ph-actions { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.ph-count { font-size: 13px; color: var(--fg-muted); }
.ph-count b { color: var(--orange); font-weight: 700; font-size: 15px; }

/* ---- Board panel — 시안: radius 8px 카드 + 그라데이션 섹션 헤더 밴드 ---- */
.card { background: var(--bo-card); border: 1px solid var(--bo-line); border-radius: var(--radius-md); box-shadow: none; overflow: hidden; }
.card + .card { margin-top: 16px; }
.card__head {
  display: flex; align-items: center; gap: 10px; padding: 11px 14px 11px 16px;
  border-top: 1px solid rgba(0,178,255,.35);
  border-bottom: 1px solid var(--bo-line-2); background: var(--section-bar);
}
.card__head h3 { margin: 0; font-size: 14px; font-weight: 500; color: var(--fg-strong); white-space: nowrap; }
.card__head .sub { font-size: 12px; color: var(--fg-subtle); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card__head .right { margin-left: auto; display: flex; gap: 8px; align-items: center; white-space: nowrap; flex-shrink: 0; }
.card__body { padding: 16px; }
.card__body.flush { padding: 0; }

/* ===================================================================== */
/* FILTER BAR                                                            */
/* ===================================================================== */
.filterbar { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px 18px; padding: 16px 18px; }
.filterbar .field { display: flex; flex-direction: column; gap: 6px; }
.filterbar .field .lbl { font-size: 12px; color: var(--fg-muted); font-weight: 500; }
.filterbar .grow { flex: 1; min-width: 160px; }
.filterbar .fb-actions { margin-left: auto; display: flex; gap: 8px; align-self: flex-end; }

/* 통합 검색바 — 입력 1개, 컴팩트 높이 (게시판 공통) */
.searchbar { margin-bottom: 14px; }
.filterbar.slim { padding: 10px 14px; gap: 10px; align-items: center; flex-wrap: nowrap; }
.filterbar.slim .inp { flex: 1; max-width: 440px; }
.filterbar.slim .fb-actions { align-self: center; }

/* ===================================================================== */
/* 조회 범위(Scope) 바 — 고객/사업장 칩 + 팝오버 (셸 개편 PR3)               */
/* ===================================================================== */
.scopebar { margin-bottom: 14px; position: relative; overflow: visible; }
.scopebar .filterbar.slim { flex-wrap: wrap; }
.scopebar .sb-lbl { font-size: 12px; font-weight: 500; color: var(--fg-subtle); white-space: nowrap; }
.scopebar .sb-div { width: 1px; height: 22px; background: var(--line-strong); margin: 0 4px; flex: none; }
.scopebar .sb-q { width: 260px; flex: none; }
.scopebar .sel { width: auto; }
.scope-chip {
  display: inline-flex; align-items: center; gap: 8px; height: 36px; padding: 0 14px;
  border-radius: var(--radius-btn); border: 1px solid transparent;
  background: var(--surface-raised); color: var(--fg); font: inherit; font-size: 13px;
  cursor: pointer; white-space: nowrap; max-width: 220px;
}
.scope-chip .val { overflow: hidden; text-overflow: ellipsis; }
.scope-chip .caret {
  width: 0; height: 0; flex: none;
  border-top: 5px solid var(--fg-muted); border-left: 4px solid transparent; border-right: 4px solid transparent;
}
.scope-chip:hover { background: #4a5d73; }
.scope-chip.scoped { background: var(--blue-dark); border-color: var(--cyan-bright); color: var(--fg-strong); }

.scope-pop {
  position: absolute; top: calc(100% + 6px); left: 14px; z-index: 60; width: 360px;
  background: var(--surface-panel); border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-pop); padding: 12px; display: flex; flex-direction: column;
}
.scope-pop[hidden] { display: none; }
.scope-pop__head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.scope-pop__head strong { font-size: 14px; color: var(--fg-strong); }
.scope-pop__head .btn-link { margin-left: auto; }
.scope-pop__x {
  margin-left: auto; width: 24px; height: 24px; border: 0; background: none; color: var(--fg-subtle);
  font-size: 18px; line-height: 1; cursor: pointer; border-radius: var(--radius-btn);
}
.scope-pop__head .btn-link + .scope-pop__x { margin-left: 6px; }
.scope-pop__x:hover { color: var(--fg-strong); background: rgba(255,255,255,.07); }
.scope-pop__search { margin-bottom: 8px; }
.scope-pop__search input {
  width: 100%; height: 34px; padding: 0 12px; font: inherit; font-size: 13px;
  color: var(--fg-strong); background: var(--bo-input); border: 1px solid var(--line-input); border-radius: var(--radius-btn);
}
.scope-pop__search input:focus { outline: none; border-color: var(--blue); }
.scope-pop__list { max-height: 300px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.scope-pop__row {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px 10px; text-align: left;
  border: 0; border-radius: var(--radius-btn); background: none; color: var(--fg-muted);
  font: inherit; font-size: 13px; cursor: pointer;
}
.scope-pop__row:hover { background: var(--bo-side-2); color: var(--fg); }
.scope-pop__row.all { color: var(--fg-strong); font-weight: 500; }
.scope-pop__row[hidden] { display: none; }
.scope-pop__empty { padding: 16px; text-align: center; color: var(--fg-subtle); font-size: 12.5px; }

/* ---- Inputs ---- */
.inp, .sel, .ta {
  height: 36px; background: var(--bo-input); border: 1px solid var(--line-input);
  border-radius: var(--radius-btn); padding: 0 12px; color: var(--fg-strong); -webkit-text-fill-color: var(--fg-strong); font: inherit; font-size: 14px;
  width: 100%; transition: border-color .14s, background .14s, box-shadow .14s;
}
.inp::placeholder, .ta::placeholder { color: var(--fg-subtle); }
/* 고정폭 입력칸의 한글 안내문은 본문 글꼴로 — mono 로 그리면 넓어져 잘린다(카메라 분석 임계값) */
.inp.mono::placeholder { font-family: var(--font-ui); letter-spacing: 0; }
.inp:focus, .sel:focus, .ta:focus { outline: none; background: var(--bo-input-foc); border-color: var(--blue); box-shadow: 0 0 0 3px rgba(50,133,255,.16); }
.inp:disabled, .sel:disabled, .ta:disabled { opacity: .5; cursor: not-allowed; }
.sel { -webkit-appearance: none; appearance: none; cursor: pointer;
  background-image: url(/css/assets/icons/icon_down-f250486234f2fd41bb7436f12957d2f2.svg); background-repeat: no-repeat; background-position: right 7px center; background-size: 20px; padding-right: 32px; }
textarea.inp, .ta { height: auto; padding: 9px 12px; line-height: 1.5; resize: vertical; min-height: 80px; }
.inp-wrap { position: relative; }
.inp-wrap .inp { padding-left: 38px; }
.inp-wrap .lead { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); width: 18px; height: 18px; opacity: .8; background: var(--ic) center/contain no-repeat; pointer-events: none; }

/* 비밀번호 입력 — 표시/숨김(eye) 토글 */
.pw-field { position: relative; }
.pw-field .inp { padding-right: 42px; }
.pw-toggle { position: absolute; top: 0; right: 0; height: 36px; width: 38px;
  border: none; background: transparent; cursor: pointer; padding: 0;
  display: grid; place-items: center; opacity: .6; transition: opacity .14s; }
.pw-toggle:hover { opacity: 1; }
.pw-toggle .ic { width: 19px; height: 19px; background: center/contain no-repeat; }
.pw-toggle .ic-off { background-image: url(/css/assets/icons/icon_show-9f2c05a49ab6d603b51b26e6c4feeb8c.svg); }
.pw-toggle .ic-on  { background-image: url(/css/assets/icons/icon_hide-5fab20f3c1d038c381c9f41116f140bd.svg); display: none; }
.pw-toggle.shown .ic-off { display: none; }
.pw-toggle.shown .ic-on  { display: block; }
/* Edge/IE 네이티브 비번 표시·지우기 아이콘 숨김 — 우리 .pw-toggle 과 중복(눈 2개) 방지 */
input[type="password"]::-ms-reveal,
input[type="password"]::-ms-clear { display: none; }

/* 자동완성(autofill) 시에도 다크 테마 배경 유지 + 입력 글자(마스킹 점) 보이게 */
.inp:-webkit-autofill, .inp:-webkit-autofill:hover,
.inp:-webkit-autofill:focus, .inp:-webkit-autofill:active {
  -webkit-text-fill-color: var(--fg-strong) !important;
  caret-color: var(--fg-strong);
  -webkit-box-shadow: 0 0 0 1000px var(--bo-input) inset !important;
  transition: background-color 9999s ease-out 0s;
}

/* segmented control */
.seg { display: inline-flex; background: var(--bo-input); border: 1px solid var(--line-input); border-radius: var(--radius-btn); padding: 2px; gap: 2px; }
.seg button { border: none; background: transparent; color: var(--fg-muted); font-size: 13px; font-weight: 500; padding: 5px 12px; border-radius: var(--radius-btn); cursor: pointer; }
.seg button.on { background: var(--surface-raised); color: var(--fg-strong); }

/* ---- Buttons ---- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  height: 36px; padding: 0 15px; border-radius: var(--radius-btn); border: 1px solid var(--gray900);
  background: var(--surface-raised); color: var(--fg-strong); font-size: 14px; font-weight: 500;
  cursor: pointer; white-space: nowrap; transition: background .14s, border-color .14s, opacity .14s;
}
.btn:hover { background: #4a5d73; }
.btn .ic { width: 16px; height: 16px; background: var(--ic) center/contain no-repeat; }
.btn.primary { background: var(--blue); border-color: transparent; }
.btn.primary:hover { background: var(--blue-light); }
.btn.line { background: transparent; border-color: var(--line-btn); color: var(--fg-muted); }
.btn.line:hover { background: rgba(255,255,255,.05); border-color: #a6b4c5; color: var(--fg-strong); }
.btn.danger { background: transparent; border-color: rgba(255,83,83,.5); color: #ff8585; }
.btn.danger:hover { background: rgba(255,83,83,.14); border-color: var(--danger); color: #ff9d9d; }
.btn.sm { height: 30px; padding: 0 11px; font-size: 13px; }
.btn.lg { height: 42px; padding: 0 22px; font-size: 15px; }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn-link { background: none; border: none; color: var(--cyan); font-size: 13px; cursor: pointer; padding: 0; }
.btn-link:hover { text-decoration: underline; }
.icon-btn { width: 32px; height: 32px; border-radius: var(--radius-btn); border: 1px solid var(--bo-line-2); background: transparent; cursor: pointer; display: grid; place-items: center; }
.icon-btn:hover { background: rgba(255,255,255,.06); }
.icon-btn .ic { width: 17px; height: 17px; opacity: .8; background: var(--ic) center/contain no-repeat; }
.icon-btn:hover .ic { opacity: 1; }

/* ===================================================================== */
/* TABLE                                                                 */
/* ===================================================================== */
.tbl-wrap { overflow-x: auto; }
.tbl { width: 100%; border-collapse: collapse; font-size: 14px; }
.tbl thead th {
  position: sticky; top: 0; background: var(--bo-card); color: var(--fg-subtle); font-weight: 600;
  font-size: 12.5px; text-align: left; padding: 0 14px; height: 40px; white-space: nowrap;
  border-bottom: 1px solid var(--bo-line-2); z-index: 1;
}
.tbl thead th.c { text-align: center; }
.tbl tbody td { padding: 0 14px; height: var(--row-h); border-bottom: 1px solid var(--bo-line); color: var(--fg); vertical-align: middle; }
.tbl tbody td.c { text-align: center; }
.tbl tbody td.strong { color: var(--fg-strong); font-weight: 500; white-space: nowrap; }
.tbl tbody tr { transition: background .1s; cursor: pointer; }
.tbl tbody tr:hover td { background: rgba(30,124,172,.16); }
.tbl tbody tr.sel td { background: rgba(33,88,168,.32); }
.tbl .muted { color: var(--fg-subtle); }
.tbl .mono { font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }
.tbl .id-cell { font-family: var(--font-mono); font-size: 13px; color: var(--fg-muted); }
.tbl .empty { text-align: center; color: var(--fg-subtle); padding: 56px 0; }
.linkish { color: var(--cyan); font-weight: 500; }
.tbl tbody tr:hover .linkish { text-decoration: underline; }

/* ---- Pills / status — 시안: 색상 텍스트 + 12% 배경 + 35% 보더 pill ---- */
.pill { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 500; padding: 3px 10px; border-radius: var(--radius-pill); border: 1px solid transparent; white-space: nowrap; }
.pill .dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.pill.green  { background: rgba(6,177,10,.12);  color: #5fd06a; border-color: rgba(6,177,10,.35); }
.pill.green  .dot { background: var(--success); }
.pill.amber  { background: rgba(255,207,95,.12); color: #ffd97a; border-color: rgba(255,207,95,.35); }
.pill.amber  .dot { background: var(--orange); }
.pill.red    { background: rgba(255,83,83,.12);  color: #ff8585; border-color: rgba(255,83,83,.35); }
.pill.red    .dot { background: var(--danger); }
.pill.gray   { background: rgba(166,180,197,.1); color: var(--fg-muted); border-color: rgba(166,180,197,.3); }
.pill.gray   .dot { background: var(--fg-subtle); }
.pill.blue   { background: rgba(50,133,255,.12); color: #7db4ff; border-color: rgba(50,133,255,.35); }
.pill.blue   .dot { background: var(--blue); }
.pill.purple { background: rgba(192,132,252,.12); color: #c084fc; border-color: rgba(192,132,252,.35); }
.pill.purple .dot { background: #c084fc; }
.pill.teal   { background: rgba(45,178,139,.12); color: #5fd0b1; border-color: rgba(45,178,139,.35); }
.pill.teal   .dot { background: #2db28b; }
.tag { display: inline-flex; align-items: center; font-size: 11.5px; font-weight: 700; padding: 2px 7px; border-radius: 4px; letter-spacing: .02em; }
.tag.r { background: rgba(166,180,197,.14); color: var(--fg-muted); }
.tag.m { background: rgba(50,133,255,.18); color: #7db4ff; }
.useyn-y { color: #5fd06a; font-weight: 600; }
.useyn-n { color: var(--fg-subtle); }

/* ---- Pagination ---- */
.pager { display: flex; align-items: center; justify-content: center; gap: 6px; padding: 16px; }
.pager button {
  min-width: 32px; height: 32px; padding: 0 6px; border-radius: var(--radius-btn); border: 1px solid var(--bo-line);
  background: transparent; color: var(--fg-muted); font-size: 13px; cursor: pointer; display: grid; place-items: center;
}
.pager button:hover:not(:disabled) { background: rgba(255,255,255,.06); color: var(--fg); }
.pager button.on { background: var(--blue-dark); border-color: var(--cyan-bright); color: var(--fg-strong); font-weight: 700; }
.pager button:disabled { opacity: .35; cursor: not-allowed; }
.pager .arr { width: 14px; height: 14px; opacity: .8; background: var(--ic) center/contain no-repeat; }
.pager .meta { margin: 0 12px; font-size: 12px; color: var(--fg-subtle); }
.pgsize { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--fg-subtle); }
.pgsize .sel { height: 30px; width: auto; font-size: 13px; padding: 0 28px 0 10px; }

/* ===================================================================== */
/* MODAL                                                                 */
/* ===================================================================== */
.scrim { position: fixed; inset: 0; background: var(--scrim); backdrop-filter: blur(2px); z-index: 100; display: grid; place-items: center; padding: 24px; animation: fade .16s ease; }
@keyframes fade { from { opacity: 0; } }
.modal { background: var(--surface-panel); border: 1px solid var(--bo-line-2); border-radius: 10px; box-shadow: var(--shadow-pop); width: 100%; max-width: 480px; max-height: 90vh; display: flex; flex-direction: column; animation: pop .18s ease; }
@keyframes pop { from { opacity: 0; transform: translateY(8px) scale(.98); } }
.modal.wide { max-width: 760px; }
.modal__head { display: flex; align-items: center; gap: 10px; padding: 18px 20px; border-bottom: 1px solid var(--bo-line); }
.modal__head h3 { margin: 0; font-size: 17px; font-weight: 700; color: var(--fg-strong); }
.modal__head .x { margin-left: auto; width: 30px; height: 30px; border-radius: 5px; border: none; background: transparent; cursor: pointer; display: grid; place-items: center; }
.modal__head .x:hover { background: rgba(255,255,255,.08); }
.modal__head .x .ic { width: 18px; height: 18px; opacity: .8; background: url(/css/assets/icons/icon_close-90a0b554e1671f1f2d32f8405ba82113.svg) center/contain no-repeat; }
.modal__body { padding: 20px; overflow-y: auto; }
.modal__foot { display: flex; gap: 10px; justify-content: flex-end; padding: 16px 20px; border-top: 1px solid var(--bo-line); }
.modal__foot.between { justify-content: space-between; }

/* confirm modal accent */
.confirm-ico { width: 46px; height: 46px; border-radius: 500px; display: grid; place-items: center; flex-shrink: 0; }
.confirm-ico .ic { width: 24px; height: 24px; }
.confirm-ico.warn { background: rgba(255,207,95,.16); }
.confirm-ico.warn .ic { background: var(--ic) center/contain no-repeat; }
.confirm-ico.danger { background: rgba(255,83,83,.16); }
.confirm-ico.danger .ic { background: var(--ic) center/contain no-repeat; }
.confirm-ico.info { background: rgba(50,133,255,.16); }
.confirm-ico.info .ic { background: var(--ic) center/contain no-repeat; }

/* ---- Form rows (detail / edit) ---- */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 22px; }
.form-grid .full { grid-column: 1 / -1; }
.field { display: flex; flex-direction: column; gap: 7px; }
/* display 를 지정한 탓에 hidden 속성이 무력화된다. 조건부로 감추는 입력칸이
   그대로 보여, 화면마다 따로 덮어쓰던 것을 여기서 한 번에 처리한다. */
.field[hidden] { display: none; }
.field > label { font-size: 13px; color: var(--fg-muted); font-weight: 500; display: flex; align-items: center; gap: 5px; }
.field .req { width: 5px; height: 5px; border-radius: 50%; background: var(--danger); }
.field .hint { font-size: 12px; color: var(--fg-subtle); }
.field .err { font-size: 12px; color: #ff8585; }
.field.has-err .inp, .field.has-err .sel { border-color: var(--danger); }

/* definition list (detail read view) */
.dl { display: grid; grid-template-columns: 104px 1fr; row-gap: 0; }
.dl dt { padding: 8px 0; font-size: 12.5px; color: var(--fg-muted); border-bottom: 1px solid var(--bo-line); }
.dl dd { padding: 8px 0; margin: 0; font-size: 13.5px; color: var(--fg-strong); border-bottom: 1px solid var(--bo-line); display: flex; align-items: center; gap: 8px; }
.dl dt:last-of-type, .dl dd:last-of-type { border-bottom: none; }

/* temp password reveal box */
.tpw { display: flex; align-items: center; gap: 12px; background: var(--bo-input); border: 1px dashed var(--blue); border-radius: 6px; padding: 14px 16px; }
.tpw .pw { font-family: var(--font-mono); font-size: 22px; font-weight: 700; letter-spacing: .06em; color: var(--cyan-bright); flex: 1; }

/* flash toast — 헤더(56) + breadcrumb(44) 아래 */
.flash-zone { position: fixed; top: 110px; right: 26px; z-index: 200; display: flex; flex-direction: column; gap: 10px; }
.flash { display: flex; align-items: center; gap: 11px; min-width: 280px; max-width: 420px; padding: 13px 16px; border-radius: 8px; background: var(--surface-panel); border: 1px solid var(--bo-line-2); box-shadow: var(--shadow-pop); animation: slidein .22s ease; }
@keyframes slidein { from { opacity: 0; transform: translateX(16px); } }
.flash .bar { width: 4px; align-self: stretch; border-radius: 4px; }
.flash.ok .bar { background: var(--success); }
.flash.err .bar { background: var(--danger); }
.flash .ic { width: 20px; height: 20px; flex-shrink: 0; }
.flash.ok .ic { background: url(/css/assets/icons/icon_ok_circle-bb52bcececc00859fddae09d859747b0.svg) center/contain no-repeat; }
.flash.err .ic { background: url(/css/assets/icons/icon_warnning-2e0f3f04c9843203a0056b86f5ec84eb.svg) center/contain no-repeat; }
.flash .msg { font-size: 13.5px; color: var(--fg-strong); flex: 1; }

/* info banner / notice */
/* display 를 주는 순간 hidden 속성이 무력해진다. 조건부 안내는 대부분 hidden 으로 켜고
   끄므로, 눌러 두지 않으면 "권한이 필요합니다" 같은 문구가 조건과 무관하게 늘 떠 있는다. */
.notice[hidden] { display: none; }
.notice { display: flex; align-items: flex-start; gap: 10px; padding: 12px 14px; border-radius: 7px; font-size: 13px; line-height: 1.5; }
.notice .ic { width: 18px; height: 18px; flex-shrink: 0; margin-top: 1px; }
.notice.info { background: rgba(50,133,255,.1); border: 1px solid rgba(50,133,255,.28); color: #aaccff; }
.notice.info .ic { background: url(/css/assets/icons/icon_tip-8c347ce641d4e0ca73bfc6f41f93439c.svg) center/contain no-repeat; }
.notice.warn { background: rgba(255,207,95,.1); border: 1px solid rgba(255,207,95,.3); color: #ffe0a3; }
.notice.warn .ic { background: url(/css/assets/icons/icon_tip-8c347ce641d4e0ca73bfc6f41f93439c.svg) center/contain no-repeat; }
.notice b { color: #fff; font-weight: 700; }
.modal__body > .notice:not(:last-child) { margin-bottom: 18px; }

/* stat tiles */
.stat-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.stat { background: var(--bo-card); border: 1px solid var(--bo-line); border-radius: 8px; padding: 16px 18px; }
.stat .k { font-size: 12.5px; color: var(--fg-muted); display: flex; align-items: center; gap: 7px; }
.stat .k .ic { width: 16px; height: 16px; opacity: .7; background: var(--ic) center/contain no-repeat; }
.stat .v { font-size: 28px; font-weight: 700; color: var(--fg-strong); margin-top: 8px; line-height: 1; }
.stat .v small { font-size: 14px; color: var(--fg-subtle); font-weight: 500; margin-left: 3px; }
.stat .v.accent { color: var(--orange); }

/* tabs */
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--bo-line); padding: 0 4px; }
.tabs button { border: none; background: transparent; color: var(--fg-muted); font-size: 14px; font-weight: 500; padding: 12px 16px; cursor: pointer; position: relative; }
.tabs button:hover { color: var(--fg); }
.tabs button.on { color: var(--fg-strong); }
.tabs button.on::after { content: ""; position: absolute; left: 12px; right: 12px; bottom: -1px; height: 2px; background: var(--cyan-bright); border-radius: 2px; }
.tabs button .cnt { margin-left: 6px; font-size: 11px; color: var(--fg-subtle); }

/* ---- 에러 화면 (403/404/500) — 셸 안에서 렌더돼 좌측 메뉴로 빠져나갈 수 있다 ---- */
.bo-error { max-width: 560px; padding: 72px 0 40px; }
.bo-error__code {
  font-size: 56px; font-weight: 700; line-height: 1; color: var(--fg-subtle);
  font-variant-numeric: tabular-nums; letter-spacing: -.02em;
}
.bo-error__title { margin: 18px 0 12px; font-size: 22px; font-weight: 700; color: var(--fg-strong); }
.bo-error__desc { margin: 0; font-size: 14.5px; line-height: 1.7; color: var(--fg-muted); }
.bo-error__path { margin: 16px 0 0; font-size: 12.5px; color: var(--fg-subtle); display: flex; flex-wrap: wrap; gap: 12px; }
.bo-error__path .mono { font-family: var(--font-mono); }
.bo-error__actions { margin-top: 28px; display: flex; gap: 10px; }

/* misc */
.row-actions { display: flex; gap: 6px; justify-content: center; }
.spacer { flex: 1; }
.skeleton-note { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 70px 20px; color: var(--fg-subtle); text-align: center; }
.skeleton-note .ic { width: 40px; height: 40px; opacity: .4; background: var(--ic) center/contain no-repeat; }
.skeleton-note h4 { margin: 0; font-size: 16px; color: var(--fg-muted); font-weight: 600; }
.skeleton-note p { margin: 0; font-size: 13px; max-width: 360px; line-height: 1.6; }
.badge-soon { font-size: 10px; font-weight: 700; letter-spacing: .04em; color: var(--orange); border: 1px solid rgba(255,207,95,.4); border-radius: 4px; padding: 1px 6px; }

/* ===================================================================== */
/* CUSTOMER SCOPE — switcher, mode label, breadcrumb, overview           */
/* ===================================================================== */
.bo-side__sw { padding: 12px 12px 4px; flex-shrink: 0; }
.cust-sw { position: relative; }
.cust-sw__btn {
  width: 100%; display: flex; align-items: center; gap: 10px;
  height: 50px; padding: 0 12px; border-radius: 8px;
  background: var(--bo-side-2); border: 1px solid var(--bo-line-2);
  color: var(--fg); cursor: pointer; text-align: left; transition: border-color .14s, background .14s;
}
.cust-sw__btn:hover { background: #2c343f; }
.cust-sw__btn.scoped { background: #20303f; border-color: rgba(0,178,255,.4); }
.cust-sw__ico { width: 24px; height: 24px; display: grid; place-items: center; flex-shrink: 0; }
.cust-sw__txt { display: flex; flex-direction: column; min-width: 0; line-height: 1.25; }
.cust-sw__txt .lbl { font-size: 10.5px; font-weight: 700; letter-spacing: .04em; color: var(--fg-subtle); text-transform: uppercase; }
.cust-sw__txt .val { font-size: 14px; font-weight: 700; color: var(--fg-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
body[data-nav="collapsed"] .bo-side__sw { padding: 12px 8px 4px; }
body[data-nav="collapsed"] .cust-sw__txt { display: none; }
body[data-nav="collapsed"] .cust-sw__btn { justify-content: center; padding: 0; }
body[data-nav="collapsed"] .cust-sw__btn > .ic-down { display: none; }

.cust-sw__pop {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 60;
  background: var(--surface-panel, #262b36); border: 1px solid var(--bo-line-2); border-radius: 10px;
  box-shadow: var(--shadow-pop); padding: 8px; max-height: 60vh; display: flex; flex-direction: column;
}
.cust-sw__search { display: flex; align-items: center; gap: 8px; padding: 7px 10px; background: var(--bo-input); border: 1px solid var(--bo-line); border-radius: 7px; margin-bottom: 8px; }
.cust-sw__search input { flex: 1; background: none; border: none; outline: none; color: var(--fg-strong); font-size: 13px; font-family: inherit; }
.cust-sw__search input::placeholder { color: var(--fg-subtle); }
.cust-sw__all { display: flex; align-items: center; gap: 9px; width: 100%; padding: 9px 10px; border-radius: 7px; border: none; background: transparent; color: var(--fg); font-size: 13.5px; cursor: pointer; text-align: left; }
.cust-sw__all:hover { background: var(--bo-side-2); }
.cust-sw__all.on { background: rgba(0,178,255,.1); color: var(--fg-strong); }
.cust-sw__all .hint { font-size: 11.5px; color: var(--fg-subtle); margin-left: 4px; }
.cust-sw__all .check { margin-left: auto; width: 7px; height: 7px; border-radius: 50%; background: var(--cyan-bright); }
.cust-sw__div { height: 1px; background: var(--bo-line); margin: 8px 4px; }
.cust-sw__list { overflow-y: auto; display: flex; flex-direction: column; gap: 1px; }
.cust-sw__empty { padding: 18px; text-align: center; color: var(--fg-subtle); font-size: 13px; }
.cust-sw__row { display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px 10px; border-radius: 7px; border: none; background: transparent; cursor: pointer; text-align: left; }
.cust-sw__row:hover { background: var(--bo-side-2); }
.cust-sw__row.on { background: #243247; }
.cust-sw__row .nm { font-size: 13.5px; font-weight: 600; color: var(--fg-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; }
.cust-sw__row .meta { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.cust-sw__row .meta .pobs { font-size: 11.5px; color: var(--fg-subtle); font-variant-numeric: tabular-nums; }

.bo-side__exit { display: inline-flex; align-items: center; gap: 5px; margin: 8px 2px 0; padding: 4px 4px; background: none; border: none; color: var(--cyan); font-size: 12.5px; cursor: pointer; }
.bo-side__exit:hover { text-decoration: underline; }
body[data-nav="collapsed"] .bo-side__exit { display: none; }
.bo-nav__mode { font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--fg-subtle); padding: 4px 22px 0; }
.bo-nav__mode.cust { color: var(--cyan); }
body[data-nav="collapsed"] .bo-nav__mode { display: none; }

.bo-crumb .root-btn { background: none; border: none; font: inherit; cursor: pointer; padding: 0; }
.bo-crumb .root-btn:hover { color: var(--fg-muted); }
.bo-crumb .crumb-cust { background: none; border: none; font-size: 13px; color: var(--cyan); cursor: pointer; padding: 0; font-weight: 600; }
.bo-crumb .crumb-cust:hover { text-decoration: underline; }

/* overview — flat board, single column, unified width & spacing */
.ov-wrap { max-width: 1180px; }
.ov-head { align-items: center; }
.ov-id .ph-sub { margin-top: 5px; }
.ov-hstats { margin-left: auto; display: flex; align-items: stretch; }
.ov-hs { display: flex; flex-direction: column; gap: 5px; padding: 2px 18px; border-left: 1px solid var(--bo-line-2); }
.ov-hs:first-child { border-left: none; }
.ov-hs .v { font-size: 19px; font-weight: 700; color: var(--fg-strong); line-height: 1; font-variant-numeric: tabular-nums; }
.ov-hs .v .u { font-size: 11px; color: var(--fg-subtle); font-weight: 500; margin-left: 2px; }
.ov-hs .l { font-size: 11.5px; color: var(--fg-muted); }
.ov-body { display: flex; flex-direction: column; gap: 16px; }
.ov-body .card + .card { margin-top: 0; }
.ov-body .card__head { min-height: 44px; }
.ov-dl2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 44px; }
@media (max-width: 720px) { .ov-dl2 { grid-template-columns: 1fr; } }


/* ===================================================================== */
/* 현장 관리 트리 사이드바 (공용) — console + 레거시 페이지 통일                */
/* ===================================================================== */
/* 트리 제거(PR4) 후 사이드바 = 순수 기능 네비 — 시안 212px */
.bo-shell.tree-shell { grid-template-columns: 212px 1fr; }
body[data-nav="collapsed"] .bo-shell.tree-shell { grid-template-columns: 212px 1fr; }

/* ---- 고객 트리 — console(고객 · 사업장) 화면 전용 패널 (사이드바에서 이동) ---- */
.console-layout { display: grid; grid-template-columns: 320px minmax(0, 1fr); gap: 16px; align-items: start; }
.console-tree {
  display: flex; flex-direction: column;
  position: sticky; top: 116px;               /* 헤더 56 + breadcrumb 44 + 여백 */
  max-height: calc(100vh - 132px);
}
.console-main { min-width: 0; }
@media (max-width: 1100px) {
  .console-layout { grid-template-columns: 1fr; }
  .console-tree { position: static; max-height: 420px; }
}

.treeside__bar { padding: 12px; display: flex; flex-direction: column; gap: 8px; border-bottom: 1px solid var(--bo-line); }
.treeside__search .lead { --ic: url('/css/assets/icons/icon_search-5ee7d0945a0d8b8d9d77069cffc66d94.svg'); }
.treeside__search .inp { border-color: var(--bo-line-2); background: var(--bo-input); }
.treeside__tree { flex: 1 1 auto; overflow: auto; padding: 8px 6px; min-height: 260px; }
.treeside__empty { padding: 40px 16px; text-align: center; color: var(--fg-subtle); font-size: 13px; }

/* 전역 검색 결과 — 트리 대신 표시. 동명 노드를 구분하도록 상위 경로를 함께 보여준다. */
.thits__empty { padding: 24px 12px; text-align: center; color: var(--fg-subtle); font-size: 12.5px; }
.tnode__row.thit { height: auto; flex-direction: column; align-items: flex-start; gap: 2px; padding: 7px 8px; }
.thit__head { display: flex; align-items: center; gap: 6px; width: 100%; }
.thit__kind {
  flex: none; font-size: 10px; font-weight: 700; color: var(--fg-subtle);
  border: 1px solid var(--bo-line-2); border-radius: 3px; padding: 0 5px; line-height: 15px;
}
.thit__path { color: var(--fg-subtle); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
/* 트리 제거 후 사이드바의 유일한 본문 — 전체 높이 사용 */
.treeside__common { padding: 10px 8px 16px; flex: 1 1 auto; overflow-y: auto; }

.tnode__row { display: flex; align-items: center; gap: 6px; height: 32px; padding: 0 8px; border-radius: 6px;
    cursor: pointer; color: var(--fg-muted); transition: background .12s, color .12s; }
.tnode__row:hover { background: var(--bo-side-2); color: var(--fg); }
.tnode__row.sel { background: #243247; color: var(--fg-strong); }
.tnode__caret { width: 16px; flex: none; display: inline-flex; align-items: center; justify-content: center; }
.tnode__caret::before { content: ""; width: 0; height: 0;
    border-left: 6px solid var(--fg-muted); border-top: 4px solid transparent; border-bottom: 4px solid transparent;
    transition: transform .12s; }
.tnode__row:hover .tnode__caret::before,
.tnode__row.sel .tnode__caret::before { border-left-color: var(--fg); }
.tnode__caret.on::before { transform: rotate(90deg); }
.tnode__row.leaf .tnode__caret { visibility: hidden; }
.tnode__nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13.5px; }
.tnode__tag { flex: none; margin-left: 6px; font-size: 10px; font-weight: 600; padding: 1px 6px; border-radius: 4px; }
.tnode__tag.g-m { background: rgba(50,133,255,.18); color: #7db4ff; }
.tnode__tag.g-r { background: rgba(166,180,197,.14); color: var(--fg-muted); }
.tnode__kids { margin-left: 14px; }
.cns-tabs {
  display: flex; align-items: center; gap: 4px; margin: 0 0 12px;
  border-bottom: 1px solid var(--bo-line);
}
.cns-tabs__button {
  position: relative; min-height: 40px; padding: 0 14px; color: var(--fg-muted);
  background: transparent; border: 0; font: inherit; font-size: 13px; cursor: pointer;
}
.cns-tabs__button:hover { color: var(--fg-strong); }
.cns-tabs__button.on { color: var(--fg-strong); font-weight: 600; }
.cns-tabs__button.on::after {
  content: ""; position: absolute; right: 12px; bottom: -1px; left: 12px;
  height: 2px; background: var(--cyan-bright); border-radius: 2px;
}
.cns-tabs__button:focus-visible { outline: 2px solid var(--cyan-bright); outline-offset: -2px; }
.cns-tab-panel[hidden] { display: none; }
.cns-empty { padding: 24px 8px; color: var(--fg-subtle); font-size: 13px; text-align: center; }


.cns-acc { margin-top: 18px; }
.cns-acc__h { font-size: 12px; color: var(--fg-muted); margin-bottom: 8px; }
.cns-acc__row { display: flex; align-items: center; gap: 10px; padding: 8px 6px; border-bottom: 1px solid var(--bo-line); cursor: pointer; border-radius: 6px; transition: background .1s; }
.cns-acc__row:hover { background: var(--bo-side-2); }
.cns-acc__row:last-child { border-bottom: none; }
.cns-acc__nm { font-size: 13.5px; color: var(--fg-strong); }
.cns-acc__id { font-size: 12.5px; color: var(--fg-subtle); }
.cns-acc__row .pill { margin-left: auto; }

/* 권한 편집 — 사업장별 관리/열람 토글 */
.auth-list { display: flex; flex-direction: column; max-height: 46vh; overflow-y: auto; }
.auth-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--bo-line); }
.auth-row:last-child { border-bottom: none; }
.auth-row__nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13.5px; color: var(--fg-strong); }
.seg { display: inline-flex; border: 1px solid var(--bo-line-2); border-radius: var(--radius-btn); overflow: hidden; flex: none; }
.seg__b { background: transparent; color: var(--fg-muted); border: none; padding: 4px 13px; font-size: 12.5px; cursor: pointer; line-height: 1.6; }
.seg__b + .seg__b { border-left: 1px solid var(--bo-line-2); }
.seg__b.on { background: var(--cyan-bright); color: #06202b; font-weight: 600; }
.seg__b:not(.on):hover { background: var(--bo-side-2); color: var(--fg); }

/* CCTV 보드 연동 API 키 */
.m2m-keyrow { display: flex; gap: 8px; align-items: center; }
.m2m-keyrow .inp { flex: 1; min-width: 0; background: rgba(120,138,160,.06); }

/* 구역 우측 카메라 목록 — 트리는 위치 탐색, 카메라는 선택 구역 안에서 관리 */
.cns-camera { min-width: 0; }
.cns-camera__head {
  display: flex; align-items: center; gap: 14px; min-height: 64px; padding: 12px 16px;
  border-bottom: 1px solid var(--bo-line-2); background: var(--bo-card-2);
}
.cns-camera__title { min-width: 0; }
.cns-camera__title h3 { margin: 0; color: var(--fg-strong); font-size: 15px; line-height: 1.35; }
.cns-camera__title p { margin: 3px 0 0; color: var(--fg-subtle); font-size: 12px; }
.cns-camera__count { margin-left: 5px; color: var(--cyan); font-variant-numeric: tabular-nums; }
.cns-camera__head-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; flex: none; }
.cns-camera__inspect,
.cns-camera__add {
  display: inline-flex; align-items: center; justify-content: center; height: 32px; padding: 0 12px;
  border-radius: 4px; font: inherit; font-size: 13px; font-weight: 500; white-space: nowrap;
  text-decoration: none; cursor: pointer;
}
.cns-camera__inspect { color: var(--fg-muted); background: transparent; border: 1px solid var(--line-btn); }
.cns-camera__inspect:hover { color: var(--fg-strong); background: rgba(255,255,255,.05); border-color: #a6b4c5; }
.cns-camera__add { color: #fff; background: var(--blue); border: 1px solid transparent; }
.cns-camera__add:hover { background: var(--blue-light); }
.cns-camera__inspect:focus-visible,
.cns-camera__add:focus-visible { outline: 2px solid var(--cyan-bright); outline-offset: 2px; }
.cns-camera__toolbar { padding: 12px 16px; border-bottom: 1px solid var(--bo-line); }
.cns-camera__input {
  display: block; width: min(420px, 100%); height: 36px; padding: 0 12px;
  color: var(--fg-strong); background: var(--bo-input); border: 1px solid var(--line-input);
  border-radius: 4px; font: inherit; font-size: 13.5px;
}
.cns-camera__input::placeholder { color: var(--fg-subtle); }
.cns-camera__input:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(50,133,255,.16); }
.cns-camera__input:disabled { opacity: .5; cursor: not-allowed; }
.cns-camera__rows { min-width: 0; }
.cns-camera__row {
  display: flex; align-items: stretch; width: 100%; min-width: 0;
  background: transparent; border-bottom: 1px solid var(--bo-line); transition: background .12s;
}
.cns-camera__row:last-child { border-bottom: 0; }
.cns-camera__row:hover { background: rgba(30,124,172,.16); }
.cns-camera__row[hidden] { display: none; }
.cns-camera__open {
  display: grid; grid-template-columns: minmax(150px, 1.15fr) auto minmax(130px, .8fr) minmax(150px, 1fr) 18px;
  align-items: center; gap: 14px; flex: 1; width: 100%; min-width: 0; min-height: 66px; padding: 10px 16px;
  color: var(--fg); background: transparent; border: 0; font: inherit; text-align: left; cursor: pointer;
}
.cns-camera__open:focus-visible { position: relative; z-index: 1; outline: 2px solid var(--cyan-bright); outline-offset: -2px; }
.cns-camera__actions {
  display: flex; align-items: center; justify-content: flex-end; flex: none; flex-wrap: wrap;
  gap: 7px; max-width: 214px; padding: 8px 12px 8px 4px;
}
.cns-camera__actions .btn-link { display: inline-flex; align-items: center; min-height: 30px; white-space: nowrap; }
.cns-camera__actions .contract-risk-row-badges {
  flex: 1 0 100%; justify-content: flex-end; min-width: 0; margin: 0;
}
.cns-camera__actions .contract-risk-row-badges:empty { display: none; }

/* CCTV operational alerts */
.cctv-operational-risk-summary {
  display: flex; align-items: center; gap: 6px; margin: 0 0 14px; padding: 10px 14px;
  border: 1px solid var(--bo-line); border-radius: 6px; background: var(--bo-card-2); color: var(--fg-muted);
}
.cctv-operational-risk-summary[hidden] { display: none; }
.cctv-operational-risk-summary strong { color: var(--fg-strong); }
.cns-camera__operational-risk:empty { display: none; }
.tbl [data-cctv-operational-risk-cell] { white-space: nowrap; }
.cns-camera__operational-risk {
  flex: 1 0 100%; justify-content: flex-end; min-width: 0; margin: 0;
}
.cns-camera__operational-risk .pill { text-decoration: none; }
/* End CCTV operational alerts */
/* CCTV ops board — CCTV 운영 현황 8칸 상황판 */
.cam-st { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; white-space: nowrap; }
.cam-st.ok { color: var(--fg-strong); }
.cam-st.err { color: var(--danger); font-weight: 600; }
.cam-st.off, .cam-st.other, .cam-st.unknown { color: var(--fg-muted); }
.cam-st.unknown .cam-st__ring { border-style: dashed; }
.cam-st__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--success); flex-shrink: 0; }
.cam-st.other .cam-st__dot { background: var(--fg-subtle); }
.cam-st__ring { width: 8px; height: 8px; border-radius: 50%; border: 1.5px solid var(--fg-subtle); background: transparent; flex-shrink: 0; }
.cam-st__warn { display: inline-grid; place-items: center; width: 14px; height: 14px; border-radius: 50%; background: var(--danger); color: var(--bo-card); font-size: 10px; font-weight: 700; flex-shrink: 0; }
.cctv-row-menu summary { list-style: none; cursor: pointer; padding: 2px 8px; border-radius: 4px; color: var(--fg-muted); }
.cctv-row-menu summary::-webkit-details-marker { display: none; }
.cctv-row-menu summary:hover, .cctv-row-menu[open] summary { background: var(--bo-card-2); color: var(--fg-strong); }
/* 목록은 .card(overflow:hidden) · .tbl-wrap(overflow-x:auto) 안이라 absolute 는 잘린다 — 행을 밀지 않게 화면 기준(fixed)으로 띄우고,
   자리는 cctv-global.html 스크립트가 ⋯ 버튼 아래로 잡는다. 스크립트 전에도 흐름을 밀지 않는다. */
.cctv-row-menu__list { position: fixed; z-index: 60; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 8px 10px; border: 1px solid var(--line-strong); border-radius: 6px; background: var(--surface-panel); box-shadow: var(--shadow-pop); white-space: nowrap; text-align: left; }
/* End CCTV ops board */
.cns-camera__move,
.cns-camera__end {
  align-self: center; flex: none; min-width: 48px; height: 30px; margin: 0; padding: 0 9px;
  background: transparent; border-radius: 4px; font: inherit; font-size: 12px; cursor: pointer;
}
.cns-camera__move { color: var(--cyan); border: 1px solid var(--cyan); }
.cns-camera__move:hover { color: #fff; background: var(--blue); border-color: var(--blue); }
.cns-camera__end { color: var(--danger); border: 1px solid var(--danger); }
.cns-camera__end:hover { color: #fff; background: var(--danger); }
.cns-camera__move:focus-visible,
.cns-camera__end:focus-visible { outline: 2px solid var(--cyan-bright); outline-offset: 2px; }
.cns-camera__identity,
.cns-camera__meta { display: flex; flex-direction: column; min-width: 0; gap: 3px; }
.cns-camera__identity strong,
.cns-camera__identity small,
.cns-camera__meta > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cns-camera__identity strong { color: var(--fg-strong); font-size: 13.5px; font-weight: 600; }
.cns-camera__identity small { color: var(--fg-subtle); font-size: 11.5px; }
.cns-camera__status { justify-self: start; }

/* 작업대 진입 화면(노드 미선택) — 조치 대상 + 전체 현황 */
.cns-home__actions { display: flex; flex-wrap: wrap; gap: 10px; }
.cns-home__action {
  display: flex; flex-direction: column; gap: 3px; min-width: 150px;
  padding: 14px 16px; border: 1px solid var(--bo-line-2); border-radius: 8px;
  background: var(--bo-side-2); color: var(--fg-muted); text-decoration: none;
  transition: border-color .14s, color .14s;
}
.cns-home__action:hover { border-color: var(--cyan); color: var(--fg); }
.cns-home__action strong { font-size: 26px; line-height: 1.1; color: var(--cyan); font-weight: 700; }
.cns-home__action span { font-size: 12.5px; }
.cns-home__clear { color: var(--fg-muted); font-size: 13.5px; margin: 0; }
.cns-home__stats { display: flex; flex-wrap: wrap; gap: 28px; margin-bottom: 14px; }
.cns-home__stats > div { display: flex; flex-direction: column; gap: 2px; }
.cns-home__stats span { font-size: 11px; font-weight: 600; letter-spacing: .04em; color: var(--fg-subtle); }
.cns-home__stats strong { font-size: 20px; color: var(--fg-strong); font-weight: 700; }
.cns-home__hint { color: var(--fg-subtle); font-size: 12.5px; margin: 0; }

/* 사용 안 함 처리된 행 — 운영 중인 행과 한눈에 구분되게 낮춘다. */
.tbl tr.row-off > td { opacity: .55; }
.cns-camera__meta { color: var(--fg-muted); font-size: 12.5px; }
.cns-camera__meta-label { color: var(--fg-subtle); font-size: 10.5px; font-weight: 600; text-transform: uppercase; }
.cns-camera__chevron { color: var(--fg-subtle); font-size: 21px; line-height: 1; }
.cns-camera__empty { padding: 44px 18px; color: var(--fg-subtle); font-size: 13px; text-align: center; }
.cns-camera__empty[hidden] { display: none; }
.cns-camera__sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.cns-camera-detail__nav {
  display: flex; align-items: center; gap: 10px; margin-bottom: 12px; color: var(--fg-subtle); font-size: 12px;
}
.cns-camera-detail__nav .btn-link { display: inline-flex; align-items: center; min-height: 30px; }

@media (max-width: 1100px) {
  .cns-camera__open { grid-template-columns: minmax(150px, 1fr) auto minmax(150px, 1fr) 18px; }
  .cns-camera__meta:nth-of-type(4) { display: none; }
}

@media (max-width: 760px) {
  .cns-camera__head { align-items: flex-start; flex-direction: column; }
  .cns-camera__head-actions { width: 100%; margin-left: 0; }
  .cns-camera__inspect, .cns-camera__add { flex: 1; }
  .cns-camera__input { width: 100%; }
  .cns-camera__open { grid-template-columns: minmax(0, 1fr) auto 14px; gap: 9px; }
  .cns-camera__meta { display: none; }
  .cns-camera__status .pill { padding: 3px 7px; }
  .cns-camera__actions { max-width: 116px; padding-left: 0; }
  .cns-camera-detail__nav > span { display: none; }
}

/* ===================================================================== */
/* COMMON FEEDBACK: TOAST / CONFIRM / BUSY                               */
/* ===================================================================== */
.bo-toast-region {
  position: fixed; top: 110px; right: 26px; z-index: 320;
  display: flex; flex-direction: column; align-items: flex-end; gap: 10px;
  width: min(420px, calc(100vw - 32px)); pointer-events: none;
}
.bo-toast {
  --bo-toast-accent: var(--blue);
  display: grid; grid-template-columns: 24px minmax(0, 1fr) auto 28px;
  align-items: center; gap: 10px; width: 100%; min-height: 52px; padding: 10px 10px 10px 13px;
  color: var(--fg-strong); background: var(--surface-panel); border: 1px solid var(--bo-line-2);
  border-left: 4px solid var(--bo-toast-accent); border-radius: 8px; box-shadow: var(--shadow-pop);
  pointer-events: auto; animation: bo-toast-in .2s ease-out both;
}
.bo-toast--success { --bo-toast-accent: var(--success); }
.bo-toast--warning { --bo-toast-accent: var(--orange); }
.bo-toast--error { --bo-toast-accent: var(--danger); }
.bo-toast__icon {
  display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%;
  color: var(--bo-toast-accent); background: rgba(50,133,255,.15);
  font-size: 13px; font-weight: 800; line-height: 1;
}
.bo-toast--success .bo-toast__icon { background: rgba(6,177,10,.15); }
.bo-toast--warning .bo-toast__icon { background: rgba(255,207,95,.15); }
.bo-toast--error .bo-toast__icon { background: rgba(255,83,83,.15); }
.bo-toast__message { min-width: 0; color: var(--fg-strong); font-size: 13.5px; line-height: 1.45; overflow-wrap: anywhere; }
.bo-toast__count { color: var(--fg-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.bo-toast__close {
  display: grid; place-items: center; width: 28px; height: 28px; padding: 0;
  color: var(--fg-muted); background: transparent; border: 0; border-radius: 4px;
  font-size: 20px; line-height: 1; cursor: pointer;
}
.bo-toast__close:hover { color: var(--fg-strong); background: rgba(255,255,255,.07); }
.bo-toast__close:focus-visible { outline: 2px solid var(--cyan-bright); outline-offset: 1px; }
.bo-toast--leaving { animation: bo-toast-out .16s ease-in both; }
@keyframes bo-toast-in { from { opacity: 0; transform: translateX(18px); } }
@keyframes bo-toast-out { to { opacity: 0; transform: translateX(18px); } }

body.bo-dialog-open { overflow: hidden; }
.bo-confirm-backdrop {
  position: fixed; inset: 0; z-index: 400; display: grid; place-items: center; padding: 24px;
  background: var(--scrim, rgba(0,0,0,.65)); backdrop-filter: blur(2px);
  animation: bo-confirm-backdrop-in .16s ease-out both;
}
.bo-confirm-dialog {
  width: min(440px, 100%); color: var(--fg); background: var(--surface-panel);
  border: 1px solid var(--bo-line-2); border-radius: 10px; box-shadow: var(--shadow-pop);
  animation: bo-confirm-dialog-in .18s ease-out both;
}
.bo-confirm__header { display: flex; align-items: center; gap: 12px; padding: 20px 20px 14px; }
.bo-confirm__mark {
  display: grid; place-items: center; flex: 0 0 34px; width: 34px; height: 34px; border-radius: 50%;
  color: #8fbaff; background: rgba(50,133,255,.16); font-size: 18px; font-weight: 800;
}
.bo-confirm-dialog--danger .bo-confirm__mark { color: #ff8585; background: rgba(255,83,83,.16); }
.bo-confirm__title { margin: 0; color: var(--fg-strong); font-size: 17px; font-weight: 700; line-height: 1.35; }
.bo-confirm__message { padding: 0 20px 20px 66px; color: var(--fg-muted); font-size: 14px; line-height: 1.6; white-space: pre-line; overflow-wrap: anywhere; }
.bo-confirm__actions {
  display: flex; justify-content: flex-end; gap: 10px; padding: 14px 20px;
  border-top: 1px solid var(--bo-line);
}
.bo-confirm__actions .btn:focus-visible { outline: 2px solid var(--cyan-bright); outline-offset: 2px; }
.bo-confirm-backdrop--leaving { animation: bo-confirm-backdrop-out .14s ease-in both; }
.bo-confirm-backdrop--leaving .bo-confirm-dialog { animation: bo-confirm-dialog-out .14s ease-in both; }
@keyframes bo-confirm-backdrop-in { from { opacity: 0; } }
@keyframes bo-confirm-backdrop-out { to { opacity: 0; } }
@keyframes bo-confirm-dialog-in { from { opacity: 0; transform: translateY(8px) scale(.98); } }
@keyframes bo-confirm-dialog-out { to { opacity: 0; transform: translateY(5px) scale(.99); } }

.bo-is-busy { cursor: wait !important; }
.bo-is-busy[aria-disabled="true"] { pointer-events: none; }
.bo-busy__content { display: inline-flex; align-items: center; justify-content: center; gap: 8px; }
.bo-busy__spinner {
  width: 14px; height: 14px; border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%; opacity: .85; animation: bo-busy-spin .7s linear infinite;
}
@keyframes bo-busy-spin { to { transform: rotate(360deg); } }

@media (max-width: 560px) {
  .bo-toast-region { top: 104px; right: 16px; left: 16px; width: auto; }
  .bo-confirm-backdrop { padding: 16px; }
  .bo-confirm__message { padding-left: 20px; }
}

@media (prefers-reduced-motion: reduce) {
  .bo-toast, .bo-toast--leaving,
  .bo-confirm-backdrop, .bo-confirm-dialog,
  .bo-confirm-backdrop--leaving, .bo-confirm-backdrop--leaving .bo-confirm-dialog {
    animation: none;
  }
  .bo-busy__spinner { animation: none; border-right-color: currentColor; opacity: .55; }
}

.modal > form { display: flex; flex-direction: column; min-height: 0; flex: 1; }

/* CCTV ops detail — CCTV 운영 상세(CCTV-02) */
.cctv-ops-tabs a { color: var(--fg-muted); font-size: 14px; font-weight: 500; padding: 12px 16px; position: relative; text-decoration: none; }
.cctv-ops-tabs a:hover { color: var(--fg); }
.cctv-ops-tabs a.on { color: var(--fg-strong); }
.cctv-ops-tabs a.on::after { content: ""; position: absolute; left: 12px; right: 12px; bottom: -1px; height: 2px; background: var(--cyan-bright); border-radius: 2px; }
.cctv-ops-core .stat { display: block; text-decoration: none; }
.cctv-ops-core .stat .s { margin-top: 8px; font-size: 12.5px; color: var(--fg-subtle); }
.cctv-ops-core a.stat:hover { border-color: var(--cyan); }
.cctv-ops-core .stat.is-disabled { opacity: .55; cursor: default; }
.cctv-ops-link { margin-left: auto; font-size: 12px; color: var(--cyan); }
.cctv-ops-summary { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
/* 두 요약 카드는 내용 길이와 상관없이 같은 높이 — 상세 보기 버튼을 바닥에 맞춘다 */
.cctv-ops-summary > .card { display: flex; flex-direction: column; margin-top: 0; }
.cctv-ops-summary > .card > .card__body { flex: 1; display: flex; flex-direction: column; }
.cctv-ops-summary__foot { margin-top: auto; padding-top: 12px; }
.cctv-ops-conn summary { list-style: none; display: inline-flex; cursor: pointer; }
.cctv-ops-conn summary::-webkit-details-marker { display: none; }
/* 상태 글자색 — pill 과 같은 색 */
.cctv-ops-detail .tone-blue { color: #7db4ff; }
.cctv-ops-detail .tone-amber { color: #ffd97a; }
.cctv-ops-detail .tone-red { color: #ff8585; }
.cctv-ops-detail .tone-purple { color: #c084fc; }
.cctv-ops-detail .tone-gray { color: var(--fg-muted); }
.cctv-ops-pills { display: flex; flex-wrap: wrap; gap: 6px; }
.cctv-ops-feats { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; }
.cctv-ops-feat { border: 1px solid var(--bo-line); border-radius: 8px; padding: 12px 14px; }
.cctv-ops-feat__head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; color: var(--fg-strong); }
.cctv-ops-hist { border-bottom: 1px solid var(--bo-line); }
.cctv-ops-hist summary { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding: 10px 0; cursor: pointer; list-style: none; }
.cctv-ops-hist summary::-webkit-details-marker { display: none; }
.cctv-ops-hist summary b { color: var(--fg-strong); font-weight: 500; }
.cctv-ops-hist .dl { padding: 0 0 12px 24px; }
/* End CCTV ops detail */
