/* 사후관리 문서변환 워크벤치 — self-host(CSP default-src 'self'). inline style 없음.
 *
 * ★이 화면들이 하는 일★ 대시보드가 아니라 분류 데스크다. 변환 API 가 내보낸 결과에 "이상하다"는
 * 신고가 왔을 때 어느 건이 왜 틀렸는지 짚고, 새 서식을 승인한다. 그래서 모든 화면의 내용물은
 * 결국 **판정**이다 — 신뢰도, 검증 결과, 승인 여부.
 *
 * ★색 규칙(이 파일의 중심 결정)★ **색은 판정에만 쓴다.** 브랜드 색이 없다 — 링크는 먹색에
 * 밑줄, 주 버튼은 먹색 단색이다. 파란 링크를 두면 화면 곳곳에서 판정과 시선을 다투기 때문이다.
 * 이 규칙이 서면 화면에서 색이 있는 것은 전부 판정이고, 훑기만 해도 상태가 읽힌다.
 *
 * ★색을 칠하지 않는 것★ 건강구분(A·B·C1·C2·D1·D2·R)과 적합여부(가~라)에는 색을 주지 않는다.
 * 등급 토큰 **모양**은 공유하되 색은 먹색이다. 임상 분류에 표현 계층이 색 의미를 부여하면,
 * 코드 대신 색을 읽은 사람이 오독할 수 있다. 콘솔은 **자기 판정에만** 색을 쓴다.
 *
 * ★글꼴★ 산문은 고딕, 데이터는 모노. ID·신뢰도·인원·시각·코드는 전부 모노 + tabular-nums 라
 * 자릿수가 세로로 맞는다. 한글 명조 제목은 검토 후 버렸다 — 기기마다 설치 여부가 달라
 * 성격이 조건부로만 발현된다.
 */

/* ── 토큰 ──────────────────────────────────────────────────────────── */
:root {
  /* 종이와 먹 — 원본이 인쇄된 검진 결과표라는 사실에서 온다. */
  --paper:   #fbfbf9;
  --sheet:   #ffffff;
  --ink:     #16181d;
  --ink-2:   #4a4f5a;
  --ink-3:   #767c88;   /* 라벨·보조. 종이 위 대비 4.5:1 이상 */
  --rule:    #e6e5df;
  --rule-2:  #cfcec6;

  /* 판정 3단. 이 색들은 **콘솔 자신의 판정**에만 등장한다. */
  --pass:    #186b52;  --pass-bg: #e9f1ed;  --pass-line: #9cc4b3;
  --watch:   #8a5a12;  --watch-bg: #f8efdf;  --watch-line: #dcb679;
  --fail:    #a32b25;  --fail-bg: #f8e8e6;  --fail-line: #d8a09b;

  --font-ui:   "Pretendard", -apple-system, "Apple SD Gothic Neo", system-ui,
               "Noto Sans KR", "Malgun Gothic", sans-serif;
  --font-data: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --rail: 3px;         /* 등급 레일 두께 — 이 파일의 시그니처 */
  --control-h: 34px;   /* 모든 폼 컨트롤의 높이(아래 주석 참조) */
}

* { box-sizing: border-box; }
body { margin: 0; font-family: var(--font-ui); color: var(--ink); background: var(--paper);
       line-height: 1.55; -webkit-font-smoothing: antialiased; }

/* ── 상단바 ────────────────────────────────────────────────────────── */
/* 먹색 판. 네비 항목 8개는 성격이 셋이라(관측 / 처리 / 관리) 얇은 구분선으로 묶는다 —
   라벨을 붙이지 않아도 무리가 보인다. */
.topbar { display: flex; flex-wrap: wrap; align-items: center; gap: 14px;
          padding: 0 20px; background: var(--ink); color: #fff; }
.topbar .brand { display: inline-flex; align-items: center; height: 46px; color: #fff;
                 text-decoration: none; font-weight: 600; font-size: 14px;
                 letter-spacing: -.01em; }
.topbar .spacer { flex: 1; }
/* 역할 라벨은 '지금 누구로 보고 있는가' 라는 상태값이다 — 계기 글꼴로 낸다. */
.topbar .who { font-family: var(--font-data); font-size: 11px; letter-spacing: .08em;
               color: rgba(255,255,255,.62); }
.topbar .nav { display: flex; gap: 0; flex-wrap: wrap; min-width: 0; }
.topbar .nav a { position: relative; white-space: nowrap; color: rgba(255,255,255,.72);
                 text-decoration: none; font-size: 13.5px; padding: 14px 11px;
                 border-bottom: 2px solid transparent; }
.topbar .nav a:hover { color: #fff; }
/* 현재 화면은 밑줄로 알린다 — 알약 배경보다 조용하고, 표의 괘선 언어와 같은 계열이다. */
.topbar .nav a[aria-current="page"] { color: #fff; border-bottom-color: #fff; font-weight: 600; }
.topbar .nav a:focus-visible { outline: 2px solid #fff; outline-offset: -4px; border-radius: 3px; }
/* 네비 무리 구분선(관측 | 처리 | 관리). 템플릿이 group 이 바뀌는 첫 항목에 표시한다. */
.topbar .nav a.groupstart { margin-left: 11px; }
.topbar .nav a.groupstart::before { content: ""; position: absolute; left: -11px; top: 14px;
                                    bottom: 14px; width: 1px; background: rgba(255,255,255,.22); }

.inline { display: inline; margin: 0; }
/* 목록 화면이 9열까지 간다 — 1080 에서는 시각 열이 스크롤 밖으로 밀렸다. */
main { max-width: 1180px; margin: 0 auto; padding: 28px 20px 72px; }

/* ── 제목 줄 ───────────────────────────────────────────────────────── */
/* 이 줄이 타이포의 순간이다: 제목 + 전폭 괘선 + 오른쪽 끝에 계기 숫자.
   목록 화면 전부가 <h1>제목 <span class="count">N</span></h1> 모양이라 CSS 만으로 선다. */
h1 { display: flex; align-items: baseline; gap: 12px; font-size: 25px; font-weight: 600;
     letter-spacing: -.02em; margin: 0 0 18px; padding-bottom: 12px;
     border-bottom: 1px solid var(--rule-2); }
h1 .count { margin-left: auto; font-family: var(--font-data); font-size: 15px;
            font-weight: 500; color: var(--ink-3); font-variant-numeric: tabular-nums;
            background: none; padding: 0; border-radius: 0; min-width: 0; }
h2 { font-size: 15px; font-weight: 600; margin: 32px 0 10px; letter-spacing: -.01em; }
/* 절 제목 옆 계기 숫자도 제목 줄과 같은 글꼴로 읽는다(전폭 괘선은 h1 에만 둔다). */
h2 .count { margin-left: 4px; font-family: var(--font-data); font-size: 13px; font-weight: 500;
            color: var(--ink-3); font-variant-numeric: tabular-nums; }
h3 { font-size: 13px; font-weight: 600; margin: 14px 0 6px; color: var(--ink-2); }
/* 제목 옆 부속(큐의 '다음 태스크 받기')은 제목 줄 안에 산다. */
.queuehead { display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
              margin: 0 0 18px; padding-bottom: 12px; border-bottom: 1px solid var(--rule-2); }
.queuehead h1 { flex: 1; margin: 0; padding-bottom: 0; border-bottom: none; }

code { font-family: var(--font-data); font-size: .92em; padding: 1px 5px;
       background: #f1f0ec; border-radius: 3px; }
a { color: var(--ink); text-decoration: underline; text-underline-offset: 2px;
    text-decoration-color: var(--rule-2); text-decoration-thickness: 1px; }
a:hover { text-decoration-color: var(--ink); }
a:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; border-radius: 2px; }

/* ── 알림 ──────────────────────────────────────────────────────────── */
/* 판정색을 쓰는 자리다. 왼쪽 레일로 종류를 알려 색맹 조건에서도 위치가 남는다. */
.flash { padding: 11px 14px; margin: 0 0 18px; font-size: 13.5px;
         border: 1px solid var(--rule); border-left: var(--rail) solid var(--rule-2);
         border-radius: 0 4px 4px 0; background: var(--sheet); }
.flash-ok { background: var(--pass-bg); color: var(--pass);
            border-color: var(--pass-line); border-left-color: var(--pass); }
.flash-warn { background: var(--watch-bg); color: var(--watch);
              border-color: var(--watch-line); border-left-color: var(--watch); }

/* ── 조작부 ────────────────────────────────────────────────────────── */
/* ★높이를 정하지 여백을 정하지 않는다★ 필터 줄에는 텍스트 입력·날짜 입력·셀렉트·버튼·
   링크버튼이 한 줄에 나란히 선다. 각자 여백만 주면(input 7px, button 8px, .btn 5px) 거기에
   셀렉트와 날짜 입력의 **네이티브 여백**이 얹혀 높이가 5~10px 씩 어긋난다 — 브라우저마다
   그 값이 달라 여백을 아무리 맞춰도 정렬은 맞지 않는다. 그래서 공통 높이(--control-h)를
   정하고 세로 가운데 정렬만 시킨다. 여백은 가로축에만 준다. */
input, textarea, select, button, .btn {
  font: inherit; font-size: 13.5px; line-height: 1.2; color: var(--ink);
  background: var(--sheet); border: 1px solid var(--rule-2); border-radius: 4px; }
input, select, button, .btn { height: var(--control-h); padding: 0 10px; }
input, textarea { width: 100%; }
textarea { padding: 8px 10px; min-height: var(--control-h); }
/* 셀렉트는 내용에 따라 폭이 제각각이 된다(「전체」 vs 「UNSUPPORTED_FILE_TYPE」).
   아래위 한계를 줘서 한 줄에 섰을 때 들쭉날쭉하지 않게 한다. */
/* ★화살표를 직접 그린다★ 네이티브 화살표는 브라우저마다 다른 규칙으로 자리를 잡아 어떤
   곳에서는 테두리에 붙어 버린다 — padding 을 키워도 엔진에 따라 따라오지 않는다. 그래서
   appearance 를 끄고 우리가 그린다. 이미지가 아니라 **그라디언트 두 장**으로 그리는 이유는
   CSP(default-src 'self') 가 data: 이미지를 막기 때문이다(그라디언트는 fetch 가 아니라 통과).
   화살표 자리(오른쪽 14px)와 글자 여백(오른쪽 30px)이 이제 모든 브라우저에서 같다. */
select {
  width: auto; min-width: 118px; max-width: 220px;
  padding: 0 30px 0 10px;
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-3) 50%),
                    linear-gradient(135deg, var(--ink-3) 50%, transparent 50%);
  background-position: calc(100% - 19px) calc(50% + 1px), calc(100% - 14px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat; }
select:hover { background-image: linear-gradient(45deg, transparent 50%, var(--ink) 50%),
                                 linear-gradient(135deg, var(--ink) 50%, transparent 50%); }
select:disabled { background-image: linear-gradient(45deg, transparent 50%, var(--rule-2) 50%),
                                    linear-gradient(135deg, var(--rule-2) 50%, transparent 50%); }
button, .btn { display: inline-flex; align-items: center; justify-content: center;
               padding: 0 15px; cursor: pointer; white-space: nowrap; text-decoration: none; }
button:hover, .btn:hover { border-color: var(--ink); }
button.primary { background: var(--ink); border-color: var(--ink); color: #fff; font-weight: 600; }
button.primary:hover { background: #000; border-color: #000; }
/* ★.ghost 는 문맥이 둘이다★ 어두운 상단바(로그아웃)와 밝은 본문(교정 없이 종료·배정 해제).
   흰 글자로 고정돼 있어 본문에서는 흰 배경 위 흰 글자였다 — 보이지 않는 버튼이었다.
   기본은 본문 기준(먹색)으로 두고, 상단바에서만 흰색으로 되돌린다. */
button.ghost { background: transparent; color: var(--ink-2); }
button.ghost:hover { border-color: var(--ink); color: var(--ink); }
.topbar button.ghost { border-color: rgba(255,255,255,.34); color: #fff; height: 30px;
                       font-size: 12.5px; padding: 0 12px; }
.topbar button.ghost:hover { border-color: #fff; color: #fff; }
/* ★.btn 은 문맥이 둘이다★ 필터 줄·페이저에서는 옆의 <button> 과 나란히 서고(같은 높이여야
   한다), 표 안에서는 행 높이를 늘리면 안 된다. 기본을 컨트롤 높이로 두고 **표 안에서만**
   줄인다 — 일괄로 줄이면 「적용」 옆의 「초기화」가 혼자 작아진다. */
button.small, .grid .btn, .grid button { height: 28px; font-size: 12.5px; padding: 0 11px; }
.btn.disabled { color: var(--ink-3); border-color: var(--rule); pointer-events: none; }
button:focus-visible, .btn:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.topbar button:focus-visible { outline-color: #fff; }
input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: 2px solid var(--ink); outline-offset: -1px; border-color: var(--ink); }
input:disabled, textarea:disabled { background: #f1f0ec; color: var(--ink-3); }
/* 체크박스는 높이 규칙에서 뺀다 — 34px 짜리 체크박스는 컨트롤이 아니라 상자다. */
input[type=checkbox], input[type=radio] { width: auto; height: auto; padding: 0; }
/* 파일 선택은 내부 버튼을 브라우저가 그리므로 높이를 고정하지 않는다. */
input[type=file] { height: auto; width: auto; padding: 6px 8px; }
/* 입력이 곧 데이터인 칸(요청 ID·인증 코드)은 계기 글꼴로 받는다. */
input[name="q"], input[name="code"], .secret { font-family: var(--font-data); }

/* ── 인증 ──────────────────────────────────────────────────────────── */
.authbox { max-width: 380px; margin: 56px auto; }
.authbox h1 { border-bottom: none; padding-bottom: 0; }
.card { display: flex; flex-direction: column; gap: 13px; padding: 20px;
        background: var(--sheet); border: 1px solid var(--rule); border-radius: 6px; }
.card label { display: flex; flex-direction: column; gap: 5px; font-size: 12px;
              color: var(--ink-2); letter-spacing: .01em; }

/* ── 표 ────────────────────────────────────────────────────────────── */
/* 원본이 괘선 서식이라 표도 괘선으로 산다 — 바깥 테두리 대신 위아래 굵은 선, 행 사이 실선.
   교차 음영(스프레드시트 관습)은 쓰지 않는다. 행의 신분은 왼쪽 등급 레일이 말한다. */
.grid { width: 100%; border-collapse: collapse; background: var(--sheet); }
.grid thead th { text-align: left; padding: 8px 12px; font-size: 11.5px; font-weight: 600;
                 color: var(--ink-3); letter-spacing: .04em; background: none;
                 border-bottom: 1px solid var(--rule-2); white-space: nowrap; }
.grid td { text-align: left; padding: 11px 12px; font-size: 13.5px; vertical-align: top;
           border-bottom: 1px solid var(--rule); }
.grid tbody tr:last-child td { border-bottom: 1px solid var(--rule-2); }
.grid tbody tr:hover td { background: #f7f7f4; }
/* 표 안의 수치·식별자는 계기 글꼴 + 자릿수 고정. 세로로 자리가 맞아야 비교가 된다. */
.grid td.mono, .grid td.num, .mono { font-family: var(--font-data); font-size: 12.5px;
                                     font-variant-numeric: tabular-nums; }
/* 계기값(요청 ID·시각)은 접지 않는다 — 두 줄로 접히면 행 높이가 들쭉날쭉해 훑기가 깨진다.
   넘치면 표가 .tablewrap 안에서 가로로 스크롤한다(페이지가 아니라). */
.grid td.mono { white-space: nowrap; }
.grid td.num { text-align: right; }
.grid th.num { text-align: right; }
.tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ★시그니처 — 등급 레일★ 원본 문서 세계의 등급 체계에서 왔다. 목록을 읽지 않고 왼쪽
   가장자리만 훑어도 어디를 봐야 하는지 잡힌다.
   ★규칙: 손댈 일이 있는 행에만 단다★ 정상까지 칠하면 26행 감사 로그가 초록 띠 하나가 되어
   정보량이 0 이 되고, 정작 실패 한 줄이 그 안에 묻힌다. 정상은 아무 표시도 하지 않는 것이
   가장 강한 대비다 — 목록에 색이 있으면 그것이 곧 볼 곳이다. */
.grid tbody tr[class*="rail-"] td:first-child { border-left: var(--rail) solid transparent; }
.grid tbody tr.rail-pass  td:first-child { border-left-color: var(--pass); }
.grid tbody tr.rail-watch td:first-child { border-left-color: var(--watch); }
.grid tbody tr.rail-fail  td:first-child { border-left-color: var(--fail); }
.grid tbody tr.rail-none  td:first-child { border-left-color: var(--rule-2); }

/* 등급 토큰 — 건강구분·적합여부처럼 **분류값**을 담는 상자. 색은 주지 않는다(위 주석 참조). */
.grade { display: inline-block; min-width: 26px; padding: 1px 6px; text-align: center;
         font-family: var(--font-data); font-size: 12px; font-weight: 600;
         border: 1px solid var(--rule-2); border-radius: 3px; background: var(--paper); }

.empty { color: var(--ink-3); font-size: 13.5px; padding: 18px 0; }
/* 화면에서만 감추고 스크린리더에는 남긴다. 결측 마커 '—' 는 문장부호 상세도 설정에 따라
   **아무 소리도 나지 않는데**, 셀이 비어 있지도 않아 리더의 'blank' 폴백조차 뜨지 않는다. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
           overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
/* 결측 마커는 자리를 지키되 실제 값과 무게를 겨루지 않는다. */
.na { color: #a8adb6; }

/* ── 판정 표기 ─────────────────────────────────────────────────────── */
/* 색만으로 구분하지 않는다 — 항상 글자가 함께 간다. */
.ok   { color: var(--pass); font-weight: 600; }
.warn { color: var(--watch); font-weight: 600; }
.other { color: var(--watch); }
.mine { color: var(--pass); font-weight: 600; }
.sev { display: inline-block; padding: 1px 7px; font-size: 11.5px; font-weight: 600;
       border-radius: 3px; vertical-align: middle; }
.sev-err  { background: var(--fail-bg);  color: var(--fail); }
.sev-warn { background: var(--watch-bg); color: var(--watch); }
.sev-info { background: #eceae4; color: var(--ink-2); }
/* 분류 라벨(자동/LLM 등) — 판정이 아니므로 무채색. */
.tag { display: inline-block; white-space: nowrap; padding: 1px 7px;
       margin: 1px 3px 1px 0; font-size: 11.5px;
       font-family: var(--font-data); background: #eceae4; color: var(--ink-2);
       border-radius: 3px; }
.subtle { color: var(--ink-2); font-size: 12px; }
.hint { color: var(--ink-3); font-size: 13px; margin: 10px 0; }
.metacell { max-width: 340px; }
/* 감사 표는 행이 많다 — 상세 태그가 줄바꿈해도 행 높이가 튀지 않게 붙여 둔다. */
.metacell .tag { margin-bottom: 2px; }
/* ── 서식 승인 ──────────────────────────────────────────────────────
   ★목록은 훑을 수 있어야 한다★ 후보 하나가 10행 표라 예전에는 20건이면 8000px 였고, 다른
   열(출처·시각·처리)이 그 긴 칸 위쪽에 떠 있었다. 표 행이 아니라 **카드**로 바꾸고 요약 한
   줄을 앞세운다 — 깨끗한 후보는 펼치지 않고 승인까지 간다. */
.cand { margin: 0 0 12px; padding: 14px 16px 12px; background: var(--sheet);
        border: 1px solid var(--rule); border-left: var(--rail) solid var(--rule-2);
        border-radius: 0 6px 6px 0; }
/* 레일은 **가장 나쁜 판정**을 말한다 — 손댈 것이 있는 카드만 색이 붙는 규율 그대로. */
.cand-bad { border-left-color: var(--fail); }
.cand-warn { border-left-color: var(--watch); }
.cand-ok { border-left-color: var(--pass-line); }
.candhead { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px; }
.candlabel { margin: 0; font-size: 14.5px; font-weight: 600; letter-spacing: -.01em; }
.candmeta { font-size: 12px; color: var(--ink-3); }
.candhead .spacer { flex: 1; }
.candhead form { display: inline; margin: 0; }

/* 요약 한 줄 — 이 화면의 훑기 단위다. */
.roll { margin: 9px 0 0; font-size: 12.5px; color: var(--ink-2); }
.roll .rollnum { font-family: var(--font-data); font-weight: 600; color: var(--ink);
                 font-variant-numeric: tabular-nums; }
.roll .fit, .roll .na { margin-left: 2px; }

.mapdetail { margin: 10px 0 0; }
.mapdetail > summary { display: inline-block; padding: 3px 0; font-size: 12px;
                       color: var(--ink-3); cursor: pointer; text-decoration: underline;
                       text-underline-offset: 2px; }
.mapdetail > summary:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.mapdetail[open] > summary { color: var(--ink-2); }

/* 판단표. ★열 너비를 고정한다★ auto 레이아웃은 남는 폭을 첫 칸에 몰아줘, 표준 필드와 열
   번호 사이에 빈 벌판이 생겼다 — 한 행을 읽으려면 눈이 화면을 가로질러야 했다. 고정 폭이면
   다섯 칸이 카드마다 같은 자리에 서고(카드를 옮겨 다녀도 눈이 다시 찾지 않는다), 좁은
   화면에서는 페이지가 아니라 .tablewrap 이 가로로 스크롤한다. 폭은 colgroup 에 있다. */
/* ★표를 카드 폭까지 늘리지 않는다★ 다섯 칸 모두 내용이 짧아, 전폭으로 펴면 표준 필드와
   판정이 1200px 떨어져 한 행을 읽는 데 눈이 화면을 왕복한다. 읽기 좋은 길이에서 끊고 남는
   폭은 오른쪽에 버린다 — 빈 자리가 아깝지 않다, 눈이 움직이는 거리가 아깝다. */
.submap { border-collapse: collapse; table-layout: fixed; width: 100%;
          min-width: 620px; max-width: 900px; margin-top: 6px; }
.submap th { text-align: left; padding: 4px 10px 5px 0; font-size: 10.5px; font-weight: 600;
             color: var(--ink-3); letter-spacing: .03em; white-space: nowrap;
             border-bottom: 1px solid var(--rule); }
.submap td { padding: 6px 10px 6px 0; font-size: 12px; vertical-align: top;
             border-bottom: 1px solid var(--rule); }
.submap tr:last-child td { border-bottom: none; }
/* 가운데 정렬 칸은 좌우 여백이 같아야 한다 — 오른쪽에만 10px 이면 글자가 반 칸 왼쪽으로
   치우쳐, 머리글과 값이 미묘하게 어긋나 보인다. */
.submap th.mid, .submap td.mid { text-align: center; padding-left: 10px; }
/* 고정 폭에서는 nowrap 이 칸 밖으로 흘러넘친다 — 열 번호가 여럿이면 접어 넣는다. */
.submap td.mono { font-family: var(--font-data); font-size: 11.5px; }
.submap .tag { margin: 0 3px 2px 0; }
.submap .subtle { font-size: 11.5px; }
/* ★레일은 모든 행에 있고 매핑된 행에서만 투명하다★ 미매핑 행에만 border 를 주면 그 행만
   글자가 밀려 열이 어긋난다 — 표에서 가장 먼저 눈에 띄는 종류의 흐트러짐이다.
   머리글도 같은 만큼(레일 3px + 9px) 들여 써야 첫 칸이 위아래로 한 줄에 선다. */
.submap th.fieldname { padding-left: calc(var(--rail) + 9px); }
.submap td.fieldname { border-left: var(--rail) solid transparent; padding-left: 9px; }
.submap tr.unmapped td.fieldname { border-left-color: var(--watch); }
.submap tr.unmapped td { color: var(--ink-3); }

/* 적합도 판정 — 색만으로 구분하지 않는다(글자가 늘 함께 간다). */
.fit { display: inline-block; padding: 1px 6px; font-size: 11px; font-weight: 600;
       border-radius: 3px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.fit.ok { background: var(--pass-bg); color: var(--pass); }
.fit.warn { background: var(--watch-bg); color: var(--watch); }
.fit.bad { background: var(--fail-bg); color: var(--fail); }
/* 추천은 판정보다 한 단 조용하다 — 참고이지 결론이 아니다. */
.suggest { display: block; margin-top: 3px; font-size: 10.5px; color: var(--ink-3); }

/* ── 운영 현황 ─────────────────────────────────────────────────────── */
/* 숫자 카드 6개를 버렸다 — 지표마다 상자를 하나씩 주는 배치는 정보량이 가장 적다.
   대신 계기판처럼 한 줄에 늘어놓고 괘선으로만 나눈다. 숫자가 크고, 라벨은 작다. */
.readout { display: flex; flex-wrap: wrap; gap: 0; margin: 0 0 8px;
           border: 1px solid var(--rule); border-radius: 6px; background: var(--sheet);
           overflow: hidden; }
.readout div { flex: 1 1 150px; padding: 14px 16px; border-left: 1px solid var(--rule); }
.readout div:first-child { border-left: none; }
.readout .statlabel { display: block; font-size: 11.5px; color: var(--ink-3);
                      letter-spacing: .03em; margin-bottom: 3px; }
.readout strong { font-family: var(--font-data); font-size: 24px; font-weight: 600;
                  font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
/* 판정이 걸린 지표에만 색이 붙는다(열린 태스크가 0 이 아니면 처리할 일이 있다). */
.readout div.attn strong { color: var(--watch); }
.readout div.attn { background: var(--watch-bg); }

/* ── 필터 ──────────────────────────────────────────────────────────── */
.filters { display: flex; flex-wrap: wrap; align-items: end; gap: 12px 14px;
           margin: 0 0 20px; padding: 14px 16px; background: var(--sheet);
           border: 1px solid var(--rule); border-radius: 6px; }
.filters label { display: flex; flex-direction: column; gap: 4px; font-size: 11.5px;
                 color: var(--ink-3); letter-spacing: .03em; }
/* 조건이 걸렸을 때만 나오는 해제 링크. '적용'과 경쟁하지 않게 작고 낮은 채도로 둔다. */
.filters .clearfilter { align-self: center; margin-left: 2px; font-size: 12px;
                        color: var(--ink-3); }

/* ── 페이저 ────────────────────────────────────────────────────────── */
.pager { display: flex; align-items: center; gap: 12px; margin: 18px 0; }
.pager .pageinfo { color: var(--ink-3); font-size: 12.5px; font-family: var(--font-data);
                   font-variant-numeric: tabular-nums; }

/* ── 서식 승인 ─────────────────────────────────────────────────────── */
.grid .actioncol { white-space: nowrap; }
.grid .actioncol form + form { margin-left: 6px; }

/* ── 변환 테스트 ───────────────────────────────────────────────────── */
/* 드롭존: 입력 요소 **자체**를 영역 전체에 투명하게 깔면 클릭도 드래그앤드롭도 브라우저가
   네이티브로 처리한다. 선택 여부는 :valid 폴백이, 선택한 파일명은 convert.js 가 채운다 —
   그 값은 브라우저 안에만 머물고 서버로 돌아가지 않는다(파일명은 그 자체로 실명일 수 있다). */
.dropzone { position: relative; display: block; padding: 26px 20px; text-align: center;
            border: 1px dashed var(--rule-2); border-radius: 6px; background: var(--sheet);
            transition: border-color .12s, background .12s; }
.dropzone:hover { border-color: var(--ink-3); background: #fdfdfc; }
.dropzone:focus-within { border-color: var(--ink); outline: 2px solid var(--ink); outline-offset: 2px; }
/* 전역 input[type=file] 규칙보다 뒤에 와야 전면 오버레이가 유지된다. */
.dropzone input[type=file] { position: absolute; inset: 0; width: 100%; height: 100%;
                             opacity: 0; cursor: pointer; }
.dropzone .zonetitle { display: block; font-weight: 600; font-size: 14px; }
.dropzone .filename { overflow-wrap: anywhere; font-family: var(--font-data); font-size: 13px; }
.dropzone .zonehint { display: block; margin-top: 5px; color: var(--ink-3); font-size: 12.5px; }
.dropzone .chosen { display: none; }
.dropzone input[type=file]:valid ~ .prompt { display: none; }
.dropzone input[type=file]:valid ~ .chosen { display: block; color: var(--pass); font-weight: 600; }
.convertbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 14px 0 26px; }

/* 결과 요약 줄 — 서식·일치도·인원·검증을 한 눈에. 칩은 알약이 아니라 **계기 눈금**처럼
   각진 상자로, 숫자는 계기 글꼴로 낸다. */
.resultbar { display: flex; flex-wrap: wrap; gap: 6px; align-items: stretch; margin: 0 0 16px; }
.chip { display: inline-flex; align-items: center; gap: 6px; padding: 6px 11px; font-size: 12.5px;
        border: 1px solid var(--rule-2); border-radius: 4px; background: var(--sheet);
        color: var(--ink-2); }
.chip b { color: var(--ink); font-family: var(--font-data); font-weight: 600;
          font-variant-numeric: tabular-nums; font-size: 13px; }
.chip.ok { border-color: var(--pass-line); background: var(--pass-bg); color: var(--pass); }
.chip.ok b { color: var(--pass); }
.chip.warn { border-color: var(--watch-line); background: var(--watch-bg); color: var(--watch); }
.chip.warn b { color: var(--watch); }
/* 결과 줄의 유일한 행동. 판정색이 아니라 먹색이라 판정 칩들과 섞이지 않는다. */
a.chip.act { border-color: var(--ink); background: var(--ink); color: #fff;
             text-decoration: none; font-weight: 600; }
a.chip.act:hover { background: #000; }
a.chip.act:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.warnlist { margin: 0 0 18px; padding-left: 0; list-style: none; font-size: 12.5px;
            border-left: var(--rail) solid var(--watch-line); padding: 2px 0 2px 12px; }
.warnlist li { margin: 4px 0; color: var(--watch); }
.warnlist li.subtle { color: var(--ink-3); }
.issuelist { margin: 0 0 18px; padding-left: 0; list-style: none; font-size: 12.5px; }
.issuelist li { margin: 4px 0; }
.issuelist .sev { margin-right: 7px; }

/* 대체 다운로드 경로. 평소엔 접혀 있어 주 버튼과 경쟁하지 않고, 인라인을 못 실은 경우에만
   펼친 채로 열린다. */
.fallback { margin: 0 0 18px; font-size: 12.5px; }
.fallback > summary { display: inline-block; padding: 4px 0; color: var(--ink-3);
                      cursor: pointer; text-decoration: underline;
                      text-underline-offset: 2px; }
.fallback > summary:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.fallback[open] { padding: 13px 15px; background: var(--watch-bg);
                  border: 1px solid var(--watch-line); border-left: var(--rail) solid var(--watch);
                  border-radius: 0 4px 4px 0; }
.fallback[open] > summary { color: var(--watch); font-weight: 600; text-decoration: none; }
.fallback p { margin: 7px 0 9px; color: var(--ink-3); }
.fallback[open] p { color: var(--watch); }
.fallback input[type=file] { font-size: 12.5px; }

/* 검진소견·사후관리는 셀 안에서 줄바꿈으로 여러 건이 이어붙는다 — 줄바꿈을 살려야 원본과 대조된다. */
td.pre { white-space: pre-wrap; }
.notes { padding-left: 18px; color: var(--ink-2); font-size: 13.5px; }
.notes li { margin: 7px 0; }

/* ── 사용자 관리 ───────────────────────────────────────────────────── */
.newuser { margin: 0 0 22px; }
.newuser > summary { cursor: pointer; font-size: 13.5px; margin-bottom: 12px;
                     text-decoration: underline; text-underline-offset: 2px; }
.newuser > summary:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.newuser .card { max-width: 420px; }
fieldset.roles { border: 1px solid var(--rule); border-radius: 4px; padding: 8px 12px 10px; }
fieldset.roles legend { font-size: 11.5px; color: var(--ink-3); padding: 0 4px;
                        letter-spacing: .03em; }
label.check { display: inline-flex; flex-direction: row; align-items: center; gap: 5px;
              margin-right: 12px; font-size: 12.5px; color: var(--ink); }
label.check input { width: auto; }
.verifybtns { display: flex; gap: 8px; }

/* ── 상세(도시에) ──────────────────────────────────────────────────── */
.back { margin: 0 0 10px; font-size: 12.5px; }
/* 상세 머리의 메타는 '계기 판독'이다 — 라벨은 작고, 값은 계기 글꼴. */
.meta { display: grid; grid-template-columns: max-content 1fr; gap: 6px 20px; margin: 0 0 24px;
        padding: 14px 16px; background: var(--sheet); border: 1px solid var(--rule);
        border-radius: 6px; }
.meta dt { color: var(--ink-3); font-size: 11.5px; letter-spacing: .03em; align-self: center; }
/* 값 전체를 모노로 두면 '미배정'·'남성' 같은 **말**까지 계기값처럼 보인다.
   모노는 템플릿이 .mono 를 붙인 칸(식별자·해시)에만 적용한다. */
.meta dd { margin: 0; font-size: 13.5px; }
.meta dd.mono { font-variant-numeric: tabular-nums; }
.record { padding: 16px; margin: 0 0 14px; background: var(--sheet);
          border: 1px solid var(--rule); border-radius: 6px; }
.recmeta { color: var(--ink-3); font-size: 12.5px; margin: 0 0 10px;
           font-family: var(--font-data); }
.finding { padding: 12px 0; border-top: 1px solid var(--rule); }
.fieldform { display: grid; grid-template-columns: 120px 1fr max-content; gap: 8px;
             align-items: start; margin: 7px 0; }
.fieldlabel { color: var(--ink-2); font-size: 12.5px; padding-top: 8px; }
/* 검증이 지목한 필드 — 리뷰어가 어디를 봐야 하는지 화면이 말한다. */
.fieldlabel.flagged { color: var(--ink); font-weight: 600; }
.actions { display: flex; gap: 10px; margin: 24px 0; }
.actions form { margin: 0; }
.history { padding-left: 18px; color: var(--ink-2); font-size: 12.5px; }
.history .ver { color: var(--ink-3); font-family: var(--font-data); }

/* ── MFA 등록 ──────────────────────────────────────────────────────── */
.qr { display: flex; justify-content: center; padding: 14px; background: var(--sheet);
      border: 1px solid var(--rule); border-radius: 6px; }
.qr img { width: 200px; height: 200px; }
.secret { padding: 11px 12px; background: #f1f0ec; border-radius: 4px; text-align: center;
          letter-spacing: .12em; word-break: break-all; user-select: all; }

/* ── 품질 바닥 ─────────────────────────────────────────────────────── */
@media (max-width: 640px) {
  main { padding: 20px 14px 56px; }
  h1 { font-size: 21px; }
  .queuehead { flex-direction: column; }
  .readout div { flex-basis: 50%; }
}
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
