/* 국책 마스터 LS
 *
 * 업무용 밀도 우선. 장식보다 판독성.
 *
 * 하루 종일 들여다보는 화면이라 세 가지를 지킨다.
 *   1. 숫자가 세로로 딱 맞을 것 — 금액을 눈으로 대조하는 일이 많다
 *   2. 선을 줄이고 여백과 농도로 구분할 것 — 표 안에 표가 들어가면 선이 감옥이 된다
 *   3. 자주 하는 일은 늘 같은 자리에 — 전표 등록은 왼쪽 위, 검색은 위쪽 가운데
 *
 * 색은 토큰으로만 쓴다. 밝은 화면과 어두운 화면이 같은 규칙으로 돈다.
 * 주조색은 LS 계열의 파란색이다. 회사 CI 색 코드가 정해지면 --brand 만 바꾸면 된다.
 * 인터넷 없이 도는 프로그램이라 글꼴(Pretendard)을 프로그램에 함께 둔다.
 */

/* ---------- 글꼴 ---------- */

@font-face {
  font-family: "Pretendard NPJT"; font-weight: 400; font-display: swap;
  src: local("Pretendard Regular"), local("Pretendard-Regular"),
       url("/static/fonts/Pretendard-Regular.otf") format("opentype");
}
@font-face {
  font-family: "Pretendard NPJT"; font-weight: 500 600; font-display: swap;
  src: local("Pretendard SemiBold"), local("Pretendard-SemiBold"),
       url("/static/fonts/Pretendard-SemiBold.otf") format("opentype");
}
@font-face {
  font-family: "Pretendard NPJT"; font-weight: 700 800; font-display: swap;
  src: local("Pretendard Bold"), local("Pretendard-Bold"),
       url("/static/fonts/Pretendard-Bold.otf") format("opentype");
}

/* ---------- 토큰 ---------- */

:root {
  /* LS 파란색 — 주 단추, 선택된 메뉴, 강조 숫자 */
  --brand:        #0058a8;
  --brand-strong: #00468a;

  /* 바탕과 글자 — 중성색에 아주 옅은 청색을 섞었다. 회색만 쓰면 화면이 탁해진다 */
  --bg:          #f3f5f9;
  --surface:     #ffffff;
  --surface-2:   #f8fafc;
  --surface-3:   #eef2f7;
  --ink:         #0f1a2a;
  --ink-2:       #475569;
  --ink-3:       #8190a3;
  --line:        #e3e8ef;
  --line-strong: #cbd3de;

  /* 왼쪽 메뉴 — 두 화면 모두 짙은 남색 */
  --side:        #0b2140;
  --side-2:      #12305a;
  --side-ink:    #e9f0f9;
  --side-mute:   #8ea3c0;
  --side-line:   rgba(255, 255, 255, .09);

  --accent:      var(--brand);
  --on-accent:   #ffffff;
  --accent-soft: #e8f1fb;
  --accent-line: #c5daf1;

  /* 예전 이름 — 화면 몇 곳이 아직 쓴다 */
  --navy:        var(--side);
  --navy-2:      var(--side-2);
  --navy-ink:    var(--side-ink);
  --navy-mute:   var(--side-mute);

  /* 상태색 — 강조색과 별개로 둔다. 좋음/주의/위험은 뜻이 정해져 있다 */
  --ok:        #12704c;
  --ok-bg:     #e5f4ec;
  --ok-line:   #b3dcc6;
  --warn:      #8f5a07;
  --warn-bg:   #fdf3e1;
  --warn-line: #ebd0a0;
  --danger:      #b4271d;
  --danger-bg:   #fdeceb;
  --danger-line: #f0bcb7;

  /* 그림자 — 선 대신 깊이로 나눈다 */
  --shadow-1: 0 1px 2px rgba(15, 26, 42, .05);
  --shadow-2: 0 1px 2px rgba(15, 26, 42, .04), 0 6px 18px rgba(15, 26, 42, .07);
  --shadow-3: 0 20px 50px rgba(10, 20, 36, .24);

  --radius:    10px;
  --radius-sm: 7px;
  --radius-pill: 999px;

  --side-w: 236px;

  --mono: "Cascadia Mono", "JetBrains Mono", "D2Coding", Consolas, Menlo, monospace;
  --sans: "Pretendard NPJT", "Pretendard Variable", Pretendard, "Malgun Gothic", "맑은 고딕",
          -apple-system, "Segoe UI", system-ui, sans-serif;

  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --brand:        #5aa3e8;
    --brand-strong: #7db7ee;

    --bg:          #0c1219;
    --surface:     #141c26;
    --surface-2:   #18222e;
    --surface-3:   #1f2a37;
    --ink:         #e3eaf3;
    --ink-2:       #a3b0c0;
    --ink-3:       #708093;
    --line:        #26313e;
    --line-strong: #364353;

    --side:        #0a1420;
    --side-2:      #13243a;
    --side-ink:    #e3eaf3;
    --side-mute:   #7a8ca3;
    --side-line:   rgba(255, 255, 255, .07);

    --on-accent:   #08111b;
    --accent-soft: #15283d;
    --accent-line: #24415f;

    --ok:        #66c59f;
    --ok-bg:     #11271e;
    --ok-line:   #235441;
    --warn:      #d9a75a;
    --warn-bg:   #2a2316;
    --warn-line: #4d3e21;
    --danger:      #e68c82;
    --danger-bg:   #2c1816;
    --danger-line: #5b2f2a;

    --shadow-1: 0 1px 2px rgba(0, 0, 0, .35);
    --shadow-2: 0 1px 2px rgba(0, 0, 0, .35), 0 6px 18px rgba(0, 0, 0, .3);
    --shadow-3: 0 20px 50px rgba(0, 0, 0, .55);

    color-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --brand:        #5aa3e8;
  --brand-strong: #7db7ee;

  --bg:          #0c1219;
  --surface:     #141c26;
  --surface-2:   #18222e;
  --surface-3:   #1f2a37;
  --ink:         #e3eaf3;
  --ink-2:       #a3b0c0;
  --ink-3:       #708093;
  --line:        #26313e;
  --line-strong: #364353;

  --side:        #0a1420;
  --side-2:      #13243a;
  --side-ink:    #e3eaf3;
  --side-mute:   #7a8ca3;
  --side-line:   rgba(255, 255, 255, .07);

  --on-accent:   #08111b;
  --accent-soft: #15283d;
  --accent-line: #24415f;

  --ok:        #66c59f;
  --ok-bg:     #11271e;
  --ok-line:   #235441;
  --warn:      #d9a75a;
  --warn-bg:   #2a2316;
  --warn-line: #4d3e21;
  --danger:      #e68c82;
  --danger-bg:   #2c1816;
  --danger-line: #5b2f2a;

  --shadow-1: 0 1px 2px rgba(0, 0, 0, .35);
  --shadow-2: 0 1px 2px rgba(0, 0, 0, .35), 0 6px 18px rgba(0, 0, 0, .3);
  --shadow-3: 0 20px 50px rgba(0, 0, 0, .55);

  color-scheme: dark;
}

* { box-sizing: border-box; }

/* hidden 속성은 언제나 이긴다. .gate 의 display:flex 가 이겨서, 로그인한 뒤에도
   빈 덮개가 화면 전체를 가렸다. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* 금액이 세로로 맞아야 눈으로 대조가 된다 */
  font-variant-numeric: tabular-nums;
  letter-spacing: -.005em;
}

a { color: var(--accent); }
::selection { background: var(--accent-soft); color: var(--ink); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

.icon { flex-shrink: 0; vertical-align: -3px; }

kbd {
  font-family: var(--sans); font-size: 10.5px; font-weight: 600;
  padding: 1px 6px; border-radius: 5px;
  border: 1px solid var(--line-strong); color: var(--ink-3);
  background: var(--surface-2);
}

/* ---------- 틀 — 왼쪽 메뉴 + 오른쪽 작업 영역 ---------- */

.sidebar {
  position: fixed; left: 0; top: 0; bottom: 0; z-index: 40;
  width: var(--side-w);
  display: flex; flex-direction: column;
  /* 도면 모눈 — 로그인 화면의 도면과 같은 말. 거의 안 보일 만큼만 */
  background:
    linear-gradient(rgba(156, 195, 236, .035) 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(90deg, rgba(156, 195, 236, .035) 1px, transparent 1px) 0 0 / 24px 24px,
    var(--side);
  color: var(--side-ink);
  border-right: 1px solid var(--side-line);
}
.workspace { margin-left: var(--side-w); min-height: 100vh; display: flex; flex-direction: column; }

.brand {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 18px 12px;
}
.brand-mark {
  display: grid; place-items: center;
  width: 30px; height: 30px; border-radius: 8px;
  background: linear-gradient(140deg, #2f86d6, #0058a8 60%, #003f7d);
  color: #fff; font-weight: 800; font-size: 12.5px; letter-spacing: -.3px;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .18);
}
.brand-text { font-weight: 700; font-size: 15.5px; letter-spacing: -.3px; }
.brand-ver {
  margin-left: auto;
  font-size: 10px; color: var(--side-mute); font-family: var(--mono);
  padding: 1px 6px;
  border: 1px solid var(--side-line); border-radius: var(--radius-pill);
}
.brand-ver.ver-stale { background: var(--danger); color: #fff; border-color: var(--danger); }

.context {
  margin: 0 12px 12px; padding: 10px;
  display: grid; gap: 8px;
  background: rgba(255, 255, 255, .045);
  border: 1px solid var(--side-line);
  border-radius: var(--radius);
}
.context label { display: grid; gap: 3px; }
.context label > span {
  font-size: 10.5px; font-weight: 600; color: var(--side-mute); letter-spacing: .04em;
}
.context select {
  width: 100%;
  background: rgba(255, 255, 255, .07);
  color: var(--side-ink);
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: var(--radius-sm);
  padding: 6px 8px; font-size: 12.5px; font-family: inherit;
  text-overflow: ellipsis;
}
.context select:hover { background: rgba(255, 255, 255, .11); }
.context select:focus { border-color: var(--brand); box-shadow: none; }
.context select option { color: #16191d; background: #fff; }

.sidebar-new {
  margin: 0 12px 10px; justify-content: center;
  padding: 8px 12px; font-size: 13px;
}
.sidebar-new kbd {
  margin-left: auto; color: rgba(255, 255, 255, .8);
  background: rgba(255, 255, 255, .14); border-color: rgba(255, 255, 255, .22);
}

.side-nav { flex: 1; overflow-y: auto; padding: 4px 10px 12px; scrollbar-width: thin; }
.nav-group { margin-top: 6px; }
.nav-label {
  padding: 4px 10px; font-size: 10.5px; font-weight: 700;
  color: var(--side-mute); letter-spacing: .06em;
}
.side-nav button {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 6px 10px; margin: 1px 0;
  border: 0; border-radius: var(--radius-sm);
  background: none; color: rgba(233, 240, 249, .82);
  font-family: inherit; font-size: 13.5px; text-align: left;
  cursor: pointer; position: relative;
  transition: background .12s, color .12s;
}
.side-nav button .icon { opacity: .8; }
.side-nav button:hover { background: rgba(255, 255, 255, .06); color: #fff; }
.side-nav button.active {
  background: rgba(90, 163, 232, .16); color: #fff; font-weight: 600;
}
.side-nav button.active .icon { opacity: 1; color: #7fbaf0; }
.side-nav button.active::before {
  content: ""; position: absolute; left: -10px; top: 7px; bottom: 7px; width: 3px;
  border-radius: 0 3px 3px 0; background: #5aa3e8;
}

.sidebar-foot {
  display: flex; align-items: flex-end; gap: 8px;
  padding: 12px; border-top: 1px solid var(--side-line);
}

.theme-toggle {
  flex-shrink: 0;
  border: 1px solid var(--side-line);
  background: rgba(255, 255, 255, .05);
  color: var(--side-ink);
  width: 32px; height: 32px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  display: grid; place-items: center;
  transition: background .12s;
}
.theme-toggle:hover { background: rgba(255, 255, 255, .12); }

.topbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: 12px;
  height: 58px; padding: 0 28px;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
.topbar-search {
  position: relative; display: flex; align-items: center;
  width: min(440px, 100%);
}
.topbar-search .search-icon { position: absolute; left: 11px; color: var(--ink-3); display: flex; }
.topbar-search input[type=search] {
  width: 100%;
  padding: 8px 64px 8px 36px; font-size: 13px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
}
.topbar-search kbd { position: absolute; right: 9px; pointer-events: none; }
.topbar-actions { margin-left: auto; display: flex; gap: 8px; align-items: center; }
/* 과제 캘린더 — 월 보기 */
.cal-card header { gap: 6px; }
.cal-title { min-width: 92px; text-align: center; font-size: 14px; }
.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); border-top: 1px solid var(--line); border-left: 1px solid var(--line); }
.cal-head { padding: 6px 8px; font-size: 12px; color: var(--ink-3); border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); background: var(--surface-3); }
.cal-cell { min-height: 92px; padding: 4px 5px 6px; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cal-cell.blank { background: var(--surface-3); opacity: .5; }
.cal-head.weekend, .cal-cell.weekend .cal-day { color: var(--danger); }
.cal-cell.today { background: var(--accent-soft); }
.cal-day { font-size: 12px; font-weight: 600; color: var(--ink-2); }
.cal-ev { display: block; width: 100%; text-align: left; border: 0; border-left: 3px solid var(--c); background: color-mix(in srgb, var(--c) 12%, transparent);
  color: var(--ink-1, inherit); border-radius: 4px; padding: 2px 5px; font-size: 11.5px; line-height: 1.35; cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-ev:hover { background: color-mix(in srgb, var(--c) 22%, transparent); }
.cal-ev.done { opacity: .5; }
.cal-ev.late { outline: 1px solid var(--danger); }
.cal-more { font-size: 11px; color: var(--ink-3); padding-left: 4px; }
.cal-list { display: none; }
.cal-row { display: flex; gap: 8px; align-items: center; padding: 3px 0; }
.cal-row .cal-ev { width: auto; flex: 1; }
.cal-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 10px; font-size: 12px; }
.cal-legend i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 4px; }
@media (max-width: 760px) { .cal-grid { display: none; } .cal-list { display: block; } }

/* 알림 — 종과 펼친 목록 */
.alert-btn { position: relative; padding-left: 10px; padding-right: 10px; }
.alert-btn .voc-count { margin-left: 4px; }
.alert-btn.has-danger [data-icon] { color: var(--danger); }
.alert-panel {
  position: fixed; top: 58px; right: 16px; z-index: 60; width: min(420px, calc(100vw - 32px)); max-height: 70vh;
  display: flex; flex-direction: column; background: var(--surface); border: 1px solid var(--line);
  border-radius: 12px; box-shadow: var(--shadow-2); overflow: hidden;
}
.alert-panel header, .alert-panel footer { display: flex; align-items: center; gap: 8px; padding: 10px 14px; font-size: 13px; }
.alert-panel header { border-bottom: 1px solid var(--line); }
.alert-panel footer { border-top: 1px solid var(--line); font-size: 12px; }
.alert-panel .spacer { flex: 1; }
.alert-panel ul { list-style: none; margin: 0; padding: 0; overflow-y: auto; }
.alert-panel li { padding: 10px 14px 10px 16px; border-bottom: 1px solid var(--line); cursor: pointer; border-left: 3px solid transparent; }
.alert-panel li:hover { background: var(--surface-2, var(--surface-3)); }
.alert-panel li.lvl-danger { border-left-color: var(--danger); }
.alert-panel li.lvl-warn { border-left-color: var(--warn); }
.alert-panel li.lvl-info { border-left-color: var(--accent); }
.alert-panel .t { font-weight: 600; font-size: 13.5px; }
.alert-panel .d { color: var(--ink-3); font-size: 12px; margin-top: 2px; }
.alert-panel .empty { padding: 24px; text-align: center; }
.digest { list-style: none; margin: 0 0 10px; padding: 0; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.digest li { padding: 9px 12px; border-bottom: 1px solid var(--line); border-left: 3px solid var(--accent); cursor: pointer; }
.digest li:last-child { border-bottom: 0; }
.digest li:hover { background: var(--surface-3); }
.digest li.lvl-danger { border-left-color: var(--danger); }
.digest li.lvl-warn { border-left-color: var(--warn); }
.digest .t { font-weight: 600; font-size: 13.5px; }
.digest .d { color: var(--ink-3); font-size: 12px; margin-top: 2px; }

/* 상시평가 — 흐름 단계와 부가세 복원 막대 */
.flow-steps { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; font-size: 12px; }
.flow-step { padding: 2px 8px; border-radius: 10px; border: 1px solid var(--line); color: var(--ink-3); white-space: nowrap; }
.flow-step.done { color: var(--ok); border-color: var(--ok-line); background: var(--ok-bg); }
.flow-step.now { color: #fff; background: var(--accent); border-color: var(--accent); font-weight: 700; }
.flow-arrow { color: var(--ink-3); }
.flow-bar { display: flex; height: 16px; border-radius: 8px; overflow: hidden; gap: 2px; background: var(--surface-3); }
.flow-bar span { min-width: 3px; }
.flow-legend { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: 10px; font-size: 13px; }
.flow-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 5px; vertical-align: -1px; }
.policy-row { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center; }
.policy-row label { display: inline-flex; align-items: center; gap: 6px; }
.rv-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 10px; }
.rv-items textarea { width: 100%; min-width: 260px; }
/* 의견 보내기 — 새 의견(관리자)·새 답(누구나) 수 */
.voc-count {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px; font-size: 11px; font-weight: 700;
  line-height: 18px; text-align: center; background: var(--danger); color: #fff;
}

main { padding: 26px 28px 64px; width: 100%; max-width: 1600px; }

/* 위치 표시 — 도면 표제란처럼 작고 단정하게. 앞의 짧은 선은 치수선 끝 */
.crumb {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  padding: 18px 28px 0; max-width: 1600px;
  font-size: 12px; color: var(--ink-3); letter-spacing: .01em;
}
.crumb:empty { display: none; }
.crumb::before { content: ""; width: 14px; height: 1px; background: var(--line-strong); }
.crumb b { color: var(--ink-2); font-weight: 600; }
.crumb-sep { color: var(--line-strong); }
.crumb-code { font-family: var(--mono); font-size: 11.5px; color: var(--ink-2); }
.crumb:not(:empty) + main { padding-top: 10px; }

/* ---------- 표제 ---------- */

h1 {
  font-size: 24px; font-weight: 800;
  margin: 0 0 5px; letter-spacing: -.02em;
  text-wrap: balance;
}
h3 { letter-spacing: -.2px; }
.subtitle {
  color: var(--ink-3); font-size: 13px;
  margin: 0 0 22px; max-width: 90ch;
}

/* ---------- 카드 ---------- */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  margin-bottom: 18px;
  overflow: hidden;
}
.card > header {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 13px 18px;
  border-bottom: 1px solid var(--line);
}
.card > header h2 {
  margin: 0; font-size: 14px; font-weight: 700; letter-spacing: -.2px;
}
.card > header .spacer { margin-left: auto; }
.card-body { padding: 18px; }
.card-body.flush { padding: 0; }

/* ---------- 단추 ---------- */

.btn {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink);
  border-radius: var(--radius-sm);
  padding: 6px 13px; min-height: 32px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  transition: background .12s, border-color .12s, box-shadow .12s, color .12s;
}
.btn:hover { background: var(--surface-2); border-color: var(--ink-3); }
.btn:active { transform: translateY(.5px); }

.btn-primary {
  background: var(--accent); border-color: var(--accent);
  color: var(--on-accent);
  box-shadow: 0 1px 2px rgba(0, 70, 138, .25);
}
.btn-primary:hover { background: var(--brand-strong); border-color: var(--brand-strong); }

.btn-ghost { background: transparent; border-color: transparent; color: var(--ink-2); }
.btn-ghost:hover { background: var(--surface-3); border-color: transparent; color: var(--ink); }

.btn-danger { color: var(--danger); border-color: var(--danger-line); }
.btn-danger:hover { background: var(--danger-bg); border-color: var(--danger); }
/* 표 줄마다 붙는 작은 삭제 단추는 평소엔 조용히 — 줄마다 빨간 테두리가 숫자보다 먼저 눈에 띄었다. 손을 대면 빨갛게 */
td .btn-sm.btn-danger { color: var(--ink-3); border-color: transparent; background: transparent; }
td .btn-sm.btn-danger:hover, td .btn-sm.btn-danger:focus-visible { color: var(--danger); border-color: var(--danger-line); background: var(--danger-bg); }

.btn-sm { padding: 3px 10px; min-height: 27px; font-size: 12px; }
.btn:disabled { opacity: .45; cursor: not-allowed; }

/* ---------- 입력 ---------- */

/* type 을 안 적은 입력칸도 글자 칸이다 — 빠뜨리면 로그인의 사번 칸만 좁게 나왔다 */
input:not([type]), input[type=text], input[type=number], input[type=date], input[type=search],
input[type=password], select, textarea {
  font-family: inherit;
  font-size: 13px;
  padding: 7px 10px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  width: 100%;
  transition: border-color .12s, box-shadow .12s;
}
input::placeholder, textarea::placeholder { color: var(--ink-3); }
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
input[type=checkbox] { accent-color: var(--accent); width: 15px; height: 15px; }
textarea { line-height: 1.6; resize: vertical; }

label.field { display: block; margin-bottom: 14px; }
label.field > span {
  display: block; font-size: 12px; color: var(--ink-2);
  margin-bottom: 5px; font-weight: 600;
}

.num {
  text-align: right;
  font-variant-numeric: tabular-nums; font-size: 12.5px;
}

/* ---------- 표 ---------- */

table { width: 100%; border-collapse: collapse; font-size: 13px; }
th, td {
  padding: 9px 12px;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: middle;
}
thead th {
  background: var(--surface-2);
  font-size: 11.5px; font-weight: 600; color: var(--ink-3);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 1;
  white-space: nowrap;
}
tbody tr { transition: background .1s; }
tbody tr:hover > td { background: var(--surface-2); }
tbody tr:last-child > td { border-bottom: 0; }
/* 숫자에 코딩용 고정폭 글꼴을 쓰지 않는다.
   Cascadia Mono 는 글자 사이가 넓어 금액이 벌어져 보인다. 자릿수를 세로로 맞추는 건
   tabular-nums 만으로 된다 — Pretendard 의 tabular 숫자는 0~9 가 모두 같은 폭이다. */
td.num, th.num {
  text-align: right;
  font-variant-numeric: tabular-nums; font-size: 13px;
}
tfoot td {
  background: var(--surface-2);
  border-top: 1px solid var(--line-strong);
  border-bottom: 0;
  font-weight: 700;
}
.table-scroll { overflow: auto; max-height: 68vh; }

tr.row-category > td { background: var(--surface-3); font-weight: 700; }
tr.row-category:hover > td { background: var(--surface-3); }
tr.row-total > td {
  background: var(--surface-3); font-weight: 700;
  border-top: 1px solid var(--line-strong);
}
tr.row-warn > td { background: var(--danger-bg); }
tr.is-selected > td { background: var(--accent-soft); }
tr.row-dup > td { background: var(--danger-bg); }
tr.fy-row > td { background: var(--surface); }
tr.fy-row:hover > td { background: var(--accent-soft); }
tr.row-muted > td { opacity: .55; }
tr.row-click { cursor: pointer; }
/* 긴 메모는 두 줄까지 — 다 보려면 마우스를 올린다(title) */
.clamp-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* 키보드로 옮겨 온 줄 — 마우스를 올린 것과 같은 색 + 테두리 */
tr.row-click:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
tr.row-click:focus-visible > td { background: var(--accent-soft); }
.alert-panel li:focus-visible, .digest li:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
tr.row-click:hover > td { background: var(--accent-soft); }

.muted { color: var(--ink-3); }
.nowrap { white-space: nowrap; }

/* ---------- 배지 ---------- */

.badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  font-size: 11.5px; font-weight: 600; white-space: nowrap;
  border: 1px solid transparent;
}
.badge-등록      { background: var(--surface-3); color: var(--ink-2); border-color: var(--line); }
.badge-이체요청   { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-line); }
.badge-대체완료   { background: var(--ok-bg); color: var(--ok); border-color: var(--ok-line); }
.badge-정산확인   { background: var(--ok-bg); color: var(--ok); border-color: var(--ok-line); }
.badge-취소      { background: var(--surface-3); color: var(--ink-3); text-decoration: line-through; }
.badge-warn     { background: var(--warn-bg); color: var(--warn); border-color: var(--warn-line); }
.badge-danger   { background: var(--danger-bg); color: var(--danger); border-color: var(--danger-line); }

/* 상태 배지를 누르면 바로 바꾼다 — 수정 창을 열지 않아도 된다 */
button.status-pick {
  font-family: inherit; cursor: pointer;
  transition: box-shadow .12s, transform .12s;
}
button.status-pick::after { content: "▾"; font-size: 9px; opacity: .6; margin-left: 1px; }
button.status-pick:hover { box-shadow: 0 0 0 3px var(--accent-soft); }

.popmenu {
  position: fixed; z-index: 450; min-width: 168px;
  padding: 5px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-3);
}
.popmenu-title { padding: 5px 9px 6px; font-size: 11px; color: var(--ink-3); font-weight: 600; }
.popmenu button {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px 9px; border: 0; border-radius: var(--radius-sm);
  background: none; color: var(--ink); font: inherit; font-size: 13px;
  cursor: pointer; text-align: left;
}
.popmenu button:hover { background: var(--surface-2); }
.popmenu button .badge { pointer-events: none; }
.popmenu .popmenu-note { margin-left: auto; font-size: 11px; color: var(--ink-3); }

/* ---------- 알림 ---------- */

/* 알림은 흰 바탕에 왼쪽 상태색 띠 — 빨간 상자가 겹겹이 쌓이면 화면 전체가 경보처럼 보여 정작 무엇이 급한지 묻힌다.
   제목만 상태색, 본문은 보통 글자색으로 읽힌다 */
.notice {
  display: flex; gap: 11px; align-items: flex-start;
  padding: 12px 16px 12px 15px;
  border-radius: var(--radius);
  border: 1px solid var(--line); border-left: 4px solid var(--ink-3);
  background: var(--surface); color: var(--ink-2); box-shadow: var(--shadow-1);
  font-size: 13px; margin-bottom: 14px;
}
.notice-warn   { border-left-color: var(--warn); }
.notice-danger { border-left-color: var(--danger); background: linear-gradient(90deg, var(--danger-bg), var(--surface) 38%); }
.notice-ok     { border-left-color: var(--ok); }
.notice-info   { border-left-color: var(--accent); }
.notice-warn strong   { color: var(--warn); }
.notice-danger strong { color: var(--danger); }
.notice-ok strong     { color: var(--ok); }
.notice-info strong   { color: var(--accent); }
.notice strong { display: block; margin-bottom: 3px; }
.notice ul { margin: 6px 0 0; padding-left: 18px; }
.notice li { margin-bottom: 2px; }

/* ---------- KPI ---------- */

.kpi-grid {
  /* 넓은 화면에서 네 칸 — 카드 7장이 5+2 로 어색하게 갈리지 않게 */
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px; margin-bottom: 20px;
}
.kpi {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  padding: 16px 18px;
  position: relative; overflow: hidden;
}
.kpi .label {
  font-size: 12px; color: var(--ink-3); margin-bottom: 8px; font-weight: 600;
}
.kpi .value {
  font-size: 24px; font-weight: 700;
  letter-spacing: -.5px; line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.kpi .sub { font-size: 12px; color: var(--ink-3); margin-top: 6px; }
/* 위쪽 색 띠로 성격을 표시한다. 카드 전체를 물들이면 화면이 시끄러워진다 */
.kpi.accent::before, .kpi.warn::before, .kpi.danger::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px;
}
.kpi.accent::before { background: var(--accent); }
.kpi.warn::before   { background: var(--warn); }
.kpi.danger::before { background: var(--danger); }
.kpi.danger .value  { color: var(--danger); }

#kpi-checks, #kpi-auditor { cursor: pointer; transition: box-shadow .14s, transform .14s; }
#kpi-checks:hover, #kpi-auditor:hover { box-shadow: var(--shadow-2); transform: translateY(-1px); }

/* ---------- 대시보드 — 사용자가 옮기고 넓히고 숨기는 칸 ---------- */

.page-head { display: flex; align-items: flex-start; gap: 16px; }
.page-head > div:first-child { flex: 1; min-width: 0; }
.page-actions { display: flex; gap: 8px; padding-top: 4px; }

.dash-grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px; align-items: start;
}
.dash-block { position: relative; min-width: 0; }
.dash-block[data-w="1"] { grid-column: span 1; }
.dash-block[data-w="2"] { grid-column: span 2; }
.dash-block[data-w="4"] { grid-column: span 4; }
.dash-block > .card { margin-bottom: 0; }
.dash-block > .kpi { height: 100%; }
.dash-kpi { align-self: stretch; }

.dash-grid.is-editing .dash-block {
  outline: 2px dashed var(--accent-line); outline-offset: 3px; border-radius: var(--radius);
  cursor: grab;
}
.dash-grid.is-editing .dash-block > .kpi,
.dash-grid.is-editing .dash-block > .card { pointer-events: none; }
.dash-block.is-dragging { opacity: .4; }
.dash-block.drop-before { box-shadow: -6px 0 0 -2px var(--accent); }
.dash-tools {
  display: flex; align-items: center; gap: 4px;
  margin-bottom: 6px; padding: 4px 6px;
  background: var(--accent-soft); border: 1px solid var(--accent-line);
  border-radius: var(--radius-sm); font-size: 11.5px; color: var(--accent);
}
.dash-tools .dash-name {
  flex: 1; min-width: 0; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dash-grip { cursor: grab; font-size: 13px; padding: 0 2px; }
.dash-tools button {
  border: 1px solid var(--accent-line); background: var(--surface); color: var(--ink-2);
  border-radius: 5px; padding: 1px 6px; font: inherit; font-size: 11px; cursor: pointer;
}
.dash-tools button:hover { color: var(--accent); border-color: var(--accent); }
.dash-empty {
  padding: 22px 14px; text-align: center; font-size: 12px; color: var(--ink-3);
  border: 1px dashed var(--line-strong); border-radius: var(--radius);
}
.dash-tray {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  margin-top: 16px; padding: 12px 14px;
  border: 1px dashed var(--line-strong); border-radius: var(--radius);
}

/* ---------- 연구장비 ---------- */

.eq-amounts {
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 10px; margin-bottom: 12px;
}
.eq-amount {
  padding: 9px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.eq-amount span { display: block; font-size: 11.5px; color: var(--ink-3); margin-bottom: 3px; }
.eq-amount b { font-size: 15px; font-variant-numeric: tabular-nums; }
.eq-facts { display: flex; flex-wrap: wrap; gap: 6px 18px; align-items: center; font-size: 12.5px; margin-bottom: 12px; }
.eq-steps {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px;
  counter-reset: step;
}
.eq-steps li { counter-increment: step; }
.eq-steps button {
  width: 100%; height: 100%; text-align: left; cursor: pointer; font: inherit;
  padding: 8px 10px 8px 34px; position: relative;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface);
}
.eq-steps button::before {
  content: counter(step); position: absolute; left: 9px; top: 9px;
  width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center;
  font-size: 10.5px; font-weight: 700; background: var(--surface-3); color: var(--ink-3);
}
.eq-steps button:hover { border-color: var(--accent); }
.eq-step-label { display: block; font-size: 12.5px; font-weight: 600; line-height: 1.35; }
.eq-step-date { display: block; font-size: 11.5px; color: var(--ink-3); margin-top: 3px; }
.eq-steps li.done button { background: var(--ok-bg); border-color: var(--ok-line); }
.eq-steps li.done button::before { content: "✓"; background: var(--ok); color: #fff; }
.eq-steps li.done .eq-step-date { color: var(--ok); }
.eq-steps li.missed button { background: var(--danger-bg); border-color: var(--danger-line); }
.eq-steps li.missed button::before { content: "!"; background: var(--danger); color: #fff; }
.eq-steps li.missed .eq-step-date { color: var(--danger); font-weight: 600; }
.eq-steps li.next button { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.eq-steps li.next .eq-step-date { color: var(--accent); font-weight: 600; }
.section-title { font-size: 15px; margin: 22px 0 10px; letter-spacing: -.2px; }
@media (max-width: 1080px) { .eq-amounts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ---------- 집행률 막대 ---------- */

.bar {
  height: 6px; background: var(--surface-3);
  border-radius: var(--radius-pill); overflow: hidden; min-width: 70px;
}
.bar > i {
  display: block; height: 100%; background: var(--accent);
  border-radius: var(--radius-pill);
  transition: width .3s ease;
}
.bar.over > i { background: var(--danger); }
.bar.high > i { background: var(--warn); }

.mini-bar {
  height: 5px; background: var(--surface-3);
  border-radius: var(--radius-pill); overflow: hidden; margin-bottom: 3px;
}
.mini-bar i { display: block; height: 100%; border-radius: var(--radius-pill); }

/* ---------- 필터 ---------- */

.filters {
  display: flex; flex-wrap: wrap; gap: 10px 12px; align-items: flex-end;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}
.filters label { font-size: 12px; color: var(--ink-2); font-weight: 600; }
.filters label > span { display: block; margin-bottom: 4px; }
.filters select, .filters input { min-width: 120px; }
.filters select { width: auto; max-width: 240px; }
.filters input[type=checkbox] { min-width: 0; width: 15px; }
.filters .grow { flex: 1; min-width: 200px; }

/* 표 제목을 눌러 정렬 */
th.sortable { cursor: pointer; user-select: none; }
th.sortable:hover { color: var(--ink); }
th.sorted { color: var(--accent); }

/* 자주 쓰는 조건 */
.saved-views {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 10px 18px; border-bottom: 1px solid var(--line); font-size: 12px;
}
.saved-views #save-view { margin-left: auto; }
.view-chip { display: inline-flex; align-items: center; gap: 2px; padding: 0 4px 0 0; }
.view-chip button {
  border: 0; background: none; font: inherit; color: inherit; cursor: pointer; padding: 3px 4px 3px 10px;
}
.view-chip button + button { padding: 3px 5px; color: var(--ink-3); }
.view-chip button + button:hover { color: var(--danger); }
.view-chip.on { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent); font-weight: 600; }

/* 전표 입력 중 잔액 미리보기 */
.budget-preview {
  display: flex; flex-wrap: wrap; gap: 6px 18px;
  margin: 8px 0 4px; padding: 8px 12px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm);
  font-size: 12.5px; color: var(--ink-2);
}
.budget-preview b { color: var(--ink); font-variant-numeric: tabular-nums; }
.budget-preview .over { color: var(--danger); font-weight: 700; }

/* ---------- 선택 툴바 ---------- */

.bulkbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 18px;
  background: var(--accent-soft);
  border-bottom: 1px solid var(--accent-line);
  font-size: 13px;
}
.bulkbar .spacer { margin-left: auto; }

/* ---------- 모달 ---------- */

.modal-host { position: fixed; inset: 0; z-index: 100; display: grid; place-items: center; }
.modal-host.hidden { display: none; }
.modal-backdrop {
  position: absolute; inset: 0;
  background: rgba(8, 16, 28, .48);
  backdrop-filter: blur(2px);
}
.modal {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  width: min(880px, 94vw); max-height: 90vh;
  display: flex; flex-direction: column;
  box-shadow: var(--shadow-3);
}
.modal.modal-wide { width: min(1080px, calc(100vw - 40px)); }
.modal-wide table input, .modal-wide table select { padding: 3px 7px; font-size: 12px; }

.modal > header {
  display: flex; align-items: center;
  padding: 16px 20px; border-bottom: 1px solid var(--line);
}
.modal > header h2 { margin: 0; font-size: 16px; font-weight: 700; letter-spacing: -.3px; }
.modal > header button {
  margin-left: auto; border: 0; background: none; font-size: 22px;
  line-height: 1; cursor: pointer; color: var(--ink-3);
  width: 30px; height: 30px; border-radius: var(--radius-sm);
  transition: background .12s, color .12s;
}
.modal > header button:hover { background: var(--surface-2); color: var(--ink); }
#modal-body { padding: 20px; overflow: auto; }
.modal > footer {
  display: flex; gap: 8px; justify-content: flex-end; align-items: center;
  padding: 13px 20px; border-top: 1px solid var(--line);
  background: var(--surface-2);
  border-radius: 0 0 14px 14px;
}
.modal > footer .push-left { margin-right: auto; }

.form-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 16px; }
.form-grid .span2 { grid-column: span 2; }
.form-grid .span3 { grid-column: span 3; }

/* ---------- 토스트 ---------- */

.toast-host {
  position: fixed; right: 22px; bottom: 22px; z-index: 200;
  display: flex; flex-direction: column; gap: 8px;
}
.toast {
  background: #172231; color: #fff;
  padding: 11px 16px; border-radius: var(--radius);
  font-size: 13px; box-shadow: var(--shadow-3); max-width: 440px;
  border-left: 3px solid #56636f;
}
.toast.ok   { border-left-color: #3fae82; }
.toast.warn { border-left-color: #d5a457; }
.toast.err  { border-left-color: #e07b70; }

/* ---------- 전역 검색 ---------- */

.search-panel {
  position: fixed; z-index: 400; width: 460px; max-height: 60vh; overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-3);
}
.search-group { border-bottom: 1px solid var(--line); }
.search-group:last-of-type { border-bottom: 0; }
.search-kind {
  position: sticky; top: 0; padding: 6px 12px;
  background: var(--surface-2);
  font-size: 11px; font-weight: 700; color: var(--ink-3);
  border-bottom: 1px solid var(--line);
}
.search-empty { padding: 20px 14px; color: var(--ink-3); text-align: center; }
.search-foot {
  display: flex; align-items: center; gap: 12px; padding: 8px 12px;
  border-top: 1px solid var(--line); background: var(--surface-2);
  font-size: 11px; color: var(--ink-3);
}
.search-foot label { display: flex; align-items: center; gap: 5px; cursor: pointer; }

.hit {
  display: flex; gap: 10px; align-items: baseline;
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
}
.hit:last-child { border-bottom: 0; }
.hit:hover { background: var(--surface-2); }
.hit.on { background: var(--accent-soft); }
.hit .t {
  font-weight: 600; flex: 0 0 auto; max-width: 190px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.hit .d {
  color: var(--ink-2); font-size: 12px; flex: 1 1 auto;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.hit .w {
  margin-left: auto; color: var(--ink-3); font-size: 11px; white-space: nowrap;
}

/* ---------- 단계 표시 ---------- */

.step-nav { display: flex; gap: 6px; margin-bottom: 18px; }
.step-nav .step {
  flex: 1; padding: 10px 13px;
  border-radius: var(--radius-sm);
  background: var(--surface);
  border: 1px solid var(--line);
  font-size: 12.5px; color: var(--ink-3);
}
.step-nav .step.active {
  background: var(--accent); border-color: var(--accent);
  color: var(--on-accent); font-weight: 700;
}
.step-nav .step.done {
  background: var(--ok-bg); border-color: var(--ok-line); color: var(--ok);
}

/* ---------- 조각들 ---------- */

.chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.chip {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  padding: 3px 11px; font-size: 12px; color: var(--ink-2);
  font-family: inherit;
  transition: background .12s, border-color .12s;
}
button.chip { cursor: pointer; }
button.chip:hover { background: var(--accent-soft); border-color: var(--accent-line); }

.hint { font-size: 12px; color: var(--ink-3); margin-top: 5px; }

.rule-source {
  display: inline-block; margin-top: 5px; padding: 1.5px 8px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  border-radius: var(--radius-pill);
  font-size: 10.5px; color: var(--accent);
}

/* 빈 자리 — 도면의 맞춤 표시(⊕)를 작게. 「비어 있음」이 고장이 아니라 아직 안 넣은 자리라는 표시 */
.empty {
  padding: 44px 20px 46px; text-align: center; color: var(--ink-3); font-size: 13px;
}
.empty::before {
  content: ""; display: block; width: 30px; height: 30px; margin: 0 auto 12px;
  border: 1.5px solid var(--line-strong); border-radius: 50%;
  background:
    linear-gradient(var(--line-strong), var(--line-strong)) center / 1.5px 100% no-repeat,
    linear-gradient(90deg, var(--line-strong), var(--line-strong)) center / 100% 1.5px no-repeat;
}
.loading { padding: 52px; text-align: center; color: var(--ink-3); font-size: 13px; }

.split { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.split-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.split-3 .card { display: flex; flex-direction: column; }
.split-3 .card-body { flex: 1; display: flex; flex-direction: column; align-items: flex-start; }
.split-3 .card-body .btn { margin-top: auto; }
@media (max-width: 1100px) { .split-3 { grid-template-columns: 1fr; } }

/* 시작하기 — 로그인 화면의 도면을 띠로 한 번 더. 처음 켠 사람이 「같은 프로그램」임을 알게 */
.welcome-band {
  position: relative; overflow: hidden; margin: 0 0 18px; border-radius: var(--radius);
  background: #022450 url("/static/img/login-blueprint.webp") no-repeat right -60px top 42%;
  background-size: 620px auto; color: #e9f0f9; box-shadow: var(--shadow-2);
}
.welcome-band::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, #022450 0%, #022450 38%, rgba(2, 36, 80, .55) 62%, rgba(2, 36, 80, .1) 100%);
}
.welcome-band-copy { position: relative; padding: 30px 32px 28px; max-width: 560px; }
.welcome-eyebrow {
  display: inline-block; font-size: 12px; font-weight: 600; letter-spacing: .08em; color: #9cc3ec;
  padding-bottom: 8px; margin-bottom: 10px; border-bottom: 1px solid rgba(156, 195, 236, .35);
}
.welcome-band h1 { color: #fff; margin: 0 0 6px; }
.welcome-band p { margin: 0; color: #9cc3ec; font-size: 13.5px; line-height: 1.6; }
@media (max-width: 760px) { .welcome-band { background-size: 420px auto; background-position: right -120px top 40%; } }

/* ---------- 도움말 ---------- */

.help-nav { display: flex; flex-wrap: wrap; gap: 6px; margin: 18px 0 20px; }
.help-nav a {
  font-size: 12px; padding: 4.5px 12px;
  border-radius: var(--radius-pill);
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--ink-2); text-decoration: none;
  transition: background .12s, border-color .12s, color .12s;
}
.help-nav a:hover {
  background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent);
}
.help-card { scroll-margin-top: 80px; }
.help-lead { margin: 0 0 11px; color: var(--ink-2); }
.help-steps { margin: 0; padding-left: 20px; color: var(--ink-2); font-size: 13px; }
.help-steps li { margin-bottom: 6px; }
.help-caution {
  margin-top: 13px; padding: 10px 13px;
  background: var(--warn-bg);
  border-left: 3px solid var(--warn-line);
  border-radius: var(--radius-sm);
  font-size: 12.5px; color: var(--warn);
}

/* 서버가 옛 판으로 도는 상태 — 화면 파일만 새것일 때 */
.stale-bar {
  display: flex; gap: 11px;
  padding: 12px 28px;
  background: var(--danger-bg);
  border-bottom: 1px solid var(--danger-line);
  color: var(--danger);
  font-size: 13px;
}
.stale-bar strong { font-weight: 700; }

/* 연속 작성 — 직전 문서 참고 패널 */
.reference {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  margin-bottom: 14px;
}
.reference > summary {
  padding: 8px 12px; cursor: pointer;
  font-size: 12.5px; font-weight: 600; color: var(--ink-2);
  list-style: none;
}
.reference > summary::before { content: "▸ "; color: var(--ink-3); }
.reference[open] > summary::before { content: "▾ "; }
.reference > summary:hover { color: var(--ink); }
.reference-body { padding: 4px 12px 12px; }
.reference-field { margin-bottom: 10px; }
.reference-label {
  display: flex; align-items: center; gap: 8px;
  font-size: 11px; font-weight: 600; color: var(--ink-3);
  margin-bottom: 3px;
}
.reference-field pre {
  margin: 0; padding: 8px 10px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: inherit; font-size: 12.5px; color: var(--ink-2);
  white-space: pre-wrap; word-break: break-word;
  max-height: 120px; overflow: auto;
}

/* 영수증에서 읽기 — 첨부 바로 위 한 줄 */
.ocr-strip {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; margin-bottom: 12px;
  background: var(--accent-soft); border: 1px dashed var(--accent-line); border-radius: var(--radius);
}
.ocr-strip .muted { flex: 1; min-width: 200px; line-height: 1.45; color: var(--ink-2); }

/* 파일을 고르는 label 은 진짜 버튼이 아니라서 :disabled 가 안 먹는다.
   읽는 중과 못 쓰는 상태를 눈으로 구분되게 직접 칠한다. */
.btn.is-busy, .btn.is-disabled {
  opacity: .55; pointer-events: none; cursor: default;
}
.btn.is-busy::after { content: ' …'; }

/* 처음 가져오기 안내 */
.guide-card h3 {
  font-size: 13.5px; margin: 18px 0 7px; color: var(--ink);
  padding-bottom: 5px; border-bottom: 1px solid var(--line);
}
.guide-card h3:first-child { margin-top: 0; }
.guide-card p { margin: 6px 0; }
.guide-card table { margin: 8px 0; }
.guide-systems {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 9px; margin: 9px 0;
}
.guide-system {
  padding: 10px 12px; border: 1px solid var(--line);
  border-radius: var(--radius-sm); background: var(--surface-2);
}
.guide-system strong { display: block; margin-bottom: 4px; font-size: 12.5px; }
.guide-system p { margin: 0; font-size: 11.5px; color: var(--ink-2); line-height: 1.55; }

/* 임포트 ②단계 — 시트·제목 줄 고르기 */
.import-source {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line);
  font-size: 12px; color: var(--ink-2);
}
.import-source label { display: flex; align-items: center; gap: 5px; }
.import-source input, .import-source select { width: auto; }
.import-source .hint { flex: 1; min-width: 200px; margin: 0; }

/* 제목 줄 고르기 — 파일 윗줄을 보여 주고 누르게 한다 */
.pick-rows tr { cursor: pointer; }
.pick-rows tr:hover > td { background: var(--accent-soft); }
.pick-rows tr.is-selected > td { background: var(--accent-soft); font-weight: 600; }
.pick-rows td span {
  display: inline-block; padding: 1px 7px; margin-right: 4px;
  border-right: 1px solid var(--line); white-space: nowrap;
  max-width: 150px; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom;
}
.pick-rows td span:last-child { border-right: 0; }

/* 아직 볼 것이 없을 때 */
.setup-needed { max-width: 640px; }
.setup-card {
  margin: 16px 0; padding: 16px 18px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-1);
}
.setup-card h2 { margin: 0 0 7px; font-size: 14px; }
.setup-card p { margin: 6px 0; font-size: 12.5px; color: var(--ink-2); line-height: 1.6; }
.setup-actions { display: flex; gap: 8px; flex-wrap: wrap; margin: 14px 0 10px; }

/* 판단해야 할 것의 크기 — 건수 옆에 금액과 비중을 같이 놓는다 */
.attention { margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--line); }
.attention-label {
  font-size: 11px; font-weight: 700; color: var(--ink-3); margin-bottom: 5px;
}
.attention-row {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 3px 0; font-size: 12px;
}
.attention-title { flex: 1; min-width: 160px; color: var(--ink); }
.attention-amount { font-variant-numeric: tabular-nums; font-weight: 600; }
.attention-share { min-width: 92px; text-align: right; color: var(--ink-3); font-size: 11.5px; }

/* ---------- 들어오는 문 ---------- */

/* 왼쪽 반은 도면(트랙터 기술 도면, Higgsfield 로 그림 — 글자·로고 없음), 오른쪽 반은 들어가는 칸.
   도면 바탕(--blueprint)은 그림 가장자리 색과 같게 맞춰 경계가 안 보이게 한다. 밝은·어두운 화면 모두 같은 남색 */
.gate {
  --blueprint: #022450;
  --blueprint-ink: #e9f0f9;
  --blueprint-mute: #9cc3ec;
  position: fixed; inset: 0; z-index: 900;
  display: flex; background: var(--bg);
}
.gate-shell { flex: 1; display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); min-height: 100%; }
.gate-art {
  position: relative; overflow: hidden; background: var(--blueprint);
  background-image: url("/static/img/login-blueprint.webp");
  background-size: cover; background-position: center 62%;
}
.gate-art::after {   /* 아래로 갈수록 살짝 어둡게 — 글자는 위에, 도면은 아래에 */
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(2, 36, 80, .92) 0%, rgba(2, 36, 80, .35) 34%, rgba(2, 36, 80, 0) 55%);
}
.gate-art-copy { position: relative; z-index: 1; padding: 56px 56px 0; color: var(--blueprint-ink); max-width: 560px; }
.gate-art-eyebrow {
  font-size: 12px; font-weight: 600; letter-spacing: .08em; color: var(--blueprint-mute);
  padding-bottom: 10px; margin-bottom: 14px; border-bottom: 1px solid rgba(156, 195, 236, .35); display: inline-block;
}
.gate-art-title { font-size: 40px; font-weight: 800; letter-spacing: -.02em; line-height: 1.1; }
.gate-art-copy p { margin: 14px 0 0; font-size: 15px; line-height: 1.7; color: var(--blueprint-mute); }
.gate-shell .gate-brand { display: none; }   /* 도면 칸이 이름을 이미 말한다 */
.gate-pane {
  display: flex; align-items: center; justify-content: center; padding: 32px 24px;
  background:
    radial-gradient(900px 500px at 100% -10%, rgba(0, 88, 168, .10), transparent 60%),
    var(--bg);
}
/* 도면이 한 번 「현상」되듯 떠오른다 — 처음 한 번만, 움직임을 줄이라는 설정이면 하지 않는다 */
@media (prefers-reduced-motion: no-preference) {
  .gate-art { animation: gate-develop 1.1s cubic-bezier(.2, .7, .2, 1) both; }
  .gate-art-copy { animation: gate-rise .7s .25s cubic-bezier(.2, .7, .2, 1) both; }
}
@keyframes gate-develop { from { filter: brightness(.55) saturate(.6); } to { filter: none; } }
@keyframes gate-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@media (max-width: 860px) {
  .gate-shell { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .gate-art { min-height: 200px; background-position: center 55%; }
  .gate-art-copy { padding: 28px 24px 24px; }
  .gate-art-title { font-size: 28px; }
  .gate-art-copy p { display: none; }
}
body.gated > .sidebar, body.gated > .workspace { visibility: hidden; }
.gate-card {
  width: 100%; max-width: 420px; padding: 30px 32px 26px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 16px; box-shadow: var(--shadow-3);
}
.gate-brand {
  display: flex; align-items: center; gap: 9px;
  font-size: 14px; font-weight: 700; color: var(--ink); margin-bottom: 18px;
}
.gate-brand::before {
  content: "LS"; display: grid; place-items: center;
  width: 28px; height: 28px; border-radius: 8px;
  background: linear-gradient(140deg, #2f86d6, #0058a8 60%, #003f7d);
  color: #fff; font-size: 11.5px; font-weight: 800;
}
.gate-brand b { display: none; }   /* 왼쪽 LS 표가 이미 있다 */
.gate-card h1 { font-size: 21px; margin: 0 0 6px; }
.gate-lead { color: var(--ink-2); font-size: 13px; line-height: 1.6; margin: 0 0 18px; }
.gate-card .field { margin-bottom: 11px; }
.gate-card .btn-primary.gate-go { width: 100%; justify-content: center; margin-top: 8px; padding: 10px; }
.gate-error {
  color: var(--danger); background: var(--danger-bg); border: 1px solid var(--danger-line);
  border-radius: var(--radius-sm); padding: 7px 10px; font-size: 12.5px; margin: 4px 0 6px;
}
.gate-lock {
  display: grid; gap: 5px; margin: 4px 0 14px; padding: 12px 14px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm);
  font-size: 13px;
}
.gate-lock span { display: inline-block; width: 84px; color: var(--ink-3); font-size: 12px; }
.gate-row { display: flex; gap: 8px; margin: 6px 0 4px; }

/* ---------- 왼쪽 아래 사용자 ---------- */

.user-chip { flex: 1; min-width: 0; display: grid; gap: 6px; }
.user-chip .btn {
  justify-content: center;
  background: rgba(255, 255, 255, .06); border-color: var(--side-line); color: var(--side-ink);
}
.user-chip .btn:hover { background: rgba(255, 255, 255, .12); }
.user-chip .btn-primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.user-chip .chip-row { display: flex; gap: 6px; }
.user-chip .chip-row .btn { flex: 1; }
.user-name {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: none; border: 0; cursor: pointer; color: inherit; font: inherit;
  padding: 4px; border-radius: var(--radius-sm); text-align: left;
}
.user-name:hover { background: rgba(255, 255, 255, .06); }
.user-avatar {
  display: grid; place-items: center; flex-shrink: 0;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--side-2); color: #cfe2f6; font-weight: 700; font-size: 12.5px;
}
.user-who { min-width: 0; display: grid; line-height: 1.3; }
.user-who strong { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.user-role { font-size: 11px; color: var(--side-mute); }
.user-sync { font-size: 11px; color: var(--side-mute); padding-left: 4px; }

/* ---------- 좁은 화면 ---------- */

@media (max-width: 1080px) {
  .split { grid-template-columns: 1fr; }
  .dash-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dash-block[data-w="4"] { grid-column: span 2; }
  .form-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 900px) {
  /* 메뉴를 위로 올린다. 왼쪽에 두면 표가 들어갈 자리가 없다 */
  .sidebar { position: static; width: auto; height: auto; }
  .workspace { margin-left: 0; }
  .side-nav { display: flex; overflow-x: auto; gap: 2px; padding: 4px 8px; }
  .nav-group { display: flex; margin: 0; }
  .nav-label, .side-nav button.active::before { display: none; }
  .side-nav button { width: auto; white-space: nowrap; }
  .context { grid-template-columns: 1fr 1fr; }
  main { padding: 18px 16px 48px; }
  .crumb { padding: 14px 16px 0; }
  .topbar { padding: 0 16px; }
}
@media (max-width: 640px) {
  .form-grid { grid-template-columns: 1fr; }
  .topbar-search kbd { display: none; }
  /* 좁은 화면 — 위 막대의 단추는 그림만(이름은 title·aria-label 에). 글자까지 두면 화면 밖으로 밀린다 */
  .topbar-actions .btn-text { display: none; }
  .topbar { gap: 8px; }
}

/* ---------- 연구원 — 막힌 단추는 보이지 않게 ----------
   서버(app/api/scope.py)가 막는 것이 기준이고, 여기는 누를 수 없는 단추를 감추기만 한다.
   여기서 빠뜨려도 새는 것은 없다 — 누르면 「연구원은 쓸 수 없는 기능입니다」가 뜬다. */
body.role-researcher #quick-voucher,
body.role-researcher .topbar-search,
body.role-researcher #export-link,
body.role-researcher a[href*="annual.pdf"],
body.role-researcher #seed, body.role-researcher #add-ms, body.role-researcher #set-target,
body.role-researcher #add-out, body.role-researcher [data-msedit], body.role-researcher [data-msdel],
body.role-researcher [data-outedit], body.role-researcher [data-outdel],
body.role-researcher [data-del], body.role-researcher [data-to-project], body.role-researcher #pl-stage,
body.role-researcher #pl-agreement, body.role-researcher #pl-next-year {
  display: none !important;
}
body.role-researcher .pl-step { pointer-events: none; }
.researcher-only { display: none; }
body.role-researcher .researcher-only { display: block; }

/* 사업비 계산 — 칸이 많은 인건비 시트를 한 화면에 */
.cp-table th, .cp-table td { padding: 8px 6px; }
.cp-table th:first-child, .cp-table td:first-child { padding-left: 14px; }
.cp-table input, .cp-table select { padding: 6px 8px; }
.cp-table tfoot td { background: var(--surface-2); }

/* 집행 가이드 */
.gd-search { margin: 4px 0 16px; }
.gd-search input[type=search] { width: 100%; max-width: 560px; margin-bottom: 8px; }
.chip.on { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent); font-weight: 600; }
.gd-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius, 10px); padding: 16px 18px; margin-bottom: 14px; }
.gd-card > header { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; margin-bottom: 10px; }
.gd-card h3 { margin: 0; font-size: 15px; }
.gd-basis { font-size: 11.5px; color: var(--ink-3); }
.gd-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 10px 18px; }
.gd-sec ul { margin: 4px 0 0; padding-left: 18px; font-size: 13px; line-height: 1.55; }
.gd-label { font-size: 11.5px; font-weight: 700; letter-spacing: .02em; }
.gd-sec.ok .gd-label { color: var(--ok); }
.gd-sec.no .gd-label { color: var(--danger); }
.gd-sec.ev .gd-label { color: var(--accent); }
.gd-sec.lim .gd-label { color: var(--warn); }
.gd-cites { display: flex; flex-direction: column; gap: 4px; margin-top: 12px; border-top: 1px dashed var(--line); padding-top: 8px; }
.gd-cite summary { cursor: pointer; font-size: 12px; color: var(--ink-2); }
.gd-cite summary:hover { color: var(--accent); }
.gd-text { white-space: pre-wrap; font-size: 12.5px; line-height: 1.65; color: var(--ink-2); background: var(--surface-2);
  border-radius: 6px; padding: 10px 12px; margin: 6px 0 4px; max-height: 340px; overflow: auto; }
.guide-hint { margin-top: 6px; font-size: 12px; color: var(--ink-2); background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 6px; padding: 6px 10px; }
.guide-hint summary { cursor: pointer; font-weight: 600; }
.guide-hint > div { margin-top: 4px; line-height: 1.5; }

/* 참여 변경 진행 */
.pc-steps { display: inline-flex; flex-wrap: wrap; gap: 2px 4px; align-items: center; font-size: 12px; color: var(--ink-3); }
.pc-steps i { font-style: normal; color: var(--line-strong, var(--ink-3)); }
.pc-steps .done { color: var(--ok); }
.pc-steps .now { color: var(--accent); font-weight: 700; }
.pc-issue { font-size: 12px; margin-top: 3px; }
.pc-issue.block { color: var(--danger); font-weight: 600; }
.pc-issue.warn { color: var(--warn); }
.pc-h { font-size: 13px; margin: 14px 0 6px; }

/* ---------- 로드맵 ---------- */
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: var(--radius-pill); overflow: hidden; background: var(--surface); }
.seg button { border: 0; background: transparent; padding: 6px 14px; font: inherit; font-size: 12.5px; color: var(--ink-2); cursor: pointer; }
.seg button.on { background: var(--accent-soft); color: var(--accent); font-weight: 700; }
.seg button:disabled { opacity: .45; cursor: default; }
.linklike { border: 0; background: none; padding: 0; font: inherit; color: var(--ink); text-align: left; cursor: pointer; }
.linklike:hover { color: var(--accent); text-decoration: underline; }
.rm-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: 8px; background: var(--surface-2); }
.rm-canvas { position: relative; padding-bottom: 6px; }
.rm-row { display: flex; height: 30px; border-bottom: 1px dashed var(--line); }
.rm-row .rm-label { position: sticky; left: 0; z-index: 3; flex: 0 0 110px; display: flex; align-items: center;
  font-size: 11.5px; font-weight: 700; color: var(--ink-2); padding-left: 10px; background: var(--surface-2);
  border-right: 1px solid var(--line); }
.rm-track { position: relative; flex: 0 0 var(--rm-w); }
.rm-axis { height: 28px; border-bottom: 1px solid var(--line); }
.rm-tick { position: absolute; top: 0; height: 28px; width: 56px; font-size: 10.5px; color: var(--ink-3); padding: 7px 0 0 4px;
  border-left: 1px solid var(--line); }
.rm-tick.year { border-left: 2px solid var(--ink-3); }
.rm-tick b { margin-right: 3px; color: var(--ink-2); }
.rm-bar { position: absolute; top: 6px; height: 18px; border-radius: 4px; font-size: 11px; line-height: 18px; padding: 0 6px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rm-bar.phase { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); font-weight: 700; }
.rm-bar.fy { background: var(--surface); border: 1px solid var(--line); color: var(--ink-2); }
.rm-bar.fy.current { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); color: var(--ink); font-weight: 600; }
.rm-pt { position: absolute; width: 12px; height: 12px; margin-left: -6px; border-radius: 50%; border: 2px solid var(--surface);
  padding: 0; cursor: pointer; box-shadow: 0 0 0 1px var(--line); }
.rm-pt.legal { border-radius: 2px; transform: rotate(45deg); }
.rm-pt:hover, .rm-pt:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; z-index: 2; }
.rm-pt.later, .rm-dot.later { background: var(--accent); }
.rm-pt.soon, .rm-dot.soon { background: var(--warn); }
.rm-pt.late, .rm-dot.late { background: var(--danger); }
.rm-pt.done, .rm-dot.done { background: var(--ok); }
.rm-today { position: absolute; top: 0; bottom: 0; width: 0; border-left: 2px solid var(--danger); pointer-events: none; }
.rm-today { z-index: 2; }
.rm-today span { position: absolute; top: 2px; left: 3px; font-size: 10px; font-weight: 700; color: var(--danger);
  background: var(--surface-2); white-space: nowrap; padding: 0 2px; }
.rm-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin: 0 5px 1px 0; vertical-align: middle; }
.rm-diamond { display: inline-block; width: 8px; height: 8px; background: var(--ink-3); transform: rotate(45deg); margin: 0 4px 1px 2px; }
.rm-legend { font-size: 11.5px; color: var(--ink-3); margin: 8px 0 4px; display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: center; }
.rm-lists { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); gap: 4px 24px; }
.rm-h { font-size: 13px; margin: 12px 0 6px; }
.rm-list { width: 100%; font-size: 12.5px; }
.rm-list td { padding: 5px 6px; border-bottom: 1px solid var(--line); vertical-align: top; }
@media (prefers-reduced-motion: no-preference) { .rm-pt { transition: transform .12s; } .rm-pt:not(.legal):hover { transform: scale(1.25); } }

/* ---------- 공유 폴더 읽기 모드 ---------- */
.readonly-bar { position: sticky; top: 0; z-index: 40; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
  padding: 8px 20px; font-size: 13px; background: color-mix(in srgb, var(--warn) 14%, var(--surface));
  border-bottom: 1px solid color-mix(in srgb, var(--warn) 45%, var(--line)); color: var(--ink); }
.readonly-bar strong { color: var(--warn); }
.readonly-bar.free { background: color-mix(in srgb, var(--ok) 14%, var(--surface));
  border-bottom-color: color-mix(in srgb, var(--ok) 45%, var(--line)); }
.readonly-bar.free strong { color: var(--ok); }
/* 고치는 단추는 감춘다 — 막는 것은 서버(관문 403 read_only)가 하고, 화면은 헛걸음을 줄일 뿐 */
body.read-only #quick-voucher, body.read-only #modal-footer .btn-primary:not(.read-ok), body.read-only .btn-danger,
body.read-only [data-del], body.read-only [data-pdel], body.read-only [data-rdel], body.read-only #chip-save {
  display: none !important; }
body.read-only #readonly-bar .btn-primary { display: inline-flex !important; }
body.read-only .topbar { top: var(--ro-h, 38px); }

/* ---------- 탑뷰 (전체현황) — 과제마다 지금 차년도를 한 줄로 ----------
 * 서명은 「집행 막대 위의 붉은 오늘 눈금」 — 로드맵의 오늘 선과 같은 뜻이다. 막대 끝과 눈금 사이가 곧 집행 속도의 차이.
 * 줄 왼쪽 띠 색은 그 과제의 가장 나쁜 상태(막힘·지난 기한 → 빨강, 속도·증빙 → 주황, 깨끗 → 초록). */

.tv-band {
  display: grid; grid-template-columns: repeat(2, minmax(0, .8fr)) minmax(0, 1.6fr) repeat(3, minmax(0, .8fr));
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-1); margin-bottom: 18px; overflow: hidden;
}
.tv-cell { display: flex; flex-direction: column; gap: 4px; padding: 15px 18px 16px; border-left: 1px solid var(--line);
  position: relative; min-width: 0; }
.tv-cell:first-child { border-left: 0; }
.tv-cell .k { font-size: 12px; font-weight: 600; color: var(--ink-3); white-space: nowrap; }
.tv-cell .k em { font-style: normal; font-weight: 500; color: var(--ink-3); opacity: .8; }
.tv-cell .v { font-size: 24px; font-weight: 800; letter-spacing: -.5px; line-height: 1.15; font-variant-numeric: tabular-nums; }
.tv-cell .v small { font-size: 13px; font-weight: 600; color: var(--ink-3); margin-left: 3px; letter-spacing: 0; }
.tv-cell .s { font-size: 12px; color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tv-cell.danger::before, .tv-cell.warn::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px; }
.tv-cell.danger::before { background: var(--danger); }
.tv-cell.danger .v { color: var(--danger); }
.tv-cell.warn::before { background: var(--warn); }
.tv-cell .tv-track { margin-top: 5px; }

/* 집행 막대 + 오늘 눈금 */
.tv-track { position: relative; height: 8px; border-radius: var(--radius-pill); background: var(--surface-3);
  box-shadow: inset 0 0 0 1px var(--line); }
.tv-track.big { height: 10px; }
.tv-track .fill { position: absolute; inset: 0 auto 0 0; border-radius: inherit; background: var(--accent); }
.tv-track .fill.over { background: var(--danger); }
.tv-track .now { position: absolute; top: -4px; bottom: -4px; width: 2px; margin-left: -1px; background: var(--danger);
  border-radius: 1px; box-shadow: 0 0 0 2px var(--surface); }
.tv-track .now::before { content: ""; position: absolute; top: -3px; left: -3px; width: 8px; height: 4px;
  background: var(--danger); clip-path: polygon(0 0, 100% 0, 50% 100%); }

/* 과제 목록 */
.tv-list > header { flex-wrap: wrap; gap: 10px; }
.tv-list > header h2 { margin-right: 4px; }
.tv-sort { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; color: var(--ink-3); font-weight: 600; }
.tv-sort select { width: auto; padding: 5px 28px 5px 10px; font-size: 12.5px; }
.tv-head, .tv-row {
  display: grid; gap: 22px; align-items: center;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1.45fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, .85fr);
  padding: 0 20px 0 22px;
}
.tv-head { padding-top: 9px; padding-bottom: 9px; background: var(--surface-2); border-bottom: 1px solid var(--line);
  font-size: 11.5px; font-weight: 600; color: var(--ink-3); }
.tv-row { position: relative; padding-top: 16px; padding-bottom: 16px; border-bottom: 1px solid var(--line); cursor: pointer;
  transition: background .12s; }
.tv-row:last-child { border-bottom: 0; border-radius: 0 0 var(--radius) var(--radius); }
.tv-row::before { content: ""; position: absolute; left: 0; top: 10px; bottom: 10px; width: 3px; border-radius: 0 3px 3px 0;
  background: var(--line-strong); }
.tv-row.is-danger::before { background: var(--danger); }
.tv-row.is-warn::before { background: var(--warn); }
.tv-row.is-ok::before { background: var(--ok); }
.tv-row.is-idle::before { background: var(--line-strong); }
.tv-row.is-done { opacity: .62; }
.tv-row:hover { background: var(--surface-2); }
.tv-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.tv-c { min-width: 0; }

.tv-code { font-family: var(--mono); font-size: 11.5px; color: var(--ink-3); display: flex; align-items: center; gap: 6px; }
.tv-code .badge { font-family: var(--sans); font-size: 10.5px; padding: 0 7px; }
.tv-name { font-size: 14.5px; font-weight: 700; margin: 3px 0 4px; line-height: 1.35; overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.tv-meta { font-size: 12px; color: var(--ink-3); font-variant-numeric: tabular-nums; }

.tv-rate { display: flex; align-items: baseline; gap: 6px; font-size: 12px; color: var(--ink-3); margin-bottom: 7px; }
.tv-rate strong { font-size: 17px; font-weight: 800; color: var(--ink); letter-spacing: -.3px; font-variant-numeric: tabular-nums; }
.tv-pace-tag { margin-left: auto; font-size: 11px; font-weight: 700; padding: 1px 8px; border-radius: var(--radius-pill);
  border: 1px solid transparent; white-space: nowrap; }
.tv-pace-tag.slow, .tv-pace-tag.fast { color: var(--warn); background: var(--warn-bg); border-color: var(--warn-line); }
.tv-pace-tag.even { color: var(--ok); background: var(--ok-bg); border-color: var(--ok-line); }
.tv-amt { font-size: 12px; color: var(--ink-2); margin-top: 7px; font-variant-numeric: tabular-nums; }
.tv-amt span { color: var(--ink-3); }

/* 비목 — 작은 세로 눈금들 */
.tv-cats { display: flex; gap: 9px; align-items: flex-end; }
.tv-cat { display: flex; flex-direction: column; align-items: center; gap: 5px; min-width: 0; }
.tv-cat .gauge { position: relative; width: 12px; height: 38px; border-radius: 3px; background: var(--surface-3);
  box-shadow: inset 0 0 0 1px var(--line); overflow: hidden; }
.tv-cat .gauge i { position: absolute; left: 0; right: 0; bottom: 0; background: var(--accent); opacity: .85; }
.tv-cat.over .gauge { box-shadow: inset 0 0 0 1px var(--danger-line); }
.tv-cat.over .gauge i { background: var(--danger); opacity: 1; }
.tv-cat .lbl { font-size: 10.5px; color: var(--ink-3); white-space: nowrap; }
.tv-cat.over .lbl { color: var(--danger); font-weight: 700; }

/* 걸릴 것 — 누르면 그 화면 */
.tv-flags { display: flex; flex-wrap: wrap; gap: 5px; }
.tv-flag, .tv-late { font: inherit; font-size: 11.5px; padding: 2px 9px; border-radius: var(--radius-pill); cursor: pointer;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--ink-2); white-space: nowrap;
  transition: box-shadow .12s; }
.tv-flag b, .tv-late b { font-variant-numeric: tabular-nums; }
.tv-flag.danger, .tv-late { color: var(--danger); background: var(--danger-bg); border-color: var(--danger-line); }
.tv-flag.warn { color: var(--warn); background: var(--warn-bg); border-color: var(--warn-line); }
.tv-flag:hover, .tv-late:hover, .tv-due:hover { box-shadow: 0 0 0 3px var(--accent-soft); }
.tv-flag:focus-visible, .tv-late:focus-visible, .tv-due:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.tv-clear { font-size: 12px; color: var(--ok); font-weight: 600; display: inline-flex; align-items: center; gap: 6px; }
.tv-clear::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--ok); }
.tv-none { font-size: 12px; color: var(--ink-3); }

/* 다음 기한 */
.tv-when { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.tv-due { font: inherit; text-align: left; display: grid; gap: 1px; padding: 4px 8px; margin: -4px -8px; border: 0;
  border-radius: var(--radius-sm); background: transparent; color: inherit; cursor: pointer; max-width: 100%; }
.tv-due .dday { font-size: 17px; font-weight: 800; letter-spacing: -.3px; font-variant-numeric: tabular-nums; }
.tv-due.warn .dday { color: var(--warn); }
.tv-due.danger .dday { color: var(--danger); }
.tv-due .what { font-size: 12px; color: var(--ink-2); line-height: 1.35; overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.tv-due .when { font-size: 11px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.tv-foot { margin: -6px 2px 24px; }

/* 불러오는 동안 — 자리만 먼저 */
.tv-skel i, .tv-skel-band .tv-cell i { display: block; height: 12px; border-radius: 6px; background: var(--surface-3); }
.tv-skel-band .tv-cell i { height: 44px; }
.tv-skel { cursor: default; min-height: 92px; }
.tv-skel::before { display: none; }
@media (prefers-reduced-motion: no-preference) {
  .tv-skel i, .tv-skel-band .tv-cell i { animation: tv-pulse 1.2s ease-in-out infinite alternate; }
  @keyframes tv-pulse { from { opacity: .45; } to { opacity: 1; } }
}

/* 좁아지면 — 두 줄(과제·집행 / 비목·걸릴 것·기한), 더 좁으면 세로로.
 * 합계 띠의 칸 사이 선은 1px 틈으로 그린다 — 칸 순서를 바꿔도(좁은 화면에서 집행 칸을 맨 위로) 선이 어긋나지 않는다 */
@media (max-width: 1440px) {
  .tv-band { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; background: var(--line); }
  .tv-band .tv-cell { border-left: 0; background: var(--surface); }
  .tv-head { display: none; }
  .tv-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); row-gap: 14px; }
  .tv-row .tv-who { grid-column: 1 / 2; }
  .tv-row .tv-money { grid-column: 2 / 4; }
}
@media (max-width: 760px) {
  .tv-band { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tv-band .tv-cell.wide { grid-column: 1 / -1; order: -1; }
  .tv-band .tv-cell:last-child { grid-column: 1 / -1; }   /* 집행 칸이 위로 가면 나머지가 다섯 — 마지막 칸이 빈자리를 채운다 */
  .tv-row { grid-template-columns: minmax(0, 1fr); padding-left: 18px; padding-right: 16px; }
  .tv-row .tv-who, .tv-row .tv-money { grid-column: auto; }
}
.ov-head { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
.ov-head > div:first-child { flex: 1 1 320px; min-width: 0; }
.ov-head .seg { margin-top: 4px; }

/* ---------- 상용 손질 (v2.62) ----------
 * 1. 비목 색 — 비목마다 한 색을 정해 집행등록 · 예산관리 · 탑뷰에서 같은 색으로 보인다(눈이 비목을 색으로 따라간다)
 * 2. 불러오는 동안 — 「불러오는 중…」 글자 대신 자리만 먼저(뼈대가 은은하게 숨 쉰다)
 * 3. 빈 화면 — 로그인 화면과 같은 청사진 그림 + 할 일 한 줄
 * 4. 줄마다 되풀이되는 수정 · 삭제 단추는 줄에 올라가거나 초점이 들어올 때만(터치 화면은 늘)
 * 5. 화면을 바꿀 때 내용이 살짝 떠오른다(움직임 줄이기 설정이면 없음) */

:root {
  --cat-1: #2563eb; --cat-2: #0891b2; --cat-3: #7c3aed; --cat-4: #d97706;
  --cat-5: #db2777; --cat-6: #059669; --cat-7: #65a30d; --cat-8: #64748b;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --cat-1: #6b9bff; --cat-2: #4cc3dc; --cat-3: #a98bff; --cat-4: #f2b544;
    --cat-5: #f07ab2; --cat-6: #4fd1a5; --cat-7: #a3e635; --cat-8: #94a3b8;
  }
}
:root[data-theme="dark"] {
  --cat-1: #6b9bff; --cat-2: #4cc3dc; --cat-3: #a98bff; --cat-4: #f2b544;
  --cat-5: #f07ab2; --cat-6: #4fd1a5; --cat-7: #a3e635; --cat-8: #94a3b8;
}
[data-cat="1"] { --cat: var(--cat-1); } [data-cat="2"] { --cat: var(--cat-2); }
[data-cat="3"] { --cat: var(--cat-3); } [data-cat="4"] { --cat: var(--cat-4); }
[data-cat="5"] { --cat: var(--cat-5); } [data-cat="6"] { --cat: var(--cat-6); }
[data-cat="7"] { --cat: var(--cat-7); } [data-cat="8"] { --cat: var(--cat-8); }

/* 집행등록 — 비목 · 세목을 한 줄로(점 색 = 비목) */
.cat-cell { display: inline-flex; align-items: center; gap: 7px; max-width: 170px; min-width: 0; }
.cat-cell::before { content: ""; flex: 0 0 8px; height: 8px; border-radius: 50%; background: var(--cat, var(--ink-3)); }
.cat-cell b { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
td.clip > .clip-in, td.clip .sub { display: block; max-width: 190px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
td.clip .sub { font-size: 11.5px; color: var(--ink-3); }

/* 예산관리 — 비목 줄 왼쪽 색 띠, 집행률 막대 */
tr.row-category[data-cat] > td:first-child { box-shadow: inset 3px 0 0 var(--cat, var(--line-strong)); }
.rate-cell { display: inline-flex; align-items: center; gap: 8px; justify-content: flex-end; }
.rate-cell .bar { width: 54px; height: 5px; border-radius: var(--radius-pill); background: var(--surface-3); overflow: hidden; }
.rate-cell .bar i { display: block; height: 100%; border-radius: inherit; background: var(--cat, var(--accent)); }
.rate-cell.over .bar i { background: var(--danger); }
.rate-cell.over { color: var(--danger); font-weight: 700; }

/* 탑뷰 — 비목 눈금도 비목 색 */
.tv-cat[data-cat] .gauge i { background: var(--cat, var(--accent)); opacity: 1; }
.tv-cat.over[data-cat] .gauge i { background: var(--danger); }

/* 줄 단추 — 올라가거나 초점이 들어올 때만 */
@media (hover: hover) and (pointer: fine) {
  tr .row-actions { opacity: 0; transition: opacity .12s; }
  tr:hover .row-actions, tr:focus-within .row-actions { opacity: 1; }
}
.row-actions { display: inline-flex; gap: 6px; justify-content: flex-end; white-space: nowrap; }

/* 불러오는 동안 — 뼈대. 화면 전체를 불러올 때(#view 바로 아래)만. 창 안 · 칸 안의 안내 글(「영수증을 읽는 중… 10초」)은
   그대로 둔다. 글은 뼈대 아래에 작게 남긴다(무엇을 기다리는지 — 화면 낭독기도 읽는다) */
#view > .loading {
  --skel: color-mix(in srgb, var(--ink-3) 22%, transparent);
  min-height: 168px; padding: 150px 24px 0; text-align: left; font-size: 12px; color: var(--ink-3);
  background:
    linear-gradient(var(--skel), var(--skel)) 24px 30px / 34% 14px no-repeat,
    linear-gradient(var(--skel), var(--skel)) 24px 62px / 72% 10px no-repeat,
    linear-gradient(var(--skel), var(--skel)) 24px 84px / 64% 10px no-repeat,
    linear-gradient(var(--skel), var(--skel)) 24px 106px / 68% 10px no-repeat;
  border-radius: var(--radius);
}
@media (prefers-reduced-motion: no-preference) {
  #view > .loading { animation: skel-breathe 1.1s ease-in-out infinite alternate; }
  @keyframes skel-breathe { from { opacity: .55; } to { opacity: 1; } }
}

/* 빈 화면 — 청사진 그림 판 */
.empty-state { display: grid; justify-items: center; text-align: center; gap: 6px; padding: 34px 20px 38px; }
.empty-state .art { width: min(300px, 78%); aspect-ratio: 3 / 2; border-radius: 14px; overflow: hidden; margin-bottom: 12px;
  background: #012352; box-shadow: var(--shadow-2); }
.empty-state .art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.empty-state h3 { margin: 0; font-size: 15.5px; font-weight: 700; color: var(--ink); }
.empty-state p { margin: 0; max-width: 46ch; font-size: 13px; color: var(--ink-3); line-height: 1.55; }
.empty-state .actions { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; justify-content: center; }
td > .empty-state { padding-top: 26px; padding-bottom: 28px; }

/* 화면 바꿀 때 */
@media (prefers-reduced-motion: no-preference) {
  #view.view-enter > *:not(.loading) { animation: view-rise .22s cubic-bezier(.2, .7, .2, 1) both; }
  #view.view-enter > *:nth-child(2) { animation-delay: .03s; }
  #view.view-enter > *:nth-child(3) { animation-delay: .06s; }
  #view.view-enter > *:nth-child(n+4) { animation-delay: .09s; }
  @keyframes view-rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
}

/* 열이 많은 표(집행등록) — 칸 옆 여백을 줄여 노트북 화면(1440)에서 가로로 넘치지 않게 */
table.dense th, table.dense td { padding-left: 9px; padding-right: 9px; }
table.dense th:first-child, table.dense td:first-child { padding-left: 16px; }

/* ---------- 대시보드 그림 (v2.63) — 「어떻게 가고 있나」 ----------
 * 붉은 「오늘」 눈금은 탑뷰 · 로드맵과 같은 표시. 색은 비목 색(--cat-n)과 상태색 토큰만. 그림은 SVG — 인터넷 없이 그린다 */
.dash-viz > .card { height: 100%; display: flex; flex-direction: column; }
.dash-viz > .card > .card-body { flex: 1; }
.dv-card > header .dv-legend { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--ink-3); }
.dv-legend i { display: inline-block; width: 14px; height: 0; border-top: 2px solid var(--accent); margin-left: 8px; }
.dv-legend i.sw-plan { border-top: 2px dashed var(--ink-3); }
.dv-legend i.sw-now { width: 2px; height: 11px; border: 0; background: var(--danger); }
.dv-note { margin: 0 0 8px; font-size: 12.5px; color: var(--ink-2); }
.dv-note b { color: var(--ink); font-variant-numeric: tabular-nums; }
.dv-click { cursor: pointer; }
.dv-card.dv-click:hover { box-shadow: var(--shadow-2); }
.dv-card.dv-click:focus-within, .dv-card.dv-click:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* 한눈 띠 */
.dv-hero { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); align-items: stretch; overflow: hidden; }
.dv-hero-main { padding: 20px 26px 18px; position: relative;
  background:
    linear-gradient(var(--line) 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(90deg, var(--line) 1px, transparent 1px) 0 0 / 24px 24px;
  background-color: var(--surface-2); }
.dv-hero-main::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(90deg, transparent 55%, var(--surface-2)); opacity: .9; }
.dv-hero-main > * { position: relative; z-index: 1; }
.dv-eyebrow { font-size: 12px; font-weight: 700; color: var(--accent); letter-spacing: .02em; }
.dv-rate { display: flex; align-items: baseline; gap: 12px; margin: 4px 0 12px; }
.dv-rate strong { font-size: 40px; font-weight: 800; letter-spacing: -1.2px; line-height: 1; font-variant-numeric: tabular-nums; }
.dv-rate .tv-pace-tag { margin-left: 0; font-size: 12px; padding: 2px 10px; }
.dv-hero .tv-track.big { height: 12px; }
.dv-scale { display: flex; justify-content: space-between; margin-top: 8px; font-size: 11.5px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.dv-scale span:nth-child(2) { color: var(--danger); font-weight: 600; }
.dv-figs { margin: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); border-left: 1px solid var(--line); }
.dv-figs > div { padding: 16px 20px; border-bottom: 1px solid var(--line); border-left: 1px solid var(--line); margin-left: -1px; min-width: 0; }
.dv-figs > div:last-child, .dv-figs > div:nth-last-child(2):nth-child(odd) { border-bottom: 0; }
.dv-figs > div:last-child:nth-child(odd) { grid-column: 1 / -1; }
.dv-figs dt { font-size: 12px; font-weight: 600; color: var(--ink-3); }
.dv-figs dd { margin: 4px 0 2px; font-size: 19px; font-weight: 800; letter-spacing: -.4px; font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dv-figs dd.neg { color: var(--danger); }
.dv-figs small { font-size: 11.5px; color: var(--ink-3); }
.dv-figs .dv-click:hover { background: var(--surface-2); }

/* 누적 흐름 */
.dv-trend { width: 100%; height: auto; display: block; }
.dv-trend .grid { stroke: var(--line); stroke-width: 1; }
.dv-trend .budget { stroke: var(--ink-3); stroke-width: 1; stroke-dasharray: 2 3; }
.dv-trend .ax { font-size: 10.5px; fill: var(--ink-3); font-family: inherit; }
.dv-trend .ax.strong { fill: var(--ink-2); font-weight: 600; }
.dv-trend .plan { fill: none; stroke: var(--ink-3); stroke-width: 1.5; stroke-dasharray: 5 4; }
.dv-trend .area { fill: color-mix(in srgb, var(--accent) 14%, transparent); }
.dv-trend .line { fill: none; stroke: var(--accent); stroke-width: 2.4; stroke-linejoin: round; stroke-linecap: round; }
.dv-trend .dot { fill: var(--surface); stroke: var(--accent); stroke-width: 2; }
.dv-trend .mbar { fill: color-mix(in srgb, var(--accent) 38%, transparent); }
.dv-trend .now { stroke: var(--danger); stroke-width: 2; }
.dv-trend .now-t { font-size: 10.5px; font-weight: 700; fill: var(--danger); }

/* 비목 도넛 */
.dv-mix { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 18px; align-items: center; }
.dv-donut { width: 150px; height: 150px; transform: rotate(-90deg); }
.dv-donut text { transform: rotate(90deg); transform-origin: 80px 80px; }
.dv-donut .track { fill: none; stroke: var(--surface-3); stroke-width: 20; }
.dv-donut .seg { fill: none; stroke: var(--cat, var(--accent)); stroke-width: 20; }
.dv-donut .d-k { font-size: 11px; fill: var(--ink-3); font-weight: 600; }
.dv-donut .d-v { font-size: 17px; fill: var(--ink); font-weight: 800; }
.dv-cats { list-style: none; margin: 0; padding: 0; display: grid; gap: 7px; }
.dv-cats li { display: grid; grid-template-columns: 10px minmax(0, 1fr) auto 64px; gap: 8px; align-items: center; font-size: 12.5px;
  padding: 3px 6px; margin: 0 -6px; border-radius: var(--radius-sm); }
.dv-cats li::before { content: ""; width: 10px; height: 10px; border-radius: 3px; background: var(--cat, var(--ink-3)); }
.dv-cats li.row-click:hover { background: var(--surface-2); }
.dv-cats .nm { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dv-cats .pc { font-weight: 700; font-variant-numeric: tabular-nums; }
.dv-cats .rt { height: 5px; border-radius: var(--radius-pill); background: var(--surface-3); overflow: hidden; }
.dv-cats .rt i { display: block; height: 100%; border-radius: inherit; background: var(--cat, var(--accent)); }
.dv-cats .rt.over i { background: var(--danger); }

/* 정산 준비 고리 */
.dv-ready { display: grid; grid-template-columns: 140px minmax(0, 1fr); gap: 18px; align-items: center; }
.dv-ring { width: 140px; height: 140px; }
.dv-ring circle { transform: rotate(-90deg); transform-origin: 70px 70px; }
.dv-ring .track { fill: none; stroke: var(--surface-3); stroke-width: 14; }
.dv-ring .seg { fill: none; stroke-width: 14; }
.dv-ring .seg.ok { stroke: var(--ok); } .dv-ring .seg.info { stroke: var(--line-strong); }
.dv-ring .seg.warn { stroke: var(--warn); } .dv-ring .seg.block { stroke: var(--danger); }
.dv-ring .d-v { font-size: 24px; font-weight: 800; fill: var(--ink); }
.dv-ring .d-k { font-size: 11px; font-weight: 600; fill: var(--ink-3); }
.dv-ready-side > b { display: block; font-size: 15px; margin-bottom: 8px; }
.dv-ready-side > b.danger { color: var(--danger); } .dv-ready-side > b.warn { color: var(--warn); } .dv-ready-side > b.ok { color: var(--ok); }
.dv-keys { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; font-size: 12.5px; color: var(--ink-2); }
.dv-keys b { font-variant-numeric: tabular-nums; margin-left: 4px; color: var(--ink); }
.dv-keys .k { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 6px; }
.dv-keys .k.ok { background: var(--ok); } .dv-keys .k.info { background: var(--line-strong); }
.dv-keys .k.warn { background: var(--warn); } .dv-keys .k.block { background: var(--danger); }
.dv-ring-empty { width: 120px; height: 120px; border-radius: 50%; border: 12px solid var(--surface-3); display: grid; place-items: center;
  font-size: 13px; font-weight: 700; color: var(--ink-3); }

/* 다음 기한 줄 */
.dv-line { list-style: none; margin: 0; padding: 0 0 0 4px; position: relative; }
.dv-line::before { content: ""; position: absolute; left: 9px; top: 10px; bottom: 10px; width: 2px; background: var(--line); }
.dv-line li { position: relative; display: grid; grid-template-columns: 14px 58px minmax(0, 1fr); gap: 10px; align-items: start;
  padding: 7px 8px 7px 0; border-radius: var(--radius-sm); cursor: pointer; }
.dv-line li:hover { background: var(--surface-2); }
.dv-line .pin { width: 12px; height: 12px; margin-top: 3px; border-radius: 50%; background: var(--surface); border: 2px solid var(--accent); z-index: 1; }
.dv-line li.warn .pin { border-color: var(--warn); background: var(--warn-bg); }
.dv-line li.danger .pin { border-color: var(--danger); background: var(--danger); }
.dv-line .dd { font-size: 13px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ink-2); }
.dv-line li.warn .dd { color: var(--warn); } .dv-line li.danger .dd { color: var(--danger); }
.dv-line .tt { font-size: 12.5px; line-height: 1.4; min-width: 0; }
.dv-line .tt small { display: block; font-size: 11px; color: var(--ink-3); }

@media (max-width: 1100px) {
  .dv-hero { grid-template-columns: minmax(0, 1fr); }
  .dv-figs { border-left: 0; border-top: 1px solid var(--line); }
}
@media (max-width: 560px) {
  .dv-mix, .dv-ready { grid-template-columns: minmax(0, 1fr); justify-items: center; }
  .dv-cats, .dv-ready-side { width: 100%; }
  .dv-rate strong { font-size: 32px; }
}
/* 한눈 띠는 두 칸(왼쪽 속도 · 오른쪽 숫자) — 위의 「.dash-viz > .card」(세로 쌓기)보다 앞서야 한다 */
.dash-viz > .card.dv-hero { display: grid; }
@media (max-width: 1100px) { .dash-viz > .card.dv-hero { grid-template-columns: minmax(0, 1fr); } }
/* 나란한 그림 카드는 키를 맞추고, 내용은 가운데로 */
.dash-block.dash-viz { align-self: stretch; }
.dash-viz .dv-mix, .dash-viz .dv-ready { align-content: center; height: 100%; }
.dv-line li:focus-visible, .dv-figs .dv-click:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* 참여가 끝난 사람 — 명단에는 남기되 흐리게(지금 참여율 합에서 뺀다) */
tr.row-ended > td { color: var(--ink-3); }
tr.row-ended > td:first-child { color: var(--ink-2); }

/* 프로그램 동작 기준 — 항목 설명 · 범위 글자 */
.as-note { font-size: 12px; color: var(--ink-3); margin-top: 2px; }
/* 읽기 모드 — 바꾸는 줄은 감춘다(막는 것은 서버) */
body.read-only .as-actions { display: none !important; }
/* 좁은 화면 — 항목 이름을 한 줄 전체로, 값과 범위는 그 아래 한 줄에 */
@media (max-width: 640px) {
  .as-table thead { display: none; }
  .as-table tr { display: grid; grid-template-columns: auto 1fr; gap: 6px 12px; padding: 12px 0;
    border-bottom: 1px solid var(--line); }
  .as-table td { border: 0; padding: 0; }
  .as-table td:first-child { grid-column: 1 / -1; }
  .as-table td.as-note { white-space: normal; align-self: center; }
  .as-actions input[name=reason] { flex: 1 1 100%; }
}
