/* 프레임워크 0. 필요한 만큼만. */
:root {
  --bd:#d8dbe0; --bg:#f6f7f9; --fg:#1d2129; --muted:#6b7280;
  --pri:#1f5fbf; --err:#b42318; --ok:#0f7b46; --row:#fbfcfd;
}
* { box-sizing:border-box; }
body { margin:0; font:14px/1.5 -apple-system,"Apple SD Gothic Neo","Malgun Gothic",sans-serif;
       color:var(--fg); background:var(--bg); }
#top { display:flex; align-items:center; gap:16px; padding:0 16px; height:48px;
       background:#fff; border-bottom:1px solid var(--bd); }
.brand { font-weight:700; text-decoration:none; color:var(--fg); }
#who { margin-left:auto; display:flex; align-items:center; gap:10px; }
#who .me { color:var(--muted); }
#shell { display:flex; min-height:calc(100vh - 48px); }

/* ── 사이드바 ──────────────────────────────────────────────────────────────
   가장 큰 문제는 **지금 어디에 있는지 알 수 없다**는 것이었다. 강조 표시가
   :hover 뿐이라, 마우스를 치우면 현재 화면의 흔적이 사라졌다.
   그래서 .on 을 넣고 색·굵기·왼쪽 막대 **셋으로** 겹쳐 말한다 — 색 하나만
   쓰면 색을 구분 못 하는 사람에게는 표시가 없는 것과 같다.
   (같은 사실을 aria-current="page" 로도 말한다 — screen.js) */
#nav { width:208px; flex:none; background:#fff; border-right:1px solid var(--bd);
       padding:6px 0 16px; }
.navgroup {
  margin:14px 0 2px; padding:6px 14px 5px;
  font-size:11px; font-weight:700; letter-spacing:.06em;
  /* 이전에는 --muted(#6b7280) 12px 였다. 묶음 머리가 항목보다 눈에 덜 띄면
     목록이 한 덩어리로 보인다. 색을 진하게 하고 밑줄로 경계를 만든다. */
  color:#4b5563; border-bottom:1px solid var(--bd);
}
.navgroup:first-child { margin-top:4px; }
.navitem {
  display:block; position:relative; padding:8px 14px 8px 16px;
  color:var(--fg); text-decoration:none; border-left:3px solid transparent;
}
.navitem:hover { background:var(--bg); }
.navitem:focus-visible { outline:2px solid var(--pri); outline-offset:-2px; }
.navitem.on {
  background:#eaf1fb; color:var(--pri); font-weight:700;
  border-left-color:var(--pri);
}
.navitem.on:hover { background:#e1ebfa; }
#app { flex:1; padding:16px 20px; min-width:0; }
.login { max-width:320px; margin:12vh auto; background:#fff; padding:24px;
         border:1px solid var(--bd); border-radius:8px; }
.login h1 { margin:0 0 16px; font-size:20px; }
.login label { display:block; margin-bottom:10px; }
.login label span { display:block; font-size:12px; color:var(--muted); margin-bottom:3px; }
.login input { width:100%; }
input, select, textarea { padding:6px 8px; border:1px solid var(--bd); border-radius:4px;
                          font:inherit; background:#fff; }
input.bad { border-color:var(--err); }
.btn { padding:6px 12px; border:1px solid var(--bd); border-radius:4px; background:#fff;
       cursor:pointer; font:inherit; }
.btn:hover { background:var(--bg); }
.btn.primary { background:var(--pri); border-color:var(--pri); color:#fff; }
.btn.ghost { border:none; background:none; color:var(--muted); }
.btn[disabled] { opacity:.45; cursor:not-allowed; }
.bar { display:flex; flex-wrap:wrap; gap:8px; align-items:flex-end; margin-bottom:10px; }
.fl { display:flex; flex-direction:column; gap:2px; }
.fl span { font-size:12px; color:var(--muted); }
.tools { display:flex; gap:8px; align-items:center; margin-bottom:8px; }
.tools .spacer { flex:1; }
.tools .count { color:var(--muted); }
.tablewrap { overflow-x:auto; background:#fff; border:1px solid var(--bd); border-radius:6px; }
table.dt { border-collapse:collapse; width:100%; }
.dt th, .dt td { padding:7px 10px; border-bottom:1px solid var(--bd); text-align:left;
                 white-space:nowrap; }
.dt th { background:#fafbfc; font-weight:600; font-size:13px; position:sticky; top:0; }
.dt th.sortable { cursor:pointer; user-select:none; }
.dt td.num, .dt th.num { text-align:right; font-variant-numeric:tabular-nums; }
.dt td.ctr, .dt th.ctr { text-align:center; }
.dt tbody tr:hover { background:var(--row); cursor:pointer; }
.dt tfoot td { font-weight:600; background:#fafbfc; }
.empty { padding:28px; text-align:center; color:var(--muted); }
.foot { display:flex; gap:10px; align-items:center; margin-top:10px; }
.muted { color:var(--muted); font-size:12px; }
.form-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr));
             gap:12px; background:#fff; padding:16px; border:1px solid var(--bd);
             border-radius:6px; }
.form-grid .f { display:flex; flex-direction:column; gap:3px; }
.form-grid .f.full { grid-column:1/-1; }
.form-grid .f > span { font-size:12px; color:var(--muted); }
.form-grid .f .req { color:var(--err); font-style:normal; }
.form-grid .hint { color:var(--err); font-size:12px; min-height:1em; }
.formfoot { display:flex; gap:8px; align-items:center; margin-top:12px; }
#banner { padding:0 20px; }
.banner { display:flex; align-items:center; gap:10px; padding:9px 12px; margin-top:8px;
          border-radius:4px; }
.banner.err { background:#fdecea; color:var(--err); border:1px solid #f3c2bd; }
.banner.ok  { background:#e8f5ef; color:var(--ok);  border:1px solid #bfe3d2; }
.banner .x { margin-left:auto; border:none; background:none; cursor:pointer; font-size:16px;
             color:inherit; }
.welcome { padding:40px; color:var(--muted); }

/* ── 전표 편집기 (P3) ─────────────────────────────────────────────────── */
.dochead { display: flex; align-items: baseline; gap: 12px; }
.docstatus { display: flex; gap: 6px; }
.pill { font-size: 12px; padding: 2px 8px; border-radius: 10px;
        background: #eceff3; color: #333; }
.pill.ok { background: #e3f2e6; color: #1b5e20; }
.pill.warn { background: #fdecea; color: #8a1c12; }
.docform { display: flex; flex-wrap: wrap; gap: 12px; margin: 10px 0; }
.docfield { display: flex; flex-direction: column; gap: 3px; font-size: 12px; }
.docfield input { padding: 5px 7px; }
.gridwrap { overflow-x: auto; }
table.grid { border-collapse: collapse; width: 100%; font-size: 13px; }
table.grid th, table.grid td { border: 1px solid #dfe3e8; padding: 2px 4px; }
table.grid th { background: #f5f7f9; font-weight: 600; text-align: left; }
table.grid td.r, table.grid th.r { text-align: right; }
table.grid td.lineno, table.grid th.lineno { width: 34px; text-align: center; color: #888; }
table.grid td.rowdel { width: 30px; text-align: center; }
table.grid input { width: 100%; border: 0; padding: 3px 4px; font: inherit; background: transparent; }
table.grid input:focus { outline: 2px solid #4c8bf5; outline-offset: -2px; }
table.grid input.amt { text-align: right; }
table.grid input.bad { background: #fdecea; }
table.grid input[readonly] { color: #555; background: #fafbfc; }
table.grid tr.opening td { background: #f7f9fb; font-style: italic; }
table.grid tfoot tr.sum td { background: #f5f7f9; font-weight: 600; }
.docfoot { display: flex; align-items: center; justify-content: space-between; margin: 8px 0; }
.doctotals { display: flex; gap: 10px; align-items: baseline; }
.doctotals .lbl { font-size: 11px; color: #888; }
.doctotals .amt { font-variant-numeric: tabular-nums; }
.doctotals .amt.ok { color: #1b5e20; }
.doctotals .amt.warn { color: #8a1c12; }
.docbtns { display: flex; gap: 8px; margin-top: 12px; }
.reportbanner { display: flex; flex-direction: column; gap: 6px; margin: 8px 0; }
.reportbody pre.csv { background: #f7f9fb; padding: 10px; overflow: auto; font-size: 12px; }
.banner.warn { background: #fff6e0; color: #7a4f00; padding: 8px 10px; border-radius: 4px; }

/* ── 코드 입력 칸 + 후보 목록 (P3b) ──────────────────────────────────── */
table.grid td.refcell { display: flex; gap: 6px; align-items: baseline; }
table.grid td.refcell input { flex: 1; min-width: 0; }
/* 칸이 130px 이라 이름에 50px 남짓 남는다. ellipsis 가 없으면 '서울영업1팀' 과
   '서울영업2팀' 이 둘 다 '서울영업' 으로 **같게** 잘리고 잘렸다는 신호도 없다.
   전체 이름은 setName 이 title 속성에 함께 쓴다. */
.refname { color: #666; font-size: 12px; white-space: nowrap; overflow: hidden;
           max-width: 45%; text-overflow: ellipsis; }
.reflist { position: fixed; z-index: 50; background: #fff; border: 1px solid #c8ced6;
           box-shadow: 0 4px 12px rgba(0,0,0,.12); max-height: 260px; overflow-y: auto;
           font-size: 13px; }
.reflist .hit { display: flex; gap: 10px; padding: 3px 8px; cursor: pointer; }
.reflist .hit[aria-selected="true"] { background: #eaf1fe; }
.reflist .hit .c { font-variant-numeric: tabular-nums; min-width: 70px; }
.reflist .more { color: #8a1c12; font-size: 11px; padding: 4px 8px; }
.reflist .note { color: #555; font-size: 11px; padding: 4px 8px; }

/* ── 조건부 필수·조언·파생 예고 (P3D) ────────────────────────────────── */
/* 배너가 이제 여러 문장을 싣는다. flex 한 줄에 갇히면 잘린다. */
.banner { flex-wrap: wrap; }
.banner span { white-space: pre-wrap; }
/* 조건부 필수 **예고** — .bad('지금 틀렸다')와 색으로 구별한다. */
table.grid td.refcell.req input { border-left: 2px solid #b06a00; }
table.grid td.refcell.warn input { background: #fff8e6; }
/* 파생 예고 — '저장하면 바뀐다'. 오류가 아니다. */
table.grid input.derived-stale { border-bottom: 2px dotted #b06a00; }
