/* ═══════════════════════════════════════════════════════════════
   AXON — 디자인 시스템

   DUNA GLIA 의 뼈대를 그대로 쓴다. 레이아웃(가운데 1180px 한 단 · 상단 알약 탭)과
   부품(카드 · 알약 · 표 · 상태 이름표)이 같아야 두 제품을 오가는 사람이 다시 배우지 않는다.

   ── 다른 것: 색 ──────────────────────────────────────────────
   GLIA 는 에메랄드/민트다. AXON 은 **인디고/바이올렛**이다.
   나란히 놓아도 다른 제품으로 읽히게, 색상환에서 가장 멀리 잡았다.

   ── 그대로 가져온 것: 상태 인코딩 ────────────────────────────
   사용자가 적록색약이다. 초록(정상)↔로즈(위반) 는 deutan 에서 갈리지 않는다.
     · 브랜드색(인디고·바이올렛)은 **조작**에만 쓴다. 상태 의미를 싣지 않는다.
     · 상태는 무채(정상) · 앰버(경고) · 적갈(위반) · 청록(오류)이고
       **언제나 글리프 + 라벨을 함께 단다.**

   ── 하나 옮긴 것: 오류색 ─────────────────────────────────────
   GLIA 의 오류색은 보라(#6E3FA0)였다. 여기서는 그것이 브랜드색과 겹친다 —
   보라 이름표가 「오류」인지 「강조」인지 알 수 없게 된다.

   처음에 청록(#0E6B72)으로 옮겼는데 **그것이 더 나빴다.** 청록은 deutan 에서
   채도를 잃고 무채색이 된다 — 「정상」 과 ΔE 2.5 로 붙어 버렸다.
   눈으로는 안 보이고 계산으로만 보였다(`tools/check_contrast.py`).

   지금은 **파랑**이다. 앰버가 노랑 쪽 끝이면 파랑이 반대쪽 끝이고,
   그 축은 적록색약에서도 살아 있다. 밝은 화면은 딥 네이비(#25327A),
   어두운 화면은 라이트 스카이(#7FD4FF) — 무채와 밝기로도 갈린다.
   ═══════════════════════════════════════════════════════════════ */

/* 글꼴은 DUNA CORE 와 같다 — SUITE. 굵기 일곱 벌을 다 싣는다.
   Light(300) 과 Heavy(900) 가 빠져 있으면 브라우저가 Regular 를 억지로
   늘리고 줄여 흉내 낸다(가짜 굵기). 파일은 이미 들어와 있었다. */
@font-face{font-family:'SUITE';src:url('fonts/suite/SUITE-Light.ttf') format('truetype');font-weight:300;font-display:swap}
@font-face{font-family:'SUITE';src:url('fonts/suite/SUITE-Regular.ttf') format('truetype');font-weight:400;font-display:swap}
@font-face{font-family:'SUITE';src:url('fonts/suite/SUITE-Medium.ttf') format('truetype');font-weight:500;font-display:swap}
@font-face{font-family:'SUITE';src:url('fonts/suite/SUITE-SemiBold.ttf') format('truetype');font-weight:600;font-display:swap}
@font-face{font-family:'SUITE';src:url('fonts/suite/SUITE-Bold.ttf') format('truetype');font-weight:700;font-display:swap}
@font-face{font-family:'SUITE';src:url('fonts/suite/SUITE-ExtraBold.ttf') format('truetype');font-weight:800;font-display:swap}
@font-face{font-family:'SUITE';src:url('fonts/suite/SUITE-Heavy.ttf') format('truetype');font-weight:900;font-display:swap}

:root{
  /* **바탕이 순백이고 카드가 옅다.** 카드는 «흰 종이» 가 아니라 흰 바탕 위에
     얹힌 아주 옅은 면이다. 차이는 4% 남짓이라 얼룩처럼 보이지 않고,
     테두리와 그림자가 나머지를 맡는다. */
  --bg:#FFFFFF; --bg-2:#F8F8FD;
  --surface:#F8F8FD; --surface-2:#EFEFF9;
  --ink:#141033; --dim:#494465; --faint:#6F6A8C;
  --line:rgba(20,16,51,.12); --line-2:rgba(20,16,51,.18);
  --indigo:#4B45C6; --indigo-ink:#3A35A3;
  --violet:#7C5BE0; --azure:#3E7FD4;
  --amber:#C2820B; --amber-ink:#8F5F06; --rose:#A8283A; --rose-ink:#8E1F2E;
  --indigo-soft:rgba(75,69,198,.10); --amber-soft:rgba(194,130,11,.12);
  --rose-soft:rgba(168,40,58,.10);
  --sky:#2C93C9; --sky-ink:#1B6D97; --sky-soft:rgba(44,147,201,.12);
  --shadow:0 1px 2px rgba(20,16,51,.06), 0 1px 1px rgba(20,16,51,.04);
  --shadow-sm:0 1px 2px rgba(20,16,51,.05);
  /* **SUITE 가 먼저다.** Pretendard 를 앞에 두면 그것이 깔린 자리에서만 글꼴이
     달라진다 — 같은 화면이 사람마다 다르게 보인다. DUNA CORE 와 같은 차례. */
  --font:'SUITE','Roboto',-apple-system,"Malgun Gothic",system-ui,sans-serif;
  --mono:'SFMono-Regular',ui-monospace,'Consolas','D2Coding',monospace;
  --r:16px; --r-sm:10px; --r-chip:6px;

  /* 브랜드색 위에 얹는 글자. **테마마다 다르다.**
     어두운 화면에서 브랜드는 밝은 라벤더가 된다 — 그 위에 흰 글자를 두면
     2.75:1 로 읽히지 않는다. 계산해 보기 전에는 몰랐다. */
  --on-brand:#FFFFFF;
  /* 배지 위에 얹는 글자. **앰버와 적갈이 다르다** — 앰버는 밝아서 어두운 글자,
     적갈은 어두워서 흰 글자다. 하나로 묶었더니 적갈 위가 2.67:1 이었다. */
  --on-amber:#1A1206; --on-rose:#FFFFFF;

  /* ── 상태 — 초록/빨강 쌍 없음 · 브랜드색과도 안 겹침 ── */
  --st-calm:#5F5B78;  --st-calm-bg:rgba(95,91,120,.10);
  --st-warn:#C2820B;  --st-warn-bg:var(--amber-soft);
  --st-fail:#A8283A;  --st-fail-bg:var(--rose-soft);
  --st-err:#25327A;   --st-err-bg:rgba(37,50,122,.10);
}

@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --bg:#0F0E1A; --bg-2:#151426;
  --surface:#17162A; --surface-2:#1E1C33;
  --ink:#EEEDF7; --dim:#BEBAD4; --faint:#918DAC;
  --line:rgba(238,237,247,.10); --line-2:rgba(238,237,247,.17);
  --indigo:#8B84F5; --indigo-ink:#ADA7FA;
  --violet:#A98BF0; --azure:#7FB0EE;
  --amber:#E0A93C; --amber-ink:#F0C577; --rose:#EE7286; --rose-ink:#F597A8;
  --indigo-soft:rgba(139,132,245,.16); --amber-soft:rgba(224,169,60,.14);
  --rose-soft:rgba(238,114,134,.14);
  --sky:#6BC5E8; --sky-ink:#9BDCF3; --sky-soft:rgba(107,197,232,.14);
  --shadow:0 1px 2px rgba(0,0,0,.5); --shadow-sm:0 1px 2px rgba(0,0,0,.4);
  --st-calm:#A6A1BE; --st-calm-bg:rgba(166,161,190,.13);
  --st-warn:#E0A93C; --st-warn-bg:var(--amber-soft);
  --st-fail:#EE7286; --st-fail-bg:var(--rose-soft);
  --st-err:#7FD4FF;  --st-err-bg:rgba(127,212,255,.14);
  --on-brand:#12102A; --on-amber:#1A1206; --on-rose:#2A0A10;
}}
:root[data-theme="dark"]{
  --bg:#0F0E1A; --bg-2:#151426;
  --surface:#17162A; --surface-2:#1E1C33;
  --ink:#EEEDF7; --dim:#BEBAD4; --faint:#918DAC;
  --line:rgba(238,237,247,.10); --line-2:rgba(238,237,247,.17);
  --indigo:#8B84F5; --indigo-ink:#ADA7FA;
  --violet:#A98BF0; --azure:#7FB0EE;
  --amber:#E0A93C; --amber-ink:#F0C577; --rose:#EE7286; --rose-ink:#F597A8;
  --indigo-soft:rgba(139,132,245,.16); --amber-soft:rgba(224,169,60,.14);
  --rose-soft:rgba(238,114,134,.14);
  --sky:#6BC5E8; --sky-ink:#9BDCF3; --sky-soft:rgba(107,197,232,.14);
  --shadow:0 1px 2px rgba(0,0,0,.5); --shadow-sm:0 1px 2px rgba(0,0,0,.4);
  --st-calm:#A6A1BE; --st-calm-bg:rgba(166,161,190,.13);
  --st-warn:#E0A93C; --st-warn-bg:var(--amber-soft);
  --st-fail:#EE7286; --st-fail-bg:var(--rose-soft);
  --st-err:#7FD4FF;  --st-err-bg:rgba(127,212,255,.14);
  --on-brand:#12102A; --on-amber:#1A1206; --on-rose:#2A0A10;

}

/* ── 호환 별칭 — 화면들이 쓰던 옛 이름을 잇는다.
      색은 이 파일 한 곳에서만 정한다. ─────────────────────────── */
:root{
  --primary:var(--indigo); --primary-d:var(--indigo-ink); --accent:var(--indigo);
  --accent-bg:var(--indigo-soft); --tint:var(--indigo-soft);
  --panel:var(--surface); --card:var(--surface); --canvas:var(--bg);
  --glass:var(--surface); --code-bg:var(--surface-2);
  --line-firm:var(--line-2); --ink2:var(--dim); --ink-soft:var(--dim);
  --ink-mute:var(--dim); --mut:var(--dim); --ink-faint:var(--faint);
  --shadow-1:var(--shadow); --sh-1:var(--shadow); --sh-2:var(--shadow);
  --sh-btn:0 8px 20px rgba(75,69,198,.26);
  --r-lg:var(--r); --r-md:var(--r-sm); --dot:var(--line-2);
  --head:#0F0B2B; --edge:var(--indigo);
  --pass:var(--st-calm); --calm:var(--st-calm); --calm-bg:var(--st-calm-bg);
  --ok:var(--st-calm); --warn:var(--st-warn); --warnc:var(--st-warn);
  --warn-bg:var(--st-warn-bg); --fail:var(--st-fail); --failc:var(--st-fail);
  --fail-bg:var(--st-fail-bg); --bad:var(--st-fail);
  --error:var(--st-err); --err:var(--st-err); --err-bg:var(--st-err-bg);
  --human:var(--dim); --human-bg:var(--surface-2);
  --info:var(--dim); --info-bg:var(--surface-2);
  --sans:var(--font);
}

*{box-sizing:border-box}

/* ── 글씨 크기 ──────────────────────────────────────────────────
   화면의 모든 글씨는 rem 이다. **여기 한 줄이 전체를 움직인다.**

   px 로 흩어져 있으면 「조금 키우자」 를 할 수가 없다. 실제로 그랬다 —
   본문은 15px 인데 나머지가 10.5~13.5px 로 눌려 있었고, 잘 안 보였다.

   비율은 안 건드린다. 12 와 15 의 관계가 흐트러지면 위계가 무너지고,
   그건 글씨가 작은 것보다 나쁘다. **똑같이 곱하기만 한다.**

   `--fs` 는 사람이 정한다 (머리 › 글씨 크기). 안 정했으면 «크게»(1.3) —
   본문이 19px 가 된다. 15px 은 한국어 화면에서 작다.

   **axon-ui.js 의 기본값과 같아야 한다.** CSS 는 글이 뜨기 전에 걸리고 JS 는
   그 뒤에 걸린다. 둘이 다르면 열 때마다 글씨가 한 번 튄다 — `type` 검사가 본다. */
:root{ --fs:1.3 }
html{height:100%;font-size:calc(16px * var(--fs))}
/* 높이를 100% 로 못 박지 않는다. 내용이 길면 페이지가 길어지고,
   브라우저 스크롤로 끝까지 볼 수 있어야 한다. */
body{margin:0;min-height:100%}
/* 셸(index.html) 안에 뜬 화면 — 틀이 제 내용에 맞춰지므로 높이를 잠그지 않는다 */
html.framed,html.framed body{height:auto;min-height:0}
body{font-family:var(--font);color:var(--ink);line-height:1.6;letter-spacing:-.006em;
  font-size:0.9375rem;-webkit-font-smoothing:antialiased;word-break:keep-all;
  background:var(--bg)}
a{color:inherit;text-decoration:none}
:focus-visible{outline:2px solid var(--indigo);outline-offset:2px}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}

/* ══ 그림 ═══════════════════════════════════════════════════════
   **그림은 이름 옆에 선다.** 이름을 대신하지 않는다 — 모양만으로 뜻을
   가르면 색이나 그림을 못 읽는 사람에게는 아무것도 안 남는다.
   currentColor 를 쓰므로 놓인 자리의 글자색을 그대로 따라간다. */
.gi{flex:0 0 auto;vertical-align:-0.18em;opacity:.72}
button:hover .gi,.navitem.active .gi{opacity:1}

/* ══ 셸 — 가운데 한 단 ═══════════════════════════════════════════ */
.app{max-width:1180px;margin:0 auto;padding:34px 28px 56px;
  display:flex;flex-direction:column;gap:26px;min-height:100%}

.hdr{display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap}
.brand{display:flex;align-items:center;gap:15px}
/* 로고는 원이다. flex 안에서 눌려 타원이 되지 않게 크기를 세 번 못 박는다. */
.orb{width:44px;height:44px;flex:0 0 44px;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle at 32% 28%,#A79FFF,var(--indigo) 60%,#332CA0);
  box-shadow:0 0 0 6px rgba(75,69,198,.10),0 8px 22px rgba(75,69,198,.30);
  animation:breathe 5s ease-in-out infinite}
@keyframes breathe{0%,100%{transform:scale(1)}50%{transform:scale(1.06)}}
@media (prefers-reduced-motion:reduce){.orb{animation:none}}
.brand h1{font-size:1.1875rem;font-weight:800;letter-spacing:-.02em;margin:0}
.brand .sub{font-size:0.75rem;color:var(--dim);margin-top:1px;letter-spacing:.01em}
.status{display:flex;align-items:center;gap:14px;flex-wrap:wrap}

.pill{display:inline-flex;align-items:center;gap:8px;font-size:0.75rem;font-weight:600;
  color:var(--indigo);background:var(--surface);padding:8px 14px;border-radius:100px;
  box-shadow:var(--shadow-sm)}
.pill.off,.pill.mut{color:var(--faint)}
.pill.calm{color:var(--st-calm)} .pill.warn{color:var(--st-warn)}
.pill.fail{color:var(--st-fail)} .pill.err{color:var(--st-err)}
.livedot{width:8px;height:8px;border-radius:50%;background:var(--indigo);
  animation:ping 2s infinite}
@keyframes ping{0%{box-shadow:0 0 0 0 rgba(75,69,198,.5)}
  70%{box-shadow:0 0 0 7px rgba(75,69,198,0)}100%{box-shadow:0 0 0 0 rgba(75,69,198,0)}}
.pill.off .livedot{background:var(--faint);animation:none}

/* ══ 탭 메뉴 — 상단 가로 알약 ════════════════════════════════════ */
.nav{display:flex;gap:9px;flex-wrap:wrap;row-gap:6px}
.navitem{border:none;background:var(--surface);color:var(--dim);font-weight:600;
  display:inline-flex;align-items:center;gap:7px;
  font-size:0.875rem;padding:11px 22px;border-radius:100px;cursor:pointer;
  box-shadow:var(--shadow-sm);display:flex;align-items:center;gap:9px;
  font-family:var(--font);transition:color .15s,transform .12s}
.navitem:hover{color:var(--ink);transform:translateY(-1px)}
.navitem.active{background:linear-gradient(180deg,var(--violet),var(--indigo));
  color:var(--on-brand);
  box-shadow:0 8px 20px rgba(75,69,198,.28)}
/* 배지 = **당신이 답해야 할 것**(사람 대기 큐). 봇이 일하는 중은 성격이 달라 점으로 따로 알린다. */
.navitem .nb{font-size:0.71875rem;background:var(--amber);color:var(--on-amber);
  border-radius:100px;
  padding:1px 8px;font-weight:700}
.navitem .nb.urgent{background:var(--rose);color:var(--on-rose)}
.navitem.active .nb{background:rgba(255,255,255,.32)}
.navrun{display:inline-block;width:7px;height:7px;border-radius:100px;
  background:var(--indigo);animation:ping 2s infinite}
.navitem.active .navrun{background:#fff;animation:none}
.navitem .soon{font-size:0.71875rem;color:var(--faint);font-weight:600}

/* ══ 카드 ═══════════════════════════════════════════════════════ */
.card{background:var(--surface);border-radius:var(--r);padding:22px 24px;
  box-shadow:var(--shadow);border:1px solid var(--line);margin-bottom:18px}
.card h2{font-size:0.9688rem;font-weight:700;margin:0 0 16px;color:var(--ink);
  letter-spacing:-.02em;display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.card h2 .msg{font-weight:500;font-size:0.7812rem;color:var(--dim)}
.card.flat{padding:16px 18px}

.sect{font-size:0.71875rem;letter-spacing:.12em;text-transform:uppercase;color:var(--indigo);
  font-weight:700;margin:22px 0 9px}

/* ══ 폼 ═══════════════════════════════════════════════════════ */
label{font-size:0.7188rem;color:var(--dim);display:block;margin-bottom:6px;font-weight:600}
input,textarea,select{font-family:var(--font);font-size:0.8438rem;color:var(--ink);
  background:var(--surface-2);border:1px solid var(--line-2);border-radius:var(--r-sm);
  padding:9px 12px;width:100%;outline:none;transition:border-color .15s,box-shadow .15s}
input::placeholder,textarea::placeholder{color:var(--faint)}
input:focus,textarea:focus,select:focus{border-color:var(--indigo);background:var(--surface);
  box-shadow:0 0 0 3px var(--indigo-soft)}
input:not([type=file]),select{height:38px;padding:0 12px}
input[type=checkbox],input[type=radio]{height:auto;width:auto;accent-color:var(--indigo)}
textarea{min-height:80px;resize:vertical;line-height:1.6;font-family:var(--mono);font-size:0.7812rem}
select{appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,var(--dim) 50%),
                   linear-gradient(135deg,var(--dim) 50%,transparent 50%);
  background-position:calc(100% - 16px) 50%,calc(100% - 11px) 50%;
  background-size:5px 5px,5px 5px;background-repeat:no-repeat;padding-right:34px}
.row{display:flex;gap:12px;align-items:flex-end;flex-wrap:wrap;margin:12px 0}
.row .grow{flex:1;min-width:180px}

/* ══ 버튼 — 알약. 초록은 조작이지 상태가 아니다 ══════════════════ */
button,.btn{background:linear-gradient(180deg,var(--violet),var(--indigo));
  color:var(--on-brand);
  border:none;border-radius:100px;padding:10px 20px;font-weight:700;font-size:0.8438rem;
  cursor:pointer;font-family:var(--font);display:inline-flex;align-items:center;
  justify-content:center;gap:7px;white-space:nowrap;box-shadow:0 6px 16px rgba(75,69,198,.22);
  transition:transform .12s,box-shadow .15s;letter-spacing:-.01em}
button:hover,.btn:hover{transform:translateY(-1px);box-shadow:0 10px 22px rgba(75,69,198,.3)}
button:active,.btn:active{transform:none}
button:disabled{opacity:.4;cursor:not-allowed;box-shadow:none;transform:none}
button.sec,.btn.sec{background:var(--surface);color:var(--indigo-ink);
  box-shadow:var(--shadow-sm);border:1px solid var(--line)}
button.sec:hover{border-color:var(--indigo)}
button.ghost{background:transparent;color:var(--dim);box-shadow:none;border:1px solid var(--line)}
button.ghost:hover{color:var(--ink);transform:none}
button.del,.btn.del{background:var(--surface);color:var(--rose-ink);
  border:1px solid var(--rose-soft);box-shadow:none}
button.del:hover{border-color:var(--rose)}
/* 기본 모양이 곧 으뜸 단추다. 그래도 이름을 준다 —
   화면이 «pri» 라고 적는데 그런 규칙이 없으면, 나중에 으뜸을 바꿀 때
   어디를 고쳐야 하는지 알 수 없다. */
button.pri,.btn.pri{background:linear-gradient(180deg,var(--violet),var(--indigo));
  color:var(--on-brand);border:none}
button.btn-sm,.btn.btn-sm{padding:7px 15px;font-size:0.7812rem}
button.sm{padding:5px 12px;font-size:0.75rem}

/* ── 카드처럼 쓰는 단추 ──────────────────────────────────────────
   기본 단추는 알약이다 — inline-flex 로 눕고, nowrap 이라 안 접힌다.
   그 안에 여러 줄을 넣으면 줄들이 **한 줄로 눕고 옆으로 밀린다.**
   실제로 현황 화면의 「담당 봇 여섯」 이 그렇게 밀렸다.

   카드로 쓸 단추는 알약 모양을 통째로 되돌린다. 되돌리는 자리를 여기
   한 곳에 둔다 — 화면마다 되돌리면 어느 화면은 잊는다. */
button.cardbtn,.btn.cardbtn{display:block;width:100%;text-align:left;
  white-space:normal;background:var(--surface);color:inherit;font-weight:400;
  letter-spacing:normal;border:1px solid var(--line);border-radius:var(--r-sm);
  box-shadow:none;padding:14px 16px;
  transition:border-color .15s,box-shadow .15s}
button.cardbtn:hover,.btn.cardbtn:hover{transform:none;box-shadow:var(--shadow);
  border-color:var(--indigo)}

.msg{font-size:0.8125rem;color:var(--dim);line-height:1.65}
.tag{display:inline-flex;align-items:center;gap:5px;background:var(--surface-2);
  color:var(--dim);font-size:0.71875rem;font-weight:600;padding:3px 10px;border-radius:100px;
  border:1px solid var(--line)}
.tag.mono{font-family:var(--mono);font-size:0.71875rem}
.tag.mut{color:var(--faint)}
.tag.calm{background:var(--st-calm-bg);color:var(--st-calm);border-color:transparent}
.tag.warn{background:var(--st-warn-bg);color:var(--st-warn);border-color:transparent}
.tag.fail{background:var(--st-fail-bg);color:var(--st-fail);border-color:transparent}
.tag.err {background:var(--st-err-bg); color:var(--st-err); border-color:transparent}
.tag.on  {background:var(--indigo-soft);  color:var(--indigo-ink);border-color:transparent}

/* ══ 표 ═══════════════════════════════════════════════════════ */
table{width:100%;border-collapse:collapse;font-size:0.8438rem}
th,td{border-bottom:1px solid var(--line);padding:11px 12px;text-align:left}
th{color:var(--dim);font-weight:700;font-size:0.71875rem;text-transform:uppercase;
  letter-spacing:.1em;padding-bottom:9px}
tbody tr:hover td{background:var(--surface-2)}
tr:last-child td{border-bottom:0}
table.tight th,table.tight td{padding:8px 10px;font-size:0.7812rem}

/* ══ 코드 ═════════════════════════════════════════════════════ */
code{font-family:var(--mono);font-size:.88em;background:var(--surface-2);
  border-radius:var(--r-chip);padding:.1em .4em}
pre{font-family:var(--mono);font-size:0.7812rem;line-height:1.6;background:var(--surface-2);
  border:1px solid var(--line);border-radius:var(--r-sm);padding:13px 15px;margin:0 0 16px;
  overflow-x:auto}
pre code{background:none;padding:0;font-size:inherit}

/* ══ 안내 상자 ════════════════════════════════════════════════ */
.note{border-left:3px solid var(--indigo);background:var(--indigo-soft);padding:12px 15px;
  border-radius:0 var(--r-sm) var(--r-sm) 0;font-size:0.8125rem;color:var(--ink);margin-bottom:16px}
.note b{color:var(--ink)}
.note.warn{border-left-color:var(--st-warn);background:var(--st-warn-bg)}
.note.fail{border-left-color:var(--st-fail);background:var(--st-fail-bg)}
.note.fail b{color:var(--st-fail)}

/* ══ 상태 — **글리프가 1차, 색은 보조** ═══════════════════════ */
.st{display:inline-flex;align-items:center;gap:6px;font-size:0.7812rem;font-weight:700}
.st .gl{width:19px;height:19px;border-radius:var(--r-chip);display:grid;place-items:center;
  font-size:0.71875rem;font-weight:800;border:1.5px solid currentColor;flex-shrink:0}
.st.calm{color:var(--st-calm)} .st.calm .gl{background:var(--st-calm-bg)}
.st.warn{color:var(--st-warn)} .st.warn .gl{background:var(--st-warn-bg)}
.st.fail{color:var(--st-fail)} .st.fail .gl{background:var(--st-fail-bg)}
.st.err {color:var(--st-err)}  .st.err  .gl{background:var(--st-err-bg);border-style:dashed}
.st.on  {color:var(--indigo-ink)} .st.on .gl{background:var(--indigo-soft)}

/* ══ 통계 타일 ════════════════════════════════════════════════ */
.tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px}
.tile{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-sm);
  padding:13px 15px}
.tile .k{font-size:0.71875rem;color:var(--dim);font-weight:700;letter-spacing:.04em}
.tile .v{font-size:1.4375rem;font-weight:800;line-height:1.2;margin-top:2px;
  font-variant-numeric:tabular-nums;letter-spacing:-.03em}
.tile .s{font-size:0.7188rem;color:var(--dim);margin-top:1px}
.tile.warn{border-color:var(--st-warn);background:var(--st-warn-bg)}
.tile.warn .v{color:var(--st-warn)}
.tile.fail{border-color:var(--st-fail);background:var(--st-fail-bg)}
.tile.fail .v{color:var(--st-fail)}

.empty{color:var(--faint);text-align:center;padding:44px 20px;font-size:0.8125rem}

@media (max-width:820px){
  .app{padding:20px 16px 44px;gap:18px}
  .navitem{padding:9px 15px;font-size:0.8125rem}
  .card{padding:16px 16px}
}

/* ══ 화면 안의 뼈대 ═════════════════════════════════════════════
   위 셸(index.html)이 화면 하나를 고르고, 화면 안은 이 뼈대를 쓴다.
   머리(수치) → 갈래(nav.tabs) → 거르개(filters) → 목록·상세(pane).
   화면마다 다시 짜면 같은 것이 조금씩 달라 보인다. 한곳에 둔다. */

/* 갈래 — 한 화면 안의 하위 탭. 위 알약과 모양을 달리해 구분한다. */
nav.tabs{display:flex;gap:2px;padding:0 26px;border-bottom:1px solid var(--line);
  background:var(--surface);overflow-x:auto;overflow-y:hidden;
  scrollbar-width:none}
nav.tabs::-webkit-scrollbar{display:none}
nav.tabs button{background:none;border:0;box-shadow:none;color:var(--dim);
  font-weight:600;font-size:0.8438rem;padding:11px 16px;border-radius:0;
  border-bottom:2px solid transparent;margin-bottom:-1px;white-space:nowrap}
nav.tabs button:hover{color:var(--ink);transform:none;box-shadow:none}
nav.tabs button[aria-selected="true"]{color:var(--ink);border-bottom-color:var(--indigo)}
nav.tabs .rt{margin-left:auto;display:flex;align-items:center;gap:8px;padding:6px 0}

/* 머리 — 이 화면이 다루는 것의 크기를 숫자로 먼저 말한다 */
.head{padding:14px 26px 11px;display:flex;align-items:center;gap:22px;flex-wrap:wrap;
  border-bottom:1px solid var(--line)}
.kpi{display:flex;flex-direction:column;font-size:0.71875rem;color:var(--dim);font-weight:700}
.kpi b{font-size:1.1875rem;color:var(--ink);font-weight:800;font-variant-numeric:tabular-nums;
  letter-spacing:-.03em}
.kpi.warn b{color:var(--st-warn)} .kpi.fail b{color:var(--st-fail)}
.kpi.err b{color:var(--st-err)} .kpi.calm b{color:var(--st-calm)}
.head .r{margin-left:auto;display:flex;gap:9px;align-items:center}

/* 거르개 */
.filters{display:flex;gap:8px;padding:11px 26px;flex-wrap:wrap;align-items:center;
  border-bottom:1px solid var(--line)}
.filters .lb{font-size:0.71875rem;letter-spacing:.11em;text-transform:uppercase;
  color:var(--dim);font-weight:800;margin-right:2px}
.chip{height:auto;box-shadow:none;background:var(--surface);color:var(--dim);
  border:1px solid var(--line-2);border-radius:100px;padding:5px 13px;font-size:0.7812rem;
  font-weight:600;transform:none}
.chip:hover{color:var(--ink);transform:none;box-shadow:none;background:var(--surface-2)}
.chip[aria-pressed="true"]{background:var(--indigo-soft);border-color:var(--indigo);
  color:var(--indigo-ink);box-shadow:none}
.filters input{width:210px;height:34px;border-radius:100px;font-size:0.7812rem}

/* 목록 · 상세 — 왼쪽에서 고르고 오른쪽에서 본다.
   높이를 화면에 묶지 않는다. 내용만큼 자라고, 넘치면 브라우저가 굴린다.
   안쪽에 스크롤 상자를 두면 볼 수 있는 것이 상자 크기에 갇힌다. */
.pane{display:grid;grid-template-columns:minmax(330px,1fr) minmax(420px,1.2fr);
  align-items:start}
.list{border-right:1px solid var(--line);padding:10px 0}
.detail{padding:22px 26px 48px;min-width:0}
/* 목록 한 줄 — 단추이지만 단추처럼 보이면 안 된다 */
.lrow{display:block;width:100%;text-align:left;background:none;border:0;border-radius:0;
  height:auto;box-shadow:none;color:inherit;font-weight:400;padding:12px 24px;
  border-left:3px solid transparent;cursor:pointer;font-family:var(--font)}
.lrow:hover{background:var(--surface-2);transform:none;box-shadow:none}
.lrow[aria-current="true"]{background:var(--surface-2);border-left-color:var(--indigo)}
.lrow .l1{display:flex;align-items:center;gap:9px;flex-wrap:wrap}
.lrow .l2{font-size:0.75rem;color:var(--dim);margin-top:3px;display:flex;gap:8px;
  align-items:center;flex-wrap:wrap}
.lrow .id{font-family:var(--mono);font-size:0.7812rem;font-weight:700;color:var(--ink)}
.lrow .rt{margin-left:auto;font-family:var(--mono);font-size:0.7812rem;font-weight:800;
  font-variant-numeric:tabular-nums}

/* 사실 격자 — 상세 위쪽에 놓는 「무엇인가」 */
.fg{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:13px 20px;
  background:var(--surface-2);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:15px 17px;margin-bottom:18px}
.fg .k{color:var(--dim);font-weight:700;font-size:0.71875rem;letter-spacing:.08em;
  text-transform:uppercase}
.fg .v{font-size:0.8438rem;color:var(--ink);margin-top:3px;overflow-wrap:anywhere;font-weight:600}
.fg .v.mono{font-family:var(--mono);font-size:0.7812rem;font-weight:400}

.dsect{font-size:0.71875rem;letter-spacing:.12em;text-transform:uppercase;color:var(--dim);
  font-weight:800;margin:24px 0 10px}
.dsect:first-child{margin-top:0}

@media (max-width:1000px){
  .pane{grid-template-columns:minmax(0,1fr)}
  .list{border-right:0;border-bottom:1px solid var(--line)} }

/* ══ 없을 때 쓰는 자리 ═════════════════════════════════════════
   지어낸 값으로 채우지 않는다. 없다고 말하고, 무엇을 하면 채워지는지 적는다. */
/* 빈 상태 상자는 **칸을 통째로 쓴다.**
   grid 나 flex 안에 그냥 넣으면 한 칸으로 끼어 찌그러진다 —
   「없습니다」 를 말하려다 더 못 읽게 만든다. */
.emptybox{padding:44px 24px;text-align:center;grid-column:1/-1;flex:1 1 100%}
/* 빈 화면이 글자만이면 «고장인가» 싶다. 동그라미 하나로 «자리는 있고
   아직 안 채워졌다» 를 먼저 말한다. */
.emptybox .ill{width:72px;height:72px;margin:0 auto 16px;border-radius:50%;
  display:grid;place-items:center;color:var(--faint);
  background:radial-gradient(circle at 38% 32%,var(--surface-2),transparent 72%);
  border:1px solid var(--line)}
.emptybox .ill .gi{opacity:.85}
.emptybox .t{font-size:1rem;font-weight:700;letter-spacing:-.02em;margin-bottom:8px}
.emptybox .d{font-size:0.8438rem;color:var(--dim);line-height:1.75;max-width:600px;
  margin:0 auto}
.emptybox .d.how{margin-top:9px}
.emptybox code{font-size:0.7812rem}

/* ══ 표본 띠 — 이 화면이 무엇을 보고 있나 ═══════════════════════
   실제가 아닌 것을 실제처럼 두지 않는다. 눈에 걸리게 만든다. */
.samplebar{display:flex;align-items:center;gap:9px;padding:9px 26px;
  background:var(--st-fail-bg);border-bottom:1px solid var(--st-fail);
  color:var(--ink);font-size:0.7812rem;line-height:1.55}
.samplebar .gl{width:19px;height:19px;border-radius:var(--r-chip);display:grid;
  place-items:center;font-size:0.71875rem;font-weight:800;color:var(--st-fail);
  border:1.5px solid currentColor;flex-shrink:0}
.samplebar b{color:var(--st-fail)}

/* ══ 팝업 — 무엇이 일어날지 먼저 보여 주고 묻는다 ═══════════════ */
.mask{position:fixed;inset:0;background:rgba(8,32,26,.42);z-index:80;
  display:grid;place-items:center;padding:24px;
  animation:maskin .14s ease-out}
@keyframes maskin{from{opacity:0}to{opacity:1}}
.modal{background:var(--surface);border-radius:var(--r);box-shadow:0 24px 60px rgba(11,45,38,.28);
  width:min(520px,100%);max-height:86vh;display:flex;flex-direction:column;overflow:hidden;
  animation:modalin .18s cubic-bezier(.2,.9,.3,1)}
@keyframes modalin{from{opacity:0;transform:translateY(10px) scale(.98)}to{opacity:1;transform:none}}
.modal .mh{padding:20px 24px 0}
.modal .mh h3{margin:0;font-size:1.125rem;font-weight:800;letter-spacing:-.02em}
.modal .mh p{margin:7px 0 0;font-size:0.8438rem;color:var(--dim);line-height:1.65}
.modal .mb{padding:16px 24px;overflow:auto;font-size:0.8438rem}
.modal .mb .steps{display:grid;gap:9px;margin:0}
.modal .mb .step{display:grid;grid-template-columns:26px minmax(0,1fr);gap:11px;align-items:start}
.modal .mb .step .no{width:22px;height:22px;border-radius:50%;background:var(--indigo-soft);
  color:var(--indigo-ink);font-size:0.71875rem;font-weight:800;display:grid;place-items:center}
.modal .mb .step b{font-weight:700}
.modal .mb .step div{color:var(--dim);font-size:0.7812rem;line-height:1.55}
.modal .mb dl{display:grid;grid-template-columns:88px minmax(0,1fr);gap:8px 14px;margin:16px 0 0;
  padding-top:14px;border-top:1px solid var(--line);font-size:0.8125rem}
.modal .mb dt{color:var(--dim);font-weight:600}
.modal .mb dd{margin:0;color:var(--ink)}
.modal .mf{padding:14px 24px 20px;display:flex;gap:9px;justify-content:flex-end;
  border-top:1px solid var(--line)}
.modal.wide{width:min(680px,100%)}
/* 결과 한 줄 — 잠깐 떴다 사라진다 */
.toast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%);z-index:90;
  background:var(--ink);color:var(--bg);padding:11px 20px;border-radius:100px;
  font-size:0.8125rem;font-weight:600;box-shadow:0 10px 30px rgba(11,45,38,.30);
  animation:toastin .2s cubic-bezier(.2,.9,.3,1)}
@keyframes toastin{from{opacity:0;transform:translate(-50%,10px)}to{opacity:1}}
@media (prefers-reduced-motion:reduce){
  .mask,.modal,.toast{animation:none} }

/* ── 마크다운 본문 ────────────────────────────────────────────────
   보고서(report.md)와 그림(diagrams.md)이 여기로 들어온다. 화면의 다른
   글과 같은 눈금(토큰)을 쓰되, 문서라는 것이 보이도록 여백을 넉넉히 준다. */
.md-body{font-size:0.875rem;line-height:1.8;color:var(--ink);max-width:74ch}
.md-body > *:first-child{margin-top:0}
.md-body h1,.md-body h2,.md-body h3,
.md-body h4,.md-body h5,.md-body h6{
  margin:26px 0 10px;line-height:1.35;letter-spacing:-.01em;font-weight:700}
.md-body h1{font-size:1.375rem;padding-bottom:9px;border-bottom:1px solid var(--line)}
.md-body h2{font-size:1.125rem}
.md-body h3{font-size:0.9688rem}
.md-body h4,.md-body h5,.md-body h6{font-size:0.875rem;color:var(--ink-soft)}
.md-body p{margin:0 0 13px}
.md-body ul,.md-body ol{margin:0 0 13px;padding-left:22px}
.md-body li{margin:3px 0}
.md-body li::marker{color:var(--ink-mute)}
.md-body strong{font-weight:700}
.md-body em{font-style:normal;color:var(--ink-soft);
  border-bottom:1px solid var(--line-firm)}
.md-body a{color:var(--accent);text-underline-offset:2px}
.md-body hr{border:0;border-top:1px solid var(--line);margin:22px 0}
.md-body blockquote{margin:0 0 13px;padding:9px 15px;
  border-left:3px solid var(--accent);background:var(--accent-bg);
  border-radius:0 var(--r-sm) var(--r-sm) 0;color:var(--ink-soft)}

.md-body code{font-family:var(--mono);font-size:.87em;
  background:var(--code-bg);border:1px solid var(--line);
  border-radius:3px;padding:1px 5px}

/* 코드 덩이 — 가로로 길면 그 안에서만 밀린다. 문서가 옆으로 밀리면 안 된다. */
.md-body pre.md-code,.md-body pre.mermaid{
  margin:0 0 15px;padding:13px 15px;background:var(--code-bg);
  border:1px solid var(--line);border-radius:var(--r-md);
  overflow-x:auto;font-family:var(--mono);font-size:0.7812rem;line-height:1.65;
  white-space:pre;color:var(--ink-soft)}
.md-body pre code{background:none;border:0;padding:0;font-size:inherit}
/* Mermaid 는 아직 그림으로 그리지 않는다. 원문임을 표시해 둔다 —
   그려 주는 척하면 안 그려진 것이 고장으로 보인다. */
.md-body pre.mermaid{border-style:dashed;position:relative;padding-top:26px}
.md-body pre.mermaid::before{content:"Mermaid 원문";position:absolute;
  top:6px;left:15px;font-size:0.71875rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-mute);font-weight:700}

/* 표 — 옆으로 긴 표는 감싼 칸 안에서만 밀린다 */
.md-body table.md-table{width:100%;border-collapse:collapse;
  margin:0 0 15px;font-size:0.8125rem;display:block;overflow-x:auto}
.md-body table.md-table th,.md-body table.md-table td{
  border-bottom:1px solid var(--line);padding:7px 11px;text-align:left;
  vertical-align:top;white-space:nowrap}
.md-body table.md-table th{font-size:0.71875rem;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-mute);font-weight:800;
  border-bottom:1px solid var(--line-firm)}
.md-body table.md-table td{font-variant-numeric:tabular-nums}
.md-body table.md-table tr:last-child td{border-bottom:0}
