/* 나리야 운영 대시보드 (BMC-111).
 *
 * 팔레트는 소개 사이트(nariweb/public/style.css)를 그대로 잇는다 — 같은 제품이고,
 * 두 벌을 들면 언젠가 한쪽만 고쳐진다. 다만 **밀도는 다르다**: 소개 사이트는 읽는
 * 화면이라 여백이 넓고, 여기는 훑는 화면이라 표가 촘촘하다. */
:root{
  --ink:#1d1d1b; --paper:#f7f7f5; --card:#ffffff; --sub:#6b6b68;
  --line:#e2e2df; --line-strong:#c9c9c4;
  --warn:#8a5a1f; --warn-bg:#f8f1e6;
  --ok:#2f6f45; --ok-bg:#e9f3ec;
  --bad:#a33a32; --bad-bg:#fbecea;
  --peak:#f0e3cd;
  --r:12px;
}
@media (prefers-color-scheme:dark){
  :root{
    --ink:#f2f2f0; --paper:#151513; --card:#1e1e1c; --sub:#a3a39f;
    --line:#2c2c29; --line-strong:#3d3d39;
    --warn:#e0b072; --warn-bg:#2a2118;
    --ok:#7fc79a; --ok-bg:#18251c;
    --bad:#e59a92; --bad-bg:#2a1a18;
    --peak:#332a1c;
  }
}
*{ box-sizing:border-box; }
body{ margin:0; background:var(--paper); color:var(--ink); font-size:14px; line-height:1.6;
  font-family:-apple-system,BlinkMacSystemFont,"Apple SD Gothic Neo","Noto Sans KR","Malgun Gothic",sans-serif;
  -webkit-font-smoothing:antialiased; }
a{ color:var(--ink); }
.mono{ font-variant-numeric:tabular-nums;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }

/* ── 상단바 ─────────────────────────────────────────────── */
.top{ background:var(--card); border-bottom:1px solid var(--line); }
.top .in{ max-width:1080px; margin:0 auto; padding:11px 22px; display:flex; align-items:center; gap:20px; }
.logo{ font-weight:600; letter-spacing:-.01em; }
.logo span{ color:var(--sub); font-weight:400; margin-left:7px; font-size:13px; }
.tabs{ display:flex; gap:2px; margin-left:6px; }
.tabs button{ font:inherit; color:var(--sub); background:none; border:0; cursor:pointer;
  padding:5px 11px; border-radius:8px; }
.tabs button[aria-selected="true"]{ background:var(--paper); color:var(--ink); font-weight:600; }
.who{ margin-left:auto; color:var(--sub); font-size:13px; }

.wrap{ max-width:1080px; margin:0 auto; padding:22px; }
h2{ font-size:15px; margin:26px 0 10px; letter-spacing:-.01em; }
h2:first-child{ margin-top:0; }
.hint{ color:var(--sub); font-size:12.5px; margin:-4px 0 10px; }

/* ── 카드·표 ────────────────────────────────────────────── */
.card{ background:var(--card); border:1px solid var(--line); border-radius:var(--r); padding:15px 17px; }
.grid{ display:grid; gap:11px; }
.g4{ grid-template-columns:repeat(4,1fr); }
.g3{ grid-template-columns:repeat(3,1fr); }
.g2{ grid-template-columns:1.4fr 1fr; }
@media (max-width:820px){ .g4,.g3,.g2{ grid-template-columns:1fr 1fr; } }
.kpi .l{ color:var(--sub); font-size:12.5px; }
.kpi .v{ font-size:23px; font-weight:600; letter-spacing:-.02em; margin-top:2px; }
.kpi .s{ color:var(--sub); font-size:12px; }

table{ width:100%; border-collapse:collapse; }
th,td{ text-align:left; padding:7px 9px; border-bottom:1px solid var(--line); vertical-align:middle; }
th{ color:var(--sub); font-weight:500; font-size:12.5px; }
tr:last-child td{ border-bottom:0; }
td.n,th.n{ text-align:right; }
tbody tr:hover{ background:var(--paper); }

/* ── 상태 배지 ──────────────────────────────────────────── */
.b{ display:inline-block; padding:1px 8px; border-radius:99px; font-size:12px; border:1px solid var(--line-strong); }
.b.ok{ background:var(--ok-bg); color:var(--ok); border-color:transparent; }
.b.warn{ background:var(--warn-bg); color:var(--warn); border-color:transparent; }
.b.bad{ background:var(--bad-bg); color:var(--bad); border-color:transparent; }

/* ── 세 창 게이지 ───────────────────────────────────────── */
.gauge{ margin:9px 0; }
.gauge .lbl{ display:flex; justify-content:space-between; font-size:12.5px; color:var(--sub); }
.gauge .bar{ height:7px; background:var(--paper); border:1px solid var(--line); border-radius:99px;
  overflow:hidden; margin-top:4px; }
.gauge .bar i{ display:block; height:100%; background:var(--ink); }
.gauge.hot .bar i{ background:var(--warn); }
.gauge.over .bar i{ background:var(--bad); }

/* ── 시간대 막대 ────────────────────────────────────────── */
.hours{ display:grid; grid-template-columns:repeat(24,1fr); gap:3px; align-items:end; height:120px; }
.hours .h{ position:relative; height:100%; display:flex; flex-direction:column; justify-content:flex-end; }
.hours .h.pk{ background:var(--peak); border-radius:4px 4px 0 0; }
.hours .h i{ display:block; background:var(--ink); border-radius:3px 3px 0 0; }
.hlabels{ display:grid; grid-template-columns:repeat(24,1fr); gap:3px; margin-top:5px;
  color:var(--sub); font-size:10px; text-align:center; }

/* ── 검색 ──────────────────────────────────────────────── */
.search{ display:flex; gap:9px; }
.search input{ flex:1; font:inherit; padding:11px 14px; border-radius:10px;
  border:1px solid var(--line-strong); background:var(--card); color:var(--ink); }
.search input:focus{ outline:2px solid var(--ink); outline-offset:-1px; }
.btn{ font:inherit; padding:10px 16px; border-radius:10px; border:1px solid var(--line-strong);
  background:var(--card); color:var(--ink); cursor:pointer; }
.btn.primary{ background:var(--ink); color:var(--paper); border-color:var(--ink); }
.btn.danger{ color:var(--bad); border-color:var(--bad); }

/* ── 로그인 ────────────────────────────────────────────── */
.login{ min-height:100vh; display:grid; grid-template-rows:1fr auto; }
.login .box{ align-self:center; width:100%; max-width:380px; margin:0 auto; padding:24px; }
.login h1{ font-size:20px; margin:0 0 4px; letter-spacing:-.02em; }
.login .sub{ color:var(--sub); font-size:13px; margin:0 0 20px; }
.login label{ display:block; font-size:12.5px; color:var(--sub); margin:12px 0 5px; }
.login input{ width:100%; font:inherit; padding:10px 13px; border-radius:10px;
  border:1px solid var(--line-strong); background:var(--card); color:var(--ink); }
.login .btn{ width:100%; margin-top:18px; padding:12px; }
.note{ color:var(--sub); font-size:12px; margin-top:14px; }

/* ── 공개 상태 블록 (로그인 화면 하단) ──────────────────── */
.status{ border-top:1px solid var(--line); background:var(--card); }
.status .in{ max-width:640px; margin:0 auto; padding:16px 24px 22px; }
.status h3{ font-size:12.5px; color:var(--sub); font-weight:500; margin:0 0 9px; }
.status .row{ display:flex; align-items:center; gap:9px; padding:6px 0; font-size:13px; }
.status .row .nm{ flex:1; }
.dot{ width:8px; height:8px; border-radius:99px; background:var(--ok); flex:none; }
.dot.warn{ background:var(--warn); } .dot.bad{ background:var(--bad); }
.dot.unk{ background:var(--line-strong); }
.status .when{ color:var(--sub); font-size:11.5px; margin-top:8px; }

/* ── 배선 뒤에 붙은 것들 (2026-09-02) ───────────────────
 *
 * 목업이 인라인 `style=` 로 하던 것을 클래스로 옮긴다. 이유는 취향이 아니라 CSP 다:
 * `style-src` 를 좁히려면 인라인 속성이 없어야 하고, 지금 남은 인라인은 승인된 목업
 * 문구에 붙은 몇 개뿐이라 `'unsafe-inline'` 을 아직 켜 두고 있다(main._hardening 주석).
 * 게이지 폭·막대 높이처럼 **값에 따라 변하는 것**은 JS 가 CSSOM 으로 준다 — 그쪽은
 * `style-src` 가 막지 않는다. */
.card.warn{ border-color:var(--warn); background:var(--warn-bg); }
.card.bad{ border-color:var(--bad); background:var(--bad-bg); }
.card + .card{ margin-top:11px; }
.warn-text{ color:var(--warn); }

#banner:not(:empty){ margin-bottom:16px; }

.who{ margin-left:auto; color:var(--sub); font-size:13px; display:flex; align-items:center; gap:9px; }
.linkish{ font:inherit; font-size:13px; color:var(--sub); background:none; border:0;
  padding:0; cursor:pointer; text-decoration:underline; }

/* 「못 읽었다」·「종단이 없다」를 그리는 판. **빈 칸이나 0 으로 그리지 않는다**는 규칙이
 * 눈에 보이는 자리가 여기다 — 두 상태를 다른 색으로 가르는 것도 같은 이유다(장애냐
 * 원래 없는 것이냐에 따라 사람이 갈 곳이 다르다). */
.na{ border:1px dashed var(--line-strong); border-radius:10px; padding:11px 13px;
  color:var(--sub); }
.na b{ color:var(--ink); font-size:13px; }
.na .hint{ margin:5px 0 0; }
.na.warn{ border-color:var(--warn); color:var(--warn); }
.na.warn b{ color:var(--warn); }
.na.bad{ border-color:var(--bad); }
.na.bad b{ color:var(--bad); }
.na-note{ color:var(--sub); font-size:11.5px; }

h3.sub{ font-size:12.5px; color:var(--sub); font-weight:500; margin:14px 0 6px; }
h3.sub:first-child{ margin-top:0; }

a.rowlink{ text-decoration:none; border-bottom:1px solid var(--line-strong); }
a.rowlink:hover{ border-bottom-color:var(--ink); }

.acts{ display:flex; gap:8px; margin-top:14px; flex-wrap:wrap; }
.btn.small{ padding:4px 10px; font-size:12.5px; border-radius:8px; }
.btn:disabled{ opacity:.45; cursor:not-allowed; }

.peaks{ margin-top:16px; }

/* ── 조치 확인 대화상자 ─────────────────────────────────
 * 조치마다 2차 인증 코드를 다시 받는 자리. 취소가 기본이 되도록 실행 버튼을 오른쪽에
 * 두고, 두 버튼의 색을 다르게 한다. */
dialog#act{ border:1px solid var(--line-strong); border-radius:var(--r); padding:20px 22px;
  background:var(--card); color:var(--ink); max-width:440px; width:calc(100% - 32px); }
dialog#act::backdrop{ background:rgba(0,0,0,.42); }
dialog#act h3{ font-size:15px; margin:0 0 6px; }
dialog#act label{ display:block; font-size:12.5px; color:var(--sub); margin:12px 0 5px; }
dialog#act label.chk{ display:flex; gap:7px; align-items:flex-start; margin-top:10px; }
dialog#act label.chk input{ width:auto; margin-top:3px; }
dialog#act input[type=text]{ width:100%; font:inherit; padding:9px 12px; border-radius:9px;
  border:1px solid var(--line-strong); background:var(--paper); color:var(--ink); }
dialog#act .sub{ color:var(--sub); font-weight:400; }
.act-err{ color:var(--bad); font-size:12.5px; margin:12px 0 0; }
.act-btns{ display:flex; gap:8px; justify-content:flex-end; margin-top:18px; }
